compare-debug 5.1 KB

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