@@ -259,6 +259,7 @@ async fn create_wrapper(options: &Options) -> tg::Result<()> {
259
259
interpreter,
260
260
name,
261
261
needed_libraries : initial_needed_libraries,
262
+ entrypoint,
262
263
} = analyze_output_file ( & options. output_path ) . await ?;
263
264
tracing:: debug!( ?is_executable, ?interpreter, ?initial_needed_libraries) ;
264
265
@@ -446,12 +447,15 @@ async fn create_wrapper(options: &Options) -> tg::Result<()> {
446
447
let output_artifact_id = output_file. id ( ) . clone ( ) . into ( ) ;
447
448
448
449
// Create the manifest.
449
- let manifest =
450
+ let mut manifest =
450
451
create_manifest ( output_artifact_id, options, interpreter, library_paths) . await ?;
451
452
tracing:: trace!( ?manifest) ;
452
453
453
454
// If requested, emebd the wrapper.
454
455
let new_wrapper = if options. embed {
456
+ if let Some ( entrypoint) = entrypoint {
457
+ manifest. executable = tangram_std:: manifest:: Executable :: Address ( entrypoint) ;
458
+ }
455
459
manifest. embed ( & tg, & output_file) . await ?
456
460
} else {
457
461
manifest. write ( & tg) . await ?
@@ -736,6 +740,8 @@ struct AnalyzeOutputFileOutput {
736
740
name : Option < String > ,
737
741
/// Does the output file specify libraries required at runtime?
738
742
needed_libraries : Vec < String > ,
743
+ /// The entrypoint of the executable.
744
+ entrypoint : Option < u64 > ,
739
745
}
740
746
741
747
/// The possible interpreter requirements of an output file.
@@ -1262,6 +1268,7 @@ fn analyze_executable(bytes: &[u8]) -> tg::Result<AnalyzeOutputFileOutput> {
1262
1268
interpreter : InterpreterRequirement :: None ,
1263
1269
name : None ,
1264
1270
needed_libraries : vec ! [ ] ,
1271
+ entrypoint : None ,
1265
1272
} ,
1266
1273
1267
1274
// Handle an ELF file.
@@ -1282,12 +1289,14 @@ fn analyze_executable(bytes: &[u8]) -> tg::Result<AnalyzeOutputFileOutput> {
1282
1289
. map ( std:: string:: ToString :: to_string)
1283
1290
. collect_vec ( ) ;
1284
1291
1292
+ let entrypoint = ( elf. entry != 0 ) . then_some ( elf. entry ) ;
1293
+
1285
1294
// Check whether or not the object requires an interpreter:
1286
1295
// - If the object has an interpreter field.
1287
1296
// - If the object is a PIE and has 1 or more NEEDS.
1288
1297
let interpreter =
1289
1298
if elf. interpreter . is_some ( ) || ( is_pie && !needed_libraries. is_empty ( ) ) {
1290
- let interpreter = elf. interpreter . unwrap ( ) ;
1299
+ let interpreter = elf. interpreter . ok_or_else ( || tg :: error! ( "missing interpreter in ELF" ) ) ? ;
1291
1300
if interpreter. starts_with ( "/lib" ) {
1292
1301
if interpreter. contains ( "musl" ) {
1293
1302
InterpreterRequirement :: Default ( InterpreterFlavor :: Musl )
@@ -1307,6 +1316,7 @@ fn analyze_executable(bytes: &[u8]) -> tg::Result<AnalyzeOutputFileOutput> {
1307
1316
interpreter,
1308
1317
name,
1309
1318
needed_libraries,
1319
+ entrypoint,
1310
1320
}
1311
1321
} ,
1312
1322
@@ -1321,12 +1331,13 @@ fn analyze_executable(bytes: &[u8]) -> tg::Result<AnalyzeOutputFileOutput> {
1321
1331
. map ( extract_filename)
1322
1332
. filter ( |file_name| name. as_ref ( ) . is_none_or ( |n| n != file_name) )
1323
1333
. collect_vec ( ) ;
1324
-
1334
+ let entrypoint = mach . entry ;
1325
1335
AnalyzeOutputFileOutput {
1326
1336
is_executable,
1327
1337
interpreter : InterpreterRequirement :: Default ( InterpreterFlavor :: Dyld ) ,
1328
1338
name,
1329
1339
needed_libraries,
1340
+ entrypoint : Some ( entrypoint)
1330
1341
}
1331
1342
} ,
1332
1343
goblin:: mach:: Mach :: Fat ( mach) => {
@@ -1353,6 +1364,7 @@ fn analyze_executable(bytes: &[u8]) -> tg::Result<AnalyzeOutputFileOutput> {
1353
1364
interpreter : InterpreterRequirement :: Default ( InterpreterFlavor :: Dyld ) ,
1354
1365
name,
1355
1366
needed_libraries,
1367
+ entrypoint : None
1356
1368
}
1357
1369
} ,
1358
1370
} ,
0 commit comments