Skip to content

Rust tests/run-make/raw-dylib-elf fails because binary tries to load a wrong shared object #611

@mati865

Description

@mati865

For reproducing the problem, I recommend doing this change:

diff --git a/tests/run-make/raw-dylib-elf/rmake.rs b/tests/run-make/raw-dylib-elf/rmake.rs
index 59f901ac1e..4a28256c3c 100644
--- a/tests/run-make/raw-dylib-elf/rmake.rs
+++ b/tests/run-make/raw-dylib-elf/rmake.rs
@@ -17,6 +17,7 @@
         .crate_type("bin")
         .input("main.rs")
         .arg(&format!("-Wl,-rpath={}", cwd().display()))
+        .arg("-Csave-temps")
         .run();

     // Now, *after* building the binary, we build the library...

It prevents removal of /tmp/rust* that contain the raw-dylib.


Import library created by Rust looks good at the first sight:

❯ readelf -Wa rustc947gHX/raw-dylibs/libf0ila6u5kpn02icz3y0bvel03.so
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          112 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         6
  Section header string table index: 1

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .shstrtab         STRTAB          0000000000000000 000040 00002a 00      0   0  1
  [ 2] .text             PROGBITS        0000000000000000 000000 000000 00      0   0  1
  [ 3] .dynstr           STRTAB          0000000000000000 0001f0 00002a 00   A  0   0  1
  [ 4] .dynsym           DYNSYM          0000000000000000 000220 000030 18   A  3   1  8
  [ 5] .dynamic          DYNAMIC         0000000000000000 000250 000020 10  WA  3   0  8
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), l (large), p (processor specific)

There are no section groups in this file.

There are no program headers in this file.

There is no dynamic section in this file.

There are no relocations in this file.
No processor specific unwind information to decode

Symbol table '.dynsym' contains 2 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    2 this_is_a_library_function

No version information found in this file.

❯ readelf -W -p .dynstr rustc947gHX/raw-dylibs/libf0ila6u5kpn02icz3y0bvel03.so

String dump of section '.dynstr':
  [     1]  liblibrary.so
  [     f]  this_is_a_library_function

But wild adds wrong dependency to DT_NEEDED:

❯ WILD_REFERENCE_LINKER=ld ./run-with ~/Projects/wild/target/release/wild
WARNING: wild: --plugin /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/liblto_plugin.so is not yet supported
ld: warning: type and size of dynamic symbol `this_is_a_library_function' are not defined
wild: ./bin
ref: ./bin.ref-linker
.dynamic.DT_NEEDED
  wild libgcc_s.so.1,libc.so.6,ld-linux-x86-64.so.2,libf0ila6u5kpn02icz3y0bvel03.so
  ref libgcc_s.so.1,libc.so.6,ld-linux-x86-64.so.2,liblibrary.so

libf0ila6u5kpn02icz3y0bvel03.so is the name of the temporary import library created by rustc. Which means somehow there was no soname at this point:

wild/libwild/src/layout.rs

Lines 4442 to 4444 in 3aa8814

if let Some(soname) = dt_info.soname {
self.lib_name = soname;
}

Following this trail, I've noticed program_headers are empty at this point for this import library:
for header in self.program_headers {

Naturally, that's why soname is None.

I haven't investigated deeper, but I should be able to find time for it if nobody else steps up.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions