3 # NON-CONFIGURABLE STUFF!
5 version="@@CT_VERSION@@"
10 my_name="$( basename "${0}" )"
13 readelf="${prefix}-readelf"
14 fake_load_addr="$((0xdeadbeef))"
15 fake_load_addr_sys="$((0x8badf00d))"
16 ld_library_path="/lib:/usr/lib"
19 printf "%s: %s\n" "${my_name}" "$*" >&2
24 printf "Try \`%s --help' for more information\n" >&2
30 [ -z "${CT_XLDD_VERBOSE}" ] && return 0
32 for((depth=0; "${#FUNCNAME[$((depth+1))]}" != 0; depth++)); do :; done
33 printf "%*s" $((4*(depth-1))) "" >&2
38 # Fake a real ldd, just in case some dumb script would check
40 ldd (crosstool-NG) ${version}
41 Copyright (C) 2010 "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
42 This is free software; see the source for copying conditions. There is NO
43 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
44 Licensed under the GPLv2, see the file LICENSES in the top-directory of the
45 sources for this package.
51 Usage: ${my_name} [OPTION]... --root DIR FILE...
52 --help print this help and exit
53 --version print version information and exit
54 --root dir treat dir as being the root of the target
55 -s, --show-system mark libs from the sysroot with a trailing '[*]'
59 ${my_name} tries to mimick the behavior of a real native ldd, but can be
60 used in a cross-development environment. Here is how it differs from a
63 If the CT_XLDD_DEBUG variable is set and non-empty, then ${myname} will
64 print a lot of debug messages, explaining how it builds the library
65 search path, and how each library was found and why.
67 The LD_LIBRARY_PATH variable is not used, as it can not reliably be
68 guessed except at runtime, and we can't run.
70 ${my_name} does not scan /etc/ld.so.cache, but instead uses /etc/ld.so.conf
71 (it understands the include directives therein for libces that have that).
73 ${my_name} will search the directory specified with --root for libraries
74 to resolve the NEEDED tags. If --root is not set, then ${my_name} will
75 use the value in the environment variable \${CT_XLDD_ROOT}. If neither
76 is set, then this is an error.
78 If NEEDED libraries can't be found in the specified root directory, then
79 ${my_name} will also look in the sysroot of the toolchain to see if it
82 For NEEDED libraries that were found, the output will look like:
83 libneeded.so => /path/to/libneeded.so (0xloadaddr)
85 and for those that were not found, the output will look like:
86 libneeded.so not found
88 The paths are relative to the specified root directory, or to the sysroot
89 (eg. /lib/libneeded.so, /usr/lib/libneeded.so, and so on...).
91 The expected load address 'loadaddr' is a faked address to match the output
92 of the real ldd, but has no actual meaning (set to some constants for now,
93 0x8badf00d for libraries from the sysroot, 0xdeadbeef for others).
97 # -d, --data-relocs process data relocations
98 # -r, --function-relocs process data and function relocations
99 # -u, --unused print unused direct dependencies
100 # -v, --verbose print all information
102 # See also this thread:
103 # http://sourceware.org/ml/crossgcc/2008-09/msg00057.html
106 # Parse command line options
107 root="${CT_XLDD_ROOT}"
130 do_opt_error "unrecognized option \`${1}'"
141 if [ -z "${root}" ]; then
142 do_opt_error "no root given"
145 if [ ! -d "${root}" ]; then
146 do_error "\`${root}': no such file or directory"
150 sysroot="$( "${gcc}" -print-sysroot 2>/dev/null )"
151 if [ -z "${sysroot}" ]; then
152 sysroot="$( "${gcc}" -print-file-name=libc.so 2>/dev/null \
153 |sed -r -e 's:/usr/lib/libc.so$::;' \
156 if [ -z "${sysroot}" ]; then
157 do_error "unable to find sysroot for \`${gcc}'"
160 do_report_needed_found() {
167 if [ -z "${system}" ]; then
168 loadaddr="${fake_load_addr}"
170 loadaddr="${fake_load_addr_sys}"
171 if [ -n "${show_system}" ]; then
176 printf "%8s%s => %s (0x%0*x)%s\n" \
185 # Search a needed file, scanning ${lib_dir} in the root directory
192 do_trace "Searching for '${needed}'\n"
194 for d in "${needed_search_path[@]}"; do
195 do_trace "-> looking in '${d}'\n"
196 if [ -f "${root}${d}/${needed}" ]; then
197 found="${d}/${needed}"
198 do_trace "---> found\n"
202 if [ -z "${found}" ]; then
203 for d in "${needed_search_path[@]}"; do
204 do_trace "-> looking in '${d}' (sysroot)\n"
205 if [ -f "${sysroot}${d}/${needed}" ]; then
206 found_sysroot="${d}/${needed}"
207 do_trace "---> found\n"
213 if [ -n "${found}" ]; then
214 do_report_needed_found "${needed}" "${found}"
215 do_process_file "${root}${found}"
216 elif [ -n "${found_sysroot}" ]; then
217 do_report_needed_found "${needed}" "${found_sysroot}" "sys"
218 do_process_file "${sysroot}${found_sysroot}"
220 printf "%8c%s not found\n" "" "${needed}"
224 # Scan a file for all NEEDED tags
228 do_trace "Parsing file '${file}'\n"
230 "${readelf}" -d "${file}" \
231 |"${grep}" -E '\(NEEDED\)' \
232 |"${sed}" -r -e 's/^.*Shared library:[[:space:]]+\[(.*)\]$/\1/;' \
233 |while read needed; do
234 do_find_needed "${needed}"
238 # Recursively scan a /etc/ld.so.conf file
239 do_scan_etc_ldsoconf() {
240 local ldsoconf="${1}"
244 [ -f "${ldsoconf}" ] || return 0
245 do_trace "Parsing ld.so.conf: '${ldsoconf}'\n"
250 g="${root}${line#include }"
251 do_trace "-> handling include directive '${g}'\n"
253 do_scan_etc_ldsoconf "${f}"
259 do_trace "-> adding search dir '${line}'\n"
260 needed_search_path+=( "${line}" )
266 # Build up the full list of search directories
267 declare -a needed_search_path
268 do_trace "Adding basic lib dirs\n"
269 ld_library_path="${ld_library_path}:"
270 while [ -n "${ld_library_path}" ]; do
271 d="${ld_library_path%%:*}"
272 if [ -n "${d}" ]; then
273 do_trace "-> adding search dir '${d}'\n"
274 needed_search_path+=( "${d}" )
276 ld_library_path="${ld_library_path#*:}"
278 do_trace "Scanning '/etc/ld.so.conf'\n"
279 do_scan_etc_ldsoconf "${root}/etc/ld.so.conf"
280 do_trace "Search path:\n"
281 for p in "${needed_search_path[@]}"; do
282 do_trace "-> '${p}'\n"
285 do_trace "Scanning file '${1}'\n"
286 do_process_file "${1}"