xref: /linux/scripts/objdiff (revision fd6e12423311697860f30d10398a0f9eb91977d2)
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
28*fd6e1242SMasahiro YamadaSRCTREE=$(git rev-parse --show-toplevel 2>/dev/null)
2979192ca8SJason Cooper
30*fd6e1242SMasahiro Yamadaif [ -z "$SRCTREE" ]; then
31*fd6e1242SMasahiro Yamada	echo "ERROR: Not a git repository."
3279192ca8SJason Cooper	exit 1
3379192ca8SJason Cooperfi
3479192ca8SJason Cooper
35*fd6e1242SMasahiro YamadaTMPD=$SRCTREE/.tmp_objdiff
36*fd6e1242SMasahiro Yamada
3779192ca8SJason Cooperusage() {
3879192ca8SJason Cooper	echo "Usage: $0 <command> <args>"
3979192ca8SJason Cooper	echo "  record    <list of object files>"
4079192ca8SJason Cooper	echo "  diff      <commitA> <commitB>"
4179192ca8SJason Cooper	echo "  clean     all | <commit>"
4279192ca8SJason Cooper	exit 1
4379192ca8SJason Cooper}
4479192ca8SJason Cooper
4579192ca8SJason Cooperdorecord() {
4679192ca8SJason Cooper	[ $# -eq 0 ] && usage
4779192ca8SJason Cooper
4879192ca8SJason Cooper	FILES="$*"
4979192ca8SJason Cooper
5079192ca8SJason Cooper	CMT="`git rev-parse --short HEAD`"
5179192ca8SJason Cooper
5279192ca8SJason Cooper	OBJDUMP="${CROSS_COMPILE}objdump"
5379192ca8SJason Cooper	OBJDIFFD="$TMPD/$CMT"
5479192ca8SJason Cooper
5579192ca8SJason Cooper	[ ! -d "$OBJDIFFD" ] && mkdir -p "$OBJDIFFD"
5679192ca8SJason Cooper
5779192ca8SJason Cooper	for f in $FILES; do
5879192ca8SJason Cooper		dn="${f%/*}"
5979192ca8SJason Cooper		bn="${f##*/}"
6079192ca8SJason Cooper
6179192ca8SJason Cooper		[ ! -d "$OBJDIFFD/$dn" ] && mkdir -p "$OBJDIFFD/$dn"
6279192ca8SJason Cooper
6379192ca8SJason Cooper		# remove addresses for a more clear diff
6479192ca8SJason Cooper		# http://dummdida.tumblr.com/post/60924060451/binary-diff-between-libc-from-scientificlinux-and
6579192ca8SJason Cooper		$OBJDUMP -D "$f" | sed "s/^[[:space:]]\+[0-9a-f]\+//" \
6679192ca8SJason Cooper			>"$OBJDIFFD/$dn/$bn"
6779192ca8SJason Cooper	done
6879192ca8SJason Cooper}
6979192ca8SJason Cooper
7079192ca8SJason Cooperdodiff() {
7179192ca8SJason Cooper	[ $# -ne 2 ] && [ $# -ne 0 ] && usage
7279192ca8SJason Cooper
7379192ca8SJason Cooper	if [ $# -eq 0 ]; then
7479192ca8SJason Cooper		SRC="`git rev-parse --short HEAD^`"
7579192ca8SJason Cooper		DST="`git rev-parse --short HEAD`"
7679192ca8SJason Cooper	else
7779192ca8SJason Cooper		SRC="`git rev-parse --short $1`"
7879192ca8SJason Cooper		DST="`git rev-parse --short $2`"
7979192ca8SJason Cooper	fi
8079192ca8SJason Cooper
8179192ca8SJason Cooper	DIFF="`which colordiff`"
8279192ca8SJason Cooper
8379192ca8SJason Cooper	if [ ${#DIFF} -eq 0 ] || [ ! -x "$DIFF" ]; then
8479192ca8SJason Cooper		DIFF="`which diff`"
8579192ca8SJason Cooper	fi
8679192ca8SJason Cooper
8779192ca8SJason Cooper	SRCD="$TMPD/$SRC"
8879192ca8SJason Cooper	DSTD="$TMPD/$DST"
8979192ca8SJason Cooper
9079192ca8SJason Cooper	if [ ! -d "$SRCD" ]; then
9179192ca8SJason Cooper		echo "ERROR: $SRCD doesn't exist"
9279192ca8SJason Cooper		exit 1
9379192ca8SJason Cooper	fi
9479192ca8SJason Cooper
9579192ca8SJason Cooper	if [ ! -d "$DSTD" ]; then
9679192ca8SJason Cooper		echo "ERROR: $DSTD doesn't exist"
9779192ca8SJason Cooper		exit 1
9879192ca8SJason Cooper	fi
9979192ca8SJason Cooper
10079192ca8SJason Cooper	$DIFF -Nurd $SRCD $DSTD
10179192ca8SJason Cooper}
10279192ca8SJason Cooper
10379192ca8SJason Cooperdoclean() {
10479192ca8SJason Cooper	[ $# -eq 0 ] && usage
10579192ca8SJason Cooper	[ $# -gt 1 ] && usage
10679192ca8SJason Cooper
10779192ca8SJason Cooper	if [ "x$1" = "xall" ]; then
10879192ca8SJason Cooper		rm -rf $TMPD/*
10979192ca8SJason Cooper	else
11079192ca8SJason Cooper		CMT="`git rev-parse --short $1`"
11179192ca8SJason Cooper
11279192ca8SJason Cooper		if [ -d "$TMPD/$CMT" ]; then
11379192ca8SJason Cooper			rm -rf $TMPD/$CMT
11479192ca8SJason Cooper		else
11579192ca8SJason Cooper			echo "$CMT not found"
11679192ca8SJason Cooper		fi
11779192ca8SJason Cooper	fi
11879192ca8SJason Cooper}
11979192ca8SJason Cooper
12079192ca8SJason Cooper[ $# -eq 0 ] &&	usage
12179192ca8SJason Cooper
12279192ca8SJason Coopercase "$1" in
12379192ca8SJason Cooper	record)
12479192ca8SJason Cooper		shift
12579192ca8SJason Cooper		dorecord $*
12679192ca8SJason Cooper		;;
12779192ca8SJason Cooper	diff)
12879192ca8SJason Cooper		shift
12979192ca8SJason Cooper		dodiff $*
13079192ca8SJason Cooper		;;
13179192ca8SJason Cooper	clean)
13279192ca8SJason Cooper		shift
13379192ca8SJason Cooper		doclean $*
13479192ca8SJason Cooper		;;
13579192ca8SJason Cooper	*)
13679192ca8SJason Cooper		echo "Unrecognized command '$1'"
13779192ca8SJason Cooper		exit 1
13879192ca8SJason Cooper		;;
13979192ca8SJason Cooperesac
140