linux-yocto/scripts/objdiff
Stephen Boyd 65ba6fa439 scripts: objdiff: Ignore debug info when comparing
If the kernel is configured to be built with debug symbols, or
has bug tables, comparing files may not work if line numbers
change. This makes comparing object files with these options
harder to do. Let's strip out the debug info and drop the
__bug_table here so that we don't see false positives. There may
be other things to drop later, and it may be architecture
specific, but this works for me with my ARM64 build.

Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
Reviewed-by: Jason Cooper <jason@lakedaemon.net>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2017-03-11 11:13:38 +09:00

2.8 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

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 " echo >&2 " record " echo >&2 " diff " echo >&2 " clean all | " 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