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