Back to index

cell-binutils  2.17cvs20070401
dwarf1.c
Go to the documentation of this file.
00001 /* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line).
00002    Copyright 1998, 1999, 2000, 2001, 2002, 2004, 2005
00003    Free Software Foundation, Inc.
00004 
00005    Written by Gavin Romig-Koch of Cygnus Solutions (gavin@cygnus.com).
00006 
00007    This file is part of BFD.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or (at
00012    your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful, but
00015    WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017    General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "libiberty.h"
00026 #include "libbfd.h"
00027 #include "elf-bfd.h"
00028 #include "elf/dwarf.h"
00029 
00030 /* dwarf1_debug is the starting point for all dwarf1 info.  */
00031 
00032 struct dwarf1_debug
00033 {
00034   /* The bfd we are working with.  */
00035   bfd* abfd;
00036 
00037   /* List of already parsed compilation units.  */
00038   struct dwarf1_unit* lastUnit;
00039 
00040   /* The buffer for the .debug section.
00041      Zero indicates that the .debug section failed to load.  */
00042   char* debug_section;
00043 
00044   /* Pointer to the end of the .debug_info section memory buffer.  */
00045   char* debug_section_end;
00046 
00047   /* The buffer for the .line section.  */
00048   char* line_section;
00049 
00050   /* End of that buffer.  */
00051   char* line_section_end;
00052 
00053   /* The current or next unread die within the .debug section.  */
00054   char* currentDie;
00055 };
00056 
00057 /* One dwarf1_unit for each parsed compilation unit die.  */
00058 
00059 struct dwarf1_unit
00060 {
00061   /* Linked starting from stash->lastUnit.  */
00062   struct dwarf1_unit* prev;
00063 
00064   /* Name of the compilation unit.  */
00065   char* name;
00066 
00067   /* The highest and lowest address used in the compilation unit.  */
00068   unsigned long low_pc;
00069   unsigned long high_pc;
00070 
00071   /* Does this unit have a statement list?  */
00072   int has_stmt_list;
00073 
00074   /* If any, the offset of the line number table in the .line section.  */
00075   unsigned long stmt_list_offset;
00076 
00077   /* If non-zero, a pointer to the first child of this unit.  */
00078   char* first_child;
00079 
00080   /* How many line entries?  */
00081   unsigned long line_count;
00082 
00083   /* The decoded line number table (line_count entries).  */
00084   struct linenumber* linenumber_table;
00085 
00086   /* The list of functions in this unit.  */
00087   struct dwarf1_func* func_list;
00088 };
00089 
00090 /* One dwarf1_func for each parsed function die.  */
00091 
00092 struct dwarf1_func
00093 {
00094   /* Linked starting from aUnit->func_list.  */
00095   struct dwarf1_func* prev;
00096 
00097   /* Name of function.  */
00098   char* name;
00099 
00100   /* The highest and lowest address used in the compilation unit.  */
00101   unsigned long low_pc;
00102   unsigned long high_pc;
00103 };
00104 
00105 /* Used to return info about a parsed die.  */
00106 struct die_info
00107 {
00108   unsigned long length;
00109   unsigned long sibling;
00110   unsigned long low_pc;
00111   unsigned long high_pc;
00112   unsigned long stmt_list_offset;
00113 
00114   char* name;
00115 
00116   int has_stmt_list;
00117 
00118   unsigned short tag;
00119 };
00120 
00121 /* Parsed line number information.  */
00122 struct linenumber
00123 {
00124   /* First address in the line.  */
00125   unsigned long addr;
00126 
00127   /* The line number.  */
00128   unsigned long linenumber;
00129 };
00130 
00131 /* Find the form of an attr, from the attr field.  */
00132 #define FORM_FROM_ATTR(attr)       ((attr) & 0xF)       /* Implicitly specified.  */
00133 
00134 /* Return a newly allocated dwarf1_unit.  It should be cleared and
00135    then attached into the 'stash' at 'stash->lastUnit'.  */
00136 
00137 static struct dwarf1_unit*
00138 alloc_dwarf1_unit (struct dwarf1_debug* stash)
00139 {
00140   bfd_size_type amt = sizeof (struct dwarf1_unit);
00141 
00142   struct dwarf1_unit* x = bfd_zalloc (stash->abfd, amt);
00143   x->prev = stash->lastUnit;
00144   stash->lastUnit = x;
00145 
00146   return x;
00147 }
00148 
00149 /* Return a newly allocated dwarf1_func.  It must be cleared and
00150    attached into 'aUnit' at 'aUnit->func_list'.  */
00151 
00152 static struct dwarf1_func *
00153 alloc_dwarf1_func (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
00154 {
00155   bfd_size_type amt = sizeof (struct dwarf1_func);
00156 
00157   struct dwarf1_func* x = bfd_zalloc (stash->abfd, amt);
00158   x->prev = aUnit->func_list;
00159   aUnit->func_list = x;
00160 
00161   return x;
00162 }
00163 
00164 /* parse_die - parse a Dwarf1 die.
00165    Parse the die starting at 'aDiePtr' into 'aDieInfo'.
00166    'abfd' must be the bfd from which the section that 'aDiePtr'
00167    points to was pulled from.
00168 
00169    Return FALSE if the die is invalidly formatted; TRUE otherwise.  */
00170 
00171 static bfd_boolean
00172 parse_die (bfd *             abfd,
00173           struct die_info * aDieInfo,
00174           char *            aDiePtr,
00175           char *            aDiePtrEnd)
00176 {
00177   char* this_die = aDiePtr;
00178   char* xptr = this_die;
00179 
00180   memset (aDieInfo, 0, sizeof (* aDieInfo));
00181 
00182   /* First comes the length.  */
00183   aDieInfo->length = bfd_get_32 (abfd, (bfd_byte *) xptr);
00184   xptr += 4;
00185   if (aDieInfo->length == 0
00186       || (this_die + aDieInfo->length) >= aDiePtrEnd)
00187     return FALSE;
00188   if (aDieInfo->length < 6)
00189     {
00190       /* Just padding bytes.  */
00191       aDieInfo->tag = TAG_padding;
00192       return TRUE;
00193     }
00194 
00195   /* Then the tag.  */
00196   aDieInfo->tag = bfd_get_16 (abfd, (bfd_byte *) xptr);
00197   xptr += 2;
00198 
00199   /* Then the attributes.  */
00200   while (xptr < (this_die + aDieInfo->length))
00201     {
00202       unsigned short attr;
00203 
00204       /* Parse the attribute based on its form.  This section
00205          must handle all dwarf1 forms, but need only handle the
00206         actual attributes that we care about.  */
00207       attr = bfd_get_16 (abfd, (bfd_byte *) xptr);
00208       xptr += 2;
00209 
00210       switch (FORM_FROM_ATTR (attr))
00211        {
00212        case FORM_DATA2:
00213          xptr += 2;
00214          break;
00215        case FORM_DATA4:
00216        case FORM_REF:
00217          if (attr == AT_sibling)
00218            aDieInfo->sibling = bfd_get_32 (abfd, (bfd_byte *) xptr);
00219          else if (attr == AT_stmt_list)
00220            {
00221              aDieInfo->stmt_list_offset = bfd_get_32 (abfd, (bfd_byte *) xptr);
00222              aDieInfo->has_stmt_list = 1;
00223            }
00224          xptr += 4;
00225          break;
00226        case FORM_DATA8:
00227          xptr += 8;
00228          break;
00229        case FORM_ADDR:
00230          if (attr == AT_low_pc)
00231            aDieInfo->low_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
00232          else if (attr == AT_high_pc)
00233            aDieInfo->high_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
00234          xptr += 4;
00235          break;
00236        case FORM_BLOCK2:
00237          xptr += 2 + bfd_get_16 (abfd, (bfd_byte *) xptr);
00238          break;
00239        case FORM_BLOCK4:
00240          xptr += 4 + bfd_get_32 (abfd, (bfd_byte *) xptr);
00241          break;
00242        case FORM_STRING:
00243          if (attr == AT_name)
00244            aDieInfo->name = xptr;
00245          xptr += strlen (xptr) + 1;
00246          break;
00247        }
00248     }
00249 
00250   return TRUE;
00251 }
00252 
00253 /* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset'
00254    into 'aUnit->linenumber_table'.  Return FALSE if an error
00255    occurs; TRUE otherwise.  */
00256 
00257 static bfd_boolean
00258 parse_line_table (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
00259 {
00260   char* xptr;
00261 
00262   /* Load the ".line" section from the bfd if we haven't already.  */
00263   if (stash->line_section == 0)
00264     {
00265       asection *msec;
00266       bfd_size_type size;
00267 
00268       msec = bfd_get_section_by_name (stash->abfd, ".line");
00269       if (! msec)
00270        return FALSE;
00271 
00272       size = msec->rawsize ? msec->rawsize : msec->size;
00273       stash->line_section = bfd_alloc (stash->abfd, size);
00274 
00275       if (! stash->line_section)
00276        return FALSE;
00277 
00278       if (! bfd_get_section_contents (stash->abfd, msec, stash->line_section,
00279                                   0, size))
00280        {
00281          stash->line_section = 0;
00282          return FALSE;
00283        }
00284 
00285       stash->line_section_end = stash->line_section + size;
00286     }
00287 
00288   xptr = stash->line_section + aUnit->stmt_list_offset;
00289   if (xptr < stash->line_section_end)
00290     {
00291       unsigned long eachLine;
00292       char *tblend;
00293       unsigned long base;
00294       bfd_size_type amt;
00295 
00296       /* First comes the length.  */
00297       tblend = bfd_get_32 (stash->abfd, (bfd_byte *) xptr) + xptr;
00298       xptr += 4;
00299 
00300       /* Then the base address for each address in the table.  */
00301       base = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
00302       xptr += 4;
00303 
00304       /* How many line entrys?
00305         10 = 4 (line number) + 2 (pos in line) + 4 (address in line).  */
00306       aUnit->line_count = (tblend - xptr) / 10;
00307 
00308       /* Allocate an array for the entries.  */
00309       amt = sizeof (struct linenumber) * aUnit->line_count;
00310       aUnit->linenumber_table = bfd_alloc (stash->abfd, amt);
00311 
00312       for (eachLine = 0; eachLine < aUnit->line_count; eachLine++)
00313        {
00314          /* A line number.  */
00315          aUnit->linenumber_table[eachLine].linenumber
00316            = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
00317          xptr += 4;
00318 
00319          /* Skip the position within the line.  */
00320          xptr += 2;
00321 
00322          /* And finally the address.  */
00323          aUnit->linenumber_table[eachLine].addr
00324            = base + bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
00325          xptr += 4;
00326        }
00327     }
00328 
00329   return TRUE;
00330 }
00331 
00332 /* Parse each function die in a compilation unit 'aUnit'.
00333    The first child die of 'aUnit' should be in 'aUnit->first_child',
00334    the result is placed in 'aUnit->func_list'.
00335    Return FALSE if error; TRUE otherwise.  */
00336 
00337 static bfd_boolean
00338 parse_functions_in_unit (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
00339 {
00340   char* eachDie;
00341 
00342   if (aUnit->first_child)
00343     for (eachDie = aUnit->first_child;
00344         eachDie < stash->debug_section_end;
00345         )
00346       {
00347        struct die_info eachDieInfo;
00348 
00349        if (! parse_die (stash->abfd, &eachDieInfo, eachDie,
00350                       stash->debug_section_end))
00351          return FALSE;
00352 
00353        if (eachDieInfo.tag == TAG_global_subroutine
00354            || eachDieInfo.tag == TAG_subroutine
00355            || eachDieInfo.tag == TAG_inlined_subroutine
00356            || eachDieInfo.tag == TAG_entry_point)
00357          {
00358            struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit);
00359 
00360            aFunc->name = eachDieInfo.name;
00361            aFunc->low_pc = eachDieInfo.low_pc;
00362            aFunc->high_pc = eachDieInfo.high_pc;
00363          }
00364 
00365        /* Move to next sibling, if none, end loop */
00366        if (eachDieInfo.sibling)
00367          eachDie = stash->debug_section + eachDieInfo.sibling;
00368        else
00369          break;
00370       }
00371 
00372   return TRUE;
00373 }
00374 
00375 /* Find the nearest line to 'addr' in 'aUnit'.
00376    Return whether we found the line (or a function) without error.  */
00377 
00378 static bfd_boolean
00379 dwarf1_unit_find_nearest_line (struct dwarf1_debug* stash,
00380                             struct dwarf1_unit* aUnit,
00381                             unsigned long addr,
00382                             const char **filename_ptr,
00383                             const char **functionname_ptr,
00384                             unsigned int *linenumber_ptr)
00385 {
00386   int line_p = FALSE;
00387   int func_p = FALSE;
00388 
00389   if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
00390     {
00391       if (aUnit->has_stmt_list)
00392        {
00393          unsigned long i;
00394          struct dwarf1_func* eachFunc;
00395 
00396          if (! aUnit->linenumber_table)
00397            {
00398              if (! parse_line_table (stash, aUnit))
00399               return FALSE;
00400            }
00401 
00402          if (! aUnit->func_list)
00403            {
00404              if (! parse_functions_in_unit (stash, aUnit))
00405               return FALSE;
00406            }
00407 
00408          for (i = 0; i < aUnit->line_count; i++)
00409            {
00410              if (aUnit->linenumber_table[i].addr <= addr
00411                 && addr < aUnit->linenumber_table[i+1].addr)
00412               {
00413                 *filename_ptr = aUnit->name;
00414                 *linenumber_ptr = aUnit->linenumber_table[i].linenumber;
00415                 line_p = TRUE;
00416                 break;
00417               }
00418            }
00419 
00420          for (eachFunc = aUnit->func_list;
00421               eachFunc;
00422               eachFunc = eachFunc->prev)
00423            {
00424              if (eachFunc->low_pc <= addr
00425                 && addr < eachFunc->high_pc)
00426               {
00427                 *functionname_ptr = eachFunc->name;
00428                 func_p = TRUE;
00429                 break;
00430               }
00431            }
00432        }
00433     }
00434 
00435   return line_p || func_p;
00436 }
00437 
00438 /* The DWARF 1 version of find_nearest line.
00439    Return TRUE if the line is found without error.  */
00440 
00441 bfd_boolean
00442 _bfd_dwarf1_find_nearest_line (bfd *abfd,
00443                             asection *section,
00444                             asymbol **symbols ATTRIBUTE_UNUSED,
00445                             bfd_vma offset,
00446                             const char **filename_ptr,
00447                             const char **functionname_ptr,
00448                             unsigned int *linenumber_ptr)
00449 {
00450   struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info;
00451 
00452   struct dwarf1_unit* eachUnit;
00453 
00454   /* What address are we looking for? */
00455   unsigned long addr = (unsigned long)(offset + section->vma);
00456 
00457   *filename_ptr = NULL;
00458   *functionname_ptr = NULL;
00459   *linenumber_ptr = 0;
00460 
00461   if (! stash)
00462     {
00463       asection *msec;
00464       bfd_size_type size = sizeof (struct dwarf1_debug);
00465 
00466       stash = elf_tdata (abfd)->dwarf1_find_line_info
00467        = bfd_zalloc (abfd, size);
00468 
00469       if (! stash)
00470        return FALSE;
00471 
00472       msec = bfd_get_section_by_name (abfd, ".debug");
00473       if (! msec)
00474        /* No dwarf1 info.  Note that at this point the stash
00475           has been allocated, but contains zeros, this lets
00476           future calls to this function fail quicker.  */
00477        return FALSE;
00478 
00479       size = msec->rawsize ? msec->rawsize : msec->size;
00480       stash->debug_section = bfd_alloc (abfd, size);
00481 
00482       if (! stash->debug_section)
00483        return FALSE;
00484 
00485       if (! bfd_get_section_contents (abfd, msec, stash->debug_section,
00486                                   0, size))
00487        {
00488          stash->debug_section = 0;
00489          return FALSE;
00490        }
00491 
00492       stash->debug_section_end = stash->debug_section + size;
00493       stash->currentDie = stash->debug_section;
00494       stash->abfd = abfd;
00495     }
00496 
00497   /* A null debug_section indicates that there was no dwarf1 info
00498      or that an error occured while setting up the stash.  */
00499 
00500   if (! stash->debug_section)
00501     return FALSE;
00502 
00503   /* Look at the previously parsed units to see if any contain
00504      the addr.  */
00505   for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev)
00506     if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc)
00507       return dwarf1_unit_find_nearest_line (stash, eachUnit, addr,
00508                                        filename_ptr,
00509                                        functionname_ptr,
00510                                        linenumber_ptr);
00511 
00512   while (stash->currentDie < stash->debug_section_end)
00513     {
00514       struct die_info aDieInfo;
00515 
00516       if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie,
00517                      stash->debug_section_end))
00518        return FALSE;
00519 
00520       if (aDieInfo.tag == TAG_compile_unit)
00521        {
00522          struct dwarf1_unit* aUnit
00523            = alloc_dwarf1_unit (stash);
00524 
00525          aUnit->name = aDieInfo.name;
00526          aUnit->low_pc = aDieInfo.low_pc;
00527          aUnit->high_pc = aDieInfo.high_pc;
00528          aUnit->has_stmt_list = aDieInfo.has_stmt_list;
00529          aUnit->stmt_list_offset = aDieInfo.stmt_list_offset;
00530 
00531          /* A die has a child if it's followed by a die that is
00532             not it's sibling.  */
00533          if (aDieInfo.sibling
00534              && stash->currentDie + aDieInfo.length
00535                     < stash->debug_section_end
00536              && stash->currentDie + aDieInfo.length
00537                    != stash->debug_section + aDieInfo.sibling)
00538            aUnit->first_child = stash->currentDie + aDieInfo.length;
00539          else
00540            aUnit->first_child = 0;
00541 
00542          if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
00543            return dwarf1_unit_find_nearest_line (stash, aUnit, addr,
00544                                             filename_ptr,
00545                                             functionname_ptr,
00546                                             linenumber_ptr);
00547        }
00548 
00549       if (aDieInfo.sibling != 0)
00550        stash->currentDie = stash->debug_section + aDieInfo.sibling;
00551       else
00552        stash->currentDie += aDieInfo.length;
00553     }
00554 
00555   return FALSE;
00556 }