@@ -14,24 +14,21 @@ use rustc_session::utils::NativeLibKind;
14
14
/// need out of the shared crate context before we get rid of it.
15
15
use rustc_session:: { filesearch, Session } ;
16
16
use rustc_span:: symbol:: Symbol ;
17
- use rustc_target:: abi:: Endian ;
18
17
use rustc_target:: spec:: crt_objects:: { CrtObjects , CrtObjectsFallback } ;
19
18
use rustc_target:: spec:: { LinkOutputKind , LinkerFlavor , LldFlavor , SplitDebuginfo } ;
20
19
use rustc_target:: spec:: { PanicStrategy , RelocModel , RelroLevel , SanitizerSet , Target } ;
21
20
22
21
use super :: archive:: { find_library, ArchiveBuilder } ;
23
22
use super :: command:: Command ;
24
23
use super :: linker:: { self , Linker } ;
24
+ use super :: metadata:: create_rmeta_file;
25
25
use super :: rpath:: { self , RPathConfig } ;
26
26
use crate :: {
27
27
looks_like_rust_object_file, CodegenResults , CompiledModule , CrateInfo , NativeLib ,
28
28
METADATA_FILENAME ,
29
29
} ;
30
30
31
31
use cc:: windows_registry;
32
- use object:: elf;
33
- use object:: write:: Object ;
34
- use object:: { Architecture , BinaryFormat , Endianness , FileFlags , SectionFlags , SectionKind } ;
35
32
use regex:: Regex ;
36
33
use tempfile:: Builder as TempFileBuilder ;
37
34
@@ -339,7 +336,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
339
336
// metadata in rlib files is wrapped in a "dummy" object file for
340
337
// the target platform so the rlib can be processed entirely by
341
338
// normal linkers for the platform.
342
- let metadata = create_metadata_file ( sess, codegen_results. metadata . raw_data ( ) ) ;
339
+ let metadata = create_rmeta_file ( sess, codegen_results. metadata . raw_data ( ) ) ;
343
340
ab. add_file ( & emit_metadata ( sess, & metadata, tmpdir) ) ;
344
341
345
342
// After adding all files to the archive, we need to update the
@@ -358,136 +355,6 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
358
355
}
359
356
}
360
357
return Ok ( ab) ;
361
-
362
- // For rlibs we "pack" rustc metadata into a dummy object file. When rustc
363
- // creates a dylib crate type it will pass `--whole-archive` (or the
364
- // platform equivalent) to include all object files from an rlib into the
365
- // final dylib itself. This causes linkers to iterate and try to include all
366
- // files located in an archive, so if metadata is stored in an archive then
367
- // it needs to be of a form that the linker will be able to process.
368
- //
369
- // Note, though, that we don't actually want this metadata to show up in any
370
- // final output of the compiler. Instead this is purely for rustc's own
371
- // metadata tracking purposes.
372
- //
373
- // With the above in mind, each "flavor" of object format gets special
374
- // handling here depending on the target:
375
- //
376
- // * MachO - macos-like targets will insert the metadata into a section that
377
- // is sort of fake dwarf debug info. Inspecting the source of the macos
378
- // linker this causes these sections to be skipped automatically because
379
- // it's not in an allowlist of otherwise well known dwarf section names to
380
- // go into the final artifact.
381
- //
382
- // * WebAssembly - we actually don't have any container format for this
383
- // target. WebAssembly doesn't support the `dylib` crate type anyway so
384
- // there's no need for us to support this at this time. Consequently the
385
- // metadata bytes are simply stored as-is into an rlib.
386
- //
387
- // * COFF - Windows-like targets create an object with a section that has
388
- // the `IMAGE_SCN_LNK_REMOVE` flag set which ensures that if the linker
389
- // ever sees the section it doesn't process it and it's removed.
390
- //
391
- // * ELF - All other targets are similar to Windows in that there's a
392
- // `SHF_EXCLUDE` flag we can set on sections in an object file to get
393
- // automatically removed from the final output.
394
- //
395
- // Note that this metdata format is kept in sync with
396
- // `rustc_codegen_ssa/src/back/metadata.rs`.
397
- fn create_metadata_file ( sess : & Session , metadata : & [ u8 ] ) -> Vec < u8 > {
398
- let endianness = match sess. target . options . endian {
399
- Endian :: Little => Endianness :: Little ,
400
- Endian :: Big => Endianness :: Big ,
401
- } ;
402
- let architecture = match & sess. target . arch [ ..] {
403
- "arm" => Architecture :: Arm ,
404
- "aarch64" => Architecture :: Aarch64 ,
405
- "x86" => Architecture :: I386 ,
406
- "s390x" => Architecture :: S390x ,
407
- "mips" => Architecture :: Mips ,
408
- "mips64" => Architecture :: Mips64 ,
409
- "x86_64" => {
410
- if sess. target . pointer_width == 32 {
411
- Architecture :: X86_64_X32
412
- } else {
413
- Architecture :: X86_64
414
- }
415
- }
416
- "powerpc" => Architecture :: PowerPc ,
417
- "powerpc64" => Architecture :: PowerPc64 ,
418
- "riscv32" => Architecture :: Riscv32 ,
419
- "riscv64" => Architecture :: Riscv64 ,
420
- "sparc64" => Architecture :: Sparc64 ,
421
-
422
- // This is used to handle all "other" targets. This includes targets
423
- // in two categories:
424
- //
425
- // * Some targets don't have support in the `object` crate just yet
426
- // to write an object file. These targets are likely to get filled
427
- // out over time.
428
- //
429
- // * Targets like WebAssembly don't support dylibs, so the purpose
430
- // of putting metadata in object files, to support linking rlibs
431
- // into dylibs, is moot.
432
- //
433
- // In both of these cases it means that linking into dylibs will
434
- // not be supported by rustc. This doesn't matter for targets like
435
- // WebAssembly and for targets not supported by the `object` crate
436
- // yet it means that work will need to be done in the `object` crate
437
- // to add a case above.
438
- _ => return metadata. to_vec ( ) ,
439
- } ;
440
-
441
- if sess. target . is_like_osx {
442
- let mut file = Object :: new ( BinaryFormat :: MachO , architecture, endianness) ;
443
-
444
- let section =
445
- file. add_section ( b"__DWARF" . to_vec ( ) , b".rmeta" . to_vec ( ) , SectionKind :: Debug ) ;
446
- file. append_section_data ( section, metadata, 1 ) ;
447
- file. write ( ) . unwrap ( )
448
- } else if sess. target . is_like_windows {
449
- const IMAGE_SCN_LNK_REMOVE : u32 = 0 ;
450
- let mut file = Object :: new ( BinaryFormat :: Coff , architecture, endianness) ;
451
-
452
- let section = file. add_section ( Vec :: new ( ) , b".rmeta" . to_vec ( ) , SectionKind :: Debug ) ;
453
- file. section_mut ( section) . flags =
454
- SectionFlags :: Coff { characteristics : IMAGE_SCN_LNK_REMOVE } ;
455
- file. append_section_data ( section, metadata, 1 ) ;
456
- file. write ( ) . unwrap ( )
457
- } else {
458
- const SHF_EXCLUDE : u64 = 0x80000000 ;
459
- let mut file = Object :: new ( BinaryFormat :: Elf , architecture, endianness) ;
460
-
461
- match & sess. target . arch [ ..] {
462
- // copied from `mipsel-linux-gnu-gcc foo.c -c` and
463
- // inspecting the resulting `e_flags` field.
464
- "mips" => {
465
- let e_flags = elf:: EF_MIPS_ARCH_32R2 | elf:: EF_MIPS_CPIC | elf:: EF_MIPS_PIC ;
466
- file. flags = FileFlags :: Elf { e_flags } ;
467
- }
468
- // copied from `mips64el-linux-gnuabi64-gcc foo.c -c`
469
- "mips64" => {
470
- let e_flags = elf:: EF_MIPS_ARCH_64R2 | elf:: EF_MIPS_CPIC | elf:: EF_MIPS_PIC ;
471
- file. flags = FileFlags :: Elf { e_flags } ;
472
- }
473
-
474
- // copied from `riscv64-linux-gnu-gcc foo.c -c`, note though
475
- // that the `+d` target feature represents whether the double
476
- // float abi is enabled.
477
- "riscv64" if sess. target . options . features . contains ( "+d" ) => {
478
- let e_flags = elf:: EF_RISCV_RVC | elf:: EF_RISCV_FLOAT_ABI_DOUBLE ;
479
- file. flags = FileFlags :: Elf { e_flags } ;
480
- }
481
-
482
- _ => { }
483
- }
484
-
485
- let section = file. add_section ( Vec :: new ( ) , b".rmeta" . to_vec ( ) , SectionKind :: Debug ) ;
486
- file. section_mut ( section) . flags = SectionFlags :: Elf { sh_flags : SHF_EXCLUDE } ;
487
- file. append_section_data ( section, metadata, 1 ) ;
488
- file. write ( ) . unwrap ( )
489
- }
490
- }
491
358
}
492
359
493
360
/// Extract all symbols defined in raw-dylib libraries, collated by library name.
0 commit comments