aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2015-08-20 10:29:39 -0400
committerMike Frysinger <vapier@gentoo.org>2015-08-20 10:29:39 -0400
commitef15f6016726ad3e06db747f188bd9db9d5ffb71 (patch)
tree411997cdef196653150a1f34f350b216336c390e
parentlddtree.py: fix glob handling w/ld.so.conf (diff)
downloadpax-utils-ef15f6016726ad3e06db747f188bd9db9d5ffb71.tar.gz
pax-utils-ef15f6016726ad3e06db747f188bd9db9d5ffb71.tar.bz2
pax-utils-ef15f6016726ad3e06db747f188bd9db9d5ffb71.zip
lddtree.sh: fix interp handling when doing a full listing
On Debian multiarch systems, the ldso path is symlinked to a different search path (and the main path isn't searched at all). When listing the deps of an ELF which links against the ldso, we end up showing the ldso being loaded by two different paths: $ ./lddtree.sh -a /bin/bash bash => /bin/bash (interpreter => /lib64/ld-linux-x86-64.so.2) libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 ld-linux-x86-64.so.2 => /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 ... Fix the output to show that ld-linux-x86-64.so.2 was located at the same path as the original interpreter as that better matches the runtime ldso behavior. $ ./lddtree.sh -a /bin/bash bash => /bin/bash (interpreter => /lib64/ld-linux-x86-64.so.2) libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 Reported-by: Tomasz Buchert <tomasz@debian.org>
-rwxr-xr-xlddtree.sh20
1 files changed, 17 insertions, 3 deletions
diff --git a/lddtree.sh b/lddtree.sh
index 07be7ab..8e6501f 100755
--- a/lddtree.sh
+++ b/lddtree.sh
@@ -126,7 +126,7 @@ find_elf() {
show_elf() {
local elf=$1 indent=$2 parent_elfs=$3
local rlib lib libs
- local interp resolved
+ local resolved
find_elf "${elf}"
resolved=${_find_elf}
elf=${elf##*/}
@@ -143,6 +143,8 @@ show_elf() {
printf "${resolved:-not found}"
fi
if [[ ${indent} -eq 0 ]] ; then
+ local elf_specs interp full_interp
+
elf_specs=$(elf_specs "${resolved}")
interp=$(scanelf -qF '#F%i' "${resolved}")
[[ -n ${interp} ]] && interp="${ROOT}${interp#/}"
@@ -159,6 +161,7 @@ show_elf() {
sed -nr -e "/^\/.*lib/{s|^/?|${ROOT}|;s|/$||;s|/?:/?|\n${ROOT}|g;p}"
)
fi
+ full_interp=${interp}
interp=${interp##*/}
# If we are in non-list mode, then we want to show the "duplicate" interp
# lines -- first the header (interp=>xxx), and then the DT_NEEDED line to
@@ -183,8 +186,19 @@ show_elf() {
# No need for leading comma w/my_allhits as we guarantee it always
# starts with one due to the way we append the value above.
[[ ${my_allhits}, == *,${lib},* ]] && continue
- find_elf "${lib}" "${resolved}"
- rlib=${_find_elf}
+ # If the interp is being linked against directly, re-use the existing
+ # full path rather than perform a search for it. When systems symlink
+ # the interp to a diff location, we might locate a different path, and
+ # displaying both doesn't make sense as it doesn't match the runtime --
+ # the ldso won't load another copy of ldso into memory from the search
+ # path, it'll re-use the existing copy that was loaded from the full
+ # hardcoded path.
+ if [[ ${lib} == "${interp}" ]] ; then
+ rlib=${full_interp}
+ else
+ find_elf "${lib}" "${resolved}"
+ rlib=${_find_elf}
+ fi
show_elf "${rlib:-${lib}}" $((indent + 4)) "${parent_elfs}"
done
}