1.1 --- a/scripts/xldd.in Tue Nov 23 21:36:01 2010 +0100
1.2 +++ b/scripts/xldd.in Fri Apr 15 00:05:53 2011 +0200
1.3 @@ -12,6 +12,7 @@
1.4 gcc="${prefix}-gcc"
1.5 readelf="${prefix}-readelf"
1.6 fake_load_addr_root="$((0xdeadbeef))"
1.7 +fake_load_addr_rpath="$((0xdeadc0de))"
1.8 fake_load_addr_sysroot="$((0x8badf00d))"
1.9 ld_library_path="/lib:/usr/lib"
1.10
1.11 @@ -53,6 +54,7 @@
1.12 --version print version information and exit
1.13 --root dir treat dir as being the root of the target
1.14 -s, --show-system mark libs from the sysroot with a trailing '[*]'
1.15 + and libs found via RPATH with a trailing '[+]'
1.16
1.17 _EOF_
1.18 cat <<_EOF_ |fmt
1.19 @@ -70,6 +72,12 @@
1.20 ${my_name} does not scan /etc/ld.so.cache, but instead uses /etc/ld.so.conf
1.21 (it understands the include directives therein for libces that have that).
1.22
1.23 +${my_name} also interprets (tries to!) the RPATH/RUNPATH records found in
1.24 +the dynamic ELF section. Such paths are searched for only relative to
1.25 +the specified root, not from the sysroot (see below). Also, those paths
1.26 +are searched for not only for the file they appear in, but also for its
1.27 +dependencies.
1.28 +
1.29 ${my_name} will search the directory specified with --root for libraries
1.30 to resolve the NEEDED tags. If --root is not set, then ${my_name} will
1.31 use the value in the environment variable \${CT_XLDD_ROOT}. If neither
1.32 @@ -90,7 +98,8 @@
1.33
1.34 The expected load address 'loadaddr' is a faked address to match the output
1.35 of the real ldd, but has no actual meaning (set to some constants for now,
1.36 -0x8badf00d for libraries from the sysroot, 0xdeadbeef for others).
1.37 +0x8badf00d for libraries from the sysroot, 0xdeadc0de for those found via
1.38 +the RPATH/RUNPATH records, and 0xdeadbeef for others).
1.39 _EOF_
1.40
1.41 # Unimplemeted yet:
1.42 @@ -168,6 +177,12 @@
1.43 root)
1.44 loadaddr="${fake_load_addr_root}"
1.45 ;;
1.46 + rpath)
1.47 + loadaddr="${fake_load_addr_rpath}"
1.48 + if [ -n "${show_system}" ]; then
1.49 + sys=" [+]"
1.50 + fi
1.51 + ;;
1.52 sysroot)
1.53 loadaddr="${fake_load_addr_sysroot}"
1.54 if [ -n "${show_system}" ]; then
1.55 @@ -189,6 +204,7 @@
1.56 do_find_needed() {
1.57 local needed="${1}"
1.58 local -a list
1.59 + local -a dirs
1.60 local found
1.61 local where
1.62 local base
1.63 @@ -196,7 +212,9 @@
1.64
1.65 do_trace "Searching for '${needed}'\n"
1.66
1.67 + # rpath shall come first!
1.68 list=( \
1.69 + "rpath:${root}" \
1.70 "root:${root}" \
1.71 "sysroot:${sysroot}" \
1.72 )
1.73 @@ -204,7 +222,12 @@
1.74 for i in "${list[@]}"; do
1.75 where="${i%%:*}"
1.76 base="${i#*:}"
1.77 - for d in "${needed_search_path[@]}"; do
1.78 + if [ "${where}" = "rpath" ]; then
1.79 + dirs=( "${search_rpath[@]}" )
1.80 + else
1.81 + dirs=( "${needed_search_path[@]}" )
1.82 + fi
1.83 + for d in "${dirs[@]}"; do
1.84 do_trace "-> looking in '${d}' (${where})\n"
1.85 if [ -f "${base}${d}/${needed}" ]; then
1.86 found="${d}/${needed}"
1.87 @@ -225,11 +248,25 @@
1.88 # Scan a file for all NEEDED tags
1.89 do_process_file() {
1.90 local file="${1}"
1.91 + local -a save_search_rpath
1.92 local n m
1.93 local found
1.94
1.95 do_trace "Parsing file '${file}'\n"
1.96
1.97 + save_search_rpath=( "${search_rpath[@]}" )
1.98 + for n in $( "${readelf}" -d "${file}" \
1.99 + |"${grep}" -E '\((RPATH|RUNPATH)\)' \
1.100 + |"${sed}" -r -e 's/^.*Library r(|un)path:[[:space:]]+\[(.*)\]$/\2/;'\
1.101 + ); do
1.102 + do_trace "-> adding rpath '${n}'\n"
1.103 + search_rpath+=( "${n}" )
1.104 + done
1.105 + do_trace ": search path:\n"
1.106 + for n in "${search_rpath[@]}" "${needed_search_path[@]}"; do
1.107 + do_trace ": - '${n}'\n"
1.108 + done
1.109 +
1.110 for n in $( "${readelf}" -d "${file}" \
1.111 |"${grep}" -E '\(NEEDED\)' \
1.112 |"${sed}" -r -e 's/^.*Shared library:[[:space:]]+\[(.*)\]$/\1/;' \
1.113 @@ -245,7 +282,9 @@
1.114 do_trace "-> handling new dependency '${n}'\n"
1.115 needed_list+=( "${n}" )
1.116 do_find_needed "${n}"
1.117 - done
1.118 + done
1.119 +
1.120 + search_rpath=( "${save_search_rpath[@]}" )
1.121 }
1.122
1.123 # Recursively scan a /etc/ld.so.conf file
1.124 @@ -297,4 +336,5 @@
1.125
1.126 do_trace "Scanning file '${1}'\n"
1.127 declare -a needed_list
1.128 +declare -a search_rpath
1.129 do_process_file "${1}"