1
1
//! Reading of the rustc metadata for rlibs and dylibs
2
2
3
+ use std:: borrow:: Cow ;
3
4
use std:: fs:: File ;
4
5
use std:: io:: Write ;
5
6
use std:: path:: Path ;
@@ -15,7 +16,6 @@ use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice};
15
16
use rustc_metadata:: creader:: MetadataLoader ;
16
17
use rustc_metadata:: fs:: METADATA_FILENAME ;
17
18
use rustc_metadata:: EncodedMetadata ;
18
- use rustc_serialize:: leb128;
19
19
use rustc_session:: Session ;
20
20
use rustc_span:: sym;
21
21
use rustc_target:: abi:: Endian ;
@@ -434,12 +434,15 @@ pub enum MetadataPosition {
434
434
/// automatically removed from the final output.
435
435
pub fn create_wrapper_file (
436
436
sess : & Session ,
437
- section_name : Vec < u8 > ,
437
+ section_name : String ,
438
438
data : & [ u8 ] ,
439
439
) -> ( Vec < u8 > , MetadataPosition ) {
440
440
let Some ( mut file) = create_object_file ( sess) else {
441
441
if sess. target . is_like_wasm {
442
- return ( create_metadata_file_for_wasm ( data, & section_name) , MetadataPosition :: First ) ;
442
+ return (
443
+ create_metadata_file_for_wasm ( sess, data, & section_name) ,
444
+ MetadataPosition :: First ,
445
+ ) ;
443
446
}
444
447
445
448
// Targets using this branch don't have support implemented here yet or
@@ -452,7 +455,7 @@ pub fn create_wrapper_file(
452
455
} else {
453
456
file. add_section (
454
457
file. segment_name ( StandardSegment :: Debug ) . to_vec ( ) ,
455
- section_name,
458
+ section_name. into_bytes ( ) ,
456
459
SectionKind :: Debug ,
457
460
)
458
461
} ;
@@ -524,7 +527,7 @@ pub fn create_compressed_metadata_file(
524
527
525
528
let Some ( mut file) = create_object_file ( sess) else {
526
529
if sess. target . is_like_wasm {
527
- return create_metadata_file_for_wasm ( & packed_metadata, b ".rustc") ;
530
+ return create_metadata_file_for_wasm ( sess , & packed_metadata, ".rustc" ) ;
528
531
}
529
532
return packed_metadata. to_vec ( ) ;
530
533
} ;
@@ -624,51 +627,41 @@ pub fn create_compressed_metadata_file_for_xcoff(
624
627
/// `data`.
625
628
///
626
629
/// NB: the `object` crate does not yet have support for writing the the wasm
627
- /// object file format. The format is simple enough that for now an extra crate
628
- /// from crates.io (such as ` wasm-encoder`). The file format is:
630
+ /// object file format. In lieu of that the `wasm-encoder` crate is used to
631
+ /// build a wasm file by hand.
629
632
///
630
- /// * 4-byte header "\0asm"
631
- /// * 4-byte version number - 1u32 in little-endian format
632
- /// * concatenated sections, which for this object is always "custom sections"
633
- ///
634
- /// Custom sections are then defined by:
635
- /// * 1-byte section identifier - 0 for a custom section
636
- /// * leb-encoded section length (size of the contents beneath this bullet)
637
- /// * leb-encoded custom section name length
638
- /// * custom section name
639
- /// * section contents
640
- ///
641
- /// One custom section, `linking`, is added here in accordance with
633
+ /// The wasm object file format is defined at
642
634
/// <https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md>
643
- /// which is required to inform LLD that this is an object file but it should
644
- /// otherwise basically ignore it if it otherwise looks at it. The linking
645
- /// section currently is defined by a single version byte (2) and then further
646
- /// sections, but we have no more sections, so it's just the byte "2".
635
+ /// and mainly consists of a `linking` custom section. In this case the custom
636
+ /// section there is empty except for a version marker indicating what format
637
+ /// it's in.
647
638
///
648
- /// The next custom section is the one we're interested in.
649
- pub fn create_metadata_file_for_wasm ( data : & [ u8 ] , section_name : & [ u8 ] ) -> Vec < u8 > {
650
- let mut bytes = b"\0 asm\x01 \0 \0 \0 " . to_vec ( ) ;
651
-
652
- let mut append_custom_section = |section_name : & [ u8 ] , data : & [ u8 ] | {
653
- let mut section_name_len = [ 0 ; leb128:: max_leb128_len :: < usize > ( ) ] ;
654
- let off = leb128:: write_usize_leb128 ( & mut section_name_len, section_name. len ( ) ) ;
655
- let section_name_len = & section_name_len[ ..off] ;
656
-
657
- let mut section_len = [ 0 ; leb128:: max_leb128_len :: < usize > ( ) ] ;
658
- let off = leb128:: write_usize_leb128 (
659
- & mut section_len,
660
- data. len ( ) + section_name_len. len ( ) + section_name. len ( ) ,
639
+ /// The main purpose of this is to contain a custom section with `section_name`,
640
+ /// which is then appended after `linking`.
641
+ ///
642
+ /// As a further detail the object needs to have a 64-bit memory if `wasm64` is
643
+ /// the target or otherwise it's interpreted as a 32-bit object which is
644
+ /// incompatible with 64-bit ones.
645
+ pub fn create_metadata_file_for_wasm ( sess : & Session , data : & [ u8 ] , section_name : & str ) -> Vec < u8 > {
646
+ assert ! ( sess. target. is_like_wasm) ;
647
+ let mut module = wasm_encoder:: Module :: new ( ) ;
648
+ let mut imports = wasm_encoder:: ImportSection :: new ( ) ;
649
+
650
+ if sess. target . pointer_width == 64 {
651
+ imports. import (
652
+ "env" ,
653
+ "__linear_memory" ,
654
+ wasm_encoder:: MemoryType { minimum : 0 , maximum : None , memory64 : true , shared : false } ,
661
655
) ;
662
- let section_len = & section_len[ ..off] ;
663
-
664
- bytes. push ( 0u8 ) ;
665
- bytes. extend_from_slice ( section_len) ;
666
- bytes. extend_from_slice ( section_name_len) ;
667
- bytes. extend_from_slice ( section_name) ;
668
- bytes. extend_from_slice ( data) ;
669
- } ;
656
+ }
670
657
671
- append_custom_section ( b"linking" , & [ 2 ] ) ;
672
- append_custom_section ( section_name, data) ;
673
- bytes
658
+ if imports. len ( ) > 0 {
659
+ module. section ( & imports) ;
660
+ }
661
+ module. section ( & wasm_encoder:: CustomSection {
662
+ name : "linking" . into ( ) ,
663
+ data : Cow :: Borrowed ( & [ 2 ] ) ,
664
+ } ) ;
665
+ module. section ( & wasm_encoder:: CustomSection { name : section_name. into ( ) , data : data. into ( ) } ) ;
666
+ module. finish ( )
674
667
}
0 commit comments