16276797fSBaptiste Daroussin#!/bin/sh 26276797fSBaptiste Daroussin 33844bbe2SBryan Drewerylibkey() { 43844bbe2SBryan Drewery libkey="lib_symbols_$1" 55f6c4518SBryan Drewery patterns=[.+,/-] 63844bbe2SBryan Drewery replacement=_ 73844bbe2SBryan Drewery while :; do 83844bbe2SBryan Drewery case " ${libkey} " in 93844bbe2SBryan Drewery *${patterns}*) 103844bbe2SBryan Drewery libkey="${libkey%%${patterns}*}${replacement}${libkey#*${patterns}}" 113844bbe2SBryan Drewery ;; 123844bbe2SBryan Drewery *) 133844bbe2SBryan Drewery break 143844bbe2SBryan Drewery ;; 153844bbe2SBryan Drewery esac 163844bbe2SBryan Drewery done 173844bbe2SBryan Drewery return 0 183844bbe2SBryan Drewery} 193844bbe2SBryan Drewery 208afa72e5SBryan Dreweryusage() { 218afa72e5SBryan Drewery cat <<-EOF 22fcd26781SBryan Drewery usage: $0 [-Uv] [-L LD_LIBRARY_PATH] file 23fcd26781SBryan Drewery -L: Specify an alternative LD_LIBRARY_PATH for the library resolution. 248afa72e5SBryan Drewery -U: Skip looking for unresolved symbols. 258afa72e5SBryan Drewery -v: Show which library each symbol is resolved to. 268afa72e5SBryan Drewery EOF 278afa72e5SBryan Drewery exit 0 288afa72e5SBryan Drewery} 298afa72e5SBryan Drewery 303554283aSBryan Dreweryret=0 313554283aSBryan DreweryCHECK_UNRESOLVED=1 32fc2ef3b2SBryan DreweryVERBOSE_RESOLVED=0 33fcd26781SBryan Drewerywhile getopts "L:Uv" flag; do 343554283aSBryan Drewery case "${flag}" in 35fcd26781SBryan Drewery L) LIB_PATH="${OPTARG}" ;; 363554283aSBryan Drewery U) CHECK_UNRESOLVED=0 ;; 37fc2ef3b2SBryan Drewery v) VERBOSE_RESOLVED=1 ;; 388afa72e5SBryan Drewery *) usage ;; 393554283aSBryan Drewery esac 403554283aSBryan Drewerydone 413554283aSBryan Dreweryshift $((OPTIND-1)) 423554283aSBryan Drewery 43d1db5f8fSBryan Dreweryif ! [ -f "$1" ]; then 44d1db5f8fSBryan Drewery echo "No such file or directory: $1" >&2 45d1db5f8fSBryan Drewery exit 1 46d1db5f8fSBryan Dreweryfi 47d1db5f8fSBryan Drewery 483554283aSBryan Drewerymime=$(file -L --mime-type $1) 493554283aSBryan Dreweryisbin=0 503554283aSBryan Drewerycase $mime in 5188741a40SBaptiste Daroussin*application/x-executable|*application/x-pie-executable) isbin=1 ;; 523554283aSBryan Drewery*application/x-sharedlib);; 533554283aSBryan Drewery*) echo "Not an elf file" >&2 ; exit 1;; 543554283aSBryan Dreweryesac 553554283aSBryan Drewery 563554283aSBryan Drewery# Gather all symbols from the target 5764ee145bSBryan Dreweryunresolved_symbols=$(nm -u -D --format=posix "$1" | awk '$2 == "U" {print $1}' | tr '\n' ' ') 5864ee145bSBryan Drewery[ ${isbin} -eq 1 ] && bss_symbols=$(nm -D --format=posix "$1" | awk '$2 == "B" && $4 != "" {print $1}' | tr '\n' ' ') 59fcd26781SBryan Dreweryif [ -n "${LIB_PATH}" ]; then 60fcd26781SBryan Drewery for libc in /lib/libc.so.*; do 61fcd26781SBryan Drewery LDD_ENV="LD_PRELOAD=${libc}" 62fcd26781SBryan Drewery done 63fcd26781SBryan Drewery LDD_ENV="${LDD_ENV} LD_LIBRARY_PATH=${LIB_PATH}" 64fcd26781SBryan Dreweryfi 65fcd26781SBryan Drewery 66fcd26781SBryan Dreweryldd_libs=$(env ${LDD_ENV} ldd $(realpath $1) | awk '{print $1 ":" $3}') 673554283aSBryan Drewery 686276797fSBaptiste Daroussin# Check for useful libs 693844bbe2SBryan Drewerylist_libs= 703844bbe2SBryan Dreweryresolved_symbols= 71daa301d1SBryan Dreweryfor lib in $(readelf -d $1 | awk '$2 ~ /\(?NEEDED\)?/ { sub(/\[/,"",$NF); sub(/\]/,"",$NF); print $NF }'); do 726276797fSBaptiste Daroussin echo -n "checking if $lib is needed: " 735f6c4518SBryan Drewery if [ -n "${lib##/*}" ]; then 743844bbe2SBryan Drewery for libpair in ${ldd_libs}; do 753844bbe2SBryan Drewery case "${libpair}" in 763844bbe2SBryan Drewery ${lib}:*) libpath="${libpair#*:}" && break ;; 773844bbe2SBryan Drewery esac 786276797fSBaptiste Daroussin done 795f6c4518SBryan Drewery else 805f6c4518SBryan Drewery libpath="${lib}" 815f6c4518SBryan Drewery fi 823844bbe2SBryan Drewery list_libs="$list_libs $lib" 833844bbe2SBryan Drewery foundone= 843554283aSBryan Drewery lib_symbols="$(nm -D --defined-only --format=posix "${libpath}" | awk '$2 ~ /C|R|D|T|W|B|V/ {print $1}' | tr '\n' ' ')" 853844bbe2SBryan Drewery if [ ${CHECK_UNRESOLVED} -eq 1 ]; then 863844bbe2SBryan Drewery # Save the global symbols for this lib 873844bbe2SBryan Drewery libkey "${lib}" 883844bbe2SBryan Drewery setvar "${libkey}" "${lib_symbols}" 893844bbe2SBryan Drewery fi 903844bbe2SBryan Drewery for fct in ${lib_symbols}; do 9164ee145bSBryan Drewery case " ${unresolved_symbols} ${bss_symbols} " in 923844bbe2SBryan Drewery *\ ${fct}\ *) foundone="${fct}" && break ;; 933844bbe2SBryan Drewery esac 943844bbe2SBryan Drewery done 953844bbe2SBryan Drewery if [ -n "${foundone}" ]; then 963844bbe2SBryan Drewery echo "yes... ${foundone}" 976276797fSBaptiste Daroussin else 986276797fSBaptiste Daroussin echo "no" 993844bbe2SBryan Drewery ret=1 1006276797fSBaptiste Daroussin fi 1016276797fSBaptiste Daroussindone 1026276797fSBaptiste Daroussin 1033844bbe2SBryan Dreweryif [ ${CHECK_UNRESOLVED} -eq 1 ]; then 1043554283aSBryan Drewery # Add in crt1 symbols 1053554283aSBryan Drewery list_libs="${list_libs} crt1.o" 1063554283aSBryan Drewery lib_symbols="$(nm --defined-only --format=posix "/usr/lib/crt1.o" | awk '$2 ~ /C|R|D|T|W|B|V/ {print $1}' | tr '\n' ' ')" 1073554283aSBryan Drewery # Save the global symbols for this lib 1083554283aSBryan Drewery libkey "crt1.o" 1093554283aSBryan Drewery setvar "${libkey}" "${lib_symbols}" 1103554283aSBryan Drewery 111b0cb3920SBryan Drewery # Now search libs for all symbols and report missing ones. 1123844bbe2SBryan Drewery for sym in ${unresolved_symbols}; do 1136276797fSBaptiste Daroussin found=0 1143844bbe2SBryan Drewery for lib in ${list_libs}; do 1153844bbe2SBryan Drewery libkey "${lib}" 1163844bbe2SBryan Drewery eval "lib_symbols=\"\${${libkey}}\"" 1173844bbe2SBryan Drewery # lib_symbols now contains symbols for the lib. 1183844bbe2SBryan Drewery case " ${lib_symbols} " in 119fc2ef3b2SBryan Drewery *\ ${sym}\ *) 120fc2ef3b2SBryan Drewery [ ${VERBOSE_RESOLVED} -eq 1 ] && 121fc2ef3b2SBryan Drewery echo "Resolved symbol ${sym} from ${lib}" 122fc2ef3b2SBryan Drewery found=1 123fc2ef3b2SBryan Drewery break 124fc2ef3b2SBryan Drewery ;; 1253844bbe2SBryan Drewery esac 1266276797fSBaptiste Daroussin done 1276276797fSBaptiste Daroussin if [ $found -eq 0 ]; then 1286276797fSBaptiste Daroussin echo "Unresolved symbol $sym" 1293844bbe2SBryan Drewery ret=1 1306276797fSBaptiste Daroussin fi 1316276797fSBaptiste Daroussin done 1323844bbe2SBryan Dreweryfi 1333844bbe2SBryan Drewery 1343844bbe2SBryan Dreweryexit ${ret} 135