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