1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
# objdiff - a small script for validating that a commit or series of commits
# didn't change object code.
#
# Copyright 2014, Jason Cooper <jason@lakedaemon.net>
#
# usage example:
#
# $ git checkout COMMIT_A
# $ <your fancy build command here>
# $ ./scripts/objdiff record path/to/*.o
#
# $ git checkout COMMIT_B
# $ <your fancy build command here>
# $ ./scripts/objdiff record path/to/*.o
#
# $ ./scripts/objdiff diff COMMIT_A COMMIT_B
# $
# And to clean up (everything is in .objdiff/*)
# $ ./scripts/objdiff clean all
#
# Note: 'make mrproper' will also remove .objdiff
SRCTREE=$(cd $(git rev-parse --show-toplevel 2>/dev/null); pwd)
if [ -z "$SRCTREE" ]; then
echo >&2 "ERROR: Not a git repository."
exit 1
fi
TMPD=$SRCTREE/.objdiff
usage() {
echo >&2 "Usage: $0 <command> <args>"
echo >&2 " record <list of object files or directories>"
echo >&2 " diff <commitA> <commitB>"
echo >&2 " clean all | <commit>"
exit 1
}
get_output_dir() {
dir=${1%/*}
if [ "$dir" = "$1" ]; then
dir=.
fi
dir=$(cd $dir; pwd)
echo $TMPD/$CMT${dir#$SRCTREE}
}
do_objdump() {
dir=$(get_output_dir $1)
base=${1##*/}
stripped=$dir/${base%.o}.stripped
dis=$dir/${base%.o}.dis
[ ! -d "$dir" ] && mkdir -p $dir
# remove addresses for a cleaner diff
# http://dummdida.tumblr.com/post/60924060451/binary-diff-between-libc-from-scientificlinux-and
$STRIP -g $1 -R __bug_table -R .note -R .comment -o $stripped
$OBJDUMP -D $stripped | sed -e "s/^[[:space:]]\+[0-9a-f]\+//" -e "s:^$stripped:$1:" > $dis
}
dorecord() {
[ $# -eq 0 ] && usage
FILES="$*"
CMT="`git rev-parse --short HEAD`"
STRIP="${CROSS_COMPILE}strip"
OBJDUMP="${CROSS_COMPILE}objdump"
for d in $FILES; do
if [ -d "$d" ]; then
for f in $(find $d -name '*.o')
do
do_objdump $f
done
else
do_objdump $d
fi
done
}
dodiff() {
[ $# -ne 2 ] && [ $# -ne 0 ] && usage
if [ $# -eq 0 ]; then
SRC="`git rev-parse --short HEAD^`"
DST="`git rev-parse --short HEAD`"
else
SRC="`git rev-parse --short $1`"
DST="`git rev-parse --short $2`"
fi
DIFF="`which colordiff`"
if [ ${#DIFF} -eq 0 ] || [ ! -x "$DIFF" ]; then
DIFF="`which diff`"
fi
SRCD="$TMPD/$SRC"
DSTD="$TMPD/$DST"
if [ ! -d "$SRCD" ]; then
echo >&2 "ERROR: $SRCD doesn't exist"
exit 1
fi
if [ ! -d "$DSTD" ]; then
echo >&2 "ERROR: $DSTD doesn't exist"
exit 1
fi
$DIFF -Nurd $SRCD $DSTD
}
doclean() {
[ $# -eq 0 ] && usage
[ $# -gt 1 ] && usage
if [ "x$1" = "xall" ]; then
rm -rf $TMPD/*
else
CMT="`git rev-parse --short $1`"
if [ -d "$TMPD/$CMT" ]; then
rm -rf $TMPD/$CMT
else
echo >&2 "$CMT not found"
fi
fi
}
[ $# -eq 0 ] && usage
case "$1" in
record)
shift
dorecord $*
;;
diff)
shift
dodiff $*
;;
clean)
shift
doclean $*
;;
*)
echo >&2 "Unrecognized command '$1'"
exit 1
;;
esac
|