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