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
...
How to know which shared object is used?
You should use the ldd
utility. In the same environment you would load your executable (Same LD_LIBRARY_PATH, e.t.c.)
How to find all shared libraries actually used during execution in Linux?
You can use ltrace(1)
for this:
$ PROG='ls -l'
# Collect call info
$ ltrace -o calls.txt -l '*' $PROG &> /dev/null
# Analyze collected data
$ cat calls.txt | sed -ne '/->/{ s/^\(.*\)->.*/\1/; p }' | sort -u
libacl.so.1
libcap.so.2
libc.so.6
libselinux.so.1
ls
# Compare with ldd
$ ldd /bin/ls | wc -l
10
How to list library dependencies of a non-native binary?
is there any way to get a list of the dynamically linked dependency for of a foreign binary
You can list direct dependencies of a binary easily enough:
readelf -d a.out | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
I know of no way to recursively continue this to get the full list (as ldd
does). You'll have to repeat the process for every NEEDED
library by hand.
How to find which shared library exported which imported symbol in my binary?
So, for example how can I find the shared library which exports the function named foo or printf or anything in an efficient way?
You can run your program with env LD_DEBUG=bindings ./a.out
. This will produce a lot of output, which you can grep
for foo
and printf
.
Note that the answer to "which external symbol in my binary is dependent on which shared library" is "whichever library defines this symbol first".
So if today your binary depends on lifoo.so
for foo
and on libc.so.6
for printf
, nothing stops you from running with a different libfoo.so
tomorrow, and that different version of libfoo.so
may define different symbols. If the new version of libfoo.so
defines printf
, that would cause the answer to your question for symbol printf
to change from libc.so.6
to libfoo.so
.
(solved) C++ Load one Shared Object with dependencies and access their functions
As a start, change the order of the arguments in the link-commands
g++ -g -shared -o libtest2.so -L. lib2.o -ltest1
g++ -g -shared -o libtest3.so -L. lib3.o -ltest1 -ltest2
Note: it's not necessary with every linker, but the newer gold
linker only resolves "from-left-to-right". Also there's a -Wl,--no-undefined
option, which is very useful to catch these error.
Then add rpath
into these commands so that the shared objects find their dependencies run-time:
g++ -g -shared -o libtest2.so "-Wl,-rpath,${PWD}" -L. lib2.o -ltest1
g++ -g -shared -o libtest3.so "-Wl,-rpath,${PWD}" -L. lib3.o -ltest1 -ltest2
After linkage, readelf -d
should show the RPATH like this:
$ readelf -d libtest3.so |head -n10
Dynamic section at offset 0xdd8 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libtest1.so]
0x0000000000000001 (NEEDED) Shared library: [libtest2.so]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000001d (RUNPATH) Library runpath: [/home/projects/proba/CatMan]
(Also there is libtool to deal with shared libraries.)
Mind you, because of name-mangling, the following change should be performed (though it is compiler-specific)
- OpenSymbol(pHandle, "printBase");
+ OpenSymbol(pHandle, "_ZN4Base9printBaseEv");
Shared library on Linux does not contain reference to one of its dependencies
Your version of cc
(or the link editor used by it) seem to default to -Wl,--as-neeeded
. In this case, the command line order matters. If -lcpdf
comes first, there are no references to its symbols yet, and so no dependency is created. -l
arguments should come last:
cc -shared -fpic -I$JAVA_HOME/include I$JAVA_HOME/include/linux jcpdfwrapper.c -o libjcpdf.so -L. -lcpdf
How to show all shared libraries used by executables in Linux?
- Use
ldd
to list shared libraries for each executable. - Cleanup the output
- Sort, compute counts, sort by count
To find the answer for all executables in the "/bin" directory:
find /bin -type f -perm /a+x -exec ldd {} \; \
| grep so \
| sed -e '/^[^\t]/ d' \
| sed -e 's/\t//' \
| sed -e 's/.*=..//' \
| sed -e 's/ (0.*)//' \
| sort \
| uniq -c \
| sort -n
Change "/bin" above to "/" to search all directories.
Output (for just the /bin directory) will look something like this:
1 /lib64/libexpat.so.0
1 /lib64/libgcc_s.so.1
1 /lib64/libnsl.so.1
1 /lib64/libpcre.so.0
1 /lib64/libproc-3.2.7.so
1 /usr/lib64/libbeecrypt.so.6
1 /usr/lib64/libbz2.so.1
1 /usr/lib64/libelf.so.1
1 /usr/lib64/libpopt.so.0
1 /usr/lib64/librpm-4.4.so
1 /usr/lib64/librpmdb-4.4.so
1 /usr/lib64/librpmio-4.4.so
1 /usr/lib64/libsqlite3.so.0
1 /usr/lib64/libstdc++.so.6
1 /usr/lib64/libz.so.1
2 /lib64/libasound.so.2
2 /lib64/libblkid.so.1
2 /lib64/libdevmapper.so.1.02
2 /lib64/libpam_misc.so.0
2 /lib64/libpam.so.0
2 /lib64/libuuid.so.1
3 /lib64/libaudit.so.0
3 /lib64/libcrypt.so.1
3 /lib64/libdbus-1.so.3
4 /lib64/libresolv.so.2
4 /lib64/libtermcap.so.2
5 /lib64/libacl.so.1
5 /lib64/libattr.so.1
5 /lib64/libcap.so.1
6 /lib64/librt.so.1
7 /lib64/libm.so.6
9 /lib64/libpthread.so.0
13 /lib64/libselinux.so.1
13 /lib64/libsepol.so.1
22 /lib64/libdl.so.2
83 /lib64/ld-linux-x86-64.so.2
83 /lib64/libc.so.6
Edit - Removed "grep -P"
Related Topics
How to Redirect Output of Systemd Service to a File
Contiguous Physical Memory from Userspace
Forward Host Port to Docker Container
How to Get Cmake to Find My Alternative Boost Installation
Bluetooth Low Energy: Listening For Notifications/Indications in Linux
How to Loop Over the Output of a Shell Command
Docker Can't Connect to Docker Daemon
How to Programmatically "Burn In" Ansi Control Codes to a File Using Unix Utils
Assembly Segmentation Fault After Making a System Call, At the End of My Code
How to Delete an Exported Environment Variable
Recursively Counting Files in a Linux Directory
How to Create Docker Overlay Network Between Multi Hosts
Does Linux Guarantee the Contents of a File Is Flushed to Disc After Close()
What Does O_Direct Really Mean
Extract One Word After a Specific Word on the Same Line
How to Get Full Path of a File
How to Invoke a System Call Via Syscall or Sysenter in Inline Assembly