#!/bin/ksh # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" # # elfcmp - compare significant sections in two ELF files # # usage: elfcmp [-v] [-S] [-s section ...] # setvar VERBOSE = '0' setvar SECTIONLIST = """" setvar SIGNING_CHECK = '0' setvar ERRORS = '0' proc usage { echo 'Usage: elfcmp [-v] [-S] [-s section ...] ' 1>&2 exit 1 } while [[ $# > 0 ]] { match $1 { with -v setvar VERBOSE = '1' with -s setvar SECTIONLIST = "$2" shift with -S setvar SIGNING_CHECK = '1' with -* usage with * break } shift } if [[ $# != 2 ]] { usage } setvar TMP1 = "/tmp/elfcmp.1.$Pid" setvar TMP2 = "/tmp/elfcmp.2.$Pid" trap "rm -f $TMP1 $TMP2" EXIT HUP INT QUIT PIPE TERM proc list_sections { dump -h $1 | grep '\[[0-9]' | awk '{print $7}' } proc list_alloc_sections { dump -hv $1 | grep '\[[0-9]' | awk '$3 ~ /A/ {print $4, $5, $6, $7}' } proc signing_filter { /usr/xpg4/bin/grep -v -e '\'$SHSTRTAB -e '\'.SUNW_signature } # get section lists for both files into temp files if [[ "$SECTIONLIST" = "" ]] { if [[ $SIGNING_CHECK = 1 ]] { setvar SHSTRNDX = $(dump -f $1 | awk '{if (NR==11) print $5}) setvar SHSTRTAB = $(dump -h $1 | grep "^\\[$SHSTRNDX\\]" | \ awk '{print $7}) setvar FILTER = 'signing_filter' } else { setvar FILTER = 'cat' } list_sections $1 | $FILTER | sort >$TMP1 list_sections $2 | $FILTER | sort >$TMP2 } else { echo $SECTIONLIST >$TMP1 echo $SECTIONLIST >$TMP2 } # determine and print which ones aren't in both of the input files setvar NOT_IN_1 = $(comm -13 $TMP1 $TMP2) if [[ ! -z "$NOT_IN_1" ]] { echo "Section(s) $NOT_IN_1 not in $1" (( ERRORS += 1 )) } setvar NOT_IN_2 = $(comm -23 $TMP1 $TMP2) if [[ ! -z "$NOT_IN_2" ]] { echo "Section(s) $NOT_IN_2 not in $2" (( ERRORS += 1 )) } # for all the sections which *are* common, do the following for s in [$(comm -12 $TMP1 $TMP2)] { dump -s -n $s $1 | sed '/:/d' >$TMP1 dump -s -n $s $2 | sed '/:/d' >$TMP2 if cmp -s $TMP1 $TMP2 { if [[ $VERBOSE = 1 ]] { echo "Section $s is the same" } } else { echo "Section $s differs" if [[ $VERBOSE = 1 ]] { dump -sv -n $s $1 | sed '/:/d' >$TMP1 dump -sv -n $s $2 | sed '/:/d' >$TMP2 diff -c $TMP1 $TMP2 } (( ERRORS += 1 )) } } # verify that allocated objects have not moved # only applies to signed objects with a program header if [[ $SIGNING_CHECK = 1 ]] { setvar HDR = $(dump -op $1 | wc -l) if [[ $HDR -gt 2 ]] { list_alloc_sections $1 | sort >$TMP1 list_alloc_sections $2 | sort >$TMP2 if cmp -s $TMP1 $TMP2 { if [[ $VERBOSE = 1 ]] { echo "Allocated sections are the same" } } else { echo "Allocated section(s) changed" if [[ $VERBOSE = 1 ]] { diff -c $TMP1 $TMP2 } (( ERRORS += 1 )) } } } exit $ERRORS