LCOV - code coverage report
Current view: top level - libdw - dwarf_formudata.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 48 59 81.4 %
Date: 2017-01-05 09:15:16 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Return unsigned constant represented by attribute.
       2             :    Copyright (C) 2003-2012, 2014 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             : internal_function unsigned char *
      38      149349 : __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
      39             :                  int err_nodata, unsigned char **endpp,
      40             :                  Dwarf_Off *offsetp)
      41             : {
      42      149349 :   if (attr == NULL)
      43             :     return NULL;
      44             : 
      45      149349 :   const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index];
      46      149349 :   if (unlikely (d == NULL))
      47             :     {
      48           0 :       __libdw_seterrno (err_nodata);
      49           0 :       return NULL;
      50             :     }
      51             : 
      52             :   Dwarf_Word offset;
      53      149349 :   if (attr->form == DW_FORM_sec_offset)
      54             :     {
      55      297716 :       if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
      56      148858 :                                cu_sec_idx (attr->cu), attr->valp,
      57      148858 :                                attr->cu->offset_size, &offset, sec_index, 0))
      58             :         return NULL;
      59             :     }
      60         491 :   else if (attr->cu->version > 3)
      61             :     goto invalid;
      62             :   else
      63         491 :     switch (attr->form)
      64             :       {
      65             :       case DW_FORM_data4:
      66             :       case DW_FORM_data8:
      67         982 :         if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
      68         491 :                                  cu_sec_idx (attr->cu),
      69         491 :                                  attr->valp,
      70             :                                  attr->form == DW_FORM_data4 ? 4 : 8,
      71             :                                  &offset, sec_index, 0))
      72             :           return NULL;
      73             :         break;
      74             : 
      75             :       default:
      76           0 :         if (INTUSE(dwarf_formudata) (attr, &offset))
      77             :           return NULL;
      78             :       };
      79             : 
      80      149349 :   unsigned char *readp = d->d_buf + offset;
      81      149349 :   unsigned char *endp = d->d_buf + d->d_size;
      82      149349 :   if (unlikely (readp >= endp))
      83             :     {
      84             :     invalid:
      85           0 :       __libdw_seterrno (DWARF_E_INVALID_DWARF);
      86           0 :       return NULL;
      87             :     }
      88             : 
      89      149349 :   if (endpp != NULL)
      90           7 :     *endpp = endp;
      91      149349 :   if (offsetp != NULL)
      92      149349 :     *offsetp = offset;
      93             :   return readp;
      94             : }
      95             : 
      96             : int
      97     1665417 : dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
      98             : {
      99     1665417 :   if (attr == NULL)
     100             :     return -1;
     101             : 
     102     1665054 :   const unsigned char *datap = attr->valp;
     103     1665054 :   const unsigned char *endp = attr->cu->endp;
     104             : 
     105     1665054 :   switch (attr->form)
     106             :     {
     107             :     case DW_FORM_data1:
     108     1241141 :       if (datap + 1 > endp)
     109             :         {
     110             :         invalid:
     111           0 :           __libdw_seterrno (DWARF_E_INVALID_DWARF);
     112           0 :           return -1;
     113             :         }
     114     1241141 :       *return_uval = *attr->valp;
     115     1241141 :       break;
     116             : 
     117             :     case DW_FORM_data2:
     118      223538 :       if (datap + 2 > endp)
     119             :         goto invalid;
     120      223538 :       *return_uval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
     121      223538 :       break;
     122             : 
     123             :     case DW_FORM_data4:
     124             :     case DW_FORM_data8:
     125             :     case DW_FORM_sec_offset:
     126             :       /* Before DWARF4 data4 and data8 are pure constants unless the
     127             :          attribute also allows offsets (*ptr classes), since DWARF4
     128             :          they are always just constants (start_scope is special though,
     129             :          since it only could express a rangelist since DWARF4).  */
     130      180338 :       if (attr->form == DW_FORM_sec_offset
     131       35764 :           || (attr->cu->version < 4 && attr->code != DW_AT_start_scope))
     132             :         {
     133      144967 :           switch (attr->code)
     134             :             {
     135             :             case DW_AT_data_member_location:
     136             :             case DW_AT_frame_base:
     137             :             case DW_AT_location:
     138             :             case DW_AT_return_addr:
     139             :             case DW_AT_segment:
     140             :             case DW_AT_static_link:
     141             :             case DW_AT_string_length:
     142             :             case DW_AT_use_location:
     143             :             case DW_AT_vtable_elem_location:
     144             :               /* loclistptr */
     145       39341 :               if (__libdw_formptr (attr, IDX_debug_loc,
     146             :                                    DWARF_E_NO_LOCLIST, NULL,
     147             :                                    return_uval) == NULL)
     148             :                 return -1;
     149             :               break;
     150             : 
     151             :             case DW_AT_macro_info:
     152             :               /* macptr into .debug_macinfo */
     153         267 :               if (__libdw_formptr (attr, IDX_debug_macinfo,
     154             :                                    DWARF_E_NO_ENTRY, NULL,
     155             :                                    return_uval) == NULL)
     156             :                 return -1;
     157             :               break;
     158             : 
     159             :             case DW_AT_GNU_macros:
     160             :               /* macptr into .debug_macro */
     161         283 :               if (__libdw_formptr (attr, IDX_debug_macro,
     162             :                                    DWARF_E_NO_ENTRY, NULL,
     163             :                                    return_uval) == NULL)
     164             :                 return -1;
     165             :               break;
     166             : 
     167             :             case DW_AT_ranges:
     168             :             case DW_AT_start_scope:
     169             :               /* rangelistptr */
     170       10262 :               if (__libdw_formptr (attr, IDX_debug_ranges,
     171             :                                    DWARF_E_NO_DEBUG_RANGES, NULL,
     172             :                                    return_uval) == NULL)
     173             :                 return -1;
     174             :               break;
     175             : 
     176             :             case DW_AT_stmt_list:
     177             :               /* lineptr */
     178       94808 :               if (__libdw_formptr (attr, IDX_debug_line,
     179             :                                    DWARF_E_NO_DEBUG_LINE, NULL,
     180             :                                    return_uval) == NULL)
     181             :                 return -1;
     182             :               break;
     183             : 
     184             :             default:
     185             :               /* sec_offset can only be used by one of the above attrs.  */
     186           6 :               if (attr->form == DW_FORM_sec_offset)
     187             :                 {
     188           0 :                   __libdw_seterrno (DWARF_E_INVALID_DWARF);
     189           0 :                   return -1;
     190             :                 }
     191             : 
     192             :               /* Not one of the special attributes, just a constant.  */
     193          12 :               if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
     194             :                                         attr->valp,
     195             :                                         attr->form == DW_FORM_data4 ? 4 : 8,
     196             :                                         return_uval))
     197             :                 return -1;
     198             :               break;
     199             :             }
     200             :         }
     201             :       else
     202             :         {
     203             :           /* We are dealing with a constant data4 or data8.  */
     204       70742 :           if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
     205             :                                     attr->valp,
     206             :                                     attr->form == DW_FORM_data4 ? 4 : 8,
     207             :                                     return_uval))
     208             :             return -1;
     209             :         }
     210             :       break;
     211             : 
     212             :     case DW_FORM_sdata:
     213       20004 :       if (datap + 1 > endp)
     214             :         goto invalid;
     215       20004 :       get_sleb128 (*return_uval, datap, endp);
     216       20004 :       break;
     217             : 
     218             :     case DW_FORM_udata:
     219          33 :       if (datap + 1 > endp)
     220             :         goto invalid;
     221          33 :       get_uleb128 (*return_uval, datap, endp);
     222          33 :       break;
     223             : 
     224             :     default:
     225           0 :       __libdw_seterrno (DWARF_E_NO_CONSTANT);
     226           0 :       return -1;
     227             :     }
     228             : 
     229             :   return 0;
     230             : }
     231             : INTDEF(dwarf_formudata)

Generated by: LCOV version 1.12