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