Commit | Line | Data |
---|---|---|
caf26be9 SB |
1 | #! /bin/sh |
2 | ||
3 | # Add a .gdb_index section to a file. | |
4 | ||
b811d2c2 | 5 | # Copyright (C) 2010-2020 Free Software Foundation, Inc. |
caf26be9 SB |
6 | # This program is free software; you can redistribute it and/or modify |
7 | # it under the terms of the GNU General Public License as published by | |
8 | # the Free Software Foundation; either version 3 of the License, or | |
9 | # (at your option) any later version. | |
10 | # | |
11 | # This program is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License | |
17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | ||
19 | # This program assumes gdb and objcopy are in $PATH. | |
20 | # If not, or you want others, pass the following in the environment | |
21 | GDB=${GDB:=gdb} | |
22 | OBJCOPY=${OBJCOPY:=objcopy} | |
2b9f6e89 | 23 | READELF=${READELF:=readelf} |
caf26be9 SB |
24 | |
25 | myname="${0##*/}" | |
26 | ||
25289ac1 JK |
27 | dwarf5="" |
28 | if [ "$1" = "-dwarf-5" ]; then | |
29 | dwarf5="$1" | |
30 | shift | |
31 | fi | |
32 | ||
caf26be9 | 33 | if test $# != 1; then |
25289ac1 | 34 | echo "usage: $myname [-dwarf-5] FILE" 1>&2 |
caf26be9 SB |
35 | exit 1 |
36 | fi | |
37 | ||
38 | file="$1" | |
39 | ||
40 | if test ! -r "$file"; then | |
41 | echo "$myname: unable to access: $file" 1>&2 | |
42 | exit 1 | |
43 | fi | |
44 | ||
45 | dir="${file%/*}" | |
46 | test "$dir" = "$file" && dir="." | |
caf26be9 | 47 | |
2b9f6e89 TV |
48 | dwz_file="" |
49 | if $READELF -S "$file" | grep -q " \.gnu_debugaltlink "; then | |
50 | dwz_file=$($READELF --string-dump=.gnu_debugaltlink "$file" \ | |
51 | | grep -A1 "'\.gnu_debugaltlink':" \ | |
52 | | tail -n +2 \ | |
53 | | sed 's/.*]//') | |
54 | dwz_file=$(echo $dwz_file) | |
55 | if $READELF -S "$dwz_file" | grep -E -q " \.(gdb_index|debug_names) "; then | |
56 | # Already has an index, skip it. | |
57 | dwz_file="" | |
58 | fi | |
59 | fi | |
60 | ||
61 | set_files () | |
62 | { | |
63 | local file="$1" | |
64 | ||
65 | index4="${file}.gdb-index" | |
66 | index5="${file}.debug_names" | |
67 | debugstr="${file}.debug_str" | |
68 | debugstrmerge="${file}.debug_str.merge" | |
69 | debugstrerr="${file}.debug_str.err" | |
70 | } | |
71 | ||
72 | tmp_files= | |
73 | for f in "$file" "$dwz_file"; do | |
74 | if [ "$f" = "" ]; then | |
75 | continue | |
76 | fi | |
77 | set_files "$f" | |
78 | tmp_files="$tmp_files $index4 $index5 $debugstr $debugstrmerge $debugstrerr" | |
79 | done | |
80 | ||
81 | rm -f $tmp_files | |
82 | ||
caf26be9 | 83 | # Ensure intermediate index file is removed when we exit. |
2b9f6e89 | 84 | trap "rm -f $tmp_files" 0 |
caf26be9 SB |
85 | |
86 | $GDB --batch -nx -iex 'set auto-load no' \ | |
25289ac1 | 87 | -ex "file $file" -ex "save gdb-index $dwarf5 $dir" || { |
caf26be9 SB |
88 | # Just in case. |
89 | status=$? | |
90 | echo "$myname: gdb error generating index for $file" 1>&2 | |
91 | exit $status | |
92 | } | |
93 | ||
94 | # In some situations gdb can exit without creating an index. This is | |
95 | # not an error. | |
96 | # E.g., if $file is stripped. This behaviour is akin to stripping an | |
97 | # already stripped binary, it's a no-op. | |
98 | status=0 | |
99 | ||
2b9f6e89 TV |
100 | handle_file () |
101 | { | |
102 | local file | |
103 | file="$1" | |
104 | ||
105 | set_files "$file" | |
106 | ||
107 | if test -f "$index4" -a -f "$index5"; then | |
108 | echo "$myname: Both index types were created for $file" 1>&2 | |
109 | status=1 | |
110 | elif test -f "$index4" -o -f "$index5"; then | |
111 | if test -f "$index4"; then | |
112 | index="$index4" | |
113 | section=".gdb_index" | |
437afbb8 | 114 | else |
2b9f6e89 TV |
115 | index="$index5" |
116 | section=".debug_names" | |
117 | fi | |
118 | debugstradd=false | |
119 | debugstrupdate=false | |
120 | if test -s "$debugstr"; then | |
121 | if ! $OBJCOPY --dump-section .debug_str="$debugstrmerge" "$file" \ | |
122 | /dev/null 2>$debugstrerr; then | |
123 | cat >&2 $debugstrerr | |
124 | exit 1 | |
125 | fi | |
126 | if grep -q "can't dump section '.debug_str' - it does not exist" \ | |
127 | $debugstrerr; then | |
128 | debugstradd=true | |
129 | else | |
130 | debugstrupdate=true | |
131 | cat >&2 $debugstrerr | |
132 | fi | |
133 | cat "$debugstr" >>"$debugstrmerge" | |
437afbb8 | 134 | fi |
437afbb8 | 135 | |
2b9f6e89 TV |
136 | $OBJCOPY --add-section $section="$index" \ |
137 | --set-section-flags $section=readonly \ | |
138 | $(if $debugstradd; then \ | |
139 | echo --add-section .debug_str="$debugstrmerge"; \ | |
140 | echo --set-section-flags .debug_str=readonly; \ | |
141 | fi; \ | |
142 | if $debugstrupdate; then \ | |
143 | echo --update-section .debug_str="$debugstrmerge"; \ | |
144 | fi) \ | |
145 | "$file" "$file" | |
146 | ||
147 | status=$? | |
148 | else | |
149 | echo "$myname: No index was created for $file" 1>&2 | |
150 | echo "$myname: [Was there no debuginfo? Was there already an index?]" \ | |
151 | 1>&2 | |
152 | fi | |
153 | } | |
437afbb8 | 154 | |
2b9f6e89 TV |
155 | handle_file "$file" |
156 | if [ "$dwz_file" != "" ]; then | |
157 | handle_file "$dwz_file" | |
caf26be9 SB |
158 | fi |
159 | ||
160 | exit $status |