rddbg.c revision 130562
112408Skvn/* rddbg.c -- Read debugging information into a generic form. 212408Skvn Copyright 1995, 1996, 1997, 2000, 2002, 2003 312408Skvn Free Software Foundation, Inc. 412408Skvn Written by Ian Lance Taylor <ian@cygnus.com>. 512408Skvn 612408Skvn This file is part of GNU Binutils. 712408Skvn 812408Skvn This program is free software; you can redistribute it and/or modify 912408Skvn it under the terms of the GNU General Public License as published by 1012408Skvn the Free Software Foundation; either version 2 of the License, or 1112408Skvn (at your option) any later version. 1212408Skvn 1312408Skvn This program is distributed in the hope that it will be useful, 1412408Skvn but WITHOUT ANY WARRANTY; without even the implied warranty of 1512408Skvn MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1612408Skvn GNU General Public License for more details. 1712408Skvn 1812408Skvn You should have received a copy of the GNU General Public License 1912408Skvn along with this program; if not, write to the Free Software 2012408Skvn Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 2112408Skvn 02111-1307, USA. */ 2212408Skvn 2312408Skvn/* This file reads debugging information into a generic form. This 2412408Skvn file knows how to dig the debugging information out of an object 2512408Skvn file. */ 2612408Skvn 2712408Skvn#include "bfd.h" 2812408Skvn#include "bucomm.h" 2912408Skvn#include "libiberty.h" 3012408Skvn#include "debug.h" 3112408Skvn#include "budbg.h" 3212408Skvn 3312408Skvnstatic bfd_boolean read_section_stabs_debugging_info 3412408Skvn (bfd *, asymbol **, long, void *, bfd_boolean *); 3512408Skvnstatic bfd_boolean read_symbol_stabs_debugging_info 3612408Skvn (bfd *, asymbol **, long, void *, bfd_boolean *); 3712408Skvnstatic bfd_boolean read_ieee_debugging_info (bfd *, void *, bfd_boolean *); 3812408Skvnstatic void save_stab (int, int, bfd_vma, const char *); 3912408Skvnstatic void stab_context (void); 4012408Skvnstatic void free_saved_stabs (void); 4112408Skvn 4212408Skvn/* Read debugging information from a BFD. Returns a generic debugging 4312408Skvn pointer. */ 4412408Skvn 4512408Skvnvoid * 4612408Skvnread_debugging_info (bfd *abfd, asymbol **syms, long symcount) 4712408Skvn{ 4812408Skvn void *dhandle; 4912408Skvn bfd_boolean found; 5012408Skvn 5112408Skvn dhandle = debug_init (); 5212408Skvn if (dhandle == NULL) 5312408Skvn return NULL; 5412408Skvn 5512408Skvn if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, 5612408Skvn &found)) 5712408Skvn return NULL; 5812408Skvn 5912408Skvn if (bfd_get_flavour (abfd) == bfd_target_aout_flavour) 6012408Skvn { 6112408Skvn if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, 6212408Skvn &found)) 6312408Skvn return NULL; 6412408Skvn } 6512408Skvn 6612408Skvn if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour) 6712408Skvn { 6812408Skvn if (! read_ieee_debugging_info (abfd, dhandle, &found)) 6912408Skvn return NULL; 7012408Skvn } 7112408Skvn 7212408Skvn /* Try reading the COFF symbols if we didn't find any stabs in COFF 7312408Skvn sections. */ 7412408Skvn if (! found 7512408Skvn && bfd_get_flavour (abfd) == bfd_target_coff_flavour 7612408Skvn && symcount > 0) 7712408Skvn { 7812408Skvn if (! parse_coff (abfd, syms, symcount, dhandle)) 7912408Skvn return NULL; 8012408Skvn found = TRUE; 8112408Skvn } 8212408Skvn 8312408Skvn if (! found) 8412408Skvn { 8512408Skvn non_fatal (_("%s: no recognized debugging information"), 8612408Skvn bfd_get_filename (abfd)); 8712408Skvn return NULL; 8812408Skvn } 8912408Skvn 9012408Skvn return dhandle; 9112408Skvn} 9212408Skvn 9312408Skvn/* Read stabs in sections debugging information from a BFD. */ 9412408Skvn 9512408Skvnstatic bfd_boolean 9612408Skvnread_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount, 9712408Skvn void *dhandle, bfd_boolean *pfound) 9812408Skvn{ 9912408Skvn static struct 10012408Skvn { 10112408Skvn const char *secname; 10212408Skvn const char *strsecname; 10312408Skvn } names[] = { { ".stab", ".stabstr" }, 10412408Skvn { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" } }; 10512408Skvn unsigned int i; 10612408Skvn void *shandle; 10712408Skvn 10812408Skvn *pfound = FALSE; 10912408Skvn shandle = NULL; 11012408Skvn 11112408Skvn for (i = 0; i < sizeof names / sizeof names[0]; i++) 11212408Skvn { 11312408Skvn asection *sec, *strsec; 11412408Skvn 11512408Skvn sec = bfd_get_section_by_name (abfd, names[i].secname); 11612408Skvn strsec = bfd_get_section_by_name (abfd, names[i].strsecname); 11712408Skvn if (sec != NULL && strsec != NULL) 11812408Skvn { 11912408Skvn bfd_size_type stabsize, strsize; 12012408Skvn bfd_byte *stabs, *strings; 12112408Skvn bfd_byte *stab; 12212408Skvn bfd_size_type stroff, next_stroff; 12312408Skvn 12412408Skvn stabsize = bfd_section_size (abfd, sec); 12512408Skvn stabs = (bfd_byte *) xmalloc (stabsize); 12612408Skvn if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize)) 12712408Skvn { 12812408Skvn fprintf (stderr, "%s: %s: %s\n", 12912408Skvn bfd_get_filename (abfd), names[i].secname, 13012408Skvn bfd_errmsg (bfd_get_error ())); 13112408Skvn return FALSE; 13212408Skvn } 13312408Skvn 13412408Skvn strsize = bfd_section_size (abfd, strsec); 13512408Skvn strings = (bfd_byte *) xmalloc (strsize); 13612408Skvn if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize)) 13712408Skvn { 13812408Skvn fprintf (stderr, "%s: %s: %s\n", 13912408Skvn bfd_get_filename (abfd), names[i].strsecname, 14012408Skvn bfd_errmsg (bfd_get_error ())); 14112408Skvn return FALSE; 14212408Skvn } 14312408Skvn 14412408Skvn if (shandle == NULL) 14512408Skvn { 14612408Skvn shandle = start_stab (dhandle, abfd, TRUE, syms, symcount); 14712408Skvn if (shandle == NULL) 14812408Skvn return FALSE; 14912408Skvn } 15012408Skvn 15112408Skvn *pfound = TRUE; 15212408Skvn 15312408Skvn stroff = 0; 15412408Skvn next_stroff = 0; 15512408Skvn for (stab = stabs; stab < stabs + stabsize; stab += 12) 15612408Skvn { 15712408Skvn unsigned int strx; 15812408Skvn int type; 15912408Skvn int other; 16012408Skvn int desc; 16112408Skvn bfd_vma value; 16212408Skvn 16312408Skvn /* This code presumes 32 bit values. */ 16412408Skvn 16512408Skvn strx = bfd_get_32 (abfd, stab); 16612408Skvn type = bfd_get_8 (abfd, stab + 4); 16712408Skvn other = bfd_get_8 (abfd, stab + 5); 16812408Skvn desc = bfd_get_16 (abfd, stab + 6); 16912408Skvn value = bfd_get_32 (abfd, stab + 8); 17012408Skvn 17112408Skvn if (type == 0) 17212408Skvn { 17312408Skvn /* Special type 0 stabs indicate the offset to the 17412408Skvn next string table. */ 17512408Skvn stroff = next_stroff; 17612408Skvn next_stroff += value; 17712408Skvn } 17812408Skvn else 17912408Skvn { 18012408Skvn char *f, *s; 18112408Skvn 18212408Skvn f = NULL; 18312408Skvn 18412408Skvn if (stroff + strx > strsize) 18512408Skvn { 18612408Skvn fprintf (stderr, "%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n", 18712408Skvn bfd_get_filename (abfd), names[i].secname, 18812408Skvn (long) (stab - stabs) / 12, strx, type); 18912408Skvn continue; 19012408Skvn } 19112408Skvn 19212408Skvn s = (char *) strings + stroff + strx; 19312408Skvn 19412408Skvn while (s[strlen (s) - 1] == '\\' 19512408Skvn && stab + 12 < stabs + stabsize) 19612408Skvn { 19712408Skvn char *p; 19812408Skvn 19912408Skvn stab += 12; 20012408Skvn p = s + strlen (s) - 1; 20112408Skvn *p = '\0'; 20212408Skvn s = concat (s, 20312408Skvn ((char *) strings 20412408Skvn + stroff 20512408Skvn + bfd_get_32 (abfd, stab)), 20612408Skvn (const char *) NULL); 20712408Skvn 20812408Skvn /* We have to restore the backslash, because, if 20912408Skvn the linker is hashing stabs strings, we may 21012408Skvn see the same string more than once. */ 21112408Skvn *p = '\\'; 21212408Skvn 21312408Skvn if (f != NULL) 21412408Skvn free (f); 21512408Skvn f = s; 21612408Skvn } 21712408Skvn 21812408Skvn save_stab (type, desc, value, s); 21912408Skvn 22012408Skvn if (! parse_stab (dhandle, shandle, type, desc, value, s)) 22112408Skvn { 22212408Skvn stab_context (); 22312408Skvn free_saved_stabs (); 22412408Skvn return FALSE; 22512408Skvn } 22612408Skvn 22712408Skvn /* Don't free f, since I think the stabs code 22812408Skvn expects strings to hang around. This should be 22912408Skvn straightened out. FIXME. */ 23012408Skvn } 23112408Skvn } 23212408Skvn 23312408Skvn free_saved_stabs (); 23412408Skvn free (stabs); 23512408Skvn 23612408Skvn /* Don't free strings, since I think the stabs code expects 23712408Skvn the strings to hang around. This should be straightened 23812408Skvn out. FIXME. */ 23912408Skvn } 24012408Skvn } 24112408Skvn 24212408Skvn if (shandle != NULL) 24312408Skvn { 24412408Skvn if (! finish_stab (dhandle, shandle)) 24512408Skvn return FALSE; 24612408Skvn } 24712408Skvn 24812408Skvn return TRUE; 24912408Skvn} 25012408Skvn 25112408Skvn/* Read stabs in the symbol table. */ 25212408Skvn 25312408Skvnstatic bfd_boolean 25412408Skvnread_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount, 25512408Skvn void *dhandle, bfd_boolean *pfound) 25612408Skvn{ 25712408Skvn void *shandle; 25812408Skvn asymbol **ps, **symend; 25912408Skvn 26012408Skvn shandle = NULL; 26112408Skvn symend = syms + symcount; 26212408Skvn for (ps = syms; ps < symend; ps++) 26312408Skvn { 26412408Skvn symbol_info i; 26512408Skvn 26612408Skvn bfd_get_symbol_info (abfd, *ps, &i); 26712408Skvn 26812408Skvn if (i.type == '-') 26912408Skvn { 27012408Skvn const char *s; 27112408Skvn char *f; 27212408Skvn 27312408Skvn if (shandle == NULL) 27412408Skvn { 27512408Skvn shandle = start_stab (dhandle, abfd, FALSE, syms, symcount); 27612408Skvn if (shandle == NULL) 27712408Skvn return FALSE; 27812408Skvn } 27912408Skvn 28012408Skvn *pfound = TRUE; 28112408Skvn 28212408Skvn s = i.name; 28312408Skvn f = NULL; 28412408Skvn while (s[strlen (s) - 1] == '\\' 28512408Skvn && ps + 1 < symend) 28612408Skvn { 28712408Skvn char *sc, *n; 28812408Skvn 28912408Skvn ++ps; 29012408Skvn sc = xstrdup (s); 29112408Skvn sc[strlen (sc) - 1] = '\0'; 29212408Skvn n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL); 29312408Skvn free (sc); 29412408Skvn if (f != NULL) 29512408Skvn free (f); 29612527Siveresov f = n; 29712527Siveresov s = n; 29812527Siveresov } 29912527Siveresov 30012527Siveresov save_stab (i.stab_type, i.stab_desc, i.value, s); 30112408Skvn 30212408Skvn if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc, 30312527Siveresov i.value, s)) 30412527Siveresov { 30512527Siveresov stab_context (); 30612527Siveresov free_saved_stabs (); 30712527Siveresov return FALSE; 30812408Skvn } 30912408Skvn 31012408Skvn /* Don't free f, since I think the stabs code expects 31112408Skvn strings to hang around. This should be straightened out. 31212408Skvn FIXME. */ 31312408Skvn } 31412408Skvn } 31512408Skvn 31612408Skvn free_saved_stabs (); 31712408Skvn 31812408Skvn if (shandle != NULL) 31912408Skvn { 32012408Skvn if (! finish_stab (dhandle, shandle)) 32112408Skvn return FALSE; 32212408Skvn } 32312408Skvn 32412408Skvn return TRUE; 32512408Skvn} 32612408Skvn 32712408Skvn/* Read IEEE debugging information. */ 32812408Skvn 32912408Skvnstatic bfd_boolean 33012408Skvnread_ieee_debugging_info (bfd *abfd, void *dhandle, bfd_boolean *pfound) 33112408Skvn{ 33212408Skvn asection *dsec; 33312408Skvn bfd_size_type size; 33412408Skvn bfd_byte *contents; 33512408Skvn 33612408Skvn /* The BFD backend puts the debugging information into a section 33712408Skvn named .debug. */ 33812408Skvn 33912408Skvn dsec = bfd_get_section_by_name (abfd, ".debug"); 34012408Skvn if (dsec == NULL) 34112408Skvn return TRUE; 34212408Skvn 34312408Skvn size = bfd_section_size (abfd, dsec); 34412408Skvn contents = (bfd_byte *) xmalloc (size); 34512408Skvn if (! bfd_get_section_contents (abfd, dsec, contents, 0, size)) 34612408Skvn return FALSE; 34712408Skvn 34812408Skvn if (! parse_ieee (dhandle, abfd, contents, size)) 34912408Skvn return FALSE; 35012408Skvn 35112408Skvn free (contents); 35212408Skvn 35312408Skvn *pfound = TRUE; 35412408Skvn 35512408Skvn return TRUE; 35612408Skvn} 35712408Skvn 35812408Skvn/* Record stabs strings, so that we can give some context for errors. */ 35912408Skvn 36012408Skvn#define SAVE_STABS_COUNT (16) 36112408Skvn 36212408Skvnstruct saved_stab 36312408Skvn{ 36412408Skvn int type; 36512408Skvn int desc; 36612408Skvn bfd_vma value; 36712408Skvn char *string; 36812408Skvn}; 36912408Skvn 37012408Skvnstatic struct saved_stab saved_stabs[SAVE_STABS_COUNT]; 37112408Skvnstatic int saved_stabs_index; 37212408Skvn 37312408Skvn/* Save a stabs string. */ 37412408Skvn 37512408Skvnstatic void 37612408Skvnsave_stab (int type, int desc, bfd_vma value, const char *string) 37712408Skvn{ 37812408Skvn if (saved_stabs[saved_stabs_index].string != NULL) 37912408Skvn free (saved_stabs[saved_stabs_index].string); 38012408Skvn saved_stabs[saved_stabs_index].type = type; 38112408Skvn saved_stabs[saved_stabs_index].desc = desc; 38212408Skvn saved_stabs[saved_stabs_index].value = value; 38312408Skvn saved_stabs[saved_stabs_index].string = xstrdup (string); 384 saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT; 385} 386 387/* Provide context for an error. */ 388 389static void 390stab_context (void) 391{ 392 int i; 393 394 fprintf (stderr, _("Last stabs entries before error:\n")); 395 fprintf (stderr, "n_type n_desc n_value string\n"); 396 397 i = saved_stabs_index; 398 do 399 { 400 struct saved_stab *stabp; 401 402 stabp = saved_stabs + i; 403 if (stabp->string != NULL) 404 { 405 const char *s; 406 407 s = bfd_get_stab_name (stabp->type); 408 if (s != NULL) 409 fprintf (stderr, "%-6s", s); 410 else if (stabp->type == 0) 411 fprintf (stderr, "HdrSym"); 412 else 413 fprintf (stderr, "%-6d", stabp->type); 414 fprintf (stderr, " %-6d ", stabp->desc); 415 fprintf_vma (stderr, stabp->value); 416 if (stabp->type != 0) 417 fprintf (stderr, " %s", stabp->string); 418 fprintf (stderr, "\n"); 419 } 420 i = (i + 1) % SAVE_STABS_COUNT; 421 } 422 while (i != saved_stabs_index); 423} 424 425/* Free the saved stab strings. */ 426 427static void 428free_saved_stabs (void) 429{ 430 int i; 431 432 for (i = 0; i < SAVE_STABS_COUNT; i++) 433 { 434 if (saved_stabs[i].string != NULL) 435 { 436 free (saved_stabs[i].string); 437 saved_stabs[i].string = NULL; 438 } 439 } 440 441 saved_stabs_index = 0; 442} 443