X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Frddbg.c;h=f9fae05d6691162f84dc02c0b1c63f7c37e901f3;hb=37cc8ec1be0959c1878e79fd2baed888da4a2775;hp=8559621b3b02f2a5ac9ee1bbb6e1f006accb4b34;hpb=e1c145993ec59ed01a1bbc88c294ac3167fa5c66;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/rddbg.c b/binutils/rddbg.c index 8559621b3b..f9fae05d66 100644 --- a/binutils/rddbg.c +++ b/binutils/rddbg.c @@ -1,5 +1,5 @@ /* rddbg.c -- Read debugging information into a generic form. - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 96, 97, 98, 2000 Free Software Foundation, Inc. Written by Ian Lance Taylor . This file is part of GNU Binutils. @@ -30,14 +30,22 @@ #include "budbg.h" static boolean read_section_stabs_debugging_info - PARAMS ((bfd *, PTR, boolean *)); + PARAMS ((bfd *, asymbol **, long, PTR, boolean *)); +static boolean read_symbol_stabs_debugging_info + PARAMS ((bfd *, asymbol **, long, PTR, boolean *)); +static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *)); +static void save_stab PARAMS ((int, int, bfd_vma, const char *)); +static void stab_context PARAMS ((void)); +static void free_saved_stabs PARAMS ((void)); /* Read debugging information from a BFD. Returns a generic debugging pointer. */ PTR -read_debugging_info (abfd) +read_debugging_info (abfd, syms, symcount) bfd *abfd; + asymbol **syms; + long symcount; { PTR dhandle; boolean found; @@ -46,15 +54,38 @@ read_debugging_info (abfd) if (dhandle == NULL) return NULL; - /* All we know about right now is stabs in sections. */ - - if (! read_section_stabs_debugging_info (abfd, dhandle, &found)) + if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, + &found)) return NULL; + if (bfd_get_flavour (abfd) == bfd_target_aout_flavour) + { + if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, + &found)) + return NULL; + } + + if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour) + { + if (! read_ieee_debugging_info (abfd, dhandle, &found)) + return NULL; + } + + /* Try reading the COFF symbols if we didn't find any stabs in COFF + sections. */ + if (! found + && bfd_get_flavour (abfd) == bfd_target_coff_flavour + && symcount > 0) + { + if (! parse_coff (abfd, syms, symcount, dhandle)) + return NULL; + found = true; + } + if (! found) { - fprintf (stderr, "%s: no recognized debugging information\n", - bfd_get_filename (abfd)); + non_fatal (_("%s: no recognized debugging information"), + bfd_get_filename (abfd)); return NULL; } @@ -64,8 +95,10 @@ read_debugging_info (abfd) /* Read stabs in sections debugging information from a BFD. */ static boolean -read_section_stabs_debugging_info (abfd, dhandle, pfound) +read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound) bfd *abfd; + asymbol **syms; + long symcount; PTR dhandle; boolean *pfound; { @@ -115,7 +148,7 @@ read_section_stabs_debugging_info (abfd, dhandle, pfound) if (shandle == NULL) { - shandle = start_stab (dhandle); + shandle = start_stab (dhandle, abfd, true, syms, symcount); if (shandle == NULL) return false; } @@ -126,7 +159,7 @@ read_section_stabs_debugging_info (abfd, dhandle, pfound) next_stroff = 0; for (stab = stabs; stab < stabs + stabsize; stab += 12) { - bfd_size_type strx; + unsigned int strx; int type; int other; int desc; @@ -152,24 +185,49 @@ read_section_stabs_debugging_info (abfd, dhandle, pfound) char *f, *s; f = NULL; + + if (stroff + strx > strsize) + { + fprintf (stderr, "%s: %s: stab entry %d is corrupt, strx = 0x%x, type = %d\n", + bfd_get_filename (abfd), names[i].secname, + (stab - stabs) / 12, strx, type); + continue; + } + s = (char *) strings + stroff + strx; + while (s[strlen (s) - 1] == '\\' && stab + 12 < stabs + stabsize) { + char *p; + stab += 12; - s[strlen (s) - 1] = '\0'; + p = s + strlen (s) - 1; + *p = '\0'; s = concat (s, ((char *) strings + stroff + bfd_get_32 (abfd, stab)), (const char *) NULL); + + /* We have to restore the backslash, because, if + the linker is hashing stabs strings, we may + see the same string more than once. */ + *p = '\\'; + if (f != NULL) free (f); f = s; } + save_stab (type, desc, value, s); + if (! parse_stab (dhandle, shandle, type, desc, value, s)) - return false; + { + stab_context (); + free_saved_stabs (); + return false; + } /* Don't free f, since I think the stabs code expects strings to hang around. This should be @@ -177,6 +235,7 @@ read_section_stabs_debugging_info (abfd, dhandle, pfound) } } + free_saved_stabs (); free (stabs); /* Don't free strings, since I think the stabs code expects @@ -193,3 +252,207 @@ read_section_stabs_debugging_info (abfd, dhandle, pfound) return true; } + +/* Read stabs in the symbol table. */ + +static boolean +read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound) + bfd *abfd; + asymbol **syms; + long symcount; + PTR dhandle; + boolean *pfound; +{ + PTR shandle; + asymbol **ps, **symend; + + shandle = NULL; + symend = syms + symcount; + for (ps = syms; ps < symend; ps++) + { + symbol_info i; + + bfd_get_symbol_info (abfd, *ps, &i); + + if (i.type == '-') + { + const char *s; + char *f; + + if (shandle == NULL) + { + shandle = start_stab (dhandle, abfd, false, syms, symcount); + if (shandle == NULL) + return false; + } + + *pfound = true; + + s = i.name; + f = NULL; + while (s[strlen (s) - 1] == '\\' + && ps + 1 < symend) + { + char *sc, *n; + + ++ps; + sc = xstrdup (s); + sc[strlen (sc) - 1] = '\0'; + n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL); + free (sc); + if (f != NULL) + free (f); + f = n; + s = n; + } + + save_stab (i.stab_type, i.stab_desc, i.value, s); + + if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc, + i.value, s)) + { + stab_context (); + free_saved_stabs (); + return false; + } + + /* Don't free f, since I think the stabs code expects + strings to hang around. This should be straightened out. + FIXME. */ + } + } + + free_saved_stabs (); + + if (shandle != NULL) + { + if (! finish_stab (dhandle, shandle)) + return false; + } + + return true; +} + +/* Read IEEE debugging information. */ + +static boolean +read_ieee_debugging_info (abfd, dhandle, pfound) + bfd *abfd; + PTR dhandle; + boolean *pfound; +{ + asection *dsec; + bfd_size_type size; + bfd_byte *contents; + + /* The BFD backend puts the debugging information into a section + named .debug. */ + + dsec = bfd_get_section_by_name (abfd, ".debug"); + if (dsec == NULL) + return true; + + size = bfd_section_size (abfd, dsec); + contents = (bfd_byte *) xmalloc (size); + if (! bfd_get_section_contents (abfd, dsec, contents, 0, size)) + return false; + + if (! parse_ieee (dhandle, abfd, contents, size)) + return false; + + free (contents); + + *pfound = true; + + return true; +} + +/* Record stabs strings, so that we can give some context for errors. */ + +#define SAVE_STABS_COUNT (16) + +struct saved_stab +{ + int type; + int desc; + bfd_vma value; + char *string; +}; + +static struct saved_stab saved_stabs[SAVE_STABS_COUNT]; +static int saved_stabs_index; + +/* Save a stabs string. */ + +static void +save_stab (type, desc, value, string) + int type; + int desc; + bfd_vma value; + const char *string; +{ + if (saved_stabs[saved_stabs_index].string != NULL) + free (saved_stabs[saved_stabs_index].string); + saved_stabs[saved_stabs_index].type = type; + saved_stabs[saved_stabs_index].desc = desc; + saved_stabs[saved_stabs_index].value = value; + saved_stabs[saved_stabs_index].string = xstrdup (string); + saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT; +} + +/* Provide context for an error. */ + +static void +stab_context () +{ + int i; + + fprintf (stderr, _("Last stabs entries before error:\n")); + fprintf (stderr, "n_type n_desc n_value string\n"); + + i = saved_stabs_index; + do + { + struct saved_stab *stabp; + + stabp = saved_stabs + i; + if (stabp->string != NULL) + { + const char *s; + + s = bfd_get_stab_name (stabp->type); + if (s != NULL) + fprintf (stderr, "%-6s", s); + else if (stabp->type == 0) + fprintf (stderr, "HdrSym"); + else + fprintf (stderr, "%-6d", stabp->type); + fprintf (stderr, " %-6d ", stabp->desc); + fprintf_vma (stderr, stabp->value); + if (stabp->type != 0) + fprintf (stderr, " %s", stabp->string); + fprintf (stderr, "\n"); + } + i = (i + 1) % SAVE_STABS_COUNT; + } + while (i != saved_stabs_index); +} + +/* Free the saved stab strings. */ + +static void +free_saved_stabs () +{ + int i; + + for (i = 0; i < SAVE_STABS_COUNT; i++) + { + if (saved_stabs[i].string != NULL) + { + free (saved_stabs[i].string); + saved_stabs[i].string = NULL; + } + } + + saved_stabs_index = 0; +}