]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/rddbg.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / binutils / rddbg.c
CommitLineData
252b5132 1/* rddbg.c -- Read debugging information into a generic form.
250d07de 2 Copyright (C) 1995-2021 Free Software Foundation, Inc.
252b5132
RH
3 Written by Ian Lance Taylor <ian@cygnus.com>.
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
32866df7 9 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
b43b5d5f
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
252b5132 21
32866df7 22
252b5132
RH
23/* This file reads debugging information into a generic form. This
24 file knows how to dig the debugging information out of an object
25 file. */
26
3db64b00 27#include "sysdep.h"
252b5132 28#include "bfd.h"
252b5132 29#include "libiberty.h"
3db64b00 30#include "bucomm.h"
252b5132
RH
31#include "debug.h"
32#include "budbg.h"
33
b34976b6 34static bfd_boolean read_section_stabs_debugging_info
2da42df6 35 (bfd *, asymbol **, long, void *, bfd_boolean *);
b34976b6 36static bfd_boolean read_symbol_stabs_debugging_info
2da42df6 37 (bfd *, asymbol **, long, void *, bfd_boolean *);
2da42df6
AJ
38static void save_stab (int, int, bfd_vma, const char *);
39static void stab_context (void);
40static void free_saved_stabs (void);
252b5132
RH
41
42/* Read debugging information from a BFD. Returns a generic debugging
43 pointer. */
44
2da42df6 45void *
82fcdb39
AM
46read_debugging_info (bfd *abfd, asymbol **syms, long symcount,
47 bfd_boolean no_messages)
252b5132 48{
2da42df6 49 void *dhandle;
b34976b6 50 bfd_boolean found;
252b5132
RH
51
52 dhandle = debug_init ();
53 if (dhandle == NULL)
54 return NULL;
55
56 if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
57 &found))
82fcdb39 58 goto err_exit;
252b5132
RH
59
60 if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
61 {
62 if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle,
63 &found))
82fcdb39 64 goto err_exit;
252b5132
RH
65 }
66
252b5132
RH
67 /* Try reading the COFF symbols if we didn't find any stabs in COFF
68 sections. */
69 if (! found
70 && bfd_get_flavour (abfd) == bfd_target_coff_flavour
71 && symcount > 0)
72 {
73 if (! parse_coff (abfd, syms, symcount, dhandle))
82fcdb39 74 goto err_exit;
b34976b6 75 found = TRUE;
252b5132
RH
76 }
77
78 if (! found)
79 {
b922d590
NC
80 if (! no_messages)
81 non_fatal (_("%s: no recognized debugging information"),
82 bfd_get_filename (abfd));
82fcdb39
AM
83 err_exit:
84 free (dhandle);
252b5132
RH
85 return NULL;
86 }
87
88 return dhandle;
89}
90
91/* Read stabs in sections debugging information from a BFD. */
92
b34976b6 93static bfd_boolean
2da42df6
AJ
94read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
95 void *dhandle, bfd_boolean *pfound)
252b5132
RH
96{
97 static struct
98 {
99 const char *secname;
100 const char *strsecname;
7806762e
NC
101 }
102 names[] =
103 {
104 { ".stab", ".stabstr" },
105 { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" },
106 { "$GDB_SYMBOLS$", "$GDB_STRINGS$" }
107 };
252b5132 108 unsigned int i;
2da42df6 109 void *shandle;
252b5132 110
b34976b6 111 *pfound = FALSE;
252b5132
RH
112 shandle = NULL;
113
114 for (i = 0; i < sizeof names / sizeof names[0]; i++)
115 {
116 asection *sec, *strsec;
117
118 sec = bfd_get_section_by_name (abfd, names[i].secname);
119 strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
120 if (sec != NULL && strsec != NULL)
121 {
122 bfd_size_type stabsize, strsize;
123 bfd_byte *stabs, *strings;
124 bfd_byte *stab;
125 bfd_size_type stroff, next_stroff;
126
fd361982 127 stabsize = bfd_section_size (sec);
252b5132
RH
128 stabs = (bfd_byte *) xmalloc (stabsize);
129 if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
130 {
131 fprintf (stderr, "%s: %s: %s\n",
132 bfd_get_filename (abfd), names[i].secname,
133 bfd_errmsg (bfd_get_error ()));
e3d39609
NC
134 free (shandle);
135 free (stabs);
b34976b6 136 return FALSE;
252b5132
RH
137 }
138
fd361982 139 strsize = bfd_section_size (strsec);
f41e4712 140 strings = (bfd_byte *) xmalloc (strsize + 1);
252b5132
RH
141 if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
142 {
143 fprintf (stderr, "%s: %s: %s\n",
144 bfd_get_filename (abfd), names[i].strsecname,
145 bfd_errmsg (bfd_get_error ()));
e3d39609
NC
146 free (shandle);
147 free (strings);
148 free (stabs);
b34976b6 149 return FALSE;
252b5132 150 }
f41e4712
NC
151 /* Zero terminate the strings table, just in case. */
152 strings [strsize] = 0;
252b5132
RH
153 if (shandle == NULL)
154 {
b34976b6 155 shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
252b5132 156 if (shandle == NULL)
e3d39609
NC
157 {
158 free (strings);
159 free (stabs);
160 return FALSE;
161 }
252b5132
RH
162 }
163
b34976b6 164 *pfound = TRUE;
252b5132
RH
165
166 stroff = 0;
167 next_stroff = 0;
f41e4712
NC
168 /* PR 17512: file: 078-60391-0.001:0.1. */
169 for (stab = stabs; stab <= (stabs + stabsize) - 12; stab += 12)
252b5132 170 {
37cc8ec1 171 unsigned int strx;
252b5132 172 int type;
3d540e93 173 int other ATTRIBUTE_UNUSED;
252b5132
RH
174 int desc;
175 bfd_vma value;
176
177 /* This code presumes 32 bit values. */
178
179 strx = bfd_get_32 (abfd, stab);
180 type = bfd_get_8 (abfd, stab + 4);
181 other = bfd_get_8 (abfd, stab + 5);
182 desc = bfd_get_16 (abfd, stab + 6);
183 value = bfd_get_32 (abfd, stab + 8);
184
185 if (type == 0)
186 {
187 /* Special type 0 stabs indicate the offset to the
f3931575 188 next string table. */
252b5132
RH
189 stroff = next_stroff;
190 next_stroff += value;
191 }
192 else
193 {
f41e4712 194 size_t len;
252b5132
RH
195 char *f, *s;
196
f41e4712 197 if (stroff + strx >= strsize)
3b7aaf81 198 {
f41e4712 199 fprintf (stderr, _("%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n"),
3b7aaf81 200 bfd_get_filename (abfd), names[i].secname,
22d82235 201 (long) (stab - stabs) / 12, strx, type);
3b7aaf81
NC
202 continue;
203 }
53c7db4b 204
252b5132 205 s = (char *) strings + stroff + strx;
f41e4712 206 f = NULL;
53c7db4b 207
f41e4712
NC
208 /* PR 17512: file: 002-87578-0.001:0.1.
209 It is possible to craft a file where, without the 'strlen (s) > 0',
210 an attempt to read the byte before 'strings' would occur. */
211 while ((len = strlen (s)) > 0
212 && s[len - 1] == '\\'
252b5132
RH
213 && stab + 12 < stabs + stabsize)
214 {
215 char *p;
216
217 stab += 12;
f41e4712 218 p = s + len - 1;
252b5132 219 *p = '\0';
f41e4712
NC
220 strx = stroff + bfd_get_32 (abfd, stab);
221 if (strx >= strsize)
222 {
223 fprintf (stderr, _("%s: %s: stab entry %ld is corrupt\n"),
224 bfd_get_filename (abfd), names[i].secname,
225 (long) (stab - stabs) / 12);
226 break;
227 }
e3d39609
NC
228
229 s = concat (s, (char *) strings + strx,
230 (const char *) NULL);
252b5132
RH
231
232 /* We have to restore the backslash, because, if
f3931575
AM
233 the linker is hashing stabs strings, we may
234 see the same string more than once. */
252b5132
RH
235 *p = '\\';
236
e3d39609 237 free (f);
252b5132
RH
238 f = s;
239 }
240
241 save_stab (type, desc, value, s);
242
243 if (! parse_stab (dhandle, shandle, type, desc, value, s))
244 {
245 stab_context ();
246 free_saved_stabs ();
e3d39609
NC
247 free (f);
248 free (shandle);
249 free (stabs);
250 free (strings);
b34976b6 251 return FALSE;
252b5132
RH
252 }
253
254 /* Don't free f, since I think the stabs code
f3931575
AM
255 expects strings to hang around. This should be
256 straightened out. FIXME. */
252b5132
RH
257 }
258 }
259
260 free_saved_stabs ();
261 free (stabs);
262
263 /* Don't free strings, since I think the stabs code expects
f3931575
AM
264 the strings to hang around. This should be straightened
265 out. FIXME. */
252b5132
RH
266 }
267 }
268
269 if (shandle != NULL)
270 {
271 if (! finish_stab (dhandle, shandle))
b34976b6 272 return FALSE;
252b5132
RH
273 }
274
b34976b6 275 return TRUE;
252b5132
RH
276}
277
278/* Read stabs in the symbol table. */
279
b34976b6 280static bfd_boolean
2da42df6
AJ
281read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
282 void *dhandle, bfd_boolean *pfound)
252b5132 283{
2da42df6 284 void *shandle;
252b5132
RH
285 asymbol **ps, **symend;
286
287 shandle = NULL;
288 symend = syms + symcount;
289 for (ps = syms; ps < symend; ps++)
290 {
291 symbol_info i;
292
293 bfd_get_symbol_info (abfd, *ps, &i);
294
295 if (i.type == '-')
296 {
297 const char *s;
298 char *f;
299
300 if (shandle == NULL)
301 {
b34976b6 302 shandle = start_stab (dhandle, abfd, FALSE, syms, symcount);
252b5132 303 if (shandle == NULL)
b34976b6 304 return FALSE;
252b5132
RH
305 }
306
b34976b6 307 *pfound = TRUE;
252b5132
RH
308
309 s = i.name;
92134dc1
NC
310 if (s == NULL || strlen (s) < 1)
311 return FALSE;
252b5132 312 f = NULL;
92134dc1 313
ca4cf9b9
NC
314 while (strlen (s) > 0
315 && s[strlen (s) - 1] == '\\'
252b5132
RH
316 && ps + 1 < symend)
317 {
318 char *sc, *n;
319
320 ++ps;
321 sc = xstrdup (s);
322 sc[strlen (sc) - 1] = '\0';
323 n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
324 free (sc);
9db70fc3 325 free (f);
252b5132
RH
326 f = n;
327 s = n;
328 }
329
330 save_stab (i.stab_type, i.stab_desc, i.value, s);
331
332 if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
333 i.value, s))
334 {
335 stab_context ();
336 free_saved_stabs ();
b34976b6 337 return FALSE;
252b5132
RH
338 }
339
340 /* Don't free f, since I think the stabs code expects
341 strings to hang around. This should be straightened out.
342 FIXME. */
343 }
344 }
345
346 free_saved_stabs ();
347
348 if (shandle != NULL)
349 {
350 if (! finish_stab (dhandle, shandle))
b34976b6 351 return FALSE;
252b5132
RH
352 }
353
b34976b6 354 return TRUE;
252b5132 355}
252b5132
RH
356\f
357/* Record stabs strings, so that we can give some context for errors. */
358
359#define SAVE_STABS_COUNT (16)
360
361struct saved_stab
362{
363 int type;
364 int desc;
365 bfd_vma value;
366 char *string;
367};
368
369static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
370static int saved_stabs_index;
371
372/* Save a stabs string. */
373
374static void
2da42df6 375save_stab (int type, int desc, bfd_vma value, const char *string)
252b5132 376{
9db70fc3 377 free (saved_stabs[saved_stabs_index].string);
252b5132
RH
378 saved_stabs[saved_stabs_index].type = type;
379 saved_stabs[saved_stabs_index].desc = desc;
380 saved_stabs[saved_stabs_index].value = value;
381 saved_stabs[saved_stabs_index].string = xstrdup (string);
382 saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
383}
384
385/* Provide context for an error. */
386
387static void
2da42df6 388stab_context (void)
252b5132
RH
389{
390 int i;
391
392 fprintf (stderr, _("Last stabs entries before error:\n"));
393 fprintf (stderr, "n_type n_desc n_value string\n");
394
395 i = saved_stabs_index;
396 do
397 {
398 struct saved_stab *stabp;
399
400 stabp = saved_stabs + i;
401 if (stabp->string != NULL)
402 {
403 const char *s;
404
405 s = bfd_get_stab_name (stabp->type);
406 if (s != NULL)
407 fprintf (stderr, "%-6s", s);
408 else if (stabp->type == 0)
409 fprintf (stderr, "HdrSym");
410 else
411 fprintf (stderr, "%-6d", stabp->type);
412 fprintf (stderr, " %-6d ", stabp->desc);
413 fprintf_vma (stderr, stabp->value);
414 if (stabp->type != 0)
415 fprintf (stderr, " %s", stabp->string);
416 fprintf (stderr, "\n");
417 }
418 i = (i + 1) % SAVE_STABS_COUNT;
419 }
420 while (i != saved_stabs_index);
421}
422
423/* Free the saved stab strings. */
424
425static void
2da42df6 426free_saved_stabs (void)
252b5132
RH
427{
428 int i;
429
430 for (i = 0; i < SAVE_STABS_COUNT; i++)
431 {
9db70fc3
AM
432 free (saved_stabs[i].string);
433 saved_stabs[i].string = NULL;
252b5132
RH
434 }
435
436 saved_stabs_index = 0;
437}