xref: /linux/scripts/objdiff (revision 7fa0e6db3cedc9b70d68a4170f1352e2b1aa0f90)
179192ca8SJason Cooper#!/bin/bash
279192ca8SJason Cooper
379192ca8SJason Cooper# objdiff - a small script for validating that a commit or series of commits
479192ca8SJason Cooper# didn't change object code.
579192ca8SJason Cooper#
679192ca8SJason Cooper# Copyright 2014, Jason Cooper <jason@lakedaemon.net>
779192ca8SJason Cooper#
879192ca8SJason Cooper# Licensed under the terms of the GNU GPL version 2
979192ca8SJason Cooper
1079192ca8SJason Cooper# usage example:
1179192ca8SJason Cooper#
1279192ca8SJason Cooper# $ git checkout COMMIT_A
1379192ca8SJason Cooper# $ <your fancy build command here>
1479192ca8SJason Cooper# $ ./scripts/objdiff record path/to/*.o
1579192ca8SJason Cooper#
1679192ca8SJason Cooper# $ git checkout COMMIT_B
1779192ca8SJason Cooper# $ <your fancy build command here>
1879192ca8SJason Cooper# $ ./scripts/objdiff record path/to/*.o
1979192ca8SJason Cooper#
2079192ca8SJason Cooper# $ ./scripts/objdiff diff COMMIT_A COMMIT_B
2179192ca8SJason Cooper# $
2279192ca8SJason Cooper
2379192ca8SJason Cooper# And to clean up (everything is in .tmp_objdiff/*)
2479192ca8SJason Cooper# $ ./scripts/objdiff clean all
2579192ca8SJason Cooper#
2679192ca8SJason Cooper# Note: 'make mrproper' will also remove .tmp_objdiff
2779192ca8SJason Cooper
2818165efaSMasahiro YamadaSRCTREE=$(cd $(git rev-parse --show-toplevel 2>/dev/null); pwd)
2979192ca8SJason Cooper
30fd6e1242SMasahiro Yamadaif [ -z "$SRCTREE" ]; then
315ab370e9SMasahiro Yamada	echo >&2 "ERROR: Not a git repository."
3279192ca8SJason Cooper	exit 1
3379192ca8SJason Cooperfi
3479192ca8SJason Cooper
35fd6e1242SMasahiro YamadaTMPD=$SRCTREE/.tmp_objdiff
36fd6e1242SMasahiro Yamada
3779192ca8SJason Cooperusage() {
385ab370e9SMasahiro Yamada	echo >&2 "Usage: $0 <command> <args>"
39*7fa0e6dbSMasahiro Yamada	echo >&2 "  record    <list of object files or directories>"
405ab370e9SMasahiro Yamada	echo >&2 "  diff      <commitA> <commitB>"
415ab370e9SMasahiro Yamada	echo >&2 "  clean     all | <commit>"
4279192ca8SJason Cooper	exit 1
4379192ca8SJason Cooper}
4479192ca8SJason Cooper
4518165efaSMasahiro Yamadaget_output_dir() {
4618165efaSMasahiro Yamada	dir=${1%/*}
4718165efaSMasahiro Yamada
4818165efaSMasahiro Yamada	if [ "$dir" = "$1" ]; then
4918165efaSMasahiro Yamada		dir=.
5018165efaSMasahiro Yamada	fi
5118165efaSMasahiro Yamada
5218165efaSMasahiro Yamada	dir=$(cd $dir; pwd)
5318165efaSMasahiro Yamada
5418165efaSMasahiro Yamada	echo $TMPD/$CMT${dir#$SRCTREE}
5518165efaSMasahiro Yamada}
5618165efaSMasahiro Yamada
57*7fa0e6dbSMasahiro Yamadado_objdump() {
58*7fa0e6dbSMasahiro Yamada	dir=$(get_output_dir $1)
59*7fa0e6dbSMasahiro Yamada	base=${1##*/}
60*7fa0e6dbSMasahiro Yamada	dis=$dir/${base%.o}.dis
61*7fa0e6dbSMasahiro Yamada
62*7fa0e6dbSMasahiro Yamada	[ ! -d "$dir" ] && mkdir -p $dir
63*7fa0e6dbSMasahiro Yamada
64*7fa0e6dbSMasahiro Yamada	# remove addresses for a cleaner diff
65*7fa0e6dbSMasahiro Yamada	# http://dummdida.tumblr.com/post/60924060451/binary-diff-between-libc-from-scientificlinux-and
66*7fa0e6dbSMasahiro Yamada	$OBJDUMP -D $1 | sed "s/^[[:space:]]\+[0-9a-f]\+//" > $dis
67*7fa0e6dbSMasahiro Yamada}
68*7fa0e6dbSMasahiro Yamada
6979192ca8SJason Cooperdorecord() {
7079192ca8SJason Cooper	[ $# -eq 0 ] && usage
7179192ca8SJason Cooper
7279192ca8SJason Cooper	FILES="$*"
7379192ca8SJason Cooper
7479192ca8SJason Cooper	CMT="`git rev-parse --short HEAD`"
7579192ca8SJason Cooper
7679192ca8SJason Cooper	OBJDUMP="${CROSS_COMPILE}objdump"
7779192ca8SJason Cooper
78*7fa0e6dbSMasahiro Yamada	for d in $FILES; do
79*7fa0e6dbSMasahiro Yamada		if [ -d "$d" ]; then
80*7fa0e6dbSMasahiro Yamada			for f in $(find $d -name '*.o')
81*7fa0e6dbSMasahiro Yamada			do
82*7fa0e6dbSMasahiro Yamada				do_objdump $f
83*7fa0e6dbSMasahiro Yamada			done
84*7fa0e6dbSMasahiro Yamada		else
85*7fa0e6dbSMasahiro Yamada			do_objdump $d
86*7fa0e6dbSMasahiro Yamada		fi
8779192ca8SJason Cooper	done
8879192ca8SJason Cooper}
8979192ca8SJason Cooper
9079192ca8SJason Cooperdodiff() {
9179192ca8SJason Cooper	[ $# -ne 2 ] && [ $# -ne 0 ] && usage
9279192ca8SJason Cooper
9379192ca8SJason Cooper	if [ $# -eq 0 ]; then
9479192ca8SJason Cooper		SRC="`git rev-parse --short HEAD^`"
9579192ca8SJason Cooper		DST="`git rev-parse --short HEAD`"
9679192ca8SJason Cooper	else
9779192ca8SJason Cooper		SRC="`git rev-parse --short $1`"
9879192ca8SJason Cooper		DST="`git rev-parse --short $2`"
9979192ca8SJason Cooper	fi
10079192ca8SJason Cooper
10179192ca8SJason Cooper	DIFF="`which colordiff`"
10279192ca8SJason Cooper
10379192ca8SJason Cooper	if [ ${#DIFF} -eq 0 ] || [ ! -x "$DIFF" ]; then
10479192ca8SJason Cooper		DIFF="`which diff`"
10579192ca8SJason Cooper	fi
10679192ca8SJason Cooper
10779192ca8SJason Cooper	SRCD="$TMPD/$SRC"
10879192ca8SJason Cooper	DSTD="$TMPD/$DST"
10979192ca8SJason Cooper
11079192ca8SJason Cooper	if [ ! -d "$SRCD" ]; then
1115ab370e9SMasahiro Yamada		echo >&2 "ERROR: $SRCD doesn't exist"
11279192ca8SJason Cooper		exit 1
11379192ca8SJason Cooper	fi
11479192ca8SJason Cooper
11579192ca8SJason Cooper	if [ ! -d "$DSTD" ]; then
1165ab370e9SMasahiro Yamada		echo >&2 "ERROR: $DSTD doesn't exist"
11779192ca8SJason Cooper		exit 1
11879192ca8SJason Cooper	fi
11979192ca8SJason Cooper
12079192ca8SJason Cooper	$DIFF -Nurd $SRCD $DSTD
12179192ca8SJason Cooper}
12279192ca8SJason Cooper
12379192ca8SJason Cooperdoclean() {
12479192ca8SJason Cooper	[ $# -eq 0 ] && usage
12579192ca8SJason Cooper	[ $# -gt 1 ] && usage
12679192ca8SJason Cooper
12779192ca8SJason Cooper	if [ "x$1" = "xall" ]; then
12879192ca8SJason Cooper		rm -rf $TMPD/*
12979192ca8SJason Cooper	else
13079192ca8SJason Cooper		CMT="`git rev-parse --short $1`"
13179192ca8SJason Cooper
13279192ca8SJason Cooper		if [ -d "$TMPD/$CMT" ]; then
13379192ca8SJason Cooper			rm -rf $TMPD/$CMT
13479192ca8SJason Cooper		else
1355ab370e9SMasahiro Yamada			echo >&2 "$CMT not found"
13679192ca8SJason Cooper		fi
13779192ca8SJason Cooper	fi
13879192ca8SJason Cooper}
13979192ca8SJason Cooper
14079192ca8SJason Cooper[ $# -eq 0 ] &&	usage
14179192ca8SJason Cooper
14279192ca8SJason Coopercase "$1" in
14379192ca8SJason Cooper	record)
14479192ca8SJason Cooper		shift
14579192ca8SJason Cooper		dorecord $*
14679192ca8SJason Cooper		;;
14779192ca8SJason Cooper	diff)
14879192ca8SJason Cooper		shift
14979192ca8SJason Cooper		dodiff $*
15079192ca8SJason Cooper		;;
15179192ca8SJason Cooper	clean)
15279192ca8SJason Cooper		shift
15379192ca8SJason Cooper		doclean $*
15479192ca8SJason Cooper		;;
15579192ca8SJason Cooper	*)
1565ab370e9SMasahiro Yamada		echo >&2 "Unrecognized command '$1'"
15779192ca8SJason Cooper		exit 1
15879192ca8SJason Cooper		;;
15979192ca8SJason Cooperesac
160