Branch data Line data Source code
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 : 34172 : 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 : : {
45 : 34172 : const bool v4_debug_types = v4_type_signaturep != NULL;
46 : 34172 : return __libdw_next_unit (dwarf, v4_debug_types, off, next_off,
47 : : header_sizep, versionp, NULL,
48 : : abbrev_offsetp, address_sizep, offset_sizep,
49 : : v4_type_signaturep, v4_type_offsetp);
50 : : }
51 : : INTDEF(dwarf_next_unit)
52 : :
53 : : int
54 : : internal_function
55 : 81084 : __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 : : {
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 : 81084 : const size_t sec_idx = v4_debug_types ? IDX_debug_types : IDX_debug_info;
67 : :
68 : : /* Maybe there has been an error before. */
69 [ - + ]: 81084 : if (dwarf == NULL)
70 : : return -1;
71 : :
72 : : /* If we reached the end before don't do anything. */
73 [ + - ]: 81084 : if (off == (Dwarf_Off) -1l
74 [ + + ]: 81084 : || 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 [ + + ]: 81038 : || unlikely (off + 4 >= dwarf->sectiondata[sec_idx]->d_size))
79 : : {
80 : 632 : *next_off = (Dwarf_Off) -1l;
81 : 632 : return 1;
82 : : }
83 : :
84 : : /* This points into the .debug_info or .debug_types section to the
85 : : beginning of the CU entry. */
86 : 80452 : const unsigned char *data = dwarf->sectiondata[sec_idx]->d_buf;
87 : 80452 : const unsigned char *bytes = data + off;
88 : 80452 : 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 [ + + ]: 80452 : uint64_t length = read_4ubyte_unaligned_inc (dwarf, bytes);
153 : 80452 : 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 [ + - ]: 80452 : if (length == DWARF3_LENGTH_64_BIT)
158 : : offset_size = 8;
159 [ - + ]: 80452 : else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE
160 : : && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE))
161 : : {
162 : 0 : invalid:
163 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
164 : 0 : return -1;
165 : : }
166 : :
167 : 0 : if (length == DWARF3_LENGTH_64_BIT)
168 : : {
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 : : }
174 : :
175 : : /* Read the version stamp. Always a 16-bit value. */
176 [ - + ]: 80452 : if (bytes_end - bytes < 2)
177 : 0 : goto invalid;
178 [ + + ]: 80452 : 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 : 80452 : uint8_t unit_type = 0;
183 [ + + ]: 80452 : if (version >= 5)
184 : : {
185 [ - + ]: 78722 : if (bytes_end - bytes < 1)
186 : 0 : goto invalid;
187 : 78722 : unit_type = *bytes++;
188 : : }
189 : :
190 : : /* All these are optional. */
191 : 80452 : Dwarf_Off subdie_off = 0;
192 : 80452 : uint64_t sig_id = 0;
193 : 80452 : Dwarf_Off abbrev_offset = 0;
194 : 80452 : uint8_t address_size = 0;
195 : :
196 [ + - ]: 80452 : if (version < 2 || version > 5
197 [ + + ]: 80452 : || (version == 5 && ! (unit_type == DW_UT_compile
198 [ + + ]: 78722 : || unit_type == DW_UT_partial
199 : : || unit_type == DW_UT_skeleton
200 [ - + ]: 154 : || unit_type == DW_UT_split_compile
201 : 0 : || unit_type == DW_UT_type
202 [ # # ]: 0 : || unit_type == DW_UT_split_type)))
203 : : {
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 : : }
208 : :
209 : : /* We have to guess the unit_type. But we don't have a real CUDIE. */
210 [ + + ]: 80452 : if (version < 5)
211 [ + + ]: 1730 : unit_type = v4_debug_types ? DW_UT_type : DW_UT_compile;
212 : :
213 : : /* Now we know how large the header is (should be). */
214 [ - + ]: 80452 : if (unlikely (__libdw_first_die_from_cu_start (off, offset_size, version,
215 : : unit_type)
216 : : >= dwarf->sectiondata[sec_idx]->d_size))
217 : : {
218 : 0 : *next_off = -1;
219 : 0 : return 1;
220 : : }
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 [ + + ]: 80452 : if (version >= 5)
226 : 78722 : 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 [ - + ]: 80452 : if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
231 : : &abbrev_offset, IDX_debug_abbrev, 0))
232 : : return -1;
233 : :
234 [ + + ]: 80452 : if (version < 5)
235 : 1730 : address_size = *bytes++;
236 : :
237 : : /* Extra fields, signature/id and type offset/padding. */
238 [ + + ]: 80452 : if (v4_debug_types
239 [ + + ]: 80400 : || (version >= 5
240 : 78722 : && (unit_type == DW_UT_skeleton || unit_type == DW_UT_split_compile
241 [ + + + - ]: 78722 : || unit_type == DW_UT_type || unit_type == DW_UT_split_type)))
242 : : {
243 [ - + ]: 206 : sig_id = read_8ubyte_unaligned_inc (dwarf, bytes);
244 : :
245 : 206 : if ((v4_debug_types
246 [ + + + - ]: 206 : || unit_type == DW_UT_type || unit_type == DW_UT_split_type))
247 : : {
248 [ - + ]: 52 : if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
249 : : &subdie_off, sec_idx, 0))
250 : : return -1;
251 : :
252 : : /* Validate that the TYPE_OFFSET points past the header. */
253 [ + - ]: 52 : if (unlikely (subdie_off < (size_t) (bytes - (data + off))))
254 : 0 : goto invalid;
255 : : }
256 : : }
257 : :
258 : 80452 : done:
259 [ + + ]: 80452 : if (unit_id8p != NULL)
260 : 46918 : *unit_id8p = sig_id;
261 : :
262 [ + + ]: 80452 : if (subdie_offsetp != NULL)
263 : 46906 : *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 [ + + ]: 80452 : if (header_sizep != NULL)
269 : 33550 : *header_sizep = bytes - (data + off);
270 : :
271 [ + + ]: 80452 : if (versionp != NULL)
272 : 46906 : *versionp = version;
273 : :
274 [ + + ]: 80452 : if (unit_typep != NULL)
275 : 46902 : *unit_typep = unit_type;
276 : :
277 [ + + ]: 80452 : if (abbrev_offsetp != NULL)
278 : 49272 : *abbrev_offsetp = abbrev_offset;
279 : :
280 [ + + ]: 80452 : if (address_sizep != NULL)
281 : 49272 : *address_sizep = address_size;
282 : :
283 : : /* Store the offset size. */
284 [ + + ]: 80452 : if (offset_sizep != NULL)
285 : 49272 : *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 : 80452 : *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 [ - + ]: 80452 : if (*next_off <= off)
295 : 0 : *next_off = (Dwarf_Off) -1;
296 : :
297 : : return 0;
298 : : }
299 : :
300 : : int
301 : 34108 : 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 : : {
305 : 34108 : return INTUSE(dwarf_next_unit) (dwarf, off, next_off, header_sizep, NULL,
306 : : abbrev_offsetp, address_sizep, offset_sizep,
307 : : NULL, NULL);
308 : : }
309 : : INTDEF(dwarf_nextcu)
|