LCOV - code coverage report
Current view: top level - libdw - dwarf_formstring.c (source / functions) Hit Total Coverage
Test: elfutils-0.175 Lines: 44 74 59.5 %
Date: 2018-11-16 13:02:39 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Return string associated with given attribute.
       2             :    Copyright (C) 2003-2010, 2013, 2017, 2018 Red Hat, Inc.
       3             :    This file is part of elfutils.
       4             : 
       5             :    This file is free software; you can redistribute it and/or modify
       6             :    it under the terms of either
       7             : 
       8             :      * the GNU Lesser General Public License as published by the Free
       9             :        Software Foundation; either version 3 of the License, or (at
      10             :        your option) any later version
      11             : 
      12             :    or
      13             : 
      14             :      * the GNU General Public License as published by the Free
      15             :        Software Foundation; either version 2 of the License, or (at
      16             :        your option) any later version
      17             : 
      18             :    or both in parallel, as here.
      19             : 
      20             :    elfutils is distributed in the hope that it will be useful, but
      21             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      22             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      23             :    General Public License for more details.
      24             : 
      25             :    You should have received copies of the GNU General Public License and
      26             :    the GNU Lesser General Public License along with this program.  If
      27             :    not, see <http://www.gnu.org/licenses/>.  */
      28             : 
      29             : #ifdef HAVE_CONFIG_H
      30             : # include <config.h>
      31             : #endif
      32             : 
      33             : #include <dwarf.h>
      34             : #include "libdwP.h"
      35             : 
      36             : 
      37             : const char *
      38     1164109 : dwarf_formstring (Dwarf_Attribute *attrp)
      39             : {
      40             :   /* Ignore earlier errors.  */
      41     1164109 :   if (attrp == NULL)
      42             :     return NULL;
      43             : 
      44             :   /* We found it.  Now determine where the string is stored.  */
      45     1021514 :   if (attrp->form == DW_FORM_string)
      46             :     /* A simple inlined string.  */
      47       70284 :     return (const char *) attrp->valp;
      48             : 
      49      951230 :   Dwarf_CU *cu = attrp->cu;
      50      951230 :   Dwarf *dbg = cu->dbg;
      51      951230 :   Dwarf *dbg_ret = ((attrp->form == DW_FORM_GNU_strp_alt
      52      951230 :                      || attrp->form == DW_FORM_strp_sup)
      53      951230 :                     ? INTUSE(dwarf_getalt) (dbg) : dbg);
      54             : 
      55      951230 :   if (unlikely (dbg_ret == NULL))
      56             :     {
      57           0 :       __libdw_seterrno (DWARF_E_NO_ALT_DEBUGLINK);
      58           0 :       return NULL;
      59             :     }
      60             : 
      61     1902460 :   Elf_Data *data = ((attrp->form == DW_FORM_line_strp)
      62             :                     ? dbg_ret->sectiondata[IDX_debug_line_str]
      63      951230 :                     : dbg_ret->sectiondata[IDX_debug_str]);
      64      951230 :   if (data == NULL)
      65             :     {
      66           0 :       __libdw_seterrno ((attrp->form == DW_FORM_line_strp)
      67             :                         ? DWARF_E_NO_DEBUG_LINE_STR
      68             :                         : DWARF_E_NO_DEBUG_STR);
      69           0 :       return NULL;
      70             :     }
      71             : 
      72             :   uint64_t off;
      73      951230 :   if (attrp->form == DW_FORM_strp
      74      951230 :       || attrp->form == DW_FORM_GNU_strp_alt
      75         158 :       || attrp->form == DW_FORM_strp_sup)
      76             :     {
      77     1902144 :       if (__libdw_read_offset (dbg, dbg_ret, cu_sec_idx (cu),
      78     1902144 :                                attrp->valp, cu->offset_size, &off,
      79             :                                IDX_debug_str, 1))
      80             :         return NULL;
      81             :     }
      82         158 :   else if (attrp->form == DW_FORM_line_strp)
      83             :     {
      84          32 :       if (__libdw_read_offset (dbg, dbg_ret, cu_sec_idx (cu),
      85          32 :                                attrp->valp, cu->offset_size, &off,
      86             :                                IDX_debug_line_str, 1))
      87             :         return NULL;
      88             :     }
      89             :   else
      90             :     {
      91             :       Dwarf_Word idx;
      92         142 :       const unsigned char *datap = attrp->valp;
      93         142 :       const unsigned char *endp = cu->endp;
      94         142 :       switch (attrp->form)
      95             :         {
      96         142 :         case DW_FORM_strx:
      97             :         case DW_FORM_GNU_str_index:
      98         142 :           if (datap >= endp)
      99             :             {
     100           0 :             invalid:
     101           0 :               __libdw_seterrno (DWARF_E_INVALID_DWARF);
     102           0 :               return NULL;
     103             :             }
     104         142 :           get_uleb128 (idx, datap, endp);
     105         142 :           break;
     106             : 
     107           0 :         case DW_FORM_strx1:
     108           0 :           if (datap >= endp - 1)
     109             :             goto invalid;
     110           0 :           idx = *datap;
     111           0 :           break;
     112             : 
     113           0 :         case DW_FORM_strx2:
     114           0 :           if (datap >= endp - 2)
     115             :             goto invalid;
     116           0 :           idx = read_2ubyte_unaligned (dbg, datap);
     117             :           break;
     118             : 
     119           0 :         case DW_FORM_strx3:
     120           0 :           if (datap >= endp - 3)
     121             :             goto invalid;
     122           0 :           idx = read_3ubyte_unaligned (dbg, datap);
     123           0 :           break;
     124             : 
     125           0 :         case DW_FORM_strx4:
     126           0 :           if (datap >= endp - 4)
     127             :             goto invalid;
     128           0 :           idx = read_4ubyte_unaligned (dbg, datap);
     129             :           break;
     130             : 
     131           0 :         default:
     132           0 :           __libdw_seterrno (DWARF_E_NO_STRING);
     133           0 :           return NULL;
     134             :         }
     135             : 
     136             :       /* So we got an index in the .debug_str_offsets.  Lets see if it
     137             :          is valid and we can get the actual .debug_str offset.  */
     138         142 :       Dwarf_Off str_off = __libdw_cu_str_off_base (cu);
     139         142 :       if (str_off == (Dwarf_Off) -1)
     140             :         return NULL;
     141             : 
     142         142 :       if (dbg->sectiondata[IDX_debug_str_offsets] == NULL)
     143             :         {
     144           0 :           __libdw_seterrno (DWARF_E_NO_STR_OFFSETS);
     145           0 :           return NULL;
     146             :         }
     147             : 
     148             :       /* The section should at least contain room for one offset.  */
     149         142 :       int offset_size = cu->offset_size;
     150         142 :       if (cu->offset_size > dbg->sectiondata[IDX_debug_str_offsets]->d_size)
     151             :         {
     152           0 :         invalid_offset:
     153           0 :           __libdw_seterrno (DWARF_E_INVALID_OFFSET);
     154           0 :           return NULL;
     155             :         }
     156             : 
     157             :       /* And the base offset should be at least inside the section.  */
     158         142 :       if (str_off > (dbg->sectiondata[IDX_debug_str_offsets]->d_size
     159         142 :                      - offset_size))
     160             :         goto invalid_offset;
     161             : 
     162         142 :       size_t max_idx = (dbg->sectiondata[IDX_debug_str_offsets]->d_size
     163         142 :                         - offset_size - str_off) / offset_size;
     164         142 :       if (idx > max_idx)
     165             :         goto invalid_offset;
     166             : 
     167         284 :       datap = (dbg->sectiondata[IDX_debug_str_offsets]->d_buf
     168         142 :                + str_off + (idx * offset_size));
     169         142 :       if (offset_size == 4)
     170         142 :         off = read_4ubyte_unaligned (dbg, datap);
     171             :       else
     172           0 :         off = read_8ubyte_unaligned (dbg, datap);
     173             : 
     174         142 :       if (off > dbg->sectiondata[IDX_debug_str]->d_size)
     175             :         goto invalid_offset;
     176             :     }
     177             : 
     178      951230 :   return (const char *) data->d_buf + off;
     179             : }
     180             : INTDEF(dwarf_formstring)

Generated by: LCOV version 1.13