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