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