Distinguish direct and indirect dependencies of a binary on Linux?

ldd on Linux will give the list of all shared libraries on which a given binary depends. This is usually much more extensive than the libraries that were listed on the linker command line used to create the binary: it will include most if not all dependencies of those libraries.

Is it possible to determine just the list of libraries that were linked explicitly (i.e. the direct dependencies) and if so, how?

Asked By: RJVB

||

You can use readelf -d to dump the "dynamic" section of the binary. This will include NEEDED libraries.

For example, comparing ldd with readelf on /bin/ls:


$ ldd /bin/ls
        linux-vdso.so.1 =>  (0x00007fff190da000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f082f94e000)
        libcap.so.2 => /lib64/libcap.so.2 (0x00007f082f749000)
        libacl.so.1 => /lib64/libacl.so.1 (0x00007f082f540000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f082f172000)
        libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f082ef10000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f082ed0c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f082fb75000)
        libattr.so.1 => /lib64/libattr.so.1 (0x00007f082eb07000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f082e8eb000)

$ readelf -d /bin/ls | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libselinux.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libcap.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libacl.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

You can also do this on .so files

$ readelf -d /lib64/libpcre.so.1 | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
Answered By: Stephen Harris

If you plan to list direct dependencies recursively, use lddtree from pax-utils:

$ lddtree /bin/file
/bin/file (interpreter => /lib64/ld-linux-x86-64.so.2)
    libmagic.so.1 => /usr/lib/libmagic.so.1
        libzstd.so.1 => /usr/lib/libzstd.so.1
        liblzma.so.5 => /usr/lib/liblzma.so.5
        libbz2.so.1.0 => /usr/lib/libbz2.so.1.0
        libz.so.1 => /usr/lib/libz.so.1
    libseccomp.so.2 => /usr/lib/libseccomp.so.2
    libc.so.6 => /usr/lib/libc.so.6

(This internally uses python-pyelftools.)

Answered By: u1686_grawity
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.