/src/elfutils/libdw/dwarf_nextcu.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Advance to next CU header. |
2 | | Copyright (C) 2002-2010, 2016, 2017 Red Hat, Inc. |
3 | | This file is part of elfutils. |
4 | | Written by Ulrich Drepper <drepper@redhat.com>, 2002. |
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 <libdwP.h> |
35 | | #include <dwarf.h> |
36 | | |
37 | | |
38 | | int |
39 | | dwarf_next_unit (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off, |
40 | | size_t *header_sizep, Dwarf_Half *versionp, |
41 | | Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep, |
42 | | uint8_t *offset_sizep, uint64_t *v4_type_signaturep, |
43 | | Dwarf_Off *v4_type_offsetp) |
44 | 0 | { |
45 | 0 | const bool v4_debug_types = v4_type_signaturep != NULL; |
46 | 0 | return __libdw_next_unit (dwarf, v4_debug_types, off, next_off, |
47 | 0 | header_sizep, versionp, NULL, |
48 | 0 | abbrev_offsetp, address_sizep, offset_sizep, |
49 | 0 | v4_type_signaturep, v4_type_offsetp); |
50 | 0 | } |
51 | | INTDEF(dwarf_next_unit) |
52 | | |
53 | | int |
54 | | internal_function |
55 | | __libdw_next_unit (Dwarf *dwarf, bool v4_debug_types, Dwarf_Off off, |
56 | | Dwarf_Off *next_off, size_t *header_sizep, |
57 | | Dwarf_Half *versionp, uint8_t *unit_typep, |
58 | | Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep, |
59 | | uint8_t *offset_sizep, uint64_t *unit_id8p, |
60 | | Dwarf_Off *subdie_offsetp) |
61 | 0 | { |
62 | | /* Note that debug_type units come from .debug_types in DWARF < 5 and |
63 | | from .debug_info in DWARF >= 5. If the user requested the |
64 | | v4_type_signature we return from .debug_types always. If no signature |
65 | | is requested we return units (any type) from .debug_info. */ |
66 | 0 | const size_t sec_idx = v4_debug_types ? IDX_debug_types : IDX_debug_info; |
67 | | |
68 | | /* Maybe there has been an error before. */ |
69 | 0 | if (dwarf == NULL) |
70 | 0 | return -1; |
71 | | |
72 | | /* If we reached the end before don't do anything. */ |
73 | 0 | if (off == (Dwarf_Off) -1l |
74 | 0 | || unlikely (dwarf->sectiondata[sec_idx] == NULL) |
75 | | /* Make sure there is enough space in the .debug_info section |
76 | | for at least the initial word. We cannot test the rest since |
77 | | we don't know yet whether this is a 64-bit object or not. */ |
78 | 0 | || unlikely (off + 4 >= dwarf->sectiondata[sec_idx]->d_size)) |
79 | 0 | { |
80 | 0 | *next_off = (Dwarf_Off) -1l; |
81 | 0 | return 1; |
82 | 0 | } |
83 | | |
84 | | /* This points into the .debug_info or .debug_types section to the |
85 | | beginning of the CU entry. */ |
86 | 0 | const unsigned char *data = dwarf->sectiondata[sec_idx]->d_buf; |
87 | 0 | const unsigned char *bytes = data + off; |
88 | 0 | const unsigned char *bytes_end = data + dwarf->sectiondata[sec_idx]->d_size; |
89 | | |
90 | | /* The format of the CU header is described in dwarf2p1 7.5.1 and |
91 | | changed in DWARFv5 (to include unit type, switch location of some |
92 | | fields and add some optional fields). |
93 | | |
94 | | 1. A 4-byte or 12-byte unsigned integer representing the length |
95 | | of the .debug_info contribution for that compilation unit, not |
96 | | including the length field itself. In the 32-bit DWARF format, |
97 | | this is a 4-byte unsigned integer (which must be less than |
98 | | 0xfffffff0); in the 64-bit DWARF format, this consists of the |
99 | | 4-byte value 0xffffffff followed by an 8-byte unsigned integer |
100 | | that gives the actual length (see Section 7.2.2). This field |
101 | | indicates whether this unit is 32-bit of 64-bit DWARF, which |
102 | | affects all other offset fields in this header. |
103 | | |
104 | | 2. A 2-byte unsigned integer representing the version of the |
105 | | DWARF information for that compilation unit. For DWARF Version |
106 | | 2.1, the value in this field is 2 (3 for v3, 4 for v4, 5 for v5). |
107 | | This fields determines the order of the next fields and whether |
108 | | there are any optional fields in this header. |
109 | | |
110 | | 3. For DWARF 2, 3 and 4 (including v4 type units): |
111 | | A 4-byte or 8-byte unsigned offset into the .debug_abbrev |
112 | | section. This offset associates the compilation unit with a |
113 | | particular set of debugging information entry abbreviations. In |
114 | | the 32-bit DWARF format, this is a 4-byte unsigned length; in |
115 | | the 64-bit DWARF format, this is an 8-byte unsigned length (see |
116 | | Section 7.4). |
117 | | |
118 | | For DWARF 5: |
119 | | A 1-byte unsigned integer representing the unit (header) type. |
120 | | This field determines what the optional fields in the header |
121 | | represent. If this is an unknown unit type then we cannot |
122 | | assume anything about the rest of the unit (header). |
123 | | |
124 | | 4. For all DWARF versions (including v4 type units): |
125 | | A 1-byte unsigned integer representing the size in bytes of |
126 | | an address on the target architecture. If the system uses |
127 | | segmented addressing, this value represents the size of the |
128 | | offset portion of an address. This is the last field in the header |
129 | | for DWARF versions 2, 3 and 4 (except for v4 type units). |
130 | | |
131 | | 5. For DWARF 5 only (this is field 3 for DWARF 2, 3, 4 and v4 types): |
132 | | A 4-byte or 8-byte unsigned offset into the .debug_abbrev |
133 | | section. This offset associates the compilation unit with a |
134 | | particular set of debugging information entry abbreviations. In |
135 | | the 32-bit DWARF format, this is a 4-byte unsigned length; in |
136 | | the 64-bit DWARF format, this is an 8-byte unsigned length. |
137 | | |
138 | | 6. For v4 type units (this is really field 5 for v4 types) and |
139 | | DWARF 5 optional (skeleton, split_compile, type and |
140 | | split_type): An 8 byte (opaque) integer constant value. For |
141 | | v4 and v5 type units this is the type signature. For skeleton |
142 | | and split compile units this is the compilation ID. |
143 | | |
144 | | 7. For v4 type units (this is really field 6 for v4 types) and |
145 | | DWARF 5 optional (type and split_type) and v4 type units: |
146 | | A 4-byte or 8-byte unsigned offset. In the 32-bit DWARF format, |
147 | | this is a 4-byte unsigned length; in the 64-bit DWARF format, |
148 | | this is an 8-byte unsigned length. This is the type DIE offset |
149 | | (which is not necessarily the first DIE in the unit). |
150 | | */ |
151 | |
|
152 | 0 | uint64_t length = read_4ubyte_unaligned_inc (dwarf, bytes); |
153 | 0 | size_t offset_size = 4; |
154 | | /* Lengths of 0xfffffff0 - 0xffffffff are escape codes. Oxffffffff is |
155 | | used to indicate that 64-bit dwarf information is being used, the |
156 | | other values are currently reserved. */ |
157 | 0 | if (length == DWARF3_LENGTH_64_BIT) |
158 | 0 | offset_size = 8; |
159 | 0 | else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE |
160 | 0 | && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE)) |
161 | 0 | { |
162 | 0 | invalid: |
163 | 0 | __libdw_seterrno (DWARF_E_INVALID_DWARF); |
164 | 0 | return -1; |
165 | 0 | } |
166 | | |
167 | 0 | if (length == DWARF3_LENGTH_64_BIT) |
168 | 0 | { |
169 | | /* This is a 64-bit DWARF format. */ |
170 | 0 | if (bytes_end - bytes < 8) |
171 | 0 | goto invalid; |
172 | 0 | length = read_8ubyte_unaligned_inc (dwarf, bytes); |
173 | 0 | } |
174 | | |
175 | | /* Read the version stamp. Always a 16-bit value. */ |
176 | 0 | if (bytes_end - bytes < 2) |
177 | 0 | goto invalid; |
178 | 0 | uint_fast16_t version = read_2ubyte_unaligned_inc (dwarf, bytes); |
179 | | |
180 | | /* We keep unit_type at zero for older DWARF since we cannot |
181 | | easily guess whether it is a compile or partial unit. */ |
182 | 0 | uint8_t unit_type = 0; |
183 | 0 | if (version >= 5) |
184 | 0 | { |
185 | 0 | if (bytes_end - bytes < 1) |
186 | 0 | goto invalid; |
187 | 0 | unit_type = *bytes++; |
188 | 0 | } |
189 | | |
190 | | /* All these are optional. */ |
191 | 0 | Dwarf_Off subdie_off = 0; |
192 | 0 | uint64_t sig_id = 0; |
193 | 0 | Dwarf_Off abbrev_offset = 0; |
194 | 0 | uint8_t address_size = 0; |
195 | |
|
196 | 0 | if (version < 2 || version > 5 |
197 | 0 | || (version == 5 && ! (unit_type == DW_UT_compile |
198 | 0 | || unit_type == DW_UT_partial |
199 | 0 | || unit_type == DW_UT_skeleton |
200 | 0 | || unit_type == DW_UT_split_compile |
201 | 0 | || unit_type == DW_UT_type |
202 | 0 | || unit_type == DW_UT_split_type))) |
203 | 0 | { |
204 | | /* We cannot really know more about the header. Just report |
205 | | the length of the unit, version and unit type. */ |
206 | 0 | goto done; |
207 | 0 | } |
208 | | |
209 | | /* We have to guess the unit_type. But we don't have a real CUDIE. */ |
210 | 0 | if (version < 5) |
211 | 0 | unit_type = v4_debug_types ? DW_UT_type : DW_UT_compile; |
212 | | |
213 | | /* Now we know how large the header is (should be). */ |
214 | 0 | if (unlikely (__libdw_first_die_from_cu_start (off, offset_size, version, |
215 | 0 | unit_type) |
216 | 0 | >= dwarf->sectiondata[sec_idx]->d_size)) |
217 | 0 | { |
218 | 0 | *next_off = -1; |
219 | 0 | return 1; |
220 | 0 | } |
221 | | |
222 | | /* The address size. Always an 8-bit value. |
223 | | Comes after abbrev_offset for version < 5, otherwise unit type |
224 | | and address size (if a known unit type) comes before abbrev_offset. */ |
225 | 0 | if (version >= 5) |
226 | 0 | address_size = *bytes++; |
227 | | |
228 | | /* Get offset in .debug_abbrev. Note that the size of the entry |
229 | | depends on whether this is a 32-bit or 64-bit DWARF definition. */ |
230 | 0 | if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size, |
231 | 0 | &abbrev_offset, IDX_debug_abbrev, 0)) |
232 | 0 | return -1; |
233 | | |
234 | 0 | if (version < 5) |
235 | 0 | address_size = *bytes++; |
236 | | |
237 | | /* Extra fields, signature/id and type offset/padding. */ |
238 | 0 | if (v4_debug_types |
239 | 0 | || (version >= 5 |
240 | 0 | && (unit_type == DW_UT_skeleton || unit_type == DW_UT_split_compile |
241 | 0 | || unit_type == DW_UT_type || unit_type == DW_UT_split_type))) |
242 | 0 | { |
243 | 0 | sig_id = read_8ubyte_unaligned_inc (dwarf, bytes); |
244 | |
|
245 | 0 | if ((v4_debug_types |
246 | 0 | || unit_type == DW_UT_type || unit_type == DW_UT_split_type)) |
247 | 0 | { |
248 | 0 | if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size, |
249 | 0 | &subdie_off, sec_idx, 0)) |
250 | 0 | return -1; |
251 | | |
252 | | /* Validate that the TYPE_OFFSET points past the header. */ |
253 | 0 | if (unlikely (subdie_off < (size_t) (bytes - (data + off)))) |
254 | 0 | goto invalid; |
255 | 0 | } |
256 | 0 | } |
257 | | |
258 | 0 | done: |
259 | 0 | if (unit_id8p != NULL) |
260 | 0 | *unit_id8p = sig_id; |
261 | |
|
262 | 0 | if (subdie_offsetp != NULL) |
263 | 0 | *subdie_offsetp = subdie_off; |
264 | | |
265 | | /* Store the header length. This is really how much we have read |
266 | | from the header. If we didn't recognize the unit type the |
267 | | header might actually be bigger. */ |
268 | 0 | if (header_sizep != NULL) |
269 | 0 | *header_sizep = bytes - (data + off); |
270 | |
|
271 | 0 | if (versionp != NULL) |
272 | 0 | *versionp = version; |
273 | |
|
274 | 0 | if (unit_typep != NULL) |
275 | 0 | *unit_typep = unit_type; |
276 | |
|
277 | 0 | if (abbrev_offsetp != NULL) |
278 | 0 | *abbrev_offsetp = abbrev_offset; |
279 | |
|
280 | 0 | if (address_sizep != NULL) |
281 | 0 | *address_sizep = address_size; |
282 | | |
283 | | /* Store the offset size. */ |
284 | 0 | if (offset_sizep != NULL) |
285 | 0 | *offset_sizep = offset_size; |
286 | | |
287 | | /* The length of the unit doesn't include the length field itself. |
288 | | The length field is either, with offset == 4: 2 * 4 - 4 == 4, |
289 | | or with offset == 8: 2 * 8 - 4 == 12. */ |
290 | 0 | *next_off = off + 2 * offset_size - 4 + length; |
291 | | |
292 | | /* This means that the length field is bogus, but return the CU anyway. |
293 | | We just won't return anything after this. */ |
294 | 0 | if (*next_off <= off) |
295 | 0 | *next_off = (Dwarf_Off) -1; |
296 | |
|
297 | 0 | return 0; |
298 | 0 | } |
299 | | |
300 | | int |
301 | | dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off, |
302 | | size_t *header_sizep, Dwarf_Off *abbrev_offsetp, |
303 | | uint8_t *address_sizep, uint8_t *offset_sizep) |
304 | 0 | { |
305 | 0 | return INTUSE(dwarf_next_unit) (dwarf, off, next_off, header_sizep, NULL, |
306 | 0 | abbrev_offsetp, address_sizep, offset_sizep, |
307 | 0 | NULL, NULL); |
308 | 0 | } |
309 | | INTDEF(dwarf_nextcu) |