[BACK]Return to rddbg.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils / dist / binutils

Annotation of src/external/gpl3/binutils/dist/binutils/rddbg.c, Revision 1.1.1.5

1.1       skrll       1: /* rddbg.c -- Read debugging information into a generic form.
1.1.1.5 ! christos    2:    Copyright (C) 1995-2018 Free Software Foundation, Inc.
1.1       skrll       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 3 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., 51 Franklin Street - Fifth Floor, Boston, MA
                     20:    02110-1301, USA.  */
                     21:
                     22:
                     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:
                     27: #include "sysdep.h"
                     28: #include "bfd.h"
                     29: #include "libiberty.h"
                     30: #include "bucomm.h"
                     31: #include "debug.h"
                     32: #include "budbg.h"
                     33:
                     34: static bfd_boolean read_section_stabs_debugging_info
                     35:   (bfd *, asymbol **, long, void *, bfd_boolean *);
                     36: static bfd_boolean read_symbol_stabs_debugging_info
                     37:   (bfd *, asymbol **, long, void *, bfd_boolean *);
                     38: static bfd_boolean read_ieee_debugging_info (bfd *, void *, bfd_boolean *);
                     39: static void save_stab (int, int, bfd_vma, const char *);
                     40: static void stab_context (void);
                     41: static void free_saved_stabs (void);
                     42:
                     43: /* Read debugging information from a BFD.  Returns a generic debugging
                     44:    pointer.  */
                     45:
                     46: void *
                     47: read_debugging_info (bfd *abfd, asymbol **syms, long symcount, bfd_boolean no_messages)
                     48: {
                     49:   void *dhandle;
                     50:   bfd_boolean found;
                     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;
                     81:       found = TRUE;
                     82:     }
                     83:
                     84:   if (! found)
                     85:     {
                     86:       if (! no_messages)
                     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 bfd_boolean
                     98: read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
                     99:                                   void *dhandle, bfd_boolean *pfound)
                    100: {
                    101:   static struct
                    102:     {
                    103:       const char *secname;
                    104:       const char *strsecname;
                    105:     }
                    106:   names[] =
                    107:     {
                    108:       { ".stab", ".stabstr" },
                    109:       { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" },
                    110:       { "$GDB_SYMBOLS$", "$GDB_STRINGS$" }
                    111:     };
                    112:   unsigned int i;
                    113:   void *shandle;
                    114:
                    115:   *pfound = FALSE;
                    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 ()));
                    138:              return FALSE;
                    139:            }
                    140:
                    141:          strsize = bfd_section_size (abfd, strsec);
1.1.1.3   christos  142:          strings = (bfd_byte *) xmalloc (strsize + 1);
1.1       skrll     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 ()));
                    148:              return FALSE;
                    149:            }
1.1.1.3   christos  150:          /* Zero terminate the strings table, just in case.  */
                    151:          strings [strsize] = 0;
1.1       skrll     152:          if (shandle == NULL)
                    153:            {
                    154:              shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
                    155:              if (shandle == NULL)
                    156:                return FALSE;
                    157:            }
                    158:
                    159:          *pfound = TRUE;
                    160:
                    161:          stroff = 0;
                    162:          next_stroff = 0;
1.1.1.3   christos  163:          /* PR 17512: file: 078-60391-0.001:0.1.  */
                    164:          for (stab = stabs; stab <= (stabs + stabsize) - 12; stab += 12)
1.1       skrll     165:            {
                    166:              unsigned int strx;
                    167:              int type;
1.1.1.2   christos  168:              int other ATTRIBUTE_UNUSED;
1.1       skrll     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
                    183:                     next string table.  */
                    184:                  stroff = next_stroff;
                    185:                  next_stroff += value;
                    186:                }
                    187:              else
                    188:                {
1.1.1.3   christos  189:                  size_t len;
1.1       skrll     190:                  char *f, *s;
                    191:
1.1.1.3   christos  192:                  if (stroff + strx >= strsize)
1.1       skrll     193:                    {
1.1.1.3   christos  194:                      fprintf (stderr, _("%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n"),
1.1       skrll     195:                               bfd_get_filename (abfd), names[i].secname,
                    196:                               (long) (stab - stabs) / 12, strx, type);
                    197:                      continue;
                    198:                    }
                    199:
                    200:                  s = (char *) strings + stroff + strx;
1.1.1.3   christos  201:                  f = NULL;
1.1       skrll     202:
1.1.1.3   christos  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] == '\\'
1.1       skrll     208:                         && stab + 12 < stabs + stabsize)
                    209:                    {
                    210:                      char *p;
                    211:
                    212:                      stab += 12;
1.1.1.3   christos  213:                      p = s + len - 1;
1.1       skrll     214:                      *p = '\0';
1.1.1.3   christos  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);
1.1       skrll     226:
                    227:                      /* We have to restore the backslash, because, if
                    228:                         the linker is hashing stabs strings, we may
                    229:                         see the same string more than once.  */
                    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 ();
                    243:                      return FALSE;
                    244:                    }
                    245:
                    246:                  /* Don't free f, since I think the stabs code
                    247:                     expects strings to hang around.  This should be
                    248:                     straightened out.  FIXME.  */
                    249:                }
                    250:            }
                    251:
                    252:          free_saved_stabs ();
                    253:          free (stabs);
                    254:
                    255:          /* Don't free strings, since I think the stabs code expects
                    256:             the strings to hang around.  This should be straightened
                    257:             out.  FIXME.  */
                    258:        }
                    259:     }
                    260:
                    261:   if (shandle != NULL)
                    262:     {
                    263:       if (! finish_stab (dhandle, shandle))
                    264:        return FALSE;
                    265:     }
                    266:
                    267:   return TRUE;
                    268: }
                    269:
                    270: /* Read stabs in the symbol table.  */
                    271:
                    272: static bfd_boolean
                    273: read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
                    274:                                  void *dhandle, bfd_boolean *pfound)
                    275: {
                    276:   void *shandle;
                    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:            {
                    294:              shandle = start_stab (dhandle, abfd, FALSE, syms, symcount);
                    295:              if (shandle == NULL)
                    296:                return FALSE;
                    297:            }
                    298:
                    299:          *pfound = TRUE;
                    300:
                    301:          s = i.name;
1.1.1.5 ! christos  302:          if (s == NULL || strlen (s) < 1)
        !           303:            return FALSE;
1.1       skrll     304:          f = NULL;
1.1.1.5 ! christos  305:
        !           306:          while (strlen (s) > 0
        !           307:                 && s[strlen (s) - 1] == '\\'
1.1       skrll     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 ();
                    330:              return FALSE;
                    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))
                    344:        return FALSE;
                    345:     }
                    346:
                    347:   return TRUE;
                    348: }
                    349:
                    350: /* Read IEEE debugging information.  */
                    351:
                    352: static bfd_boolean
                    353: read_ieee_debugging_info (bfd *abfd, void *dhandle, bfd_boolean *pfound)
                    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)
                    364:     return TRUE;
                    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))
                    369:     return FALSE;
                    370:
                    371:   if (! parse_ieee (dhandle, abfd, contents, size))
                    372:     return FALSE;
                    373:
                    374:   free (contents);
                    375:
                    376:   *pfound = TRUE;
                    377:
                    378:   return TRUE;
                    379: }
                    380: 
                    381: /* Record stabs strings, so that we can give some context for errors.  */
                    382:
                    383: #define SAVE_STABS_COUNT (16)
                    384:
                    385: struct saved_stab
                    386: {
                    387:   int type;
                    388:   int desc;
                    389:   bfd_vma value;
                    390:   char *string;
                    391: };
                    392:
                    393: static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
                    394: static int saved_stabs_index;
                    395:
                    396: /* Save a stabs string.  */
                    397:
                    398: static void
                    399: save_stab (int type, int desc, bfd_vma value, const char *string)
                    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:
                    412: static void
                    413: stab_context (void)
                    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:
                    450: static void
                    451: free_saved_stabs (void)
                    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: }

CVSweb <webmaster@jp.NetBSD.org>