@@ -9,7 +9,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
99use rustc_hashes:: Hash128 ;
1010use rustc_hir:: attrs:: NativeLibKind ;
1111use rustc_session:: Session ;
12- use rustc_session:: cstore:: DllImport ;
12+ use rustc_session:: cstore:: { DllImport , DllImportSymbolType } ;
1313use rustc_span:: Symbol ;
1414use rustc_target:: spec:: Arch ;
1515
@@ -95,14 +95,14 @@ pub(super) fn create_raw_dylib_dll_import_libs<'a>(
9595 true ,
9696 )
9797 } ) ,
98- is_data : ! import. is_fn ,
98+ is_data : import. symbol_type != DllImportSymbolType :: Function ,
9999 }
100100 } else {
101101 ImportLibraryItem {
102102 name : import. name . to_string ( ) ,
103103 ordinal : import. ordinal ( ) ,
104104 symbol_name : None ,
105- is_data : ! import. is_fn ,
105+ is_data : import. symbol_type != DllImportSymbolType :: Function ,
106106 }
107107 }
108108 } )
@@ -271,10 +271,10 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
271271 vers. push ( ( version_name, dynstr) ) ;
272272 id
273273 } ;
274- syms. push ( ( name, dynstr, Some ( ver) , symbol. is_fn ) ) ;
274+ syms. push ( ( name, dynstr, Some ( ver) , symbol. symbol_type , symbol . size ) ) ;
275275 } else {
276276 let dynstr = stub. add_dynamic_string ( symbol_name. as_bytes ( ) ) ;
277- syms. push ( ( symbol_name, dynstr, None , symbol. is_fn ) ) ;
277+ syms. push ( ( symbol_name, dynstr, None , symbol. symbol_type , symbol . size ) ) ;
278278 }
279279 }
280280
@@ -296,6 +296,8 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
296296 stub. reserve_shstrtab_section_index ( ) ;
297297 let text_section_name = stub. add_section_name ( ".text" . as_bytes ( ) ) ;
298298 let text_section = stub. reserve_section_index ( ) ;
299+ let data_section_name = stub. add_section_name ( ".data" . as_bytes ( ) ) ;
300+ let data_section = stub. reserve_section_index ( ) ;
299301 stub. reserve_dynsym_section_index ( ) ;
300302 stub. reserve_dynstr_section_index ( ) ;
301303 if !vers. is_empty ( ) {
@@ -375,7 +377,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
375377 // Section headers
376378 stub. write_null_section_header ( ) ;
377379 stub. write_shstrtab_section_header ( ) ;
378- // Create a dummy .text section for our dummy symbols.
380+ // Create a dummy .text section for our dummy non-data symbols.
379381 stub. write_section_header ( & write:: SectionHeader {
380382 name : Some ( text_section_name) ,
381383 sh_type : elf:: SHT_PROGBITS ,
@@ -385,7 +387,20 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
385387 sh_size : 0 ,
386388 sh_link : 0 ,
387389 sh_info : 0 ,
388- sh_addralign : 1 ,
390+ sh_addralign : 16 ,
391+ sh_entsize : 0 ,
392+ } ) ;
393+ // And also a dummy .data section for our dummy data symbols.
394+ stub. write_section_header ( & write:: SectionHeader {
395+ name : Some ( data_section_name) ,
396+ sh_type : elf:: SHT_PROGBITS ,
397+ sh_flags : ( elf:: SHF_WRITE | elf:: SHF_ALLOC ) as u64 ,
398+ sh_addr : 0 ,
399+ sh_offset : 0 ,
400+ sh_size : 0 ,
401+ sh_link : 0 ,
402+ sh_info : 0 ,
403+ sh_addralign : 16 ,
389404 sh_entsize : 0 ,
390405 } ) ;
391406 stub. write_dynsym_section_header ( 0 , 1 ) ;
@@ -398,17 +413,28 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
398413
399414 // .dynsym
400415 stub. write_null_dynamic_symbol ( ) ;
401- for ( _name, dynstr, _ver, is_fn) in syms. iter ( ) . copied ( ) {
402- let sym_type = if is_fn { elf:: STT_FUNC } else { elf:: STT_NOTYPE } ;
416+ // Linkers like LLD require at least somewhat reasonable symbol values rather than zero,
417+ // otherwise all the symbols might get put at the same address. Thus we increment the value
418+ // every time we write a symbol.
419+ let mut st_value = 0 ;
420+ for ( _name, dynstr, _ver, symbol_type, size) in syms. iter ( ) . copied ( ) {
421+ let sym_type = match symbol_type {
422+ DllImportSymbolType :: Function => elf:: STT_FUNC ,
423+ DllImportSymbolType :: Static => elf:: STT_OBJECT ,
424+ DllImportSymbolType :: ThreadLocal => elf:: STT_TLS ,
425+ } ;
426+ let section =
427+ if symbol_type == DllImportSymbolType :: Static { data_section } else { text_section } ;
403428 stub. write_dynamic_symbol ( & write:: Sym {
404429 name : Some ( dynstr) ,
405430 st_info : ( elf:: STB_GLOBAL << 4 ) | sym_type,
406431 st_other : elf:: STV_DEFAULT ,
407- section : Some ( text_section ) ,
432+ section : Some ( section ) ,
408433 st_shndx : 0 , // ignored by object in favor of the `section` field
409- st_value : 0 ,
410- st_size : 0 ,
434+ st_value,
435+ st_size : size . bytes ( ) ,
411436 } ) ;
437+ st_value += 8 ;
412438 }
413439
414440 // .dynstr
@@ -418,7 +444,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
418444 if !vers. is_empty ( ) {
419445 // .gnu_version
420446 stub. write_null_gnu_versym ( ) ;
421- for ( _name, _dynstr, ver, _is_fn ) in syms. iter ( ) . copied ( ) {
447+ for ( _name, _dynstr, ver, _symbol_type , _size ) in syms. iter ( ) . copied ( ) {
422448 stub. write_gnu_versym ( if let Some ( ver) = ver {
423449 assert ! ( ( 2 + ver as u16 ) < elf:: VERSYM_HIDDEN ) ;
424450 elf:: VERSYM_HIDDEN | ( 2 + ver as u16 )
0 commit comments