#!/bin/bash ########################################## # this script checks for missing symbols # ########################################## # # $1 = file to check (optional, does whole system otherwise) # $2 = space-separated additional libs to check # # 1 for pass 1,2,3 failures # 2 for pass 2,3 failures # 3 for pass 3 failures SYMVERBOSE=3 # anything but 3 here is asking for lots of warnings symscan() { readelf -W -D -s "$1" | grep 'DEFAULT UND ' | awk '{ print $9 }' | grep -v '^_' | tail -n +4; } libsymscan() { if [ -f /tmp/tableindex.file."${1//\//\`}" ]; then cat /tmp/tableindex.file."${1//\//\`}"; else file "$(readlink -f "$1")" | grep -q ELF\ .*shared && readelf -W -s "$1" | grep -v 'DEFAULT UND ' | awk '{ print $8 }' | tail -n +4 | cut -d'@' -f1 | tee /tmp/tableindex.file."${1//\//\`}"; fi } libscan() { ldd "$1" 2> /dev/null | cut -d'>' -f2 | cut -d' ' -f2 | grep '^/'; } tablegen() { TOTAL=$(cat "$1" | wc -l) TABLECOUNT=0 while read line; do #local fileline="${line//\//\`}" #libsymscan $line | tee /tmp/tableindex.file."$fileline" libsymscan $line | tee /tmp/tableindex.file."$fileline" progress_bar $((++TABLECOUNT)) $TOTAL 60 > /dev/stderr done < "$1" | cut -d@ -f1 | grep -v '^_' | sort | uniq > "$2" clear_line } tablegenall() { [ ! -f /tmp/tableindex ] && { # find $(cat /etc/ld.so.conf) -maxdepth 1 -type f 2> /dev/null > /tmp/tablelist gaze from .so | cut -d: -f2- > /tmp/tablelist echo message "Generating symbol lists for all .so files" tablegen /tmp/tablelist /tmp/tableindex rm /tmp/tablelist } } tablegenlog() { [ ! -f /tmp/tableindex."$1" ] && { gaze install "$1" > /tmp/tablelist."$1" echo message "Generating symbol lists within spell $1" tablegen /tmp/tablelist."$1" /tmp/tableindex."$1".source cat /tmp/tableindex /tmp/tableindex."$1".source | sort | uniq > /tmp/tableindex."$1" rm /tmp/tableindex."$1".source rm /tmp/tablelist."$1" } } symbolcheck() { FILE="$1" SPELL="$($COMPRESSBIN -cd $COMPILE_LOGS/"$( gaze from "^${FILE}" | tail -n 1 | cut -d: -f1 )"$EXTENSION 2> /dev/null | head -n 1 | awk '{ print $4 }' )" ADDITIONALLIBS="$2" symscan "$FILE" | sort | uniq > /tmp/tableneed { libscan "$FILE" for i in $ADDITIONALLIBS; do find /usr/lib /lib -maxdepth 1 -name 'lib$i.so*' 2> /dev/null ls "$i" 2> /dev/null done echo "$FILE" } | while read line; do libsymscan "$line" done | cut -d@ -f1 | grep -v '^_' | sort | uniq > /tmp/tablehave CHECKSELF="$(diff /tmp/tableneed /tmp/tablehave | grep '^< ' | cut -c3-)" if [ -n "$CHECKSELF" ]; then if [ $SYMVERBOSE -lt 2 ]; then clear_line echo -e "$SPELL_COLOR$i$QUERY_COLOR: pass 1 failure$DEFAULT_COLOR" message " Failed Symbol Check, searching libraries." echo -n ' ' fi tablegenall CHECKALL="$(diff /tmp/tableneed /tmp/tableindex | grep '^< ' | cut -c3-)" if [ -n "$CHECKALL" ]; then if [ $SYMVERBOSE -lt 3 ]; then clear_line echo -e "$SPELL_COLOR$i$QUERY_COLOR: pass 2 failure$DEFAULT_COLOR" message " Still Failed Symbol Check, searching install log." echo -e " missing symbols:\n$CHECKALL" echo -n ' ' fi tablegenlog "$SPELL" CHECKLOG="$(diff /tmp/tableneed /tmp/tableindex."$SPELL" | grep '^< ' | cut -c3-)" if [ -n "$CHECKLOG" ]; then if [ $SYMVERBOSE -lt 4 ]; then clear_line echo -e "$SPELL_COLOR$i$QUERY_COLOR: pass 3 total failure$DEFAULT_COLOR" message " Completely Failed Symbol Check" echo -e " missing symbols:\n$CHECKLOG" echo -n ' ' fi else debug " Symbol Check passed in third and final phase" if [ $SYMVERBOSE -lt 3 ]; then clear_line echo -e "$SPELL_COLOR$i$QUERY_COLOR: pass 3 success$DEFAULT_COLOR" echo -n ' ' fi fi else debug " Symbol Check passed in second phase" if [ $SYMVERBOSE -lt 2 ]; then clear_line echo -e "$SPELL_COLOR$i$QUERY_COLOR: pass 2 success$DEFAULT_COLOR" message " missing symbols:\n$CHECKSELF" message " are defined here:" find /tmp -maxdepth 1 -name 'tableindex.file.*' -print0 | xargs -0 grep -Hx "$(echo "$CHECKSELF" | tr '\n' '\a' | sed -e 's/\a$//;s/\a/\\\|/g')" | cut -d: -f1 | uniq | cut -d'.' -f3- | tr '`' '/' echo -n ' ' fi fi else debug " Symbol Check Passed" fi } . /etc/sorcery/config if [[ "$1" ]]; then i="$1" ldd -r "$i" 2>&1 | grep -q 'undefined symbol' && symbolcheck "$i" "$2" || echo "Check passed..." else COUNT=0 ALL="$(find /bin/ /lib/ /usr/bin/ /usr/lib/ /usr/X11R6/bin/ /usr/X11R6/lib/ -maxdepth 1)" TOTAL="$(echo "$ALL" | wc -l)" echo "$ALL" | while read i; do #echo "checking $i:" [ ! -h "$i" -a -f "$i" ] && ldd -r "$i" 2>&1 | grep -q 'undefined symbol' && symbolcheck "$i" progress_bar $((++COUNT)) $TOTAL 60 > /dev/stderr done clear_line fi ## clear the caches #rm /tmp/tableindex 2> /dev/null #rm /tmp/tableindex.$SPELL 2> /dev/null #rm /tmp/tableindex.file.* 2> /dev/null #rm /tmp/tableneed 2> /dev/null #rm /tmp/tablehave 2> /dev/null