xref: /openbmc/linux/scripts/objdiff (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
179192ca8SJason Cooper#!/bin/bash
2958349ccSThomas Gleixner# SPDX-License-Identifier: GPL-2.0-only
379192ca8SJason Cooper
479192ca8SJason Cooper# objdiff - a small script for validating that a commit or series of commits
579192ca8SJason Cooper# didn't change object code.
679192ca8SJason Cooper#
779192ca8SJason Cooper# Copyright 2014, Jason Cooper <jason@lakedaemon.net>
879192ca8SJason Cooper#
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
23*b0d6207bSMasahiro Yamada# And to clean up (everything is in .objdiff/*)
2479192ca8SJason Cooper# $ ./scripts/objdiff clean all
2579192ca8SJason Cooper#
26*b0d6207bSMasahiro Yamada# Note: 'make mrproper' will also remove .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
35*b0d6207bSMasahiro YamadaTMPD=$SRCTREE/.objdiff
36fd6e1242SMasahiro Yamada
3779192ca8SJason Cooperusage() {
385ab370e9SMasahiro Yamada	echo >&2 "Usage: $0 <command> <args>"
397fa0e6dbSMasahiro 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
577fa0e6dbSMasahiro Yamadado_objdump() {
587fa0e6dbSMasahiro Yamada	dir=$(get_output_dir $1)
597fa0e6dbSMasahiro Yamada	base=${1##*/}
6065ba6fa4SStephen Boyd	stripped=$dir/${base%.o}.stripped
617fa0e6dbSMasahiro Yamada	dis=$dir/${base%.o}.dis
627fa0e6dbSMasahiro Yamada
637fa0e6dbSMasahiro Yamada	[ ! -d "$dir" ] && mkdir -p $dir
647fa0e6dbSMasahiro Yamada
657fa0e6dbSMasahiro Yamada	# remove addresses for a cleaner diff
667fa0e6dbSMasahiro Yamada	# http://dummdida.tumblr.com/post/60924060451/binary-diff-between-libc-from-scientificlinux-and
6765ba6fa4SStephen Boyd	$STRIP -g $1 -R __bug_table -R .note -R .comment -o $stripped
6865ba6fa4SStephen Boyd	$OBJDUMP -D $stripped | sed -e "s/^[[:space:]]\+[0-9a-f]\+//" -e "s:^$stripped:$1:" > $dis
697fa0e6dbSMasahiro Yamada}
707fa0e6dbSMasahiro Yamada
7179192ca8SJason Cooperdorecord() {
7279192ca8SJason Cooper	[ $# -eq 0 ] && usage
7379192ca8SJason Cooper
7479192ca8SJason Cooper	FILES="$*"
7579192ca8SJason Cooper
7679192ca8SJason Cooper	CMT="`git rev-parse --short HEAD`"
7779192ca8SJason Cooper
7865ba6fa4SStephen Boyd	STRIP="${CROSS_COMPILE}strip"
7979192ca8SJason Cooper	OBJDUMP="${CROSS_COMPILE}objdump"
8079192ca8SJason Cooper
817fa0e6dbSMasahiro Yamada	for d in $FILES; do
827fa0e6dbSMasahiro Yamada		if [ -d "$d" ]; then
837fa0e6dbSMasahiro Yamada			for f in $(find $d -name '*.o')
847fa0e6dbSMasahiro Yamada			do
857fa0e6dbSMasahiro Yamada				do_objdump $f
867fa0e6dbSMasahiro Yamada			done
877fa0e6dbSMasahiro Yamada		else
887fa0e6dbSMasahiro Yamada			do_objdump $d
897fa0e6dbSMasahiro Yamada		fi
9079192ca8SJason Cooper	done
9179192ca8SJason Cooper}
9279192ca8SJason Cooper
9379192ca8SJason Cooperdodiff() {
9479192ca8SJason Cooper	[ $# -ne 2 ] && [ $# -ne 0 ] && usage
9579192ca8SJason Cooper
9679192ca8SJason Cooper	if [ $# -eq 0 ]; then
9779192ca8SJason Cooper		SRC="`git rev-parse --short HEAD^`"
9879192ca8SJason Cooper		DST="`git rev-parse --short HEAD`"
9979192ca8SJason Cooper	else
10079192ca8SJason Cooper		SRC="`git rev-parse --short $1`"
10179192ca8SJason Cooper		DST="`git rev-parse --short $2`"
10279192ca8SJason Cooper	fi
10379192ca8SJason Cooper
10479192ca8SJason Cooper	DIFF="`which colordiff`"
10579192ca8SJason Cooper
10679192ca8SJason Cooper	if [ ${#DIFF} -eq 0 ] || [ ! -x "$DIFF" ]; then
10779192ca8SJason Cooper		DIFF="`which diff`"
10879192ca8SJason Cooper	fi
10979192ca8SJason Cooper
11079192ca8SJason Cooper	SRCD="$TMPD/$SRC"
11179192ca8SJason Cooper	DSTD="$TMPD/$DST"
11279192ca8SJason Cooper
11379192ca8SJason Cooper	if [ ! -d "$SRCD" ]; then
1145ab370e9SMasahiro Yamada		echo >&2 "ERROR: $SRCD doesn't exist"
11579192ca8SJason Cooper		exit 1
11679192ca8SJason Cooper	fi
11779192ca8SJason Cooper
11879192ca8SJason Cooper	if [ ! -d "$DSTD" ]; then
1195ab370e9SMasahiro Yamada		echo >&2 "ERROR: $DSTD doesn't exist"
12079192ca8SJason Cooper		exit 1
12179192ca8SJason Cooper	fi
12279192ca8SJason Cooper
12379192ca8SJason Cooper	$DIFF -Nurd $SRCD $DSTD
12479192ca8SJason Cooper}
12579192ca8SJason Cooper
12679192ca8SJason Cooperdoclean() {
12779192ca8SJason Cooper	[ $# -eq 0 ] && usage
12879192ca8SJason Cooper	[ $# -gt 1 ] && usage
12979192ca8SJason Cooper
13079192ca8SJason Cooper	if [ "x$1" = "xall" ]; then
13179192ca8SJason Cooper		rm -rf $TMPD/*
13279192ca8SJason Cooper	else
13379192ca8SJason Cooper		CMT="`git rev-parse --short $1`"
13479192ca8SJason Cooper
13579192ca8SJason Cooper		if [ -d "$TMPD/$CMT" ]; then
13679192ca8SJason Cooper			rm -rf $TMPD/$CMT
13779192ca8SJason Cooper		else
1385ab370e9SMasahiro Yamada			echo >&2 "$CMT not found"
13979192ca8SJason Cooper		fi
14079192ca8SJason Cooper	fi
14179192ca8SJason Cooper}
14279192ca8SJason Cooper
14379192ca8SJason Cooper[ $# -eq 0 ] &&	usage
14479192ca8SJason Cooper
14579192ca8SJason Coopercase "$1" in
14679192ca8SJason Cooper	record)
14779192ca8SJason Cooper		shift
14879192ca8SJason Cooper		dorecord $*
14979192ca8SJason Cooper		;;
15079192ca8SJason Cooper	diff)
15179192ca8SJason Cooper		shift
15279192ca8SJason Cooper		dodiff $*
15379192ca8SJason Cooper		;;
15479192ca8SJason Cooper	clean)
15579192ca8SJason Cooper		shift
15679192ca8SJason Cooper		doclean $*
15779192ca8SJason Cooper		;;
15879192ca8SJason Cooper	*)
1595ab370e9SMasahiro Yamada		echo >&2 "Unrecognized command '$1'"
16079192ca8SJason Cooper		exit 1
16179192ca8SJason Cooper		;;
16279192ca8SJason Cooperesac
163