LCOV - code coverage report
Current view: top level - libdw - dwarf_getabbrev.c (source / functions) Hit Total Coverage
Test: elfutils-0.172 Lines: 49 54 90.7 %
Date: 2018-06-11 22:52:14 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Get abbreviation at given offset.
       2             :    Copyright (C) 2003, 2004, 2005, 2006, 2014, 2017 Red Hat, Inc.
       3             :    This file is part of elfutils.
       4             :    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
       5             : 
       6             :    This file is free software; you can redistribute it and/or modify
       7             :    it under the terms of either
       8             : 
       9             :      * the GNU Lesser General Public License as published by the Free
      10             :        Software Foundation; either version 3 of the License, or (at
      11             :        your option) any later version
      12             : 
      13             :    or
      14             : 
      15             :      * the GNU General Public License as published by the Free
      16             :        Software Foundation; either version 2 of the License, or (at
      17             :        your option) any later version
      18             : 
      19             :    or both in parallel, as here.
      20             : 
      21             :    elfutils is distributed in the hope that it will be useful, but
      22             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      24             :    General Public License for more details.
      25             : 
      26             :    You should have received copies of the GNU General Public License and
      27             :    the GNU Lesser General Public License along with this program.  If
      28             :    not, see <http://www.gnu.org/licenses/>.  */
      29             : 
      30             : #ifdef HAVE_CONFIG_H
      31             : # include <config.h>
      32             : #endif
      33             : 
      34             : #include <dwarf.h>
      35             : #include "libdwP.h"
      36             : 
      37             : 
      38             : Dwarf_Abbrev *
      39             : internal_function
      40      654747 : __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset,
      41             :                    size_t *lengthp, Dwarf_Abbrev *result)
      42             : {
      43             :   /* Don't fail if there is not .debug_abbrev section.  */
      44      654747 :   if (dbg->sectiondata[IDX_debug_abbrev] == NULL)
      45             :     return NULL;
      46             : 
      47      654747 :   if (offset >= dbg->sectiondata[IDX_debug_abbrev]->d_size)
      48             :     {
      49           0 :       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
      50           0 :       return NULL;
      51             :     }
      52             : 
      53      654747 :   const unsigned char *abbrevp
      54      654747 :     = (unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + offset;
      55             : 
      56      654747 :   if (*abbrevp == '\0')
      57             :     /* We are past the last entry.  */
      58             :     return DWARF_END_ABBREV;
      59             : 
      60             :   /* 7.5.3 Abbreviations Tables
      61             : 
      62             :      [...] Each declaration begins with an unsigned LEB128 number
      63             :      representing the abbreviation code itself.  [...]  The
      64             :      abbreviation code is followed by another unsigned LEB128
      65             :      number that encodes the entry's tag.  [...]
      66             : 
      67             :      [...] Following the tag encoding is a 1-byte value that
      68             :      determines whether a debugging information entry using this
      69             :      abbreviation has child entries or not. [...]
      70             : 
      71             :      [...] Finally, the child encoding is followed by a series of
      72             :      attribute specifications. Each attribute specification
      73             :      consists of two parts. The first part is an unsigned LEB128
      74             :      number representing the attribute's name. The second part is
      75             :      an unsigned LEB128 number representing the attribute's form.  */
      76      653671 :   const unsigned char *end = (dbg->sectiondata[IDX_debug_abbrev]->d_buf
      77             :                               + dbg->sectiondata[IDX_debug_abbrev]->d_size);
      78      653671 :   const unsigned char *start_abbrevp = abbrevp;
      79             :   unsigned int code;
      80      653671 :   get_uleb128 (code, abbrevp, end);
      81             : 
      82             :   /* Check whether this code is already in the hash table.  */
      83      653671 :   bool foundit = false;
      84      653671 :   Dwarf_Abbrev *abb = NULL;
      85      653671 :   if (cu == NULL
      86      597607 :       || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL)) == NULL)
      87             :     {
      88      653665 :       if (result == NULL)
      89      597601 :         abb = libdw_typed_alloc (dbg, Dwarf_Abbrev);
      90             :       else
      91             :         abb = result;
      92             :     }
      93             :   else
      94             :     {
      95           6 :       foundit = true;
      96             : 
      97           6 :       if (unlikely (abb->offset != offset))
      98             :         {
      99             :           /* A duplicate abbrev code at a different offset,
     100             :              that should never happen.  */
     101           0 :         invalid:
     102           0 :           __libdw_seterrno (DWARF_E_INVALID_DWARF);
     103           0 :           return NULL;
     104             :         }
     105             : 
     106             :       /* If the caller doesn't need the length we are done.  */
     107           6 :       if (lengthp == NULL)
     108             :         goto out;
     109             :     }
     110             : 
     111             :   /* If there is already a value in the hash table we are going to
     112             :      overwrite its content.  This must not be a problem, since the
     113             :      content better be the same.  */
     114      653671 :   abb->code = code;
     115      653671 :   if (abbrevp >= end)
     116             :     goto invalid;
     117      653671 :   get_uleb128 (abb->tag, abbrevp, end);
     118      653671 :   if (abbrevp + 1 >= end)
     119             :     goto invalid;
     120      653671 :   abb->has_children = *abbrevp++ == DW_CHILDREN_yes;
     121      653671 :   abb->attrp = (unsigned char *) abbrevp;
     122      653671 :   abb->offset = offset;
     123             : 
     124             :   /* Skip over all the attributes and check rest of the abbrev is valid.  */
     125             :   unsigned int attrname;
     126             :   unsigned int attrform;
     127             :   do
     128             :     {
     129     3217955 :       if (abbrevp >= end)
     130             :         goto invalid;
     131     3217955 :       get_uleb128 (attrname, abbrevp, end);
     132     3217955 :       if (abbrevp >= end)
     133             :         goto invalid;
     134     3217955 :       get_uleb128 (attrform, abbrevp, end);
     135     3217955 :       if (attrform == DW_FORM_implicit_const)
     136             :         {
     137             :           int64_t formval __attribute__((__unused__));
     138         225 :           if (abbrevp >= end)
     139             :             goto invalid;
     140         225 :           get_sleb128 (formval, abbrevp, end);
     141             :         }
     142             :     }
     143     3217955 :   while (attrname != 0 && attrform != 0);
     144             : 
     145             :   /* Return the length to the caller if she asked for it.  */
     146      653671 :   if (lengthp != NULL)
     147      653671 :     *lengthp = abbrevp - start_abbrevp;
     148             : 
     149             :   /* Add the entry to the hash table.  */
     150      653671 :   if (cu != NULL && ! foundit)
     151      597601 :     (void) Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, abb->code, abb);
     152             : 
     153       56070 :  out:
     154             :   return abb;
     155             : }
     156             : 
     157             : 
     158             : Dwarf_Abbrev *
     159         948 : dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, size_t *lengthp)
     160             : {
     161         948 :   if (die == NULL || die->cu == NULL)
     162             :     return NULL;
     163             : 
     164          75 :   Dwarf_CU *cu = die->cu;
     165          75 :   Dwarf *dbg = cu->dbg;
     166          75 :   Dwarf_Off abbrev_offset = cu->orig_abbrev_offset;
     167          75 :   Elf_Data *data = dbg->sectiondata[IDX_debug_abbrev];
     168          75 :   if (data == NULL)
     169             :     return NULL;
     170             : 
     171          75 :   if (offset >= data->d_size - abbrev_offset)
     172             :     {
     173           6 :       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
     174           6 :       return NULL;
     175             :     }
     176             : 
     177          69 :   return __libdw_getabbrev (dbg, cu, abbrev_offset + offset, lengthp, NULL);
     178             : }

Generated by: LCOV version 1.13