(root)/
binutils-2.41/
bfd/
dwarf1.c
       1  /* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line).
       2     Copyright (C) 1998-2023 Free Software Foundation, Inc.
       3  
       4     Written by Gavin Romig-Koch of Cygnus Solutions (gavin@cygnus.com).
       5  
       6     This file is part of BFD.
       7  
       8     This program is free software; you can redistribute it and/or modify
       9     it under the terms of the GNU General Public License as published by
      10     the Free Software Foundation; either version 3 of the License, or (at
      11     your option) any later version.
      12  
      13     This program is distributed in the hope that it will be useful, but
      14     WITHOUT ANY WARRANTY; without even the implied warranty of
      15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16     General Public License for more details.
      17  
      18     You should have received a copy of the GNU General Public License
      19     along with this program; if not, write to the Free Software
      20     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
      21     MA 02110-1301, USA.  */
      22  
      23  #include "sysdep.h"
      24  #include "bfd.h"
      25  #include "libiberty.h"
      26  #include "libbfd.h"
      27  #include "elf-bfd.h"
      28  #include "elf/dwarf.h"
      29  
      30  /* dwarf1_debug is the starting point for all dwarf1 info.  */
      31  
      32  struct dwarf1_debug
      33  {
      34    /* The bfd we are working with.  */
      35    bfd* abfd;
      36  
      37    /* Pointer to the symbol table.  */
      38    asymbol** syms;
      39  
      40    /* List of already parsed compilation units.  */
      41    struct dwarf1_unit* lastUnit;
      42  
      43    /* The buffer for the .debug section.
      44       Zero indicates that the .debug section failed to load.  */
      45    bfd_byte *debug_section;
      46  
      47    /* Pointer to the end of the .debug_info section memory buffer.  */
      48    bfd_byte *debug_section_end;
      49  
      50    /* The buffer for the .line section.  */
      51    bfd_byte *line_section;
      52  
      53    /* End of that buffer.  */
      54    bfd_byte *line_section_end;
      55  
      56    /* The current or next unread die within the .debug section.  */
      57    bfd_byte *currentDie;
      58  };
      59  
      60  /* One dwarf1_unit for each parsed compilation unit die.  */
      61  
      62  struct dwarf1_unit
      63  {
      64    /* Linked starting from stash->lastUnit.  */
      65    struct dwarf1_unit* prev;
      66  
      67    /* Name of the compilation unit.  */
      68    char *name;
      69  
      70    /* The highest and lowest address used in the compilation unit.  */
      71    unsigned long low_pc;
      72    unsigned long high_pc;
      73  
      74    /* Does this unit have a statement list?  */
      75    int has_stmt_list;
      76  
      77    /* If any, the offset of the line number table in the .line section.  */
      78    unsigned long stmt_list_offset;
      79  
      80    /* If non-zero, a pointer to the first child of this unit.  */
      81    bfd_byte *first_child;
      82  
      83    /* How many line entries?  */
      84    unsigned long line_count;
      85  
      86    /* The decoded line number table (line_count entries).  */
      87    struct linenumber* linenumber_table;
      88  
      89    /* The list of functions in this unit.  */
      90    struct dwarf1_func* func_list;
      91  };
      92  
      93  /* One dwarf1_func for each parsed function die.  */
      94  
      95  struct dwarf1_func
      96  {
      97    /* Linked starting from aUnit->func_list.  */
      98    struct dwarf1_func* prev;
      99  
     100    /* Name of function.  */
     101    char* name;
     102  
     103    /* The highest and lowest address used in the compilation unit.  */
     104    unsigned long low_pc;
     105    unsigned long high_pc;
     106  };
     107  
     108  /* Used to return info about a parsed die.  */
     109  struct die_info
     110  {
     111    unsigned long length;
     112    unsigned long sibling;
     113    unsigned long low_pc;
     114    unsigned long high_pc;
     115    unsigned long stmt_list_offset;
     116  
     117    char* name;
     118  
     119    int has_stmt_list;
     120  
     121    unsigned short tag;
     122  };
     123  
     124  /* Parsed line number information.  */
     125  struct linenumber
     126  {
     127    /* First address in the line.  */
     128    unsigned long addr;
     129  
     130    /* The line number.  */
     131    unsigned long linenumber;
     132  };
     133  
     134  /* Find the form of an attr, from the attr field.  */
     135  #define FORM_FROM_ATTR(attr)	((attr) & 0xF)	/* Implicitly specified.  */
     136  
     137  /* Return a newly allocated dwarf1_unit.  It should be cleared and
     138     then attached into the 'stash' at 'stash->lastUnit'.  */
     139  
     140  static struct dwarf1_unit*
     141  alloc_dwarf1_unit (struct dwarf1_debug* stash)
     142  {
     143    size_t amt = sizeof (struct dwarf1_unit);
     144  
     145    struct dwarf1_unit* x = (struct dwarf1_unit *) bfd_zalloc (stash->abfd, amt);
     146    if (x)
     147      {
     148        x->prev = stash->lastUnit;
     149        stash->lastUnit = x;
     150      }
     151  
     152    return x;
     153  }
     154  
     155  /* Return a newly allocated dwarf1_func.  It must be cleared and
     156     attached into 'aUnit' at 'aUnit->func_list'.  */
     157  
     158  static struct dwarf1_func *
     159  alloc_dwarf1_func (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
     160  {
     161    size_t amt = sizeof (struct dwarf1_func);
     162  
     163    struct dwarf1_func* x = (struct dwarf1_func *) bfd_zalloc (stash->abfd, amt);
     164    if (x)
     165      {
     166        x->prev = aUnit->func_list;
     167        aUnit->func_list = x;
     168      }
     169  
     170    return x;
     171  }
     172  
     173  /* parse_die - parse a Dwarf1 die.
     174     Parse the die starting at 'aDiePtr' into 'aDieInfo'.
     175     'abfd' must be the bfd from which the section that 'aDiePtr'
     176     points to was pulled from.
     177  
     178     Return FALSE if the die is invalidly formatted; TRUE otherwise.  */
     179  
     180  static bool
     181  parse_die (bfd *	     abfd,
     182  	   struct die_info * aDieInfo,
     183  	   bfd_byte *	     aDiePtr,
     184  	   bfd_byte *	     aDiePtrEnd)
     185  {
     186    bfd_byte *this_die = aDiePtr;
     187    bfd_byte *xptr = this_die;
     188  
     189    memset (aDieInfo, 0, sizeof (* aDieInfo));
     190  
     191    /* First comes the length.  */
     192    if (xptr + 4 > aDiePtrEnd)
     193      return false;
     194    aDieInfo->length = bfd_get_32 (abfd, xptr);
     195    xptr += 4;
     196    if (aDieInfo->length <= 4
     197        || (size_t) (aDiePtrEnd - this_die) < aDieInfo->length)
     198      return false;
     199    aDiePtrEnd = this_die + aDieInfo->length;
     200    if (aDieInfo->length < 6)
     201      {
     202        /* Just padding bytes.  */
     203        aDieInfo->tag = TAG_padding;
     204        return true;
     205      }
     206  
     207    /* Then the tag.  */
     208    if (xptr + 2 > aDiePtrEnd)
     209      return false;
     210    aDieInfo->tag = bfd_get_16 (abfd, xptr);
     211    xptr += 2;
     212  
     213    /* Then the attributes.  */
     214    while (xptr + 2 <= aDiePtrEnd)
     215      {
     216        unsigned int   block_len;
     217        unsigned short attr;
     218  
     219        /* Parse the attribute based on its form.  This section
     220  	 must handle all dwarf1 forms, but need only handle the
     221  	 actual attributes that we care about.  */
     222        attr = bfd_get_16 (abfd, xptr);
     223        xptr += 2;
     224  
     225        switch (FORM_FROM_ATTR (attr))
     226  	{
     227  	case FORM_DATA2:
     228  	  xptr += 2;
     229  	  break;
     230  	case FORM_DATA4:
     231  	case FORM_REF:
     232  	  if (xptr + 4 <= aDiePtrEnd)
     233  	    {
     234  	      if (attr == AT_sibling)
     235  		aDieInfo->sibling = bfd_get_32 (abfd, xptr);
     236  	      else if (attr == AT_stmt_list)
     237  		{
     238  		  aDieInfo->stmt_list_offset = bfd_get_32 (abfd, xptr);
     239  		  aDieInfo->has_stmt_list = 1;
     240  		}
     241  	    }
     242  	  xptr += 4;
     243  	  break;
     244  	case FORM_DATA8:
     245  	  xptr += 8;
     246  	  break;
     247  	case FORM_ADDR:
     248  	  if (xptr + 4 <= aDiePtrEnd)
     249  	    {
     250  	      if (attr == AT_low_pc)
     251  		aDieInfo->low_pc = bfd_get_32 (abfd, xptr);
     252  	      else if (attr == AT_high_pc)
     253  		aDieInfo->high_pc = bfd_get_32 (abfd, xptr);
     254  	    }
     255  	  xptr += 4;
     256  	  break;
     257  	case FORM_BLOCK2:
     258  	  if (xptr + 2 <= aDiePtrEnd)
     259  	    {
     260  	      block_len = bfd_get_16 (abfd, xptr);
     261  	      if ((size_t) (aDiePtrEnd - xptr) < block_len)
     262  		return false;
     263  	      xptr += block_len;
     264  	    }
     265  	  xptr += 2;
     266  	  break;
     267  	case FORM_BLOCK4:
     268  	  if (xptr + 4 <= aDiePtrEnd)
     269  	    {
     270  	      block_len = bfd_get_32 (abfd, xptr);
     271  	      if ((size_t) (aDiePtrEnd - xptr) < block_len)
     272  		return false;
     273  	      xptr += block_len;
     274  	    }
     275  	  xptr += 4;
     276  	  break;
     277  	case FORM_STRING:
     278  	  if (attr == AT_name)
     279  	    aDieInfo->name = (char *) xptr;
     280  	  xptr += strnlen ((char *) xptr, aDiePtrEnd - xptr) + 1;
     281  	  break;
     282  	}
     283      }
     284  
     285    return true;
     286  }
     287  
     288  /* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset'
     289     into 'aUnit->linenumber_table'.  Return FALSE if an error
     290     occurs; TRUE otherwise.  */
     291  
     292  static bool
     293  parse_line_table (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
     294  {
     295    bfd_byte *xptr;
     296  
     297    /* Load the ".line" section from the bfd if we haven't already.  */
     298    if (stash->line_section == 0)
     299      {
     300        asection *msec;
     301        bfd_size_type size;
     302  
     303        msec = bfd_get_section_by_name (stash->abfd, ".line");
     304        if (! msec || (msec->flags & SEC_HAS_CONTENTS) == 0)
     305  	return false;
     306  
     307        size = msec->rawsize ? msec->rawsize : msec->size;
     308        stash->line_section
     309  	= bfd_simple_get_relocated_section_contents (stash->abfd, msec, NULL,
     310  						     stash->syms);
     311  
     312        if (! stash->line_section)
     313  	return false;
     314  
     315        stash->line_section_end = stash->line_section + size;
     316      }
     317  
     318    xptr = stash->line_section + aUnit->stmt_list_offset;
     319    if (xptr + 8 <= stash->line_section_end)
     320      {
     321        unsigned long eachLine;
     322        bfd_byte *tblend;
     323        unsigned long base;
     324        bfd_size_type amt;
     325  
     326        /* First comes the length.  */
     327        tblend = bfd_get_32 (stash->abfd, (bfd_byte *) xptr) + xptr;
     328        xptr += 4;
     329  
     330        /* Then the base address for each address in the table.  */
     331        base = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
     332        xptr += 4;
     333  
     334        /* How many line entrys?
     335  	 10 = 4 (line number) + 2 (pos in line) + 4 (address in line).  */
     336        aUnit->line_count = (tblend - xptr) / 10;
     337  
     338        /* Allocate an array for the entries.  */
     339        amt = sizeof (struct linenumber) * aUnit->line_count;
     340        aUnit->linenumber_table = (struct linenumber *) bfd_alloc (stash->abfd,
     341  								 amt);
     342        if (!aUnit->linenumber_table)
     343  	return false;
     344  
     345        for (eachLine = 0; eachLine < aUnit->line_count; eachLine++)
     346  	{
     347  	  if (xptr + 10 > stash->line_section_end)
     348  	    {
     349  	      aUnit->line_count = eachLine;
     350  	      break;
     351  	    }
     352  	  /* A line number.  */
     353  	  aUnit->linenumber_table[eachLine].linenumber
     354  	    = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
     355  	  xptr += 4;
     356  
     357  	  /* Skip the position within the line.  */
     358  	  xptr += 2;
     359  
     360  	  /* And finally the address.  */
     361  	  aUnit->linenumber_table[eachLine].addr
     362  	    = base + bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
     363  	  xptr += 4;
     364  	}
     365      }
     366  
     367    return true;
     368  }
     369  
     370  /* Parse each function die in a compilation unit 'aUnit'.
     371     The first child die of 'aUnit' should be in 'aUnit->first_child',
     372     the result is placed in 'aUnit->func_list'.
     373     Return FALSE if error; TRUE otherwise.  */
     374  
     375  static bool
     376  parse_functions_in_unit (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
     377  {
     378    bfd_byte *eachDie;
     379  
     380    if (aUnit->first_child)
     381      for (eachDie = aUnit->first_child;
     382  	 eachDie < stash->debug_section_end;
     383  	 )
     384        {
     385  	struct die_info eachDieInfo;
     386  
     387  	if (! parse_die (stash->abfd, &eachDieInfo, eachDie,
     388  			 stash->debug_section_end))
     389  	  return false;
     390  
     391  	if (eachDieInfo.tag == TAG_global_subroutine
     392  	    || eachDieInfo.tag == TAG_subroutine
     393  	    || eachDieInfo.tag == TAG_inlined_subroutine
     394  	    || eachDieInfo.tag == TAG_entry_point)
     395  	  {
     396  	    struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit);
     397  	    if (!aFunc)
     398  	      return false;
     399  
     400  	    aFunc->name = eachDieInfo.name;
     401  	    aFunc->low_pc = eachDieInfo.low_pc;
     402  	    aFunc->high_pc = eachDieInfo.high_pc;
     403  	  }
     404  
     405  	/* Move to next sibling, if none, end loop */
     406  	if (eachDieInfo.sibling)
     407  	  eachDie = stash->debug_section + eachDieInfo.sibling;
     408  	else
     409  	  break;
     410        }
     411  
     412    return true;
     413  }
     414  
     415  /* Find the nearest line to 'addr' in 'aUnit'.
     416     Return whether we found the line (or a function) without error.  */
     417  
     418  static bool
     419  dwarf1_unit_find_nearest_line (struct dwarf1_debug* stash,
     420  			       struct dwarf1_unit* aUnit,
     421  			       unsigned long addr,
     422  			       const char **filename_ptr,
     423  			       const char **functionname_ptr,
     424  			       unsigned int *linenumber_ptr)
     425  {
     426    int line_p = false;
     427    int func_p = false;
     428  
     429    if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
     430      {
     431        if (aUnit->has_stmt_list)
     432  	{
     433  	  unsigned long i;
     434  	  struct dwarf1_func* eachFunc;
     435  
     436  	  if (! aUnit->linenumber_table)
     437  	    {
     438  	      if (! parse_line_table (stash, aUnit))
     439  		return false;
     440  	    }
     441  
     442  	  if (! aUnit->func_list)
     443  	    {
     444  	      if (! parse_functions_in_unit (stash, aUnit))
     445  		return false;
     446  	    }
     447  
     448  	  for (i = 0; i < aUnit->line_count; i++)
     449  	    {
     450  	      if (aUnit->linenumber_table[i].addr <= addr
     451  		  && addr < aUnit->linenumber_table[i+1].addr)
     452  		{
     453  		  *filename_ptr = aUnit->name;
     454  		  *linenumber_ptr = aUnit->linenumber_table[i].linenumber;
     455  		  line_p = true;
     456  		  break;
     457  		}
     458  	    }
     459  
     460  	  for (eachFunc = aUnit->func_list;
     461  	       eachFunc;
     462  	       eachFunc = eachFunc->prev)
     463  	    {
     464  	      if (eachFunc->low_pc <= addr
     465  		  && addr < eachFunc->high_pc)
     466  		{
     467  		  *functionname_ptr = eachFunc->name;
     468  		  func_p = true;
     469  		  break;
     470  		}
     471  	    }
     472  	}
     473      }
     474  
     475    return line_p || func_p;
     476  }
     477  
     478  /* The DWARF 1 version of find_nearest line.
     479     Return TRUE if the line is found without error.  */
     480  
     481  bool
     482  _bfd_dwarf1_find_nearest_line (bfd *abfd,
     483  			       asymbol **symbols,
     484  			       asection *section,
     485  			       bfd_vma offset,
     486  			       const char **filename_ptr,
     487  			       const char **functionname_ptr,
     488  			       unsigned int *linenumber_ptr)
     489  {
     490    struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info;
     491  
     492    struct dwarf1_unit* eachUnit;
     493  
     494    /* What address are we looking for? */
     495    unsigned long addr = (unsigned long)(offset + section->vma);
     496  
     497    *filename_ptr = NULL;
     498    *functionname_ptr = NULL;
     499    *linenumber_ptr = 0;
     500  
     501    if (! stash)
     502      {
     503        asection *msec;
     504        bfd_size_type size = sizeof (struct dwarf1_debug);
     505  
     506        stash = elf_tdata (abfd)->dwarf1_find_line_info
     507  	= (struct dwarf1_debug *) bfd_zalloc (abfd, size);
     508  
     509        if (! stash)
     510  	return false;
     511  
     512        msec = bfd_get_section_by_name (abfd, ".debug");
     513        if (! msec
     514  	  || (msec->flags & SEC_HAS_CONTENTS) == 0)
     515  	/* No dwarf1 info.  Note that at this point the stash
     516  	   has been allocated, but contains zeros, this lets
     517  	   future calls to this function fail quicker.  */
     518  	return false;
     519  
     520        size = msec->rawsize ? msec->rawsize : msec->size;
     521        stash->debug_section
     522  	= bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
     523  						     symbols);
     524  
     525        if (! stash->debug_section)
     526  	return false;
     527  
     528        stash->debug_section_end = stash->debug_section + size;
     529        stash->currentDie = stash->debug_section;
     530        stash->abfd = abfd;
     531        stash->syms = symbols;
     532      }
     533  
     534    /* A null debug_section indicates that there was no dwarf1 info
     535       or that an error occured while setting up the stash.  */
     536  
     537    if (! stash->debug_section)
     538      return false;
     539  
     540    /* Look at the previously parsed units to see if any contain
     541       the addr.  */
     542    for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev)
     543      if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc)
     544        return dwarf1_unit_find_nearest_line (stash, eachUnit, addr,
     545  					    filename_ptr,
     546  					    functionname_ptr,
     547  					    linenumber_ptr);
     548  
     549    while (stash->currentDie < stash->debug_section_end)
     550      {
     551        struct die_info aDieInfo;
     552  
     553        if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie,
     554  		       stash->debug_section_end))
     555  	return false;
     556  
     557        if (aDieInfo.tag == TAG_compile_unit)
     558  	{
     559  	  struct dwarf1_unit* aUnit
     560  	    = alloc_dwarf1_unit (stash);
     561  	  if (!aUnit)
     562  	    return false;
     563  
     564  	  aUnit->name = aDieInfo.name;
     565  	  aUnit->low_pc = aDieInfo.low_pc;
     566  	  aUnit->high_pc = aDieInfo.high_pc;
     567  	  aUnit->has_stmt_list = aDieInfo.has_stmt_list;
     568  	  aUnit->stmt_list_offset = aDieInfo.stmt_list_offset;
     569  
     570  	  /* A die has a child if it's followed by a die that is
     571  	     not it's sibling.  */
     572  	  if (aDieInfo.sibling
     573  	      && stash->currentDie + aDieInfo.length
     574  		    < stash->debug_section_end
     575  	      && stash->currentDie + aDieInfo.length
     576  		    != stash->debug_section + aDieInfo.sibling)
     577  	    aUnit->first_child = stash->currentDie + aDieInfo.length;
     578  	  else
     579  	    aUnit->first_child = 0;
     580  
     581  	  if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
     582  	    return dwarf1_unit_find_nearest_line (stash, aUnit, addr,
     583  						  filename_ptr,
     584  						  functionname_ptr,
     585  						  linenumber_ptr);
     586  	}
     587  
     588        if (aDieInfo.sibling != 0)
     589  	stash->currentDie = stash->debug_section + aDieInfo.sibling;
     590        else
     591  	stash->currentDie += aDieInfo.length;
     592      }
     593  
     594    return false;
     595  }
     596  
     597  void
     598  _bfd_dwarf1_cleanup_debug_info (bfd *abfd ATTRIBUTE_UNUSED, void **pinfo)
     599  {
     600    struct dwarf1_debug* stash = *pinfo;
     601  
     602    if (stash == NULL)
     603      return;
     604  
     605    free (stash->debug_section);
     606    free (stash->line_section);
     607  }