Search code examples
dynamic-linkingobjdumpldd

API for ldd (or objdump)?


I need to programmatically inspect the library dependencies of a given executable. Is there a better way than running the ldd (or objdump) commands and parsing their output? Is there an API available which gives the same results as ldd ?


Solution

  • I need to programmatically inspect the library dependencies of a given executable.

    I am going to assume that you are using an ELF system (probably Linux).

    Dynamic library dependencies of an executable or a shared library are encoded as a table on Elf{32_,64}_Dyn entries in the PT_DYNAMIC segment of the library or executable. The ldd (indirectly, but that's an implementation detail) interprets these entries and then uses various details of system configuration and/or LD_LIBRARY_PATH environment variable to locate the needed libraries.

    You can print the contents of PT_DYNAMIC with readelf -d a.out. For example:

    $ readelf -d /bin/date
    
    Dynamic section at offset 0x19df8 contains 26 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
     0x000000000000000c (INIT)               0x3000
     0x000000000000000d (FINI)               0x12780
     0x0000000000000019 (INIT_ARRAY)         0x1a250
     0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
     0x000000000000001a (FINI_ARRAY)         0x1a258
     0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
     0x000000006ffffef5 (GNU_HASH)           0x308
     0x0000000000000005 (STRTAB)             0xb38
     0x0000000000000006 (SYMTAB)             0x358
     0x000000000000000a (STRSZ)              946 (bytes)
     0x000000000000000b (SYMENT)             24 (bytes)
     0x0000000000000015 (DEBUG)              0x0
     0x0000000000000003 (PLTGOT)             0x1b000
     0x0000000000000002 (PLTRELSZ)           1656 (bytes)
     0x0000000000000014 (PLTREL)             RELA
     0x0000000000000017 (JMPREL)             0x2118
     0x0000000000000007 (RELA)               0x1008
     0x0000000000000008 (RELASZ)             4368 (bytes)
     0x0000000000000009 (RELAENT)            24 (bytes)
     0x000000006ffffffb (FLAGS_1)            Flags: PIE
     0x000000006ffffffe (VERNEED)            0xf98
     0x000000006fffffff (VERNEEDNUM)         1
     0x000000006ffffff0 (VERSYM)             0xeea
     0x000000006ffffff9 (RELACOUNT)          170
     0x0000000000000000 (NULL)               0x0
    

    This tells you that the only library needed for this binary is libc.so.6 (the NEEDED entry).

    If your real question is "what other libraries does this ELF binary require", then that is pretty easy to obtain: just look for DT_NEEDED entries in the dynamic symbol table. Doing this programmatically is rather easy:

    1. Locate the table of program headers (the ELF file header .e_phoff tells you where it starts).
    2. Iterate over them to find the one with PT_DYNAMIC .p_type.
    3. That segment contains a set of fixed sized Elf{32,64}_Dyn records.
    4. Iterate over them, looking for ones with .d_tag == DT_NEEDED.

    Voila.

    P.S. There is a bit of a complication: the strings, such as libc.so.6 are not part of the PT_DYNAMIC. But there is a pointer to where they are in the .d_tag == DT_STRTAB entry. See this answer for example code.