| #!/bin/sh |
| # check-each-file |
| # Used to narrow down a miscompilation to one .o file from a list. Please read |
| # the usage procedure, below, for command-line syntax (or run it with --help). |
| # This script depends on the llvm-native-gcc script. |
| |
| if [ x$1 = x--make-linker-script ] |
| then |
| program=$2 |
| linker=./link-$program |
| echo "Building $program with llvm-native-gcc" |
| rm -f $program |
| gmake -e $program CC=llvm-native-gcc CXX=llvm-native-gxx |
| echo "Erasing $program and re-linking it" |
| rm -f $program |
| echo "rm -f $program" > $linker |
| gmake -n $program >> $linker |
| chmod 755 $linker |
| echo "Linker script created in $linker; testing it out" |
| output=`./$linker 2>&1` |
| case "$output" in |
| *undefined*reference*__main*) |
| echo "$program appears to need a dummy __main function; adding one" |
| echo "void __main () { }" > __main.c |
| gcc -c __main.c |
| echo "Done; rebuilding $linker" |
| echo "rm -f $program" > $linker |
| gmake -n $program 2>&1 | sed '/gcc/s/$/__main.o/' >> $linker |
| ./$linker > /dev/null 2>&1 |
| if [ ! -x $program ] |
| then |
| echo "WARNING: linker script didn't work" |
| fi |
| ;; |
| *) |
| if [ ! -x $program ] |
| then |
| echo "WARNING: linker script didn't work" |
| fi |
| ;; |
| esac |
| echo "Linker script created in $linker; please check it manually" |
| exit 0 |
| fi |
| |
| checkfiles="$1" |
| program="$2" |
| linker="$3" |
| checker="$4" |
| |
| usage () { |
| myname=`basename $0` |
| echo "$myname --make-linker-script PROGRAM" |
| echo "$myname OBJECTS-FILE PROGRAM LINKER CHECKER" |
| echo "" |
| echo "OBJECTS-FILE is a text file containing the names of all the .o files" |
| echo "PROGRAM is the name of the executable under test" |
| echo "(there must also exist a Makefile in the current directory which" |
| echo "has PROGRAM as a target)" |
| echo "LINKER is the script that builds PROGRAM; try --make-linker-script" |
| echo "to automatically generate it" |
| echo "CHECKER is the script that exits 0 if PROGRAM is ok, 1 if it is not OK" |
| echo "(LINKER and CHECKER must be in your PATH, or you should specify ./)" |
| echo "" |
| echo "Bugs to <gaeke@uiuc.edu>." |
| exit 1 |
| } |
| |
| if [ x$1 = x--help ] |
| then |
| usage |
| fi |
| |
| if [ -z "$checkfiles" ] |
| then |
| echo "ERROR: Must specify name of file w/ list of objects as 1st arg." |
| echo "(got \"$checkfiles\")" |
| usage |
| fi |
| if [ ! -f "$checkfiles" ] |
| then |
| echo "ERROR: $checkfiles not found" |
| usage |
| fi |
| if [ -z "$program" ] |
| then |
| echo "ERROR: Must specify name of program as 2nd arg." |
| usage |
| fi |
| if [ -z "$linker" ] |
| then |
| echo "ERROR: Must specify name of link script as 3rd arg." |
| usage |
| fi |
| if [ ! -x "$linker" ] |
| then |
| echo "ERROR: $linker not found or not executable" |
| echo "You may wish to try: $0 --make-linker-script $program" |
| usage |
| fi |
| if [ -z "$checker" ] |
| then |
| echo "ERROR: Must specify name of $program check script as 3rd arg." |
| usage |
| fi |
| if [ ! -x "$checker" ] |
| then |
| echo "ERROR: $checker not found or not executable" |
| usage |
| fi |
| |
| files=`cat $checkfiles` |
| echo "Recompiling everything with llvm-native-gcc" |
| for f in $files |
| do |
| rm -f $f |
| gmake $f CC=llvm-native-gcc CXX=llvm-native-gxx |
| done |
| rm -f $program |
| $linker |
| if $checker |
| then |
| echo "Sorry, I can't help you, $program is OK when compiled with llvm-native-gcc" |
| exit 1 |
| fi |
| for f in $files |
| do |
| echo Trying to compile $f with native gcc and rebuild $program |
| mv ${f} ${f}__OLD__ |
| gmake ${f} CC=gcc > /dev/null 2>&1 |
| $linker |
| echo Checking validity of new $program |
| if $checker |
| then |
| echo Program is OK |
| okfiles="$okfiles $f" |
| else |
| echo Program is not OK |
| notokfiles="$notokfiles $f" |
| fi |
| mv ${f}__OLD__ ${f} |
| done |
| echo "" |
| echo "Program is OK when these files are recompiled with native gcc: " |
| echo "$okfiles" |
| echo "" |
| echo "Program is not OK when these files are recompiled with native gcc: " |
| echo "$notokfiles" |
| echo "" |
| exit 0 |