compare-debug revision 1.1.1.3 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.3 mrg # Copyright (C) 2007, 2008, 2009, 2010, 2012, 2020 Free Software Foundation
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