# check if stdout is a terminal... if test -t 1; then # see if it supports colors... ncolors=$(tput colors) if test -n "$ncolors" && test $ncolors -ge 8; then bold="$(tput bold)" underline="$(tput smul)" standout="$(tput smso)" normal="$(tput sgr0)" black="$(tput setaf 0)" red="$(tput setaf 1)" green="$(tput setaf 2)" yellow="$(tput setaf 3)" blue="$(tput setaf 4)" magenta="$(tput setaf 5)" cyan="$(tput setaf 6)" white="$(tput setaf 7)" fi fi function error { >&2 echo "${red}$1${normal}" } # helper function to get the runpath (-Wl,-rpath in gcc) function getrunpath() { local elfout=$(readelf -d $1 | grep "RUNPATH") regex="\[/([[:alpha:]/@_-\.[:digit:]]+)\]" if [[ $elfout =~ $regex ]]; then local myRPath=${BASH_REMATCH[1]} else error "Could not find RUNPATH for test $2" fi echo "$myRPath" } # helper function to list the dependencies of each executable function getdeps() { local deps=$(ldd $1) retsysdeps=() retlcldeps=() while IFS= read -r line; do regex1="/([[:alpha:]/@_-\.[:digit:]]+)" regex2="(libcfa[[:alpha:]\.[:digit:]]+) => not found" regex3="linux-vdso.so.1" if [[ $line =~ $regex1 ]]; then retsysdeps+=(${BASH_REMATCH[1]}) elif [[ $line =~ $regex2 ]]; then retlcldeps+=(${BASH_REMATCH[1]}) elif [[ $line =~ $regex3 ]]; then # echo "ignoring '$line}': intrinsic" : else error "Could not find dependency '$line' for test $2" fi done <<< "$deps" } # make a symlink, with better errors function makelink() { local source=$1 local target=$2 if [ ! -f $source ]; then error "Source of link $source does not exist" fi if [ ! -e $target ] && [ ! -L $target ]; then ln -s $source $target return fi if [ ! -L $target ]; then error "Cannot create link $target for $source, existing regular file" else want=$(readlink -f $source) have=$(readlink -f $target) if [ $want == $have ]; then return fi error "Target link $(basename $target) for $source already exists and has incorrect target $have" fi } # ======================================== # make sure this computer is acceptable myarch=$(uname -m) if [ ! -z $arch ] && [ "$myarch" != "$arch" ]; then error "Wrong architecture, is : $myarch, need: $arch" exit 1 fi myname=$(uname -n) if [ ! -z $name ] && [ "$myname" != "$name" ]; then >&2 echo "${yellow}Unexpected machine name, is: $myname, expected: $name${normal}" fi # ======================================== # make sure we use the right paths srcdir=$(readlink -f $(dirname "$0")) outdir=$(readlink -f $(pwd)) rnpaths=() sysdeps=() lcldeps=() # find all the tests programs=($(find $srcdir/tests/crashes -name exe)) if [ ${#programs[@]} -eq 0 ]; then error "ERROR no executables found in archive" exit 1 fi # ======================================== # for each tests echo "generating command files ..." for pgm in "${programs[@]}" do # find the test's name regex="tests/crashes/[[[:alpha:]/-]+/([[:alpha:]/\@_\-\.[:digit:]]+)/exe" if [[ $pgm =~ $regex ]]; then name=${BASH_REMATCH[1]} else error "Executable '$pgm' has ill-formed path" fi # get a path to the executable exe=$(readlink -f "$pgm") # check the executable exist if [ ! -x $exe ]; then error "Executable for '$name' does not have execute permission" continue fi ldd $exe > /dev/null 2>&1 if [ $? -ne 0 ]; then error "Executable for '$name' is not valid for this architecture" continue fi # get the corresponding core file core="$(dirname "$exe")/core" if [ ! -f "$core" ]; then error "No core found for test '$name'" fi # create the command file file="${name//\//.}.com" echo "$file" echo "set solib-absolute-prefix $outdir" > $file echo "file $exe" >> $file echo "core-file $core" >> $file # find the system dependencies getdeps $exe $name sysdeps+=("${retsysdeps[@]}") lcldeps+=("${retlcldeps[@]}") # find it's expected runpath rnpaths+=("$(getrunpath $exe $name)") done <<< "$programs" echo "done" # ======================================== # eliminate duplicates from the list of dependencies # get unique elements of array function getuniques() { echo "$*" | tr ' ' '\n' | sort -u | tr '\n' ' ' } rnpaths=($(getuniques ${rnpaths[@]})) sysdeps=($(getuniques ${sysdeps[@]})) lcldeps=($(getuniques ${lcldeps[@]})) # ======================================== # create symlinks to cforall dependencies echo "setting up local dependencies ..." for rpath in "${rnpaths[@]}" do # find the debug level if [[ $rpath =~ 'nodebug' ]]; then level="-nodebug" elif [[ $rpath =~ 'debug' ]]; then level="-debug" else error "Executable(s) with ill-formed rpath" fi # create the right directory mkdir -p "$outdir/$rpath" # for each dependencies create them # this might create unnecessary pairs, but I don't care for lib in "${lcldeps[@]}" do echo "$lib$level" source=$(find "$srcdir" -name "$lib*" -a -path "*$level*") target="$outdir/$rpath/$lib" makelink $source $target done done echo "done" # ======================================== # create symlinks to system dependencies echo "setting up system dependencies ..." for dep in "${sysdeps[@]}" do echo $dep mkdir -p "$outdir/$(dirname $dep)" makelink "/$dep" "$outdir/$dep" done echo "done"