diff options
author | Mike Frysinger <vapier@gentoo.org> | 2015-08-20 10:29:39 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2015-08-20 10:29:39 -0400 |
commit | ef15f6016726ad3e06db747f188bd9db9d5ffb71 (patch) | |
tree | 411997cdef196653150a1f34f350b216336c390e | |
parent | lddtree.py: fix glob handling w/ld.so.conf (diff) | |
download | pax-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-x | lddtree.sh | 20 |
1 files changed, 17 insertions, 3 deletions
@@ -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 } |