Fix address violation errors parsing corrupt binary files.
[deliverable/binutils-gdb.git] / binutils / rddbg.c
CommitLineData
252b5132 1/* rddbg.c -- Read debugging information into a generic form.
2571583a 2 Copyright (C) 1995-2017 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
AJ
37 (bfd *, asymbol **, long, void *, bfd_boolean *);
38static bfd_boolean read_ieee_debugging_info (bfd *, void *, bfd_boolean *);
39static void save_stab (int, int, bfd_vma, const char *);
40static void stab_context (void);
41static void free_saved_stabs (void);
252b5132
RH
42
43/* Read debugging information from a BFD. Returns a generic debugging
44 pointer. */
45
2da42df6 46void *
b922d590 47read_debugging_info (bfd *abfd, asymbol **syms, long symcount, 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))
58 return NULL;
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))
64 return NULL;
65 }
66
67 if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
68 {
69 if (! read_ieee_debugging_info (abfd, dhandle, &found))
70 return NULL;
71 }
72
73 /* Try reading the COFF symbols if we didn't find any stabs in COFF
74 sections. */
75 if (! found
76 && bfd_get_flavour (abfd) == bfd_target_coff_flavour
77 && symcount > 0)
78 {
79 if (! parse_coff (abfd, syms, symcount, dhandle))
80 return NULL;
b34976b6 81 found = TRUE;
252b5132
RH
82 }
83
84 if (! found)
85 {
b922d590
NC
86 if (! no_messages)
87 non_fatal (_("%s: no recognized debugging information"),
88 bfd_get_filename (abfd));
252b5132
RH
89 return NULL;
90 }
91
92 return dhandle;
93}
94
95/* Read stabs in sections debugging information from a BFD. */
96
b34976b6 97static bfd_boolean
2da42df6
AJ
98read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
99 void *dhandle, bfd_boolean *pfound)
252b5132
RH
100{
101 static struct
102 {
103 const char *secname;
104 const char *strsecname;
7806762e
NC
105 }
106 names[] =
107 {
108 { ".stab", ".stabstr" },
109 { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" },
110 { "$GDB_SYMBOLS$", "$GDB_STRINGS$" }
111 };
252b5132 112 unsigned int i;
2da42df6 113 void *shandle;
252b5132 114
b34976b6 115 *pfound = FALSE;
252b5132
RH
116 shandle = NULL;
117
118 for (i = 0; i < sizeof names / sizeof names[0]; i++)
119 {
120 asection *sec, *strsec;
121
122 sec = bfd_get_section_by_name (abfd, names[i].secname);
123 strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
124 if (sec != NULL && strsec != NULL)
125 {
126 bfd_size_type stabsize, strsize;
127 bfd_byte *stabs, *strings;
128 bfd_byte *stab;
129 bfd_size_type stroff, next_stroff;
130
131 stabsize = bfd_section_size (abfd, sec);
132 stabs = (bfd_byte *) xmalloc (stabsize);
133 if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
134 {
135 fprintf (stderr, "%s: %s: %s\n",
136 bfd_get_filename (abfd), names[i].secname,
137 bfd_errmsg (bfd_get_error ()));
b34976b6 138 return FALSE;
252b5132
RH
139 }
140
141 strsize = bfd_section_size (abfd, strsec);
f41e4712 142 strings = (bfd_byte *) xmalloc (strsize + 1);
252b5132
RH
143 if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
144 {
145 fprintf (stderr, "%s: %s: %s\n",
146 bfd_get_filename (abfd), names[i].strsecname,
147 bfd_errmsg (bfd_get_error ()));
b34976b6 148 return FALSE;
252b5132 149 }
f41e4712
NC
150 /* Zero terminate the strings table, just in case. */
151 strings [strsize] = 0;
252b5132
RH
152 if (shandle == NULL)
153 {
b34976b6 154 shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
252b5132 155 if (shandle == NULL)
b34976b6 156 return FALSE;
252b5132
RH
157 }
158
b34976b6 159 *pfound = TRUE;
252b5132
RH
160
161 stroff = 0;
162 next_stroff = 0;
f41e4712
NC
163 /* PR 17512: file: 078-60391-0.001:0.1. */
164 for (stab = stabs; stab <= (stabs + stabsize) - 12; stab += 12)
252b5132 165 {
37cc8ec1 166 unsigned int strx;
252b5132 167 int type;
3d540e93 168 int other ATTRIBUTE_UNUSED;
252b5132
RH
169 int desc;
170 bfd_vma value;
171
172 /* This code presumes 32 bit values. */
173
174 strx = bfd_get_32 (abfd, stab);
175 type = bfd_get_8 (abfd, stab + 4);
176 other = bfd_get_8 (abfd, stab + 5);
177 desc = bfd_get_16 (abfd, stab + 6);
178 value = bfd_get_32 (abfd, stab + 8);
179
180 if (type == 0)
181 {
182 /* Special type 0 stabs indicate the offset to the
f3931575 183 next string table. */
252b5132
RH
184 stroff = next_stroff;
185 next_stroff += value;
186 }
187 else
188 {
f41e4712 189 size_t len;
252b5132
RH
190 char *f, *s;
191
f41e4712 192 if (stroff + strx >= strsize)
3b7aaf81 193 {
f41e4712 194 fprintf (stderr, _("%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n"),
3b7aaf81 195 bfd_get_filename (abfd), names[i].secname,
22d82235 196 (long) (stab - stabs) / 12, strx, type);
3b7aaf81
NC
197 continue;
198 }
53c7db4b 199
252b5132 200 s = (char *) strings + stroff + strx;
f41e4712 201 f = NULL;
53c7db4b 202
f41e4712
NC
203 /* PR 17512: file: 002-87578-0.001:0.1.
204 It is possible to craft a file where, without the 'strlen (s) > 0',
205 an attempt to read the byte before 'strings' would occur. */
206 while ((len = strlen (s)) > 0
207 && s[len - 1] == '\\'
252b5132
RH
208 && stab + 12 < stabs + stabsize)
209 {
210 char *p;
211
212 stab += 12;
f41e4712 213 p = s + len - 1;
252b5132 214 *p = '\0';
f41e4712
NC
215 strx = stroff + bfd_get_32 (abfd, stab);
216 if (strx >= strsize)
217 {
218 fprintf (stderr, _("%s: %s: stab entry %ld is corrupt\n"),
219 bfd_get_filename (abfd), names[i].secname,
220 (long) (stab - stabs) / 12);
221 break;
222 }
223 else
224 s = concat (s, (char *) strings + strx,
225 (const char *) NULL);
252b5132
RH
226
227 /* We have to restore the backslash, because, if
f3931575
AM
228 the linker is hashing stabs strings, we may
229 see the same string more than once. */
252b5132
RH
230 *p = '\\';
231
232 if (f != NULL)
233 free (f);
234 f = s;
235 }
236
237 save_stab (type, desc, value, s);
238
239 if (! parse_stab (dhandle, shandle, type, desc, value, s))
240 {
241 stab_context ();
242 free_saved_stabs ();
b34976b6 243 return FALSE;
252b5132
RH
244 }
245
246 /* Don't free f, since I think the stabs code
f3931575
AM
247 expects strings to hang around. This should be
248 straightened out. FIXME. */
252b5132
RH
249 }
250 }
251
252 free_saved_stabs ();
253 free (stabs);
254
255 /* Don't free strings, since I think the stabs code expects
f3931575
AM
256 the strings to hang around. This should be straightened
257 out. FIXME. */
252b5132
RH
258 }
259 }
260
261 if (shandle != NULL)
262 {
263 if (! finish_stab (dhandle, shandle))
b34976b6 264 return FALSE;
252b5132
RH
265 }
266
b34976b6 267 return TRUE;
252b5132
RH
268}
269
270/* Read stabs in the symbol table. */
271
b34976b6 272static bfd_boolean
2da42df6
AJ
273read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
274 void *dhandle, bfd_boolean *pfound)
252b5132 275{
2da42df6 276 void *shandle;
252b5132
RH
277 asymbol **ps, **symend;
278
279 shandle = NULL;
280 symend = syms + symcount;
281 for (ps = syms; ps < symend; ps++)
282 {
283 symbol_info i;
284
285 bfd_get_symbol_info (abfd, *ps, &i);
286
287 if (i.type == '-')
288 {
289 const char *s;
290 char *f;
291
292 if (shandle == NULL)
293 {
b34976b6 294 shandle = start_stab (dhandle, abfd, FALSE, syms, symcount);
252b5132 295 if (shandle == NULL)
b34976b6 296 return FALSE;
252b5132
RH
297 }
298
b34976b6 299 *pfound = TRUE;
252b5132
RH
300
301 s = i.name;
92134dc1
NC
302 if (s == NULL || strlen (s) < 1)
303 return FALSE;
252b5132 304 f = NULL;
92134dc1 305
ca4cf9b9
NC
306 while (strlen (s) > 0
307 && s[strlen (s) - 1] == '\\'
252b5132
RH
308 && ps + 1 < symend)
309 {
310 char *sc, *n;
311
312 ++ps;
313 sc = xstrdup (s);
314 sc[strlen (sc) - 1] = '\0';
315 n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
316 free (sc);
317 if (f != NULL)
318 free (f);
319 f = n;
320 s = n;
321 }
322
323 save_stab (i.stab_type, i.stab_desc, i.value, s);
324
325 if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
326 i.value, s))
327 {
328 stab_context ();
329 free_saved_stabs ();
b34976b6 330 return FALSE;
252b5132
RH
331 }
332
333 /* Don't free f, since I think the stabs code expects
334 strings to hang around. This should be straightened out.
335 FIXME. */
336 }
337 }
338
339 free_saved_stabs ();
340
341 if (shandle != NULL)
342 {
343 if (! finish_stab (dhandle, shandle))
b34976b6 344 return FALSE;
252b5132
RH
345 }
346
b34976b6 347 return TRUE;
252b5132
RH
348}
349
350/* Read IEEE debugging information. */
351
b34976b6 352static bfd_boolean
2da42df6 353read_ieee_debugging_info (bfd *abfd, void *dhandle, bfd_boolean *pfound)
252b5132
RH
354{
355 asection *dsec;
356 bfd_size_type size;
357 bfd_byte *contents;
358
359 /* The BFD backend puts the debugging information into a section
360 named .debug. */
361
362 dsec = bfd_get_section_by_name (abfd, ".debug");
363 if (dsec == NULL)
b34976b6 364 return TRUE;
252b5132
RH
365
366 size = bfd_section_size (abfd, dsec);
367 contents = (bfd_byte *) xmalloc (size);
368 if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
b34976b6 369 return FALSE;
252b5132
RH
370
371 if (! parse_ieee (dhandle, abfd, contents, size))
b34976b6 372 return FALSE;
252b5132
RH
373
374 free (contents);
375
b34976b6 376 *pfound = TRUE;
252b5132 377
b34976b6 378 return TRUE;
252b5132
RH
379}
380\f
381/* Record stabs strings, so that we can give some context for errors. */
382
383#define SAVE_STABS_COUNT (16)
384
385struct saved_stab
386{
387 int type;
388 int desc;
389 bfd_vma value;
390 char *string;
391};
392
393static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
394static int saved_stabs_index;
395
396/* Save a stabs string. */
397
398static void
2da42df6 399save_stab (int type, int desc, bfd_vma value, const char *string)
252b5132
RH
400{
401 if (saved_stabs[saved_stabs_index].string != NULL)
402 free (saved_stabs[saved_stabs_index].string);
403 saved_stabs[saved_stabs_index].type = type;
404 saved_stabs[saved_stabs_index].desc = desc;
405 saved_stabs[saved_stabs_index].value = value;
406 saved_stabs[saved_stabs_index].string = xstrdup (string);
407 saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
408}
409
410/* Provide context for an error. */
411
412static void
2da42df6 413stab_context (void)
252b5132
RH
414{
415 int i;
416
417 fprintf (stderr, _("Last stabs entries before error:\n"));
418 fprintf (stderr, "n_type n_desc n_value string\n");
419
420 i = saved_stabs_index;
421 do
422 {
423 struct saved_stab *stabp;
424
425 stabp = saved_stabs + i;
426 if (stabp->string != NULL)
427 {
428 const char *s;
429
430 s = bfd_get_stab_name (stabp->type);
431 if (s != NULL)
432 fprintf (stderr, "%-6s", s);
433 else if (stabp->type == 0)
434 fprintf (stderr, "HdrSym");
435 else
436 fprintf (stderr, "%-6d", stabp->type);
437 fprintf (stderr, " %-6d ", stabp->desc);
438 fprintf_vma (stderr, stabp->value);
439 if (stabp->type != 0)
440 fprintf (stderr, " %s", stabp->string);
441 fprintf (stderr, "\n");
442 }
443 i = (i + 1) % SAVE_STABS_COUNT;
444 }
445 while (i != saved_stabs_index);
446}
447
448/* Free the saved stab strings. */
449
450static void
2da42df6 451free_saved_stabs (void)
252b5132
RH
452{
453 int i;
454
455 for (i = 0; i < SAVE_STABS_COUNT; i++)
456 {
457 if (saved_stabs[i].string != NULL)
458 {
459 free (saved_stabs[i].string);
460 saved_stabs[i].string = NULL;
461 }
462 }
463
464 saved_stabs_index = 0;
465}
This page took 0.818693 seconds and 4 git commands to generate.