(root)/
binutils-2.41/
binutils/
rddbg.c
       1  /* rddbg.c -- Read debugging information into a generic form.
       2     Copyright (C) 1995-2023 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 bool read_section_stabs_debugging_info
      35    (bfd *, asymbol **, long, void *, bool *);
      36  static bool read_symbol_stabs_debugging_info
      37    (bfd *, asymbol **, long, void *, bool *);
      38  static void save_stab (int, int, bfd_vma, const char *);
      39  static void stab_context (void);
      40  static void free_saved_stabs (void);
      41  
      42  /* Read debugging information from a BFD.  Returns a generic debugging
      43     pointer.  */
      44  
      45  void *
      46  read_debugging_info (bfd *abfd, asymbol **syms, long symcount,
      47  		     bool no_messages)
      48  {
      49    void *dhandle;
      50    bool found;
      51  
      52    dhandle = debug_init (abfd);
      53    if (dhandle == NULL)
      54      return NULL;
      55  
      56    if (!debug_set_filename (dhandle, bfd_get_filename (abfd)))
      57      return NULL;
      58  
      59    if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
      60  					   &found))
      61      return NULL;
      62  
      63    if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
      64      {
      65        if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle,
      66  					      &found))
      67  	return NULL;
      68      }
      69  
      70    /* Try reading the COFF symbols if we didn't find any stabs in COFF
      71       sections.  */
      72    if (! found
      73        && bfd_get_flavour (abfd) == bfd_target_coff_flavour
      74        && symcount > 0)
      75      {
      76        if (! parse_coff (abfd, syms, symcount, dhandle))
      77  	return NULL;
      78        found = true;
      79      }
      80  
      81    if (! found)
      82      {
      83        if (! no_messages)
      84  	non_fatal (_("%s: no recognized debugging information"),
      85  		   bfd_get_filename (abfd));
      86        return NULL;
      87      }
      88  
      89    return dhandle;
      90  }
      91  
      92  /* Read stabs in sections debugging information from a BFD.  */
      93  
      94  static bool
      95  read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
      96  				   void *dhandle, bool *pfound)
      97  {
      98    static struct
      99      {
     100        const char *secname;
     101        const char *strsecname;
     102      }
     103    names[] =
     104      {
     105        { ".stab", ".stabstr" },
     106        { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" },
     107        { "$GDB_SYMBOLS$", "$GDB_STRINGS$" }
     108      };
     109    unsigned int i;
     110    void *shandle;
     111    bool ret = false;
     112  
     113    *pfound = false;
     114    shandle = NULL;
     115  
     116    for (i = 0; i < sizeof names / sizeof names[0]; i++)
     117      {
     118        asection *sec, *strsec;
     119  
     120        sec = bfd_get_section_by_name (abfd, names[i].secname);
     121        strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
     122        if (sec != NULL
     123  	  && (bfd_section_flags (sec) & SEC_HAS_CONTENTS) != 0
     124  	  && bfd_section_size (sec) >= 12
     125  	  && strsec != NULL
     126  	  && (bfd_section_flags (strsec) & SEC_HAS_CONTENTS) != 0)
     127  	{
     128  	  bfd_size_type stabsize, strsize;
     129  	  bfd_byte *stabs, *strings;
     130  	  bfd_byte *stab;
     131  	  bfd_size_type stroff, next_stroff;
     132  
     133  	  if (!bfd_malloc_and_get_section (abfd, sec, &stabs))
     134  	    {
     135  	      fprintf (stderr, "%s: %s: %s\n",
     136  		       bfd_get_filename (abfd), names[i].secname,
     137  		       bfd_errmsg (bfd_get_error ()));
     138  	      goto out;
     139  	    }
     140  
     141  	  if (!bfd_malloc_and_get_section (abfd, strsec, &strings))
     142  	    {
     143  	      fprintf (stderr, "%s: %s: %s\n",
     144  		       bfd_get_filename (abfd), names[i].strsecname,
     145  		       bfd_errmsg (bfd_get_error ()));
     146  	      free (stabs);
     147  	      goto out;
     148  	    }
     149  	  /* Zero terminate the strings table, just in case.  */
     150  	  strsize = bfd_section_size (strsec);
     151  	  if (strsize != 0)
     152  	    strings [strsize - 1] = 0;
     153  	  if (shandle == NULL)
     154  	    {
     155  	      shandle = start_stab (dhandle, abfd, true, syms, symcount);
     156  	      if (shandle == NULL)
     157  		{
     158  		  free (strings);
     159  		  free (stabs);
     160  		  goto out;
     161  		}
     162  	    }
     163  
     164  	  *pfound = true;
     165  
     166  	  stroff = 0;
     167  	  next_stroff = 0;
     168  	  stabsize = bfd_section_size (sec);
     169  	  /* PR 17512: file: 078-60391-0.001:0.1.  */
     170  	  for (stab = stabs; stab <= (stabs + stabsize) - 12; stab += 12)
     171  	    {
     172  	      unsigned int strx;
     173  	      int type;
     174  	      int other ATTRIBUTE_UNUSED;
     175  	      int desc;
     176  	      bfd_vma value;
     177  
     178  	      /* This code presumes 32 bit values.  */
     179  
     180  	      strx = bfd_get_32 (abfd, stab);
     181  	      type = bfd_get_8 (abfd, stab + 4);
     182  	      other = bfd_get_8 (abfd, stab + 5);
     183  	      desc = bfd_get_16 (abfd, stab + 6);
     184  	      value = bfd_get_32 (abfd, stab + 8);
     185  
     186  	      if (type == 0)
     187  		{
     188  		  /* Special type 0 stabs indicate the offset to the
     189  		     next string table.  */
     190  		  stroff = next_stroff;
     191  		  next_stroff += value;
     192  		}
     193  	      else
     194  		{
     195  		  size_t len;
     196  		  char *f, *s;
     197  
     198  		  if (stroff + strx >= strsize)
     199  		    {
     200  		      fprintf (stderr, _("%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n"),
     201  			       bfd_get_filename (abfd), names[i].secname,
     202  			       (long) (stab - stabs) / 12, strx, type);
     203  		      continue;
     204  		    }
     205  
     206  		  s = (char *) strings + stroff + strx;
     207  		  f = NULL;
     208  
     209  		  /* PR 17512: file: 002-87578-0.001:0.1.
     210  		     It is possible to craft a file where, without the 'strlen (s) > 0',
     211  		     an attempt to read the byte before 'strings' would occur.  */
     212  		  while ((len = strlen (s)) > 0
     213  			 && s[len  - 1] == '\\'
     214  			 && stab + 16 <= stabs + stabsize)
     215  		    {
     216  		      char *p;
     217  
     218  		      stab += 12;
     219  		      p = s + len - 1;
     220  		      *p = '\0';
     221  		      strx = stroff + bfd_get_32 (abfd, stab);
     222  		      if (strx >= strsize)
     223  			{
     224  			  fprintf (stderr, _("%s: %s: stab entry %ld is corrupt\n"),
     225  				   bfd_get_filename (abfd), names[i].secname,
     226  				   (long) (stab - stabs) / 12);
     227  			  break;
     228  			}
     229  
     230  		      s = concat (s, (char *) strings + strx,
     231  				  (const char *) NULL);
     232  
     233  		      /* We have to restore the backslash, because, if
     234  			 the linker is hashing stabs strings, we may
     235  			 see the same string more than once.  */
     236  		      *p = '\\';
     237  
     238  		      free (f);
     239  		      f = s;
     240  		    }
     241  
     242  		  save_stab (type, desc, value, s);
     243  
     244  		  if (!parse_stab (dhandle, shandle, type, desc, value, s))
     245  		    {
     246  		      stab_context ();
     247  		      free_saved_stabs ();
     248  		      free (f);
     249  		      free (stabs);
     250  		      free (strings);
     251  		      goto out;
     252  		    }
     253  
     254  		  free (f);
     255  		}
     256  	    }
     257  
     258  	  free_saved_stabs ();
     259  	  free (stabs);
     260  	  free (strings);
     261  	}
     262      }
     263    ret = true;
     264  
     265   out:
     266    if (shandle != NULL)
     267      {
     268        if (! finish_stab (dhandle, shandle, ret))
     269  	return false;
     270      }
     271  
     272    return ret;
     273  }
     274  
     275  /* Read stabs in the symbol table.  */
     276  
     277  static bool
     278  read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
     279  				  void *dhandle, bool *pfound)
     280  {
     281    void *shandle;
     282    asymbol **ps, **symend;
     283  
     284    shandle = NULL;
     285    symend = syms + symcount;
     286    for (ps = syms; ps < symend; ps++)
     287      {
     288        symbol_info i;
     289  
     290        bfd_get_symbol_info (abfd, *ps, &i);
     291  
     292        if (i.type == '-')
     293  	{
     294  	  const char *s;
     295  	  char *f;
     296  
     297  	  if (shandle == NULL)
     298  	    {
     299  	      shandle = start_stab (dhandle, abfd, false, syms, symcount);
     300  	      if (shandle == NULL)
     301  		return false;
     302  	    }
     303  
     304  	  *pfound = true;
     305  
     306  	  s = i.name;
     307  	  if (s == NULL || strlen (s) < 1)
     308  	    break;
     309  	  f = NULL;
     310  
     311  	  while (strlen (s) > 0
     312  		 && s[strlen (s) - 1] == '\\'
     313  		 && ps + 1 < symend)
     314  	    {
     315  	      char *sc, *n;
     316  
     317  	      ++ps;
     318  	      sc = xstrdup (s);
     319  	      sc[strlen (sc) - 1] = '\0';
     320  	      n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
     321  	      free (sc);
     322  	      free (f);
     323  	      f = n;
     324  	      s = n;
     325  	    }
     326  
     327  	  save_stab (i.stab_type, i.stab_desc, i.value, s);
     328  
     329  	  if (!parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
     330  			   i.value, s))
     331  	    {
     332  	      stab_context ();
     333  	      free (f);
     334  	      break;
     335  	    }
     336  
     337  	  free (f);
     338  	}
     339      }
     340    bool ret = ps >= symend;
     341  
     342    free_saved_stabs ();
     343  
     344    if (shandle != NULL)
     345      {
     346        if (! finish_stab (dhandle, shandle, ret))
     347  	return false;
     348      }
     349  
     350    return ret;
     351  }
     352  
     353  /* Record stabs strings, so that we can give some context for errors.  */
     354  
     355  #define SAVE_STABS_COUNT (16)
     356  
     357  struct saved_stab
     358  {
     359    int type;
     360    int desc;
     361    bfd_vma value;
     362    char *string;
     363  };
     364  
     365  static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
     366  static int saved_stabs_index;
     367  
     368  /* Save a stabs string.  */
     369  
     370  static void
     371  save_stab (int type, int desc, bfd_vma value, const char *string)
     372  {
     373    free (saved_stabs[saved_stabs_index].string);
     374    saved_stabs[saved_stabs_index].type = type;
     375    saved_stabs[saved_stabs_index].desc = desc;
     376    saved_stabs[saved_stabs_index].value = value;
     377    saved_stabs[saved_stabs_index].string = xstrdup (string);
     378    saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
     379  }
     380  
     381  /* Provide context for an error.  */
     382  
     383  static void
     384  stab_context (void)
     385  {
     386    int i;
     387  
     388    fprintf (stderr, _("Last stabs entries before error:\n"));
     389    fprintf (stderr, "n_type n_desc n_value  string\n");
     390  
     391    i = saved_stabs_index;
     392    do
     393      {
     394        struct saved_stab *stabp;
     395  
     396        stabp = saved_stabs + i;
     397        if (stabp->string != NULL)
     398  	{
     399  	  const char *s;
     400  
     401  	  s = bfd_get_stab_name (stabp->type);
     402  	  if (s != NULL)
     403  	    fprintf (stderr, "%-6s", s);
     404  	  else if (stabp->type == 0)
     405  	    fprintf (stderr, "HdrSym");
     406  	  else
     407  	    fprintf (stderr, "%-6d", stabp->type);
     408  	  fprintf (stderr, " %-6d ", stabp->desc);
     409  	  fprintf (stderr, "%08" PRIx64, (uint64_t) stabp->value);
     410  	  if (stabp->type != 0)
     411  	    fprintf (stderr, " %s", stabp->string);
     412  	  fprintf (stderr, "\n");
     413  	}
     414        i = (i + 1) % SAVE_STABS_COUNT;
     415      }
     416    while (i != saved_stabs_index);
     417  }
     418  
     419  /* Free the saved stab strings.  */
     420  
     421  static void
     422  free_saved_stabs (void)
     423  {
     424    int i;
     425  
     426    for (i = 0; i < SAVE_STABS_COUNT; i++)
     427      {
     428        free (saved_stabs[i].string);
     429        saved_stabs[i].string = NULL;
     430      }
     431  
     432    saved_stabs_index = 0;
     433  }