1*1debfc3dSmrg#! /bin/sh 2*1debfc3dSmrg 3*1debfc3dSmrg# Compare stripped copies of two given object files. 4*1debfc3dSmrg 5*1debfc3dSmrg# Copyright (C) 2007, 2008, 2009, 2010, 2012 Free Software Foundation 6*1debfc3dSmrg# Originally by Alexandre Oliva <aoliva@redhat.com> 7*1debfc3dSmrg 8*1debfc3dSmrg# This file is part of GCC. 9*1debfc3dSmrg 10*1debfc3dSmrg# GCC is free software; you can redistribute it and/or modify it under 11*1debfc3dSmrg# the terms of the GNU General Public License as published by the Free 12*1debfc3dSmrg# Software Foundation; either version 3, or (at your option) any later 13*1debfc3dSmrg# version. 14*1debfc3dSmrg 15*1debfc3dSmrg# GCC is distributed in the hope that it will be useful, but WITHOUT 16*1debfc3dSmrg# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17*1debfc3dSmrg# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 18*1debfc3dSmrg# License for more details. 19*1debfc3dSmrg 20*1debfc3dSmrg# You should have received a copy of the GNU General Public License 21*1debfc3dSmrg# along with GCC; see the file COPYING3. If not see 22*1debfc3dSmrg# <http://www.gnu.org/licenses/>. 23*1debfc3dSmrg 24*1debfc3dSmrgrm='rm -f' 25*1debfc3dSmrg 26*1debfc3dSmrgcase $1 in 27*1debfc3dSmrg-p | --preserve) 28*1debfc3dSmrg rm='echo preserving' 29*1debfc3dSmrg shift 30*1debfc3dSmrg ;; 31*1debfc3dSmrgesac 32*1debfc3dSmrg 33*1debfc3dSmrgif test $# != 2; then 34*1debfc3dSmrg echo 'usage: compare-debug file1.o file2.o' >&2 35*1debfc3dSmrg exit 1 36*1debfc3dSmrgfi 37*1debfc3dSmrg 38*1debfc3dSmrgif test ! -f "$1"; then 39*1debfc3dSmrg echo "$1" does not exist >&2 40*1debfc3dSmrg exit 1 41*1debfc3dSmrgfi 42*1debfc3dSmrg 43*1debfc3dSmrgif test ! -f "$2"; then 44*1debfc3dSmrg echo "$2" does not exist >&2 45*1debfc3dSmrg exit 1 46*1debfc3dSmrgfi 47*1debfc3dSmrg 48*1debfc3dSmrgsuf1=stripped 49*1debfc3dSmrgwhile test -f "$1.$suf1"; do 50*1debfc3dSmrg suf1=$suf1. 51*1debfc3dSmrgdone 52*1debfc3dSmrg 53*1debfc3dSmrgsuf2=stripped 54*1debfc3dSmrgwhile test -f "$2.$suf2"; do 55*1debfc3dSmrg suf2=$suf2. 56*1debfc3dSmrgdone 57*1debfc3dSmrg 58*1debfc3dSmrgtrap 'rm -f "$1.$suf1" "$2.$suf2"' 0 1 2 15 59*1debfc3dSmrg 60*1debfc3dSmrgcase `uname -s` in 61*1debfc3dSmrgDarwin) 62*1debfc3dSmrg # The strip command on darwin does not remove all debug info. 63*1debfc3dSmrg # Fortunately, we can use ld to do it instead. 64*1debfc3dSmrg ld -S -r -no_uuid "$1" -o "$1.$suf1" 65*1debfc3dSmrg ld -S -r -no_uuid "$2" -o "$2.$suf2" 66*1debfc3dSmrg ;; 67*1debfc3dSmrg*) 68*1debfc3dSmrg cp "$1" "$1.$suf1" 69*1debfc3dSmrg strip "$1.$suf1" 70*1debfc3dSmrg 71*1debfc3dSmrg cp "$2" "$2.$suf2" 72*1debfc3dSmrg strip "$2.$suf2" 73*1debfc3dSmrg ;; 74*1debfc3dSmrgesac 75*1debfc3dSmrg 76*1debfc3dSmrgremove_comment () 77*1debfc3dSmrg{ 78*1debfc3dSmrg file=$1 79*1debfc3dSmrg opts= 80*1debfc3dSmrg for s in `objdump --section-headers "$file" | awk '{ print $2 }'`; do 81*1debfc3dSmrg case "$s" in 82*1debfc3dSmrg .comment*) 83*1debfc3dSmrg opts="$opts --remove-section $s" 84*1debfc3dSmrg ;; 85*1debfc3dSmrg esac 86*1debfc3dSmrg done 87*1debfc3dSmrg [ -n "$opts" ] && objcopy $opts $file 88*1debfc3dSmrg} 89*1debfc3dSmrg 90*1debfc3dSmrgif cmp "$1.$suf1" "$2.$suf2"; then 91*1debfc3dSmrg status=0 92*1debfc3dSmrgelse 93*1debfc3dSmrg status=1 94*1debfc3dSmrg 95*1debfc3dSmrg # Remove any .comment sections. 96*1debfc3dSmrg if (objcopy -v) 2>&1 | grep ' --remove-section' > /dev/null \ 97*1debfc3dSmrg && (objdump --help) 2>&1 | grep ' --\[*section-\]*headers' > /dev/null; then 98*1debfc3dSmrg remove_comment "$1.$suf1" 99*1debfc3dSmrg remove_comment "$2.$suf2" 100*1debfc3dSmrg if cmp "$1.$suf1" "$2.$suf2"; then 101*1debfc3dSmrg status=0 102*1debfc3dSmrg fi 103*1debfc3dSmrg fi 104*1debfc3dSmrg 105*1debfc3dSmrg # Assembler-generated CFI will add an .eh_frame section for -g not 106*1debfc3dSmrg # present in -g0. Try to cope with it by checking that an .eh_frame 107*1debfc3dSmrg # section is present in either object file, and then stripping it 108*1debfc3dSmrg # off before re-comparing. 109*1debfc3dSmrg 110*1debfc3dSmrg cmd= 111*1debfc3dSmrg cmp1= 112*1debfc3dSmrg cmp2= 113*1debfc3dSmrg 114*1debfc3dSmrg for t in objdump readelf eu-readelf; do 115*1debfc3dSmrg if ($t --help) 2>&1 | grep ' --\[*section-\]*headers' > /dev/null; then 116*1debfc3dSmrg cmd=$t 117*1debfc3dSmrg 118*1debfc3dSmrg $cmd --section-headers "$1.$suf1" | grep '\.eh_frame' > /dev/null 119*1debfc3dSmrg cmp1=$? 120*1debfc3dSmrg 121*1debfc3dSmrg $cmd --section-headers "$2.$suf2" | grep '\.eh_frame' > /dev/null 122*1debfc3dSmrg cmp2=$? 123*1debfc3dSmrg 124*1debfc3dSmrg break 125*1debfc3dSmrg fi 126*1debfc3dSmrg done 127*1debfc3dSmrg 128*1debfc3dSmrg # If we found .eh_frame in one but not the other, or if we could not 129*1debfc3dSmrg # find a command to tell, or if there are LTO sections, try to strip 130*1debfc3dSmrg # off the .eh_frame and LTO sections from both. 131*1debfc3dSmrg if test "x$cmp1" != "x$cmp2" || test "x$cmd" = "x" || 132*1debfc3dSmrg $cmd --section-headers "$1.$suf1" | grep '.gnu.lto_' > /dev/null || 133*1debfc3dSmrg $cmd --section-headers "$2.$suf2" | grep '.gnu.lto_' > /dev/null ; then 134*1debfc3dSmrg suf3=$suf1. 135*1debfc3dSmrg while test -f "$1.$suf3"; do 136*1debfc3dSmrg suf3=$suf3. 137*1debfc3dSmrg done 138*1debfc3dSmrg 139*1debfc3dSmrg suf4=$suf2. 140*1debfc3dSmrg while test -f "$2.$suf4"; do 141*1debfc3dSmrg suf4=$suf4. 142*1debfc3dSmrg done 143*1debfc3dSmrg 144*1debfc3dSmrg trap 'rm -f "$1.$suf1" "$2.$suf2" "$1.$suf3" "$2.$suf4"' 0 1 2 15 145*1debfc3dSmrg 146*1debfc3dSmrg echo stripping off .eh_frame and LTO sections, then retrying >&2 147*1debfc3dSmrg 148*1debfc3dSmrg seclist=".eh_frame .rel.eh_frame .rela.eh_frame" 149*1debfc3dSmrg if test "x$cmd" != "x"; then 150*1debfc3dSmrg seclist="$seclist "`{ $cmd --section-headers "$1.$suf1"; $cmd --section-headers "$2.$suf2"; } | sed -n 's,.* \(\.gnu\.lto_[^ ]*\).*,\1,p' | sort -u` 151*1debfc3dSmrg fi 152*1debfc3dSmrg rsopts=`for sec in $seclist; do echo " --remove-section $sec"; done` 153*1debfc3dSmrg 154*1debfc3dSmrg if (objcopy -v) 2>&1 | grep ' --remove-section' > /dev/null; then 155*1debfc3dSmrg objcopy $rsopts "$1.$suf1" "$1.$suf3" 156*1debfc3dSmrg mv "$1.$suf3" "$1.$suf1" 157*1debfc3dSmrg 158*1debfc3dSmrg objcopy $rsopts "$2.$suf2" "$2.$suf4" 159*1debfc3dSmrg mv "$2.$suf4" "$2.$suf2" 160*1debfc3dSmrg elif (strip --help) 2>&1 | grep ' --remove-section' > /dev/null; then 161*1debfc3dSmrg cp "$1.$suf1" "$1.$suf3" 162*1debfc3dSmrg strip $rsopts "$1.$suf3" 163*1debfc3dSmrg mv "$1.$suf3" "$1.$suf1" 164*1debfc3dSmrg 165*1debfc3dSmrg cp "$2.$suf2" "$2.$suf4" 166*1debfc3dSmrg strip $rsopts "$2.$suf4" 167*1debfc3dSmrg mv "$2.$suf4" "$2.$suf2" 168*1debfc3dSmrg else 169*1debfc3dSmrg echo failed to strip off .eh_frame >&2 170*1debfc3dSmrg fi 171*1debfc3dSmrg 172*1debfc3dSmrg trap 'rm -f "$1.$suf1" "$2.$suf2"' 0 1 2 15 173*1debfc3dSmrg 174*1debfc3dSmrg if cmp "$1.$suf1" "$2.$suf2"; then 175*1debfc3dSmrg status=0 176*1debfc3dSmrg else 177*1debfc3dSmrg status=1 178*1debfc3dSmrg fi 179*1debfc3dSmrg fi 180*1debfc3dSmrgfi 181*1debfc3dSmrg 182*1debfc3dSmrg$rm "$1.$suf1" "$2.$suf2" 183*1debfc3dSmrg 184*1debfc3dSmrgtrap "exit $status; exit" 0 1 2 15 185*1debfc3dSmrg 186*1debfc3dSmrgif test -f "$1".gkd || test -f "$2".gkd; then 187*1debfc3dSmrg if cmp "$1".gkd "$2".gkd; then 188*1debfc3dSmrg : 189*1debfc3dSmrg else 190*1debfc3dSmrg status=$? 191*1debfc3dSmrg fi 192*1debfc3dSmrgfi 193*1debfc3dSmrg 194*1debfc3dSmrgexit $status 195