@@ -307,11 +307,14 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
307307 stub. reserve_section_headers ( ) ;
308308 stub. reserve_dynsym ( ) ;
309309 stub. reserve_dynstr ( ) ;
310+ let verdef_count = 1 + vers. len ( ) ;
311+ let mut dynamic_entries = 2 ; // DT_SONAME, DT_NULL
310312 if !vers. is_empty ( ) {
311313 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
313316 }
314- stub. reserve_dynamic ( 2 ) ; // DT_SONAME, DT_NULL
317+ stub. reserve_dynamic ( dynamic_entries ) ;
315318
316319 // First write the ELF header with the arch information.
317320 let e_machine = match ( arch, sub_arch) {
@@ -443,9 +446,13 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
443446 // .dynamic
444447 // the DT_SONAME will be used by the linker to populate DT_NEEDED
445448 // which the loader uses to find the library.
446- // DT_NULL terminates the .dynamic table.
447449 stub. write_align_dynamic ( ) ;
448450 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.
449456 stub. write_dynamic ( elf:: DT_NULL , 0 ) ;
450457
451458 stub_buf
0 commit comments