| 1 |
#!/bin/bash |
| 2 |
|
| 3 |
source lddtree /../..source.lddtree || exit 1 |
| 4 |
|
| 5 |
argv0=${0##*/} |
| 6 |
|
| 7 |
usage() { |
| 8 |
cat <<-EOF |
| 9 |
Display libraries that satisfy undefined symbols, as a tree |
| 10 |
|
| 11 |
Usage: ${argv0} [options] <ELF file[s]> |
| 12 |
|
| 13 |
Options: |
| 14 |
-x Run with debugging |
| 15 |
-h Show this help output |
| 16 |
EOF |
| 17 |
exit ${1:-0} |
| 18 |
} |
| 19 |
|
| 20 |
sym_list() { |
| 21 |
# with large strings, bash is much slower than sed |
| 22 |
local type=$1; shift |
| 23 |
echo "%${type}%$@" | sed "s:,:,%${type}%:g" |
| 24 |
} |
| 25 |
show_elf() { |
| 26 |
local elf=$1 |
| 27 |
local rlib lib libs |
| 28 |
local resolved=$(find_elf "${elf}") |
| 29 |
|
| 30 |
printf "%s\n" "${resolved}" |
| 31 |
|
| 32 |
libs=$(scanelf -qF '#F%n' "${resolved}") |
| 33 |
|
| 34 |
local u uu d dd |
| 35 |
u=$(scanelf -q -F'%s#F' -s'%u%' "${elf}") |
| 36 |
for lib in ${libs//,/ } ; do |
| 37 |
lib=${lib##*/} |
| 38 |
rlib=$(find_elf "${lib}" "${resolved}") |
| 39 |
|
| 40 |
d=$(scanelf -qF'%s#F' -s`sym_list d "${u}"` "${rlib}") |
| 41 |
if [[ -n ${d} ]] ; then |
| 42 |
dd=${dd:+${dd},}${d} |
| 43 |
printf "%4s%s => %s\n" "" "${lib}" "${d}" |
| 44 |
else |
| 45 |
printf "%4s%s => %s\n" "" "${lib}" "!?! useless link !?!" |
| 46 |
fi |
| 47 |
done |
| 48 |
|
| 49 |
uu= |
| 50 |
for u in `echo "${u}" | sed 's:,: :g'` ; do |
| 51 |
[[ ,${dd}, != *,${u},* ]] && uu=${uu:+${uu},}${u} |
| 52 |
done |
| 53 |
if [[ -n ${uu} ]] ; then |
| 54 |
u=${uu} |
| 55 |
dd=$(scanelf -qF'%s#F' -s`sym_list w "${u}"` "${resolved}") |
| 56 |
if [[ -n ${dd} ]] ; then |
| 57 |
printf "%4s%s => %s\n" "" "WEAK" "${dd}" |
| 58 |
uu= |
| 59 |
for u in `echo "${u}" | sed 's:,: :g'` ; do |
| 60 |
[[ ,${dd}, != *,${u},* ]] && uu=${uu:+${uu},}${u} |
| 61 |
done |
| 62 |
fi |
| 63 |
if [[ -n ${uu} ]] ; then |
| 64 |
printf "%4s%s => %s\n" "" "UNRESOLVED" "${uu}" |
| 65 |
fi |
| 66 |
fi |
| 67 |
} |
| 68 |
|
| 69 |
SET_X=false |
| 70 |
|
| 71 |
while getopts hx OPT ; do |
| 72 |
case ${OPT} in |
| 73 |
x) SET_X=true;; |
| 74 |
h) usage;; |
| 75 |
*) usage 1;; |
| 76 |
esac |
| 77 |
done |
| 78 |
shift $((OPTIND - 1)) |
| 79 |
[[ -z $1 ]] && usage 1 |
| 80 |
|
| 81 |
${SET_X} && set -x |
| 82 |
|
| 83 |
ret=0 |
| 84 |
for elf in "$@" ; do |
| 85 |
if [[ ! -e ${elf} ]] ; then |
| 86 |
error "${elf}: file does not exist" |
| 87 |
elif [[ ! -r ${elf} ]] ; then |
| 88 |
error "${elf}: file is not readable" |
| 89 |
elif [[ -d ${elf} ]] ; then |
| 90 |
error "${elf}: is a directory" |
| 91 |
else |
| 92 |
[[ ${elf} != */* ]] && elf="./${elf}" |
| 93 |
show_elf "${elf}" 0 "" |
| 94 |
fi |
| 95 |
done |
| 96 |
exit ${ret} |