linux-yocto/scripts/objdiff
Jason Cooper 79192ca8eb scripts: objdiff: detect object code changes between two commits
objdiff is useful when doing large code cleanups.  For example, when
removing checkpatch warnings and errors from new drivers in the staging
tree.

objdiff can be used in conjunction with a git rebase to confirm that
each commit made no changes to the resulting object code.  It has the
same return values as diff(1).

This was written specifically to support adding the skein and threefish
cryto drivers to the staging tree.  I needed a programmatic way to
confirm that commits changing >90% of the lines didn't inadvertently
change the code.

Temporary files (objdump output) are stored in

  /path/to/linux/.tmp_objdiff

'make mrproper' will remove this directory.

Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Signed-off-by: Michal Marek <mmarek@suse.cz>
2014-04-08 16:41:44 +02:00

2.5 KiB
Executable File

#!/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

$

$ ./scripts/objdiff record path/to/*.o

$ git checkout COMMIT_B

$

$ ./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

GIT_DIR="git rev-parse --git-dir"

if [ -d "$GIT_DIR" ]; then TMPD="${GIT_DIR%git}tmp_objdiff"

[ -d "$TMPD" ] || mkdir "$TMPD"

else echo "ERROR: git directory not found." exit 1 fi

usage() { echo "Usage: $0 " echo " record " echo " diff " echo " clean all | " exit 1 }

dorecord() { [ $# -eq 0 ] && usage

FILES="$*"

CMT="`git rev-parse --short HEAD`"

OBJDUMP="${CROSS_COMPILE}objdump"
OBJDIFFD="$TMPD/$CMT"

[ ! -d "$OBJDIFFD" ] && mkdir -p "$OBJDIFFD"

for f in $FILES; do
	dn="${f%/*}"
	bn="${f##*/}"

	[ ! -d "$OBJDIFFD/$dn" ] && mkdir -p "$OBJDIFFD/$dn"

	# remove addresses for a more clear diff
	# http://dummdida.tumblr.com/post/60924060451/binary-diff-between-libc-from-scientificlinux-and
	$OBJDUMP -D "$f" | sed "s/^[[:space:]]\+[0-9a-f]\+//" \
		>"$OBJDIFFD/$dn/$bn"
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 "ERROR: $SRCD doesn't exist"
	exit 1
fi

if [ ! -d "$DSTD" ]; then
	echo "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 "$CMT not found"
	fi
fi

}

[ $# -eq 0 ] && usage

case "$1" in record) shift dorecord $* ;; diff) shift dodiff $* ;; clean) shift doclean $* ;; *) echo "Unrecognized command '$1'" exit 1 ;; esac