Closed
Description
Describe the bug
I cannot --add-needed
and --replace-needed
on the same invocation.
It produces a binary with incorrect DT_NEEDED
and gnu.version_r
sections.
Steps To Reproduce
❯ cp /usr/bin/ruby /tmp/ruby
❯ ./src/patchelf --print-needed /tmp/ruby
libruby-2.7.so.2.7
libc.so.6
❯ ./src/patchelf --replace-needed libruby-2.7.so.2.7 /lib/x86_64-linux-gnu/libruby-2.7.so.2.7 \
--replace-needed libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 \
--add-needed /lib/x86_64-linux-gnu/libcrypt.so.1 \
--add-needed /lib/x86_64-linux-gnu/libdl.so.2 \
--add-needed /lib/x86_64-linux-gnu/libgmp.so.10 \
--add-needed /lib/x86_64-linux-gnu/libm.so.6 \
--add-needed /lib/x86_64-linux-gnu/libpthread.so.0 \
--add-needed /lib/x86_64-linux-gnu/librt.so.1 /tmp/ruby
❯ ./src/patchelf --print-needed /tmp/ruby
/lib/x86_64-linux-gnu/libcrypt.so.1
/lib/x86_64-linux-gnu/libdl.so.2
/lib/x86_64-linux-gnu/libgmp.so.10
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libpthread.so.0
/lib/x86_64-linux-gnu/librt.so.1
/lib/x86_64-linux-gnu/libcrypt.so.1
x86_64-linux-gnu/libdl.so.2
Please see that there are multiple copies of libcrypt.so.1
and libdl.so.2
, the last one is not even a full path.
The .gnu.version_r
also looks incorrect. It is now x86_64-linux-gnu/libdl.so.2
instead of glibc
.
❯ readelf -a /tmp/ruby | grep -A 5 gnu.version_r
[ 3] .gnu.version_r VERNEED 00000000000006e0 000006e0
0000000000000030 0000000000000000 A 22 1 8
[ 4] .rela.dyn RELA 0000000000000710 00000710
00000000000000c0 0000000000000018 A 1 0 8
[ 5] .rela.plt RELA 00000000000007d0 000007d0
00000000000000a8 0000000000000018 AI 1 16 8
--
01 .dynsym .gnu.version .gnu.version_r .rela.dyn .rela.plt
02
03 .init .plt .plt.got .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .eh_frame_hdr
06 .init_array .fini_array .got .data .bss
--
Version needs section '.gnu.version_r' contains 1 entry:
Addr: 0x00000000000006e0 Offset: 0x0006e0 Link: 22 (.dynstr)
000000: Version: 1 File: x86_64-linux-gnu/libdl.so.2 Cnt: 2
0x0010: Name: GLIBC_2.4 Flags: none Version: 3
0x0020: Name: GLIBC_2.2.5 Flags: none Version: 2
Expected behavior
I expect the --print-needed
to reflect what was passed in.
patchelf --version
output
❯ ./src/patchelf --version
patchelf 0.14.3
Additional context
I discovered this also when trying to do the same in patchelf itself via #357