xref: /illumos-gate/usr/src/tools/scripts/elfcmp.sh (revision 89b2a9fbeabf42fa54594df0e5927bcc50a07cc9)
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#ident	"%Z%%M%	%I%	%E% SMI"
28#
29# elfcmp - compare significant sections in two ELF files
30#
31# usage: elfcmp [-v] [-S] [-s section ...] <f1> <f2>
32#
33
34VERBOSE=0
35SECTIONLIST=""
36SIGNING_CHECK=0
37ERRORS=0
38
39usage() {
40	echo 'Usage: elfcmp [-v] [-S] [-s section ...] <f1> <f2>' 1>&2
41	exit 1
42}
43
44while [[ $# > 0 ]]
45do
46	case "$1" in
47	-v)
48		VERBOSE=1
49		;;
50	-s)
51		SECTIONLIST="$2"
52		shift
53		;;
54	-S)
55		SIGNING_CHECK=1
56		;;
57	-*)
58		usage
59		;;
60	*)
61		break
62		;;
63	esac
64	shift
65done
66
67if [[ $# != 2 ]]
68then
69	usage
70fi
71
72TMP1=/tmp/elfcmp.1.$$
73TMP2=/tmp/elfcmp.2.$$
74trap "rm -f $TMP1 $TMP2" EXIT HUP INT QUIT PIPE TERM
75
76list_sections() {
77	dump -h "$1" | grep '\[[0-9]' | awk '{print $7}'
78}
79
80list_alloc_sections() {
81	dump -hv "$1" | grep '\[[0-9]' | awk '$3 ~ /A/ {print $4, $5, $6, $7}'
82}
83
84signing_filter() {
85	/usr/xpg4/bin/grep -v -e \\$SHSTRTAB -e \\.SUNW_signature
86}
87
88# get section lists for both files into temp files
89
90if [[ "$SECTIONLIST" = "" ]]
91then
92	if [[ $SIGNING_CHECK = 1 ]]
93	then
94		SHSTRNDX=`dump -f "$1" | awk '{if (NR==11) print $5}'`
95		SHSTRTAB=`dump -h "$1" | grep "^\\[$SHSTRNDX\\]" | \
96			awk '{print $7}'`
97		FILTER=signing_filter
98	else
99		FILTER=cat
100	fi
101
102	list_sections "$1" | $FILTER | sort >$TMP1
103	list_sections "$2" | $FILTER | sort >$TMP2
104else
105	echo "$SECTIONLIST" >$TMP1
106	echo "$SECTIONLIST" >$TMP2
107fi
108
109# determine and print which ones aren't in both of the input files
110
111NOT_IN_1=$(comm -13 $TMP1 $TMP2)
112if [[ ! -z "$NOT_IN_1" ]]
113then
114	echo "Section(s) $NOT_IN_1 not in $1"
115	(( ERRORS += 1 ))
116fi
117NOT_IN_2=$(comm -23 $TMP1 $TMP2)
118if [[ ! -z "$NOT_IN_2" ]]
119then
120	echo "Section(s) $NOT_IN_2 not in $2"
121	(( ERRORS += 1 ))
122fi
123
124# for all the sections which *are* common, do the following
125
126for s in $(comm -12 $TMP1 $TMP2)
127do
128	dump -s -n $s "$1" | sed '/:/d' >$TMP1
129	dump -s -n $s "$2" | sed '/:/d' >$TMP2
130	if cmp -s $TMP1 $TMP2
131	then
132		if [[ $VERBOSE = 1 ]]
133		then
134			echo "Section $s is the same"
135		fi
136	else
137		echo "Section $s differs"
138		if [[ $VERBOSE = 1 ]]
139		then
140			dump -sv -n $s "$1" | sed '/:/d' >$TMP1
141			dump -sv -n $s "$2" | sed '/:/d' >$TMP2
142			diff -c $TMP1 $TMP2
143		fi
144		(( ERRORS += 1 ))
145	fi
146done
147
148# verify that allocated objects have not moved
149# only applies to signed objects with a program header
150
151if [[ $SIGNING_CHECK = 1 ]]
152then
153	HDR=$(dump -op $1 | wc -l)
154	if [[ $HDR -gt 2 ]]
155	then
156		list_alloc_sections "$1" | sort >$TMP1
157		list_alloc_sections "$2" | sort >$TMP2
158		if cmp -s $TMP1 $TMP2
159		then
160			if [[ $VERBOSE = 1 ]]
161			then
162				echo "Allocated sections are the same"
163			fi
164		else
165			echo "Allocated section(s) changed"
166			if [[ $VERBOSE = 1 ]]
167			then
168				diff -c $TMP1 $TMP2
169			fi
170			(( ERRORS += 1 ))
171		fi
172	fi
173fi
174
175exit $ERRORS
176