xref: /illumos-gate/usr/src/tools/scripts/elfcmp.sh (revision 2a6e99a0f1f7d22c0396e8b2ce9b9babbd1056cf)
1#!/bin/ksh
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License, Version 1.0 only
7# (the "License").  You may not use this file except in compliance
8# with the License.
9#
10# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11# or http://www.opensolaris.org/os/licensing.
12# See the License for the specific language governing permissions
13# and limitations under the License.
14#
15# When distributing Covered Code, include this CDDL HEADER in each
16# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17# If applicable, add the following below this CDDL HEADER, with the
18# fields enclosed by brackets "[]" replaced with your own identifying
19# information: Portions Copyright [yyyy] [name of copyright owner]
20#
21# CDDL HEADER END
22#
23#
24# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26#
27# elfcmp - compare significant sections in two ELF files
28#
29# usage: elfcmp [-v] [-S] [-s section ...] <f1> <f2>
30#
31
32VERBOSE=0
33SECTIONLIST=""
34SIGNING_CHECK=0
35ERRORS=0
36
37usage() {
38	echo 'Usage: elfcmp [-v] [-S] [-s section ...] <f1> <f2>' 1>&2
39	exit 1
40}
41
42while [[ $# > 0 ]]
43do
44	case "$1" in
45	-v)
46		VERBOSE=1
47		;;
48	-s)
49		SECTIONLIST="$2"
50		shift
51		;;
52	-S)
53		SIGNING_CHECK=1
54		;;
55	-*)
56		usage
57		;;
58	*)
59		break
60		;;
61	esac
62	shift
63done
64
65if [[ $# != 2 ]]
66then
67	usage
68fi
69
70TMP1=/tmp/elfcmp.1.$$
71TMP2=/tmp/elfcmp.2.$$
72trap "rm -f $TMP1 $TMP2" EXIT HUP INT QUIT PIPE TERM
73
74list_sections() {
75	dump -h "$1" | grep '\[[0-9]' | awk '{print $7}'
76}
77
78list_alloc_sections() {
79	dump -hv "$1" | grep '\[[0-9]' | awk '$3 ~ /A/ {print $4, $5, $6, $7}'
80}
81
82signing_filter() {
83	/usr/bin/grep -v -e \\$SHSTRTAB -e \\.SUNW_signature
84}
85
86# get section lists for both files into temp files
87
88if [[ "$SECTIONLIST" = "" ]]
89then
90	if [[ $SIGNING_CHECK = 1 ]]
91	then
92		SHSTRNDX=`dump -f "$1" | awk '{if (NR==11) print $5}'`
93		SHSTRTAB=`dump -h "$1" | grep "^\\[$SHSTRNDX\\]" | \
94			awk '{print $7}'`
95		FILTER=signing_filter
96	else
97		FILTER=cat
98	fi
99
100	list_sections "$1" | $FILTER | sort >$TMP1
101	list_sections "$2" | $FILTER | sort >$TMP2
102else
103	echo "$SECTIONLIST" >$TMP1
104	echo "$SECTIONLIST" >$TMP2
105fi
106
107# determine and print which ones aren't in both of the input files
108
109NOT_IN_1=$(comm -13 $TMP1 $TMP2)
110if [[ ! -z "$NOT_IN_1" ]]
111then
112	echo "Section(s) $NOT_IN_1 not in $1"
113	(( ERRORS += 1 ))
114fi
115NOT_IN_2=$(comm -23 $TMP1 $TMP2)
116if [[ ! -z "$NOT_IN_2" ]]
117then
118	echo "Section(s) $NOT_IN_2 not in $2"
119	(( ERRORS += 1 ))
120fi
121
122# for all the sections which *are* common, do the following
123
124for s in $(comm -12 $TMP1 $TMP2)
125do
126	dump -s -n $s "$1" | sed '/:/d' >$TMP1
127	dump -s -n $s "$2" | sed '/:/d' >$TMP2
128	if cmp -s $TMP1 $TMP2
129	then
130		if [[ $VERBOSE = 1 ]]
131		then
132			echo "Section $s is the same"
133		fi
134	else
135		echo "Section $s differs"
136		if [[ $VERBOSE = 1 ]]
137		then
138			dump -sv -n $s "$1" | sed '/:/d' >$TMP1
139			dump -sv -n $s "$2" | sed '/:/d' >$TMP2
140			diff -c $TMP1 $TMP2
141		fi
142		(( ERRORS += 1 ))
143	fi
144done
145
146# verify that allocated objects have not moved
147# only applies to signed objects with a program header
148
149if [[ $SIGNING_CHECK = 1 ]]
150then
151	HDR=$(dump -op $1 | wc -l)
152	if [[ $HDR -gt 2 ]]
153	then
154		list_alloc_sections "$1" | sort >$TMP1
155		list_alloc_sections "$2" | sort >$TMP2
156		if cmp -s $TMP1 $TMP2
157		then
158			if [[ $VERBOSE = 1 ]]
159			then
160				echo "Allocated sections are the same"
161			fi
162		else
163			echo "Allocated section(s) changed"
164			if [[ $VERBOSE = 1 ]]
165			then
166				diff -c $TMP1 $TMP2
167			fi
168			(( ERRORS += 1 ))
169		fi
170	fi
171fi
172
173exit $ERRORS
174