14fee23f9Smrg#! /bin/sh 24fee23f9Smrg 34fee23f9Smrg# Compare stripped copies of two given object files. 44fee23f9Smrg 5*b1e83836Smrg# Copyright (C) 2007, 2008, 2009, 2010, 2012, 2020 Free Software Foundation 64fee23f9Smrg# Originally by Alexandre Oliva <aoliva@redhat.com> 74fee23f9Smrg 84fee23f9Smrg# This file is part of GCC. 94fee23f9Smrg 104fee23f9Smrg# GCC is free software; you can redistribute it and/or modify it under 114fee23f9Smrg# the terms of the GNU General Public License as published by the Free 124fee23f9Smrg# Software Foundation; either version 3, or (at your option) any later 134fee23f9Smrg# version. 144fee23f9Smrg 154fee23f9Smrg# GCC is distributed in the hope that it will be useful, but WITHOUT 164fee23f9Smrg# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 174fee23f9Smrg# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 184fee23f9Smrg# License for more details. 194fee23f9Smrg 204fee23f9Smrg# You should have received a copy of the GNU General Public License 214fee23f9Smrg# along with GCC; see the file COPYING3. If not see 224fee23f9Smrg# <http://www.gnu.org/licenses/>. 234fee23f9Smrg 244fee23f9Smrgrm='rm -f' 254fee23f9Smrg 264fee23f9Smrgcase $1 in 274fee23f9Smrg-p | --preserve) 284fee23f9Smrg rm='echo preserving' 294fee23f9Smrg shift 304fee23f9Smrg ;; 314fee23f9Smrgesac 324fee23f9Smrg 334fee23f9Smrgif test $# != 2; then 344fee23f9Smrg echo 'usage: compare-debug file1.o file2.o' >&2 354fee23f9Smrg exit 1 364fee23f9Smrgfi 374fee23f9Smrg 384fee23f9Smrgif test ! -f "$1"; then 394fee23f9Smrg echo "$1" does not exist >&2 404fee23f9Smrg exit 1 414fee23f9Smrgfi 424fee23f9Smrg 434fee23f9Smrgif test ! -f "$2"; then 444fee23f9Smrg echo "$2" does not exist >&2 454fee23f9Smrg exit 1 464fee23f9Smrgfi 474fee23f9Smrg 484fee23f9Smrgsuf1=stripped 494fee23f9Smrgwhile test -f "$1.$suf1"; do 504fee23f9Smrg suf1=$suf1. 514fee23f9Smrgdone 524fee23f9Smrg 534fee23f9Smrgsuf2=stripped 544fee23f9Smrgwhile test -f "$2.$suf2"; do 554fee23f9Smrg suf2=$suf2. 564fee23f9Smrgdone 574fee23f9Smrg 584fee23f9Smrgtrap 'rm -f "$1.$suf1" "$2.$suf2"' 0 1 2 15 594fee23f9Smrg 604fee23f9Smrgcase `uname -s` in 614fee23f9SmrgDarwin) 624fee23f9Smrg # The strip command on darwin does not remove all debug info. 634fee23f9Smrg # Fortunately, we can use ld to do it instead. 644fee23f9Smrg ld -S -r -no_uuid "$1" -o "$1.$suf1" 654fee23f9Smrg ld -S -r -no_uuid "$2" -o "$2.$suf2" 664fee23f9Smrg ;; 674fee23f9Smrg*) 684fee23f9Smrg cp "$1" "$1.$suf1" 694fee23f9Smrg strip "$1.$suf1" 704fee23f9Smrg 714fee23f9Smrg cp "$2" "$2.$suf2" 724fee23f9Smrg strip "$2.$suf2" 734fee23f9Smrg ;; 744fee23f9Smrgesac 754fee23f9Smrg 7648fb7bfaSmrgremove_comment () 7748fb7bfaSmrg{ 7848fb7bfaSmrg file=$1 7948fb7bfaSmrg opts= 8048fb7bfaSmrg for s in `objdump --section-headers "$file" | awk '{ print $2 }'`; do 8148fb7bfaSmrg case "$s" in 8248fb7bfaSmrg .comment*) 8348fb7bfaSmrg opts="$opts --remove-section $s" 8448fb7bfaSmrg ;; 8548fb7bfaSmrg esac 8648fb7bfaSmrg done 8748fb7bfaSmrg [ -n "$opts" ] && objcopy $opts $file 8848fb7bfaSmrg} 8948fb7bfaSmrg 904fee23f9Smrgif cmp "$1.$suf1" "$2.$suf2"; then 914fee23f9Smrg status=0 924fee23f9Smrgelse 934fee23f9Smrg status=1 944fee23f9Smrg 9548fb7bfaSmrg # Remove any .comment sections. 9648fb7bfaSmrg if (objcopy -v) 2>&1 | grep ' --remove-section' > /dev/null \ 9748fb7bfaSmrg && (objdump --help) 2>&1 | grep ' --\[*section-\]*headers' > /dev/null; then 9848fb7bfaSmrg remove_comment "$1.$suf1" 9948fb7bfaSmrg remove_comment "$2.$suf2" 10048fb7bfaSmrg if cmp "$1.$suf1" "$2.$suf2"; then 10148fb7bfaSmrg status=0 10248fb7bfaSmrg fi 10348fb7bfaSmrg fi 10448fb7bfaSmrg 1054fee23f9Smrg # Assembler-generated CFI will add an .eh_frame section for -g not 1064fee23f9Smrg # present in -g0. Try to cope with it by checking that an .eh_frame 1074fee23f9Smrg # section is present in either object file, and then stripping it 1084fee23f9Smrg # off before re-comparing. 1094fee23f9Smrg 1104fee23f9Smrg cmd= 1114fee23f9Smrg cmp1= 1124fee23f9Smrg cmp2= 1134fee23f9Smrg 1144fee23f9Smrg for t in objdump readelf eu-readelf; do 1154fee23f9Smrg if ($t --help) 2>&1 | grep ' --\[*section-\]*headers' > /dev/null; then 1164fee23f9Smrg cmd=$t 1174fee23f9Smrg 1184fee23f9Smrg $cmd --section-headers "$1.$suf1" | grep '\.eh_frame' > /dev/null 1194fee23f9Smrg cmp1=$? 1204fee23f9Smrg 1214fee23f9Smrg $cmd --section-headers "$2.$suf2" | grep '\.eh_frame' > /dev/null 1224fee23f9Smrg cmp2=$? 1234fee23f9Smrg 1244fee23f9Smrg break 1254fee23f9Smrg fi 1264fee23f9Smrg done 1274fee23f9Smrg 1284fee23f9Smrg # If we found .eh_frame in one but not the other, or if we could not 12948fb7bfaSmrg # find a command to tell, or if there are LTO sections, try to strip 13048fb7bfaSmrg # off the .eh_frame and LTO sections from both. 13148fb7bfaSmrg if test "x$cmp1" != "x$cmp2" || test "x$cmd" = "x" || 13248fb7bfaSmrg $cmd --section-headers "$1.$suf1" | grep '.gnu.lto_' > /dev/null || 13348fb7bfaSmrg $cmd --section-headers "$2.$suf2" | grep '.gnu.lto_' > /dev/null ; then 1344fee23f9Smrg suf3=$suf1. 1354fee23f9Smrg while test -f "$1.$suf3"; do 1364fee23f9Smrg suf3=$suf3. 1374fee23f9Smrg done 1384fee23f9Smrg 1394fee23f9Smrg suf4=$suf2. 1404fee23f9Smrg while test -f "$2.$suf4"; do 1414fee23f9Smrg suf4=$suf4. 1424fee23f9Smrg done 1434fee23f9Smrg 1444fee23f9Smrg trap 'rm -f "$1.$suf1" "$2.$suf2" "$1.$suf3" "$2.$suf4"' 0 1 2 15 1454fee23f9Smrg 14648fb7bfaSmrg echo stripping off .eh_frame and LTO sections, then retrying >&2 14748fb7bfaSmrg 14848fb7bfaSmrg seclist=".eh_frame .rel.eh_frame .rela.eh_frame" 14948fb7bfaSmrg if test "x$cmd" != "x"; then 15048fb7bfaSmrg seclist="$seclist "`{ $cmd --section-headers "$1.$suf1"; $cmd --section-headers "$2.$suf2"; } | sed -n 's,.* \(\.gnu\.lto_[^ ]*\).*,\1,p' | sort -u` 15148fb7bfaSmrg fi 15248fb7bfaSmrg rsopts=`for sec in $seclist; do echo " --remove-section $sec"; done` 1534fee23f9Smrg 1544fee23f9Smrg if (objcopy -v) 2>&1 | grep ' --remove-section' > /dev/null; then 15548fb7bfaSmrg objcopy $rsopts "$1.$suf1" "$1.$suf3" 1564fee23f9Smrg mv "$1.$suf3" "$1.$suf1" 1574fee23f9Smrg 15848fb7bfaSmrg objcopy $rsopts "$2.$suf2" "$2.$suf4" 1594fee23f9Smrg mv "$2.$suf4" "$2.$suf2" 1604fee23f9Smrg elif (strip --help) 2>&1 | grep ' --remove-section' > /dev/null; then 1614fee23f9Smrg cp "$1.$suf1" "$1.$suf3" 16248fb7bfaSmrg strip $rsopts "$1.$suf3" 1634fee23f9Smrg mv "$1.$suf3" "$1.$suf1" 1644fee23f9Smrg 1654fee23f9Smrg cp "$2.$suf2" "$2.$suf4" 16648fb7bfaSmrg strip $rsopts "$2.$suf4" 1674fee23f9Smrg mv "$2.$suf4" "$2.$suf2" 1684fee23f9Smrg else 1694fee23f9Smrg echo failed to strip off .eh_frame >&2 1704fee23f9Smrg fi 1714fee23f9Smrg 1724fee23f9Smrg trap 'rm -f "$1.$suf1" "$2.$suf2"' 0 1 2 15 1734fee23f9Smrg 1744fee23f9Smrg if cmp "$1.$suf1" "$2.$suf2"; then 1754fee23f9Smrg status=0 1764fee23f9Smrg else 1774fee23f9Smrg status=1 1784fee23f9Smrg fi 1794fee23f9Smrg fi 1804fee23f9Smrgfi 1814fee23f9Smrg 1824fee23f9Smrg$rm "$1.$suf1" "$2.$suf2" 1834fee23f9Smrg 1844fee23f9Smrgtrap "exit $status; exit" 0 1 2 15 1854fee23f9Smrg 186*b1e83836Smrg# Replace the suffix in $1 and $2 with .*.gkd, compare them if a 187*b1e83836Smrg# single file is found by the globbing. 188*b1e83836Smrgbase1=`echo "$1" | sed '$s,\.[^.]*$,,'` gkd1= 189*b1e83836Smrgfor f in "$base1".*.gkd; do 190*b1e83836Smrg if test "x$gkd1" != x; then 191*b1e83836Smrg gkd1= 192*b1e83836Smrg break 193*b1e83836Smrg elif test -f "$f"; then 194*b1e83836Smrg gkd1=$f 195*b1e83836Smrg fi 196*b1e83836Smrgdone 197*b1e83836Smrgbase2=`echo "$2" | sed '$s,\.[^.]*$,,'` gkd2= 198*b1e83836Smrgfor f in "$base2".*.gkd; do 199*b1e83836Smrg if test "x$gkd2" != x; then 200*b1e83836Smrg gkd2= 201*b1e83836Smrg break 202*b1e83836Smrg elif test -f "$f"; then 203*b1e83836Smrg gkd2=$f 204*b1e83836Smrg fi 205*b1e83836Smrgdone 206*b1e83836Smrgif test "x$gkd1" != x || test "x$gkd2" != x; then 207*b1e83836Smrg if cmp "${gkd1-/dev/null}" "${gkd2-/dev/null}"; then 2084fee23f9Smrg : 2094fee23f9Smrg else 2104fee23f9Smrg status=$? 2114fee23f9Smrg fi 2124fee23f9Smrgfi 2134fee23f9Smrg 2144fee23f9Smrgexit $status 215