Home | History | Annotate | Download | only in scripts
      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 
     34 VERBOSE=0
     35 SECTIONLIST=""
     36 SIGNING_CHECK=0
     37 ERRORS=0
     38 
     39 usage() {
     40 	echo 'Usage: elfcmp [-v] [-S] [-s section ...] <f1> <f2>' 1>&2
     41 	exit 1
     42 }
     43 
     44 while [[ $# > 0 ]]
     45 do
     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
     65 done
     66 
     67 if [[ $# != 2 ]]
     68 then
     69 	usage
     70 fi
     71 
     72 TMP1=/tmp/elfcmp.1.$$
     73 TMP2=/tmp/elfcmp.2.$$
     74 trap "rm -f $TMP1 $TMP2" EXIT HUP INT QUIT PIPE TERM
     75 
     76 list_sections() {
     77 	dump -h "$1" | grep '\[[0-9]' | awk '{print $7}'
     78 }
     79 
     80 list_alloc_sections() {
     81 	dump -hv "$1" | grep '\[[0-9]' | awk '$3 ~ /A/ {print $4, $5, $6, $7}'
     82 }
     83 
     84 signing_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 
     90 if [[ "$SECTIONLIST" = "" ]]
     91 then
     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
    104 else
    105 	echo "$SECTIONLIST" >$TMP1
    106 	echo "$SECTIONLIST" >$TMP2
    107 fi
    108 
    109 # determine and print which ones aren't in both of the input files
    110 
    111 NOT_IN_1=$(comm -13 $TMP1 $TMP2)
    112 if [[ ! -z "$NOT_IN_1" ]]
    113 then
    114 	echo "Section(s) $NOT_IN_1 not in $1"
    115 	(( ERRORS += 1 ))
    116 fi
    117 NOT_IN_2=$(comm -23 $TMP1 $TMP2)
    118 if [[ ! -z "$NOT_IN_2" ]]
    119 then
    120 	echo "Section(s) $NOT_IN_2 not in $2"
    121 	(( ERRORS += 1 ))
    122 fi
    123 
    124 # for all the sections which *are* common, do the following
    125 
    126 for s in $(comm -12 $TMP1 $TMP2)
    127 do
    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
    146 done
    147 
    148 # verify that allocated objects have not moved
    149 # only applies to signed objects with a program header
    150 
    151 if [[ $SIGNING_CHECK = 1 ]]
    152 then
    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
    173 fi
    174 
    175 exit $ERRORS
    176