Home | History | Annotate | Download | only in binutils
      1 /* rddbg.c -- Read debugging information into a generic form.
      2    Copyright (C) 1995-2014 Free Software Foundation, Inc.
      3    Written by Ian Lance Taylor <ian (at) 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 
    377 /* Record stabs strings, so that we can give some context for errors.  */
    379 
    380 #define SAVE_STABS_COUNT (16)
    381 
    382 struct saved_stab
    383 {
    384   int type;
    385   int desc;
    386   bfd_vma value;
    387   char *string;
    388 };
    389 
    390 static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
    391 static int saved_stabs_index;
    392 
    393 /* Save a stabs string.  */
    394 
    395 static void
    396 save_stab (int type, int desc, bfd_vma value, const char *string)
    397 {
    398   if (saved_stabs[saved_stabs_index].string != NULL)
    399     free (saved_stabs[saved_stabs_index].string);
    400   saved_stabs[saved_stabs_index].type = type;
    401   saved_stabs[saved_stabs_index].desc = desc;
    402   saved_stabs[saved_stabs_index].value = value;
    403   saved_stabs[saved_stabs_index].string = xstrdup (string);
    404   saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
    405 }
    406 
    407 /* Provide context for an error.  */
    408 
    409 static void
    410 stab_context (void)
    411 {
    412   int i;
    413 
    414   fprintf (stderr, _("Last stabs entries before error:\n"));
    415   fprintf (stderr, "n_type n_desc n_value  string\n");
    416 
    417   i = saved_stabs_index;
    418   do
    419     {
    420       struct saved_stab *stabp;
    421 
    422       stabp = saved_stabs + i;
    423       if (stabp->string != NULL)
    424 	{
    425 	  const char *s;
    426 
    427 	  s = bfd_get_stab_name (stabp->type);
    428 	  if (s != NULL)
    429 	    fprintf (stderr, "%-6s", s);
    430 	  else if (stabp->type == 0)
    431 	    fprintf (stderr, "HdrSym");
    432 	  else
    433 	    fprintf (stderr, "%-6d", stabp->type);
    434 	  fprintf (stderr, " %-6d ", stabp->desc);
    435 	  fprintf_vma (stderr, stabp->value);
    436 	  if (stabp->type != 0)
    437 	    fprintf (stderr, " %s", stabp->string);
    438 	  fprintf (stderr, "\n");
    439 	}
    440       i = (i + 1) % SAVE_STABS_COUNT;
    441     }
    442   while (i != saved_stabs_index);
    443 }
    444 
    445 /* Free the saved stab strings.  */
    446 
    447 static void
    448 free_saved_stabs (void)
    449 {
    450   int i;
    451 
    452   for (i = 0; i < SAVE_STABS_COUNT; i++)
    453     {
    454       if (saved_stabs[i].string != NULL)
    455 	{
    456 	  free (saved_stabs[i].string);
    457 	  saved_stabs[i].string = NULL;
    458 	}
    459     }
    460 
    461   saved_stabs_index = 0;
    462 }
    463