If you are running Portage≥2.2 with FEATURES=preserve-libs
, you should rarely ever need revdep-rebuild
anymore as old .so.
vers will be preserved as needed (though you still need to rebuild carefully, as stuff still goes kaboom when libA.so.0
wants libC.so.0
and libB.so.0
wants libC.so.1
and some binary wants both libA.so.0
and libB.so.0
).
That being said, what ldd
does is to get the dynamic linker to do load the executable or library as it usually would, but print out some info along the way. This is a recursive "binary needs library needs other library&hellip" search, because that's what the dynamic linker does.
I'm currently running Linux/ppc32; on Linux/x86, the dynamic linker is usually /lib/ld-linux.so.2
, and on Linux/x86_64, the dynamic linker is usually /lib/ld-linux-x86-64.so.2
. Here, I call it directly just to hammer in the point that all ldd
is nothing more than a shell script that calls upon the dynamic linker to perform its magic.
$ /lib/ld.so.1 /sbin/badblocks
Usage: /sbin/badblocks [-b block_size] [-i input_file] [-o output_file] [-svwnf]
[-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks]
[-p num_passes] [-t test_pattern [-t test_pattern [...]]]
device [last_block [first_block]]
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /sbin/badblocks
linux-vdso32.so.1 => (0x00100000)
libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000)
libc.so.6 => /lib/libc.so.6 (0x0fdfa000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000)
/lib/ld.so.1 (0x48000000)
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /lib/libcom_err.so.2
linux-vdso32.so.1 => (0x00100000)
libpthread.so.0 => /lib/libpthread.so.0 (0x6ffa2000)
libc.so.6 => /lib/libc.so.6 (0x6fe18000)
/lib/ld.so.1 (0x203ba000)
$ grep -l pthread /sbin/badblocks /lib/libcom_err.so.2
/lib/libcom_err.so.2
/sbin/badblocks
doesn't list libpthread.so.0
as a library dependency, but it gets pulled in by libcom_err.so.2
.
Is your problem that ldd
doesn't output a nice-looking dependency tree? Use ldd -v
.
$ LD_TRACE_LOADED_OBJECTS=1 LD_VERBOSE=1 /lib/ld.so.1 /sbin/badblocks
linux-vdso32.so.1 => (0x00100000)
libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000)
libc.so.6 => /lib/libc.so.6 (0x0fdfa000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000)
/lib/ld.so.1 (0x201f9000)
Version information:
/sbin/badblocks:
libc.so.6 (GLIBC_2.2) => /lib/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6
/lib/libext2fs.so.2:
libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.3) => /lib/libc.so.6
libc.so.6 (GLIBC_2.2) => /lib/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
/lib/libcom_err.so.2:
ld.so.1 (GLIBC_2.3) => /lib/ld.so.1
libpthread.so.0 (GLIBC_2.1) => /lib/libpthread.so.0
libpthread.so.0 (GLIBC_2.0) => /lib/libpthread.so.0
libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
/lib/libc.so.6:
ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1
ld.so.1 (GLIBC_2.3) => /lib/ld.so.1
/lib/libpthread.so.0:
ld.so.1 (GLIBC_2.3) => /lib/ld.so.1
ld.so.1 (GLIBC_2.1) => /lib/ld.so.1
ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1
libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
libc.so.6 (GLIBC_2.3.2) => /lib/libc.so.6
libc.so.6 (GLIBC_2.2) => /lib/libc.so.6
libc.so.6 (GLIBC_PRIVATE) => /lib/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
If you want, you can read the ELF headers directly instead of depending on the dynamic linker.
$ readelf -d /sbin/badblocks | grep NEEDED
0x00000001 (NEEDED) Shared library: [libext2fs.so.2]
0x00000001 (NEEDED) Shared library: [libcom_err.so.2]
0x00000001 (NEEDED) Shared library: [libc.so.6]
$ readelf -d /lib/libcom_err.so.2 | grep NEEDED
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x00000001 (NEEDED) Shared library: [ld.so.1]
You can also man ld.so
for other cute tricks you can play with glibc
's dynamic linker.
ldd -v
output shows only libraries with versioned symbols – Steffen