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