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