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 : 1503440 : dwarf_formstring (Dwarf_Attribute *attrp)
39 : : {
40 : : /* Ignore earlier errors. */
41 [ + + ]: 1503440 : if (attrp == NULL)
42 : : return NULL;
43 : :
44 : : /* We found it. Now determine where the string is stored. */
45 [ + + ]: 1317227 : if (attrp->form == DW_FORM_string)
46 : : /* A simple inlined string. */
47 : 75817 : return (const char *) attrp->valp;
48 : :
49 : 1241410 : Dwarf_CU *cu = attrp->cu;
50 : 1241410 : Dwarf *dbg = cu->dbg;
51 : 2482820 : Dwarf *dbg_ret = ((attrp->form == DW_FORM_GNU_strp_alt
52 : 1241410 : || attrp->form == DW_FORM_strp_sup)
53 [ + + ]: 1241410 : ? INTUSE(dwarf_getalt) (dbg) : dbg);
54 : :
55 [ - + ]: 1241410 : if (unlikely (dbg_ret == NULL))
56 : : {
57 : 0 : __libdw_seterrno (DWARF_E_NO_ALT_DEBUGLINK);
58 : 0 : return NULL;
59 : : }
60 : :
61 : 2482820 : Elf_Data *data = ((attrp->form == DW_FORM_line_strp)
62 : : ? dbg_ret->sectiondata[IDX_debug_line_str]
63 [ + + ]: 1241410 : : dbg_ret->sectiondata[IDX_debug_str]);
64 [ - + ]: 1241410 : 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 : 1241410 : uint64_t off;
73 : 2482820 : if (attrp->form == DW_FORM_strp
74 [ + + ]: 1241410 : || attrp->form == DW_FORM_GNU_strp_alt
75 [ - + ]: 158 : || attrp->form == DW_FORM_strp_sup)
76 : : {
77 [ + - ]: 1241252 : if (__libdw_read_offset (dbg, dbg_ret, cu_sec_idx (cu),
78 : 1241252 : 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 : : 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 : 284 : if (str_off > (dbg->sectiondata[IDX_debug_str_offsets]->d_size
159 [ - + ]: 142 : - offset_size))
160 : : goto invalid_offset;
161 : :
162 : 284 : 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 : 1241410 : return (const char *) data->d_buf + off;
179 : : }
180 : : INTDEF(dwarf_formstring)
|