@@ -307,11 +307,14 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
307
307
stub. reserve_section_headers ( ) ;
308
308
stub. reserve_dynsym ( ) ;
309
309
stub. reserve_dynstr ( ) ;
310
+ let verdef_count = 1 + vers. len ( ) ;
311
+ let mut dynamic_entries = 2 ; // DT_SONAME, DT_NULL
310
312
if !vers. is_empty ( ) {
311
313
stub. reserve_gnu_versym ( ) ;
312
- stub. reserve_gnu_verdef ( 1 + vers. len ( ) , 1 + vers. len ( ) ) ;
314
+ stub. reserve_gnu_verdef ( verdef_count, verdef_count) ;
315
+ dynamic_entries += 1 ; // DT_VERDEFNUM
313
316
}
314
- stub. reserve_dynamic ( 2 ) ; // DT_SONAME, DT_NULL
317
+ stub. reserve_dynamic ( dynamic_entries ) ;
315
318
316
319
// First write the ELF header with the arch information.
317
320
let e_machine = match ( arch, sub_arch) {
@@ -443,9 +446,13 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
443
446
// .dynamic
444
447
// the DT_SONAME will be used by the linker to populate DT_NEEDED
445
448
// which the loader uses to find the library.
446
- // DT_NULL terminates the .dynamic table.
447
449
stub. write_align_dynamic ( ) ;
448
450
stub. write_dynamic_string ( elf:: DT_SONAME , soname) ;
451
+ // LSB section "2.7. Symbol Versioning" requires `DT_VERDEFNUM` to be reliable.
452
+ if verdef_count > 1 {
453
+ stub. write_dynamic ( elf:: DT_VERDEFNUM , verdef_count as u64 ) ;
454
+ }
455
+ // DT_NULL terminates the .dynamic table.
449
456
stub. write_dynamic ( elf:: DT_NULL , 0 ) ;
450
457
451
458
stub_buf
0 commit comments