#!/bin/sh # shellcheck disable=SC2086 # shellcheck source=conf/default.conf . "${0%/*}/../conf/default.conf" usage( ) { >&2 cat < ] 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 "${work_dir}/tmp.check-opcodes.XXXXXX") 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 # shellcheck disable=SC2044 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=$(${base_dir}/bin/opcode $OPCODE_ARGS -m 1 < $tmp_dir/$file.asm | 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