#!/bin/sh -ef . /usr/lib/rpm/functions [ -z "$RPM_BUILD_ROOT" ] || ValidateBuildRoot RTLD=/lib/ld-linux.so.2 RTLD_libpath=/lib:/usr/lib:/usr/X11R6/lib elf1_libpath() { local elf="$1" libpath="$RTLD_libpath" [ -z "$LD_LIBRARY_PATH" ] || libpath="$LD_LIBRARY_PATH:$libpath" [ -z "$RPM_FINDPROV_LIB_PATH" ] || libpath="$RPM_FINDPROV_LIB_PATH:$libpath" local info= rpath= info="$(objdump -p "$elf")" || return rpath="$(echo "$info" |awk '($1=="RPATH"){printf "%s:", $2}')" [ -z "$rpath" ] || libpath="$rpath$libpath" if [ -n "$RPM_BUILD_ROOT" ]; then local BR_libpath= path= IFS=: for path in $libpath; do BR_libpath="$BR_libpath:$RPM_BUILD_ROOT$path" done libpath="${BR_libpath#:}:$libpath" fi echo "$libpath" } elf1_ldd() { local elf="$1" libpath= libpath="$(elf1_libpath "$elf")" || return LD_TRACE_LOADED_OBJECTS=1 LD_WARN=1 LD_BIND_NOW=1 LD_VERBOSE= \ "$RTLD" --library-path "$libpath" --inhibit-rpath "$elf" "$elf" } elf1_undefined_symbols() { local elf="$1" out= if ! out="$(elf1_ldd "$elf" 2>&1)"; then echo "$PROG: $elf: ldd failed:" >&2 echo "$out" >&2 return 2 fi if [ -n "$out" -a -z "${out##* not found*}" ]; then echo "$PROG: $elf: unresolved dependencies:" >&2 echo "$out" |grep -F ' not found' >&2 return 1 fi if [ -n "$out" -a -z "${out##*undefined symbol:*}" ]; then echo "$out" |awk '/^undefined symbol:/ { gsub("^[(]|[)]$", "", $NF) print $3 "\t" $NF }' fi } elf1_verify_strict() { local elf="$1" err= err="$(elf1_undefined_symbols "$elf")" || return 2 [ -n "$err" ] || return 0 local sym= obj= while IFS=$'\t' read -r sym obj; do [ "$obj" = "$elf" ] && echo "$PROG: $elf: undefined symbol: $sym" >&2 || echo "$PROG: $elf: undefined symbol: $sym ($obj)" >&2 done <<<"$err" return 1 } elf1_verify_relaxed() { local elf="$1" symtab="$2" err= err="$(elf1_undefined_symbols "$elf")" || return 2 [ -n "$err" ] || return 0 local rc=0 sym= obj= while IFS=$'\t' read -r sym obj; do if [ "$obj" != "$elf" ]; then echo "$PROG: $elf: undefined symbol: $sym ($obj)" >&2 rc=1 elif ! bloom -e "$sym" "$symtab"; then echo "$PROG: $elf: undefined symbol: $sym" >&2 rc=1 fi done <<<"$err" return $rc } : ${VERIFY_ELF_SYM:=normal} case "$VERIFY_ELF_SYM" in strict|normal|relaxed) : ;; no|none|skip) exit 0 ;; *) Fatal "Unrecognized $PROG method: $VERIFY_ELF_SYM" ;; esac rc=0 symtab="$1" shift for elf; do if ! type="$(file -bL "$elf")"; then echo "$PROG: $elf: $type" >&2 rc=1 continue fi [ -n "$type" ] || continue [ -z "${type##*ELF*dynamic*}" -o -z "${type##*ELF*shared*}" ] || continue if [ "$VERIFY_ELF_SYM" = strict ]; then elf1_verify_strict "$elf" || rc=1 elif [ "$VERIFY_ELF_SYM" = relaxed ]; then elf1_verify_relaxed "$elf" "$symtab" || rc=1 elif [ -z "${type##*ELF*executable*}" ]; then elf1_verify_strict "$elf" || rc=1 elif [ -z "${type##*ELF*shared*}" -a -z "${elf##*/lib/lib*.so*}" ]; then elf1_verify_strict "$elf" || rc=1 else elf1_verify_relaxed "$elf" "$symtab" || rc=1 fi done exit $rc