xref: /netbsd-src/external/gpl3/gcc.old/dist/contrib/compare-debug (revision 1debfc3d3fad8af6f31804271c18e67f77b4d718)
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