Subversion Repositories Kolibri OS

Rev

Rev 5217 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* rddbg.c -- Read debugging information into a generic form.
  2.    Copyright (C) 1995-2015 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 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);
  142.           strings = (bfd_byte *) xmalloc (strsize + 1);
  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.             }
  150.           /* Zero terminate the strings table, just in case.  */
  151.           strings [strsize] = 0;
  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;
  163.           /* PR 17512: file: 078-60391-0.001:0.1.  */
  164.           for (stab = stabs; stab <= (stabs + stabsize) - 12; stab += 12)
  165.             {
  166.               unsigned int strx;
  167.               int type;
  168.               int other ATTRIBUTE_UNUSED;
  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.                 {
  189.                   size_t len;
  190.                   char *f, *s;
  191.  
  192.                   if (stroff + strx >= strsize)
  193.                     {
  194.                       fprintf (stderr, _("%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n"),
  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;
  201.                   f = NULL;
  202.  
  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] == '\\'
  208.                          && stab + 12 < stabs + stabsize)
  209.                     {
  210.                       char *p;
  211.  
  212.                       stab += 12;
  213.                       p = s + len - 1;
  214.                       *p = '\0';
  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);
  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;
  302.           f = NULL;
  303.           while (s[strlen (s) - 1] == '\\'
  304.                  && ps + 1 < symend)
  305.             {
  306.               char *sc, *n;
  307.  
  308.               ++ps;
  309.               sc = xstrdup (s);
  310.               sc[strlen (sc) - 1] = '\0';
  311.               n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
  312.               free (sc);
  313.               if (f != NULL)
  314.                 free (f);
  315.               f = n;
  316.               s = n;
  317.             }
  318.  
  319.           save_stab (i.stab_type, i.stab_desc, i.value, s);
  320.  
  321.           if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
  322.                             i.value, s))
  323.             {
  324.               stab_context ();
  325.               free_saved_stabs ();
  326.               return FALSE;
  327.             }
  328.  
  329.           /* Don't free f, since I think the stabs code expects
  330.              strings to hang around.  This should be straightened out.
  331.              FIXME.  */
  332.         }
  333.     }
  334.  
  335.   free_saved_stabs ();
  336.  
  337.   if (shandle != NULL)
  338.     {
  339.       if (! finish_stab (dhandle, shandle))
  340.         return FALSE;
  341.     }
  342.  
  343.   return TRUE;
  344. }
  345.  
  346. /* Read IEEE debugging information.  */
  347.  
  348. static bfd_boolean
  349. read_ieee_debugging_info (bfd *abfd, void *dhandle, bfd_boolean *pfound)
  350. {
  351.   asection *dsec;
  352.   bfd_size_type size;
  353.   bfd_byte *contents;
  354.  
  355.   /* The BFD backend puts the debugging information into a section
  356.      named .debug.  */
  357.  
  358.   dsec = bfd_get_section_by_name (abfd, ".debug");
  359.   if (dsec == NULL)
  360.     return TRUE;
  361.  
  362.   size = bfd_section_size (abfd, dsec);
  363.   contents = (bfd_byte *) xmalloc (size);
  364.   if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
  365.     return FALSE;
  366.  
  367.   if (! parse_ieee (dhandle, abfd, contents, size))
  368.     return FALSE;
  369.  
  370.   free (contents);
  371.  
  372.   *pfound = TRUE;
  373.  
  374.   return TRUE;
  375. }
  376. /* Record stabs strings, so that we can give some context for errors.  */
  377.  
  378. #define SAVE_STABS_COUNT (16)
  379.  
  380. struct saved_stab
  381. {
  382.   int type;
  383.   int desc;
  384.   bfd_vma value;
  385.   char *string;
  386. };
  387.  
  388. static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
  389. static int saved_stabs_index;
  390.  
  391. /* Save a stabs string.  */
  392.  
  393. static void
  394. save_stab (int type, int desc, bfd_vma value, const char *string)
  395. {
  396.   if (saved_stabs[saved_stabs_index].string != NULL)
  397.     free (saved_stabs[saved_stabs_index].string);
  398.   saved_stabs[saved_stabs_index].type = type;
  399.   saved_stabs[saved_stabs_index].desc = desc;
  400.   saved_stabs[saved_stabs_index].value = value;
  401.   saved_stabs[saved_stabs_index].string = xstrdup (string);
  402.   saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
  403. }
  404.  
  405. /* Provide context for an error.  */
  406.  
  407. static void
  408. stab_context (void)
  409. {
  410.   int i;
  411.  
  412.   fprintf (stderr, _("Last stabs entries before error:\n"));
  413.   fprintf (stderr, "n_type n_desc n_value  string\n");
  414.  
  415.   i = saved_stabs_index;
  416.   do
  417.     {
  418.       struct saved_stab *stabp;
  419.  
  420.       stabp = saved_stabs + i;
  421.       if (stabp->string != NULL)
  422.         {
  423.           const char *s;
  424.  
  425.           s = bfd_get_stab_name (stabp->type);
  426.           if (s != NULL)
  427.             fprintf (stderr, "%-6s", s);
  428.           else if (stabp->type == 0)
  429.             fprintf (stderr, "HdrSym");
  430.           else
  431.             fprintf (stderr, "%-6d", stabp->type);
  432.           fprintf (stderr, " %-6d ", stabp->desc);
  433.           fprintf_vma (stderr, stabp->value);
  434.           if (stabp->type != 0)
  435.             fprintf (stderr, " %s", stabp->string);
  436.           fprintf (stderr, "\n");
  437.         }
  438.       i = (i + 1) % SAVE_STABS_COUNT;
  439.     }
  440.   while (i != saved_stabs_index);
  441. }
  442.  
  443. /* Free the saved stab strings.  */
  444.  
  445. static void
  446. free_saved_stabs (void)
  447. {
  448.   int i;
  449.  
  450.   for (i = 0; i < SAVE_STABS_COUNT; i++)
  451.     {
  452.       if (saved_stabs[i].string != NULL)
  453.         {
  454.           free (saved_stabs[i].string);
  455.           saved_stabs[i].string = NULL;
  456.         }
  457.     }
  458.  
  459.   saved_stabs_index = 0;
  460. }
  461.