I know two ways to find dependencies,
ldd app.out
which returns this for a simple app:
linux-vdso.so.1 (0x00007ffff93f5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f02383a0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0238800000)
and readelf -d app.out | grep NEEDED
which returns:
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
I want to understand why is output difference, libc.so
is in both cases, /lib64/ld-linux-x86-64.so.2
is interpreter and makes sense to be in the first one, but about about linux-vdso.so.1
? and which one is more accurate?
readelf -d
shows what the app wants, ldd
shows what the linker wants.
They're different because:
ldd
shows the transitive closure of dependencies (i.e. recursively), while readelf
only shows the immediate dependenciesldd
shows the loader, which readelf
considers seperate from a dynamic dependencyldd
shows virtual libraries, which are a system implementation detail that the app doesn't care aboutThis means that which is more accurate is up to you and your use case.
If you are creating a VM image and need to copy all dependencies, you would use ldd
because it determines what the current system needs to run the app. If you are writing a compatibility layer like wine
, you would use readelf
because it determines what the app needs from the host system.