* rddbg.c (read_section_stabs_debugging_info): Also recognize
[deliverable/binutils-gdb.git] / binutils / rddbg.c
1 /* rddbg.c -- Read debugging information into a generic form.
2 Copyright 1995, 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
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
9 the Free Software Foundation; either version 2 of the License, or
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
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22 /* This file reads debugging information into a generic form. This
23 file knows how to dig the debugging information out of an object
24 file. */
25
26 #include "bfd.h"
27 #include "bucomm.h"
28 #include "libiberty.h"
29 #include "debug.h"
30 #include "budbg.h"
31
32 static boolean read_section_stabs_debugging_info
33 PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
34 static boolean read_symbol_stabs_debugging_info
35 PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
36 static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *));
37 static void save_stab PARAMS ((int, int, bfd_vma, const char *));
38 static void stab_context PARAMS ((void));
39 static void free_saved_stabs PARAMS ((void));
40
41 /* Read debugging information from a BFD. Returns a generic debugging
42 pointer. */
43
44 PTR
45 read_debugging_info (abfd, syms, symcount)
46 bfd *abfd;
47 asymbol **syms;
48 long symcount;
49 {
50 PTR dhandle;
51 boolean found;
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;
82 found = true;
83 }
84
85 if (! found)
86 {
87 non_fatal (_("%s: no recognized debugging information"),
88 bfd_get_filename (abfd));
89 return NULL;
90 }
91
92 return dhandle;
93 }
94
95 /* Read stabs in sections debugging information from a BFD. */
96
97 static boolean
98 read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
99 bfd *abfd;
100 asymbol **syms;
101 long symcount;
102 PTR dhandle;
103 boolean *pfound;
104 {
105 static struct
106 {
107 const char *secname;
108 const char *strsecname;
109 } names[] = { { ".stab", ".stabstr" },
110 { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" } };
111 unsigned int i;
112 PTR shandle;
113
114 *pfound = false;
115 shandle = NULL;
116
117 for (i = 0; i < sizeof names / sizeof names[0]; i++)
118 {
119 asection *sec, *strsec;
120
121 sec = bfd_get_section_by_name (abfd, names[i].secname);
122 strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
123 if (sec != NULL && strsec != NULL)
124 {
125 bfd_size_type stabsize, strsize;
126 bfd_byte *stabs, *strings;
127 bfd_byte *stab;
128 bfd_size_type stroff, next_stroff;
129
130 stabsize = bfd_section_size (abfd, sec);
131 stabs = (bfd_byte *) xmalloc (stabsize);
132 if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
133 {
134 fprintf (stderr, "%s: %s: %s\n",
135 bfd_get_filename (abfd), names[i].secname,
136 bfd_errmsg (bfd_get_error ()));
137 return false;
138 }
139
140 strsize = bfd_section_size (abfd, strsec);
141 strings = (bfd_byte *) xmalloc (strsize);
142 if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
143 {
144 fprintf (stderr, "%s: %s: %s\n",
145 bfd_get_filename (abfd), names[i].strsecname,
146 bfd_errmsg (bfd_get_error ()));
147 return false;
148 }
149
150 if (shandle == NULL)
151 {
152 shandle = start_stab (dhandle, abfd, true, syms, symcount);
153 if (shandle == NULL)
154 return false;
155 }
156
157 *pfound = true;
158
159 stroff = 0;
160 next_stroff = 0;
161 for (stab = stabs; stab < stabs + stabsize; stab += 12)
162 {
163 unsigned int strx;
164 int type;
165 int other;
166 int desc;
167 bfd_vma value;
168
169 /* This code presumes 32 bit values. */
170
171 strx = bfd_get_32 (abfd, stab);
172 type = bfd_get_8 (abfd, stab + 4);
173 other = bfd_get_8 (abfd, stab + 5);
174 desc = bfd_get_16 (abfd, stab + 6);
175 value = bfd_get_32 (abfd, stab + 8);
176
177 if (type == 0)
178 {
179 /* Special type 0 stabs indicate the offset to the
180 next string table. */
181 stroff = next_stroff;
182 next_stroff += value;
183 }
184 else
185 {
186 char *f, *s;
187
188 f = NULL;
189
190 if (stroff + strx > strsize)
191 {
192 fprintf (stderr, "%s: %s: stab entry %d is corrupt, strx = 0x%x, type = %d\n",
193 bfd_get_filename (abfd), names[i].secname,
194 (stab - stabs) / 12, strx, type);
195 continue;
196 }
197
198 s = (char *) strings + stroff + strx;
199
200 while (s[strlen (s) - 1] == '\\'
201 && stab + 12 < stabs + stabsize)
202 {
203 char *p;
204
205 stab += 12;
206 p = s + strlen (s) - 1;
207 *p = '\0';
208 s = concat (s,
209 ((char *) strings
210 + stroff
211 + bfd_get_32 (abfd, stab)),
212 (const char *) NULL);
213
214 /* We have to restore the backslash, because, if
215 the linker is hashing stabs strings, we may
216 see the same string more than once. */
217 *p = '\\';
218
219 if (f != NULL)
220 free (f);
221 f = s;
222 }
223
224 save_stab (type, desc, value, s);
225
226 if (! parse_stab (dhandle, shandle, type, desc, value, s))
227 {
228 stab_context ();
229 free_saved_stabs ();
230 return false;
231 }
232
233 /* Don't free f, since I think the stabs code
234 expects strings to hang around. This should be
235 straightened out. FIXME. */
236 }
237 }
238
239 free_saved_stabs ();
240 free (stabs);
241
242 /* Don't free strings, since I think the stabs code expects
243 the strings to hang around. This should be straightened
244 out. FIXME. */
245 }
246 }
247
248 if (shandle != NULL)
249 {
250 if (! finish_stab (dhandle, shandle))
251 return false;
252 }
253
254 return true;
255 }
256
257 /* Read stabs in the symbol table. */
258
259 static boolean
260 read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
261 bfd *abfd;
262 asymbol **syms;
263 long symcount;
264 PTR dhandle;
265 boolean *pfound;
266 {
267 PTR shandle;
268 asymbol **ps, **symend;
269
270 shandle = NULL;
271 symend = syms + symcount;
272 for (ps = syms; ps < symend; ps++)
273 {
274 symbol_info i;
275
276 bfd_get_symbol_info (abfd, *ps, &i);
277
278 if (i.type == '-')
279 {
280 const char *s;
281 char *f;
282
283 if (shandle == NULL)
284 {
285 shandle = start_stab (dhandle, abfd, false, syms, symcount);
286 if (shandle == NULL)
287 return false;
288 }
289
290 *pfound = true;
291
292 s = i.name;
293 f = NULL;
294 while (s[strlen (s) - 1] == '\\'
295 && ps + 1 < symend)
296 {
297 char *sc, *n;
298
299 ++ps;
300 sc = xstrdup (s);
301 sc[strlen (sc) - 1] = '\0';
302 n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
303 free (sc);
304 if (f != NULL)
305 free (f);
306 f = n;
307 s = n;
308 }
309
310 save_stab (i.stab_type, i.stab_desc, i.value, s);
311
312 if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
313 i.value, s))
314 {
315 stab_context ();
316 free_saved_stabs ();
317 return false;
318 }
319
320 /* Don't free f, since I think the stabs code expects
321 strings to hang around. This should be straightened out.
322 FIXME. */
323 }
324 }
325
326 free_saved_stabs ();
327
328 if (shandle != NULL)
329 {
330 if (! finish_stab (dhandle, shandle))
331 return false;
332 }
333
334 return true;
335 }
336
337 /* Read IEEE debugging information. */
338
339 static boolean
340 read_ieee_debugging_info (abfd, dhandle, pfound)
341 bfd *abfd;
342 PTR dhandle;
343 boolean *pfound;
344 {
345 asection *dsec;
346 bfd_size_type size;
347 bfd_byte *contents;
348
349 /* The BFD backend puts the debugging information into a section
350 named .debug. */
351
352 dsec = bfd_get_section_by_name (abfd, ".debug");
353 if (dsec == NULL)
354 return true;
355
356 size = bfd_section_size (abfd, dsec);
357 contents = (bfd_byte *) xmalloc (size);
358 if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
359 return false;
360
361 if (! parse_ieee (dhandle, abfd, contents, size))
362 return false;
363
364 free (contents);
365
366 *pfound = true;
367
368 return true;
369 }
370 \f
371 /* Record stabs strings, so that we can give some context for errors. */
372
373 #define SAVE_STABS_COUNT (16)
374
375 struct saved_stab
376 {
377 int type;
378 int desc;
379 bfd_vma value;
380 char *string;
381 };
382
383 static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
384 static int saved_stabs_index;
385
386 /* Save a stabs string. */
387
388 static void
389 save_stab (type, desc, value, string)
390 int type;
391 int desc;
392 bfd_vma value;
393 const char *string;
394 {
395 if (saved_stabs[saved_stabs_index].string != NULL)
396 free (saved_stabs[saved_stabs_index].string);
397 saved_stabs[saved_stabs_index].type = type;
398 saved_stabs[saved_stabs_index].desc = desc;
399 saved_stabs[saved_stabs_index].value = value;
400 saved_stabs[saved_stabs_index].string = xstrdup (string);
401 saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
402 }
403
404 /* Provide context for an error. */
405
406 static void
407 stab_context ()
408 {
409 int i;
410
411 fprintf (stderr, _("Last stabs entries before error:\n"));
412 fprintf (stderr, "n_type n_desc n_value string\n");
413
414 i = saved_stabs_index;
415 do
416 {
417 struct saved_stab *stabp;
418
419 stabp = saved_stabs + i;
420 if (stabp->string != NULL)
421 {
422 const char *s;
423
424 s = bfd_get_stab_name (stabp->type);
425 if (s != NULL)
426 fprintf (stderr, "%-6s", s);
427 else if (stabp->type == 0)
428 fprintf (stderr, "HdrSym");
429 else
430 fprintf (stderr, "%-6d", stabp->type);
431 fprintf (stderr, " %-6d ", stabp->desc);
432 fprintf_vma (stderr, stabp->value);
433 if (stabp->type != 0)
434 fprintf (stderr, " %s", stabp->string);
435 fprintf (stderr, "\n");
436 }
437 i = (i + 1) % SAVE_STABS_COUNT;
438 }
439 while (i != saved_stabs_index);
440 }
441
442 /* Free the saved stab strings. */
443
444 static void
445 free_saved_stabs ()
446 {
447 int i;
448
449 for (i = 0; i < SAVE_STABS_COUNT; i++)
450 {
451 if (saved_stabs[i].string != NULL)
452 {
453 free (saved_stabs[i].string);
454 saved_stabs[i].string = NULL;
455 }
456 }
457
458 saved_stabs_index = 0;
459 }
This page took 0.039577 seconds and 5 git commands to generate.