diff options
Diffstat (limited to 'scripts/objdiff')
| -rwxr-xr-x | scripts/objdiff | 159 | 
1 files changed, 159 insertions, 0 deletions
diff --git a/scripts/objdiff b/scripts/objdiff new file mode 100755 index 00000000000..62e51dae213 --- /dev/null +++ b/scripts/objdiff @@ -0,0 +1,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  | 
