Home | History | Annotate | Line # | Download | only in contrib
      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