LCOV - code coverage report
Current view: top level - libdw - dwarf_getabbrev.c (source / functions) Hit Total Coverage
Test: elfutils-0.191 Lines: 54 71 76.1 %
Date: 2024-03-01 16:42:08 Functions: 2 2 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 36 52 69.2 %

           Branch data     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                 :    1887112 : __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         [ -  + ]:    1887112 :   if (dbg->sectiondata[IDX_debug_abbrev] == NULL)
      45                 :          0 :     return NULL;
      46                 :            : 
      47         [ -  + ]:    1887112 :   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                 :    1887112 :   const unsigned char *abbrevp
      54                 :    1887112 :     = (unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + offset;
      55                 :            : 
      56         [ +  + ]:    1887112 :   if (*abbrevp == '\0')
      57                 :            :     /* We are past the last entry.  */
      58                 :       3430 :     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                 :    1883682 :   const unsigned char *end = (dbg->sectiondata[IDX_debug_abbrev]->d_buf
      77                 :    1883682 :                               + dbg->sectiondata[IDX_debug_abbrev]->d_size);
      78                 :    1883682 :   const unsigned char *start_abbrevp = abbrevp;
      79                 :            :   unsigned int code;
      80                 :            :   // We start off with abbrevp at offset, which is checked above.
      81                 :    1883682 :   get_uleb128 (code, abbrevp, end);
      82                 :            : 
      83                 :            :   /* Check whether this code is already in the hash table.  */
      84                 :    1883682 :   bool foundit = false;
      85                 :    1883682 :   Dwarf_Abbrev *abb = NULL;
      86         [ +  + ]:    1883682 :   if (cu == NULL
      87         [ +  + ]:    1755462 :       || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code)) == NULL)
      88                 :            :     {
      89         [ +  + ]:    1883670 :       if (result == NULL)
      90         [ +  + ]:    1755450 :         abb = libdw_typed_alloc (dbg, Dwarf_Abbrev);
      91                 :            :       else
      92                 :     128220 :         abb = result;
      93                 :            :     }
      94                 :            :   else
      95                 :            :     {
      96                 :         12 :       foundit = true;
      97                 :            : 
      98         [ -  + ]:         12 :       if (unlikely (abb->offset != offset))
      99                 :            :         {
     100                 :            :           /* A duplicate abbrev code at a different offset,
     101                 :            :              that should never happen.  */
     102                 :          0 :         invalid:
     103         [ #  # ]:          0 :           if (! foundit)
     104                 :          0 :             libdw_typed_unalloc (dbg, Dwarf_Abbrev);
     105                 :          0 :           __libdw_seterrno (DWARF_E_INVALID_DWARF);
     106                 :          0 :           return NULL;
     107                 :            :         }
     108                 :            : 
     109                 :            :       /* If the caller doesn't need the length we are done.  */
     110         [ -  + ]:         12 :       if (lengthp == NULL)
     111                 :          0 :         goto out;
     112                 :            :     }
     113                 :            : 
     114                 :            :   /* If there is already a value in the hash table we are going to
     115                 :            :      overwrite its content.  This must not be a problem, since the
     116                 :            :      content better be the same.  */
     117                 :    1883682 :   abb->code = code;
     118         [ -  + ]:    1883682 :   if (abbrevp >= end)
     119                 :          0 :     goto invalid;
     120                 :    1883682 :   get_uleb128 (abb->tag, abbrevp, end);
     121         [ -  + ]:    1883682 :   if (abbrevp + 1 >= end)
     122                 :          0 :     goto invalid;
     123                 :    1883682 :   abb->has_children = *abbrevp++ == DW_CHILDREN_yes;
     124                 :    1883682 :   abb->attrp = (unsigned char *) abbrevp;
     125                 :    1883682 :   abb->offset = offset;
     126                 :            : 
     127                 :            :   /* Skip over all the attributes and check rest of the abbrev is valid.  */
     128                 :            :   unsigned int attrname;
     129                 :            :   unsigned int attrform;
     130                 :            :   do
     131                 :            :     {
     132         [ -  + ]:   11160152 :       if (abbrevp >= end)
     133                 :          0 :         goto invalid;
     134                 :   11160152 :       get_uleb128 (attrname, abbrevp, end);
     135         [ -  + ]:   11160152 :       if (abbrevp >= end)
     136                 :          0 :         goto invalid;
     137                 :   11160152 :       get_uleb128 (attrform, abbrevp, end);
     138         [ +  + ]:   11160152 :       if (attrform == DW_FORM_implicit_const)
     139                 :            :         {
     140                 :            :           int64_t formval __attribute__((__unused__));
     141         [ -  + ]:     857952 :           if (abbrevp >= end)
     142                 :          0 :             goto invalid;
     143                 :     857952 :           get_sleb128 (formval, abbrevp, end);
     144                 :            :         }
     145                 :            :     }
     146   [ +  +  -  + ]:   11160152 :   while (attrname != 0 || attrform != 0);
     147                 :            : 
     148                 :            :   /* Return the length to the caller if she asked for it.  */
     149         [ +  - ]:    1883682 :   if (lengthp != NULL)
     150                 :    1883682 :     *lengthp = abbrevp - start_abbrevp;
     151                 :            : 
     152                 :            :   /* Add the entry to the hash table.  */
     153   [ +  +  +  + ]:    1883682 :   if (cu != NULL && ! foundit)
     154         [ +  - ]:    1755450 :     if (Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, abb->code, abb) == -1)
     155                 :            :       {
     156                 :            :         /* The entry was already in the table, remove the one we just
     157                 :            :            created and get the one already inserted.  */
     158                 :          0 :         libdw_typed_unalloc (dbg, Dwarf_Abbrev);
     159                 :          0 :         abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code);
     160                 :            :       }
     161                 :            : 
     162                 :    1883682 :  out:
     163                 :    1883682 :   return abb;
     164                 :            : }
     165                 :            : 
     166                 :            : 
     167                 :            : Dwarf_Abbrev *
     168                 :       2454 : dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, size_t *lengthp)
     169                 :            : {
     170   [ +  -  +  + ]:       2454 :   if (die == NULL || die->cu == NULL)
     171                 :       2304 :     return NULL;
     172                 :            : 
     173                 :        150 :   Dwarf_CU *cu = die->cu;
     174                 :        150 :   Dwarf *dbg = cu->dbg;
     175                 :        150 :   Dwarf_Off abbrev_offset = cu->orig_abbrev_offset;
     176                 :        150 :   Elf_Data *data = dbg->sectiondata[IDX_debug_abbrev];
     177         [ -  + ]:        150 :   if (data == NULL)
     178                 :          0 :     return NULL;
     179                 :            : 
     180         [ +  + ]:        150 :   if (offset >= data->d_size - abbrev_offset)
     181                 :            :     {
     182                 :         12 :       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
     183                 :         12 :       return NULL;
     184                 :            :     }
     185                 :            : 
     186                 :        138 :   return __libdw_getabbrev (dbg, cu, abbrev_offset + offset, lengthp, NULL);
     187                 :            : }

Generated by: LCOV version 1.14