index : builder | |
Archlinux32 build system | gitolite user |
summaryrefslogtreecommitdiff |
author | Andreas Baumann <mail@andreasbaumann.cc> | 2018-01-19 22:20:49 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2018-01-19 22:20:49 +0100 |
commit | 636ee90f79a5a1551220427c89865c40bc0b65a7 (patch) | |
tree | cdcbbac04fd1eac8d80477413a25831678f64c8d /bin/check_opcodes | |
parent | 473118c413fad4050edcbd5e36e59de8a899f342 (diff) |
-rwxr-xr-x | bin/check_opcodes | 164 |
diff --git a/bin/check_opcodes b/bin/check_opcodes new file mode 100755 index 0000000..648be5c --- /dev/null +++ b/bin/check_opcodes @@ -0,0 +1,164 @@ +#!/bin/sh + +usage( ) { + >&2 cat <<EOF + +check_opcodes: [ -a <arch> ] <package> + +possible optons: + -h|--help: Show this help page + -v|--verbose: Verbose output + -a|--architecture: architecture family to check against, one of + i486, i686, pentium4 + +EOF + exit 1 +} + +VERBOSE=0 +EXIT_CODE=0 +log( ) { + if test $VERBOSE = 1; then + echo $* + fi +} + +err( ) { + echo "ERROR: $*" + EXIT_CODE=1 +} + +tmp_dir=$(mktemp -d 'tmp.check-opcodes.XXXXXXXXXX' --tmpdir) +trap "rm -rf --one-file-system '${tmp_dir:?}'" EXIT + +ARCH=i686 + +while getopts ":va:h-:" opt; do + case $opt in + -) + case "$OPTARG" in + help) + usage + ;; + verbose) + VERBOSE=1 + ;; + *) + echo "ERROR: Invalid option: --$OPTARG" >&2 + usage + ;; + esac + ;; + h) + usage + ;; + v) + VERBOSE=1 + ;; + a) + ARCH=$OPTARG + ;; + \?) + echo "ERROR: Invalid option: -$OPTARG" >&2 + usage + ;; + esac +done + +shift $((OPTIND-1)) + +PACKAGE=$1 + +if test "x$PACKAGE" = "x"; then + echo "ERROR: Filename of a package required as argument" >&2 + usage + exit 1 +fi + +OPCODE_ARGS="" +case $ARCH in + i486) + OPCODE_ARGS='-r -a 486 -v' + ;; + i686) + OPCODE_ARGS='-s MMX -s SSE -s SSE2' + ;; + pentium4) + OPCODE_ARGS='-s SSE3 -s SSSE3 -s AVX' + ;; + *) + echo "ERROR: architecture must currently be one of i486 and i686" >&2 + usage + exit 1 +esac + +log "Checking for architecture: $ARCH ($OPCODE_ARGS)" +bsdtar --no-fflags -x -C $tmp_dir -f $PACKAGE + +for absfile in `find $tmp_dir -name '*.so*' -type f`; do + file=`basename $absfile` + log "Checking shared library: $file" + readelf -a $absfile > $tmp_dir/$file.elf + objdump -f $absfile > $tmp_dir/$file.objdump + file $absfile > $tmp_dir/$file.file + + arch=`grep ^architecture $tmp_dir/$file.objdump | sed 's/^architecture: //g' | cut -f 1 -d ,` + case $arch in + i386:x86-64) + arch='x86_64' + ;; + i386) + arch='x86' + ;; + *) + arch='unknown' + ;; + esac + log " Objdump architecture: $arch" + + archelf=`grep '^ \+Class' $tmp_dir/$file.elf | cut -f 2 -d : | tr -d ' '` + case $archelf in + ELF64) + archelf='x86_64' + ;; + ELF32) + archelf='x86' + ;; + *) + archelf='unknown' + ;; + esac + log " Readelf architecture: $archelf" + + if test $arch != $archelf; then + err "$file ambigous architecture information (objdump: $arch, ELF: $archelf)" + fi + + if test $arch = "x86_64"; then + err "$file is a 64-bit library!" + continue + fi + + objdump -M intel -d $absfile > $tmp_dir/$file.asm + bad_opcodes=`cat $tmp_dir/$file.asm | ./opcode $OPCODE_ARGS -m 1 | wc -l` + if test $bad_opcodes != 0; then + case $ARCH in + i486) + err "$file is not built for plain i486 opcodes" + ;; + i686) + err "$file contains MMX, SSE or SSE2 opcodes" + ;; + pentium4) + err "$file contains SSE3 or newer opcodes" + ;; + esac + else + if test $VERBOSE = 1; then + log "$file fullfills architecture constraint for $ARCH" + fi + fi + +done + +exit $EXIT_CODE |