Loading...
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 | #!/bin/bash # 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> # # Licensed under the terms of the GNU GPL version 2 # 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 .tmp_objdiff/*) # $ ./scripts/objdiff clean all # # Note: 'make mrproper' will also remove .tmp_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/.tmp_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##*/} 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 $OBJDUMP -D $1 | sed "s/^[[:space:]]\+[0-9a-f]\+//" > $dis } dorecord() { [ $# -eq 0 ] && usage FILES="$*" CMT="`git rev-parse --short HEAD`" 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 |