Differencebetween Ldd and Objdump

What is the difference between ldd and objdump?

You can see the difference in the output.

objdump is simply dumping what the object itself lists as libraries containing unresolved symbols.

ldd is listing which libraries ld.so would actually load. And it follows the graph backward, so that you can see what would be loaded by those libraries. Which is how libpthread.so.0 winds up in the ldd output, despite not being in the objdump output.

So ldd is going to give a much, much better picture of what really needs to be available at runtime. But, when resolving compile/link-time problems, objdump is pretty helpful.

API for ldd (or objdump)?


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.

Why the differences in memory address or offset between xxd and objdump?


Why the differences in memory address or offset between xxd and objdump?

Because they show you largely unrelated views of the data.

  • xxd shows you the raw bits of an arbitrary file, with no interpretation of their meaning.

  • objdump (with the flags you used) shows you what the contents of memory would look like when your executable is loaded into memory.

    objdump arrives at that view by examining and understanding the meaning of the ELF file header, program headers and section headers.

You can use readelf --segments and readelf --sections to examine these headers.

cross compiler ldd

This is a bit of a kluge, but it's the best solution I could find, and it really works quite well for basic use - just save this script as "arm-none-linux-gnueabi-ldd" with your other cross tools.

#!/bin/sh
arm-none-linux-gnueabi-readelf -a $1 | grep "Shared library:"

Determine direct shared object dependencies of a Linux binary?

You can use readelf to explore the ELF headers. readelf -d will list the direct dependencies as NEEDED sections.

 $ readelf -d elfbin

Dynamic section at offset 0xe30 contains 22 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libssl.so.1.0.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x400520
0x000000000000000d (FINI) 0x400758
...

Is it possible to know which library pulled in another one using ldd?

To know this you will have to use readelf recursively. First run it on your executable, and look for NEEDED libraries. This will tell you what your executable needs directly. After that you should iteratively repeat the process for every library which is needed, and once you arrive at the library in question you will know the inclusion path.

objdump and resolving linkage of local function calls?


Is there a way, without actually linking, to get an assembly listing that has the function names resolved?

Yes: use objdump -dr foo.o



Related Topics



Leave a reply



Submit