Branch data 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 : 1361561 : dwarf_formstring (Dwarf_Attribute *attrp) 39 : : { 40 : : /* Ignore earlier errors. */ 41 [ + + ]: 1361561 : if (attrp == NULL) 42 : : return NULL; 43 : : 44 : : /* We found it. Now determine where the string is stored. */ 45 [ + + ]: 1194165 : if (attrp->form == DW_FORM_string) 46 : : /* A simple inlined string. */ 47 : 77210 : return (const char *) attrp->valp; 48 : : 49 : 1116955 : Dwarf_CU *cu = attrp->cu; 50 : 1116955 : Dwarf *dbg = cu->dbg; 51 : 2233910 : Dwarf *dbg_ret = ((attrp->form == DW_FORM_GNU_strp_alt 52 : 1116955 : || attrp->form == DW_FORM_strp_sup) 53 [ + + ]: 1116955 : ? INTUSE(dwarf_getalt) (dbg) : dbg); 54 : : 55 [ - + ]: 1116955 : if (unlikely (dbg_ret == NULL)) 56 : : { 57 : 0 : __libdw_seterrno (DWARF_E_NO_ALT_DEBUGLINK); 58 : 0 : return NULL; 59 : : } 60 : : 61 : 2233910 : Elf_Data *data = ((attrp->form == DW_FORM_line_strp) 62 : : ? dbg_ret->sectiondata[IDX_debug_line_str] 63 [ + + ]: 1116955 : : dbg_ret->sectiondata[IDX_debug_str]); 64 [ - + ]: 1116955 : 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 : 1116955 : uint64_t off; 73 : 1116955 : if (attrp->form == DW_FORM_strp 74 [ + + ]: 1116955 : || attrp->form == DW_FORM_GNU_strp_alt 75 [ - + ]: 158 : || attrp->form == DW_FORM_strp_sup) 76 : : { 77 [ + - ]: 1116797 : if (__libdw_read_offset (dbg, dbg_ret, cu_sec_idx (cu), 78 : 1116797 : 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 [ + - ]: 16 : if (__libdw_read_offset (dbg, dbg_ret, cu_sec_idx (cu), 85 : 16 : attrp->valp, cu->offset_size, &off, 86 : : IDX_debug_line_str, 1)) 87 : : return NULL; 88 : : } 89 : : else 90 : : { 91 : 142 : 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 : 0 : goto invalid; 110 : 0 : idx = *datap; 111 : 0 : break; 112 : : 113 : 0 : case DW_FORM_strx2: 114 [ # # ]: 0 : if (datap >= endp - 2) 115 : 0 : goto invalid; 116 [ # # ]: 0 : idx = read_2ubyte_unaligned (dbg, datap); 117 : 0 : break; 118 : : 119 : 0 : case DW_FORM_strx3: 120 [ # # ]: 0 : if (datap >= endp - 3) 121 : 0 : 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 : 0 : goto invalid; 128 [ # # ]: 0 : idx = read_4ubyte_unaligned (dbg, datap); 129 : 0 : 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 : 0 : 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 : 0 : goto invalid_offset; 166 : : 167 : 142 : datap = (dbg->sectiondata[IDX_debug_str_offsets]->d_buf 168 : 142 : + str_off + (idx * offset_size)); 169 [ + - ]: 142 : if (offset_size == 4) 170 [ - + ]: 284 : 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 : 0 : goto invalid_offset; 176 : : } 177 : : 178 : 1116955 : return (const char *) data->d_buf + off; 179 : : } 180 : : INTDEF(dwarf_formstring)