Search code examples
linuxprocesslinux-kernelelfldd

Get accurate ELF dependencies


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?


Solution

  • 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 dependencies
    • ldd shows the loader, which readelf considers seperate from a dynamic dependency
    • ldd shows virtual libraries, which are a system implementation detail that the app doesn't care about

    This 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.