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:
- Locate the table of program headers (the ELF file header
.e_phoff
tells you where it starts). - Iterate over them to find the one with
PT_DYNAMIC
.p_type
. - That segment contains a set of fixed sized
Elf{32,64}_Dyn
records. - 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 theELF
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
What Is the Linux Built-In Driver Load Order
How to Use Both 64 Bit and 32 Bit Instructions in the Same Executable in 64 Bit Linux
Why Is Crond Failing to Run a Non-Root Crontab on Alpine Linux
How to Toggle Cr/Lf in Gnu Screen
Parsing Shell Script Arguments
How to Find Out What Linux Capabilities a Process Requires to Work
Fallocate() Command Equivalent in Os X
Linux Raw Ethernet Socket Bind to Specific Protocol
Git Gui Like Bzr Explorer But for Git
How to Use the Linux Flock Command to Prevent Another Root Process from Deleting a File
Docker Alpine Executable Binary Not Found Even If in Path
Is It Ok (Performance-Wise) to Have Hundreds or Thousands of Files in the Same Linux Directory
Add Blank Line After Every Result in Grep
Accessing .So Libraries Using Dlopen() Throws Undefined Symbol Error
Is It Necessary to Deregister a Socket from Epoll Before Closing It