When developing for native platform, I can use ldd to list all the shared libraries (.so files) a binary executable I build will try to load upon start-up. But when cross-co
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.
while in gdb
, info shared is similar to ldd
. It gives complete human readable runtime information of the executable.
readelf
would miss path and other libraries information.
readelf
is a very good tool for on the host study. Developer may choose that works.
A bit late for this addition but someone might benefit/clarify. Doesn't the -A flag to readelf give the same result as ldd?
$ readelf -AW /bin/vi
Library list section '.gnu.liblist' contains 8 entries:
Library Time Stamp Checksum Version Flags
0: libselinux.so.1 2011-07-25T08:02:58 0x17a7d5f7 0 0
1: libtermcap.so.2 2011-07-25T08:02:59 0x29ae9ff7 0 0
2: libacl.so.1 2011-07-25T08:02:58 0x60748842 0 0
3: libc.so.6 2011-07-25T08:02:58 0x0c2c7eeb 0 0
4: libdl.so.2 2011-07-25T08:02:58 0xdfbfc467 0 0
5: libsepol.so.1 2011-07-25T08:02:58 0x857499cb 0 0
6: /lib64/ld-linux-x86-64.so.2 2011-07-25T08:02:58 0x9e6549b7 0 0
7: libattr.so.1 2011-07-25T08:02:58 0x862f1546 0 0
The only info missing here seems to be the full path where those libraries are located.
On the other hand, the tools mentioned so far are only useful once you have an installation known to work. My most common problems are:
Can anyone shed some light on these issues? BTW, I have tried reading installation instructions and release notes but they are almost always nowhere near sufficient.
A beefy example may put everything into context, so please try compiling Cinelerra.
some depends idiot just uploaded this. i'm sure it shows things LDD doesn't but it's not well tested yet. a small bit of output is shown below.
http://sourceforge.net/p/dep-trace/
http://sourceforge.net/projects/dep-trace/files/libdeps
should show total dependancy table of what ldconfig(1) will load (or has already loaded) and show which libs are NOT_FOUND (ie, no version or file) and then also what is effected.
try it, enjoy. it's very new so don't say i didn't tell you. it did just find some things below i didn't know about my lib system - i'm just about to go fix that.
# libdeps objdump -h
Experimental - see help
libdeps [objdump | ldd] [-l | file]
-l use find *.so is used on ldconfig dirs
file one file.so per line
snip...
# libdeps objdump -d
LIBTABLE
ld-linux.so.2(file)
ld-linux.so.2(GLIBC_2.0)(file)
ld-linux.so.2(GLIBC_2.1)(file)
ld-linux.so.2(GLIBC_2.0)(file)
ld-linux.so.2(GLIBC_2.3)(file)
ld-linux.so.2(GLIBC_2.1)(file)
ld-linux.so.2(GLIBC_PRIVATE)(file)
ld-linux.so.2(GLIBC_2.3)(file)
libBrokenLocale.so.1(file)
snip ...
libc.so.6 libc.so.6(file) ld-linux.so.2 ld-linux.so.2(GLIBC_2.0) ld-linux.so.2(GLIBC_2.1) ld-linux.so.2(GLIBC_PRIVATE)
snip ...
libanl.so.1 libanl.so.1(file) ld-linux.so.2 ld-linux.so.2(GLIBC_2.0) ld-linux.so.2(GLIBC_2.1) ld-linux.so.2(GLIBC_PRIVATE) libc.so.6(GLIBC_2.1.3) libc.so.6(GLIBC_2.0) libc.so.6 libc.so.6(GLIBC_2.1) libc.so.6(GLIBC_2.3) libc.so.6(GLIBC_2.2) libc.so.6(GLIBC_PRIVATE) libc.so.6(GLIBC_2.3.2) libc.so.6(GLIBC_2.1.2) libpthread.so.0(GLIBC_2.1) libpthread.so.0
libnss_db.so.2 libnss_db.so.2(file) ld-linux.so.2 ld-linux.so.2(GLIBC_2.0) ld-linux.so.2(GLIBC_2.1) ld-linux.so.2(GLIBC_PRIVATE) libc.so.6(GLIBC_2.1.3) libc.so.6(GLIBC_2.0) libc.so.6 libc.so.6(GLIBC_2.1) libc.so.6(GLIBC_2.3) libc.so.6(GLIBC_2.2) libc.so.6(GLIBC_PRIVATE) libnss_files.so.2 libnss_files.so.2(GLIBC_PRIVATE) libdb3.so.3(NOT_FOUND) libdb3.so.3(DB3_2)(NOT_FOUND)
snip...
NOT_FOUND
libctutils.so.0
libdb3.so.3
libdb3.so.3(DB3_2)
EFFECTED
libctutils.so.0 libconsole.so.0
libdb3.so.3 libnss_db.so.2
libdb3.so.3(DB3_2) libnss_db.so.2
libconsole.so.0
libnss_db.so.2
12/04/14 21:56 -0500 Thursday, December 04, 2014, 09:56:35 PM EST
Sorry to make a zombie thread, but I am working on some things for my OpenWRT router and wanted this to check some dependencies to see if I had enough space on my jffs2 partition to copy over just e2fsck
. Short answer: nope.avi.
Anyhoo, I made a little script that uses the accepted answer plus some (probably overly verbose) grep
calls and with a little hand waving and some unicorn tears (no worries, they were happy tears!) I managed to put together the following script that gives you all the dependencies. I'm sure there's lots of room for improvement especially RE: the loops and recursion, as well as the fact that it's all bashisms all the time (i.e. indexed arrays) but this is at least nominally working for me:
#!/bin/bash
declare -a search_path
declare -a found_deps
find_dependencies() {
local file="$1"
local -a deps
local -a deps_to_process
deps=( $( readelf -d "$file" | grep "NEEDED" | \
grep -o -E "\[[^]]*\]" | grep -o -E "[^][]*" ) )
local add_this_dep=true
# always assume we've found $file and add it to the $found_deps list
# if it's not there
for found_dep in "${found_deps[@]}"
do
if [ "$found_dep" = "$(basename $file)" ]
then
add_this_dep=false
break
fi
done
# if $add_this_dep is true, go ahead and add to the found_deps list
if $add_this_dep
then
found_deps+=("$(basename $file)")
fi
# for every dependency found by readelf (no path)
for dep in "${deps[@]}"
do
local process_dep=true
# if the basename of the file passed into the function is
# this dep, skip processing altogether
if [ "$dep" = "$(basename $file)" ]
then
break
else
# otherwise, if it's one of the 'found deps' don't process it
for found_dep in "${found_deps[@]}"
do
if [ "$dep" = "$found_dep" ]
then
process_dep=false
break
fi
done
# it wasn't one of the 'found deps' so add
# it to the found_deps list
if $process_dep
then
found_deps+=($dep)
fi
fi
# if we are supposed to process this dep
if $process_dep
then
local file_path=
# check each search path for a file named $dep underneath it
for dir in $search_path
do
file_path=$( find "$dir" -name "$dep" | head -n 1 )
# if the $file_path is not empty, then we found
# a copy of it, so break out of the loop
if [ -n "$file_path" ]; then break; fi;
done
# if the $file_path is not empty, then we found a copy
# of the file, place it the list of deps to be processed
if [ -n "$file_path" ]
then
deps_to_process+=($file_path)
fi
fi
done
# now, go through all of our $deps_to_process (with path)
# and run "find_dependencies" on them
for dep_to_process in "${deps_to_process[@]}"
do
find_dependencies "$dep_to_process"
done
}
argc=$#
if [ $argc -eq 0 ]
then
printf '%s: prints dependencies of a (potentially) non-native elf executable, recursively\n'
printf '\n'
printf 'usage:\n'
printf '\t%s <non-native elf executable> [ --supress-header ] [ <path> ... ]\n' "$(basename $0)"
printf '\twhere\n'
printf '\t\t<non-native elf executable> is the name of a file to find the dependencies of.\n'
printf '\t\t[ <path> ... ] is an optional list of directories under which to search for libraries.\n'
printf '\t\t[ --supress-header ] is an optional flag that prints nothing other than the list of files to stdout.\n'
printf '\t\t\t(without the parameter a banner is sent to stderr)'
printf '\n'
else
file="$1"
shift 1
show_header=true
if [ "$1" = "--supress-header" ]; then show_header=false; shift 1; fi;
if $show_header
then
printf ' -------------------------------------------------------------------------------------------------------------\n' 1>&2
printf ' ldd-nonnative: find all dependencies of a (potentially) non-native binary %s\n' "$file" 1>&2
printf ' -------------------------------------------------------------------------------------------------------------\n' 1>&2
fi
search_path="$@"
find_dependencies $file
printf '\t%s\n' "${found_deps[@]}"
fi
# ❤ copyheart, shelleybutterfly, 2014
# love is never subject to the low; please copy and share with love :)
# contact information:
# shelleybutterfly@mojoprocode.com
# I hereby dedicate this software to the public domain in all jurisdictions
# where possible. In other jurisdictions, I license it to you under your
# choice of permissive license, as defined by the Open Source Institute (OSI),
# found at URL http://opensource.org. Should such a license be unavailable in
# your jurisdiection, you may use any copyleft open source license, again as
# defined by OSI; and if that too is unavailable, then you are licensed this
# software under the least restrictive possible terms allowed in your
# jurisdiction.
# I request but do not require that you give credit to me, shelleybutterfly,
# which I will accept in cases of licensing other than the public domain as
# valuable consideration for your use of my software. (I love to know that
# my name is plastered all over some obscure piece of code that's at least
# appreciated by those who do see it, and I consider that more than enough
# consideration. :D) This software is provided completely as-is, and I take
# absolutely no responsibility for any damages that it may cause. It has
# not been fully tested and should be considered pre-alpha release quality,
# (that is to say, it is likely unstable and unsafe to use without your own
# validation to ensure that it meets some or any your needs without: among
# other things: melting your computer, calling your grandma at midnight,
# telling your girlfriend she's fat, and throwing your computer in the
# dishwasher to make sure it's clean, and you take full responsibility for
# doing your own testing to ensure that it suits your needs, and operates
# properly int the conditions under which you intend to use it.
# Should you not be willing to take this risk, it is highly recommended
# that you do not use this software at all, ever, and that you instead find
# a real commercial piece of software, or other warranted piece of software,
# as I can not and do not and shall not provide any warranty of fitness for
# any purpose whatsoever, even to scrub your toilet, and it's provided with
# the understanding that it will be used primarily as an educational tool
# rather than any sort of production code. I disclaim any responsibility for
# anything that may happen to you due to your use of software, even if it
# causes huge zits, a rash under your boobs that wont go away, or a burning
# sensation when you pee. Sorry, **especially** for a burning sensation when
# you pee.
# Your use of this software implies acceptance of these terms as well as
# any painful urination or other issues it may cause in your life.
# [deep breath]
# my love to you all; I hope this software was useful to you in some way; if
# you end up using it despite the dire warnings against doing so, feel free
# to drop me a note at shelleybutterfly@mojoprocode.com, as I imagine it
# will be rare enough to make my day, every time. ♥
So, there ya go. Hope it helps someone. Egads it's taken me a long time to even get good enough with shell scripting to be able to pull something like this off, nevermind the fact that it took me much longer than it probably should have, so please forgive what has likely shaken some of you script gurus out there to the very core of your being. :)
To list shared libraries dependency of a non-native binary, you can try the following tool: http://www.mathembedded.com/component/k2/item/1-cross-ldd.html
I use it on SH4 and MIPS. As reported in other answer, you can achieve the same using readelf output and a recursive loop, but I have never try by myself since cross-ldd exist.