xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_arange.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1bc1f688bSRobert Mustacchi /*
2bc1f688bSRobert Mustacchi 
3bc1f688bSRobert Mustacchi   Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
4*4d9fdb46SRobert Mustacchi   Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved.
5*4d9fdb46SRobert Mustacchi   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
6*4d9fdb46SRobert Mustacchi 
7bc1f688bSRobert Mustacchi 
8bc1f688bSRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
9bc1f688bSRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
10bc1f688bSRobert Mustacchi   as published by the Free Software Foundation.
11bc1f688bSRobert Mustacchi 
12bc1f688bSRobert Mustacchi   This program is distributed in the hope that it would be useful, but
13bc1f688bSRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
14bc1f688bSRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15bc1f688bSRobert Mustacchi 
16bc1f688bSRobert Mustacchi   Further, this software is distributed without any warranty that it is
17bc1f688bSRobert Mustacchi   free of the rightful claim of any third person regarding infringement
18bc1f688bSRobert Mustacchi   or the like.  Any license provided herein, whether implied or
19bc1f688bSRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
20bc1f688bSRobert Mustacchi   any, provided herein do not apply to combinations of this program with
21bc1f688bSRobert Mustacchi   other software, or any other product whatsoever.
22bc1f688bSRobert Mustacchi 
23bc1f688bSRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
24bc1f688bSRobert Mustacchi   License along with this program; if not, write the Free Software
25bc1f688bSRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
26bc1f688bSRobert Mustacchi   USA.
27bc1f688bSRobert Mustacchi 
28bc1f688bSRobert Mustacchi */
29bc1f688bSRobert Mustacchi 
30bc1f688bSRobert Mustacchi #include "config.h"
31bc1f688bSRobert Mustacchi #include <stdio.h>
32*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
33*4d9fdb46SRobert Mustacchi #include "dwarf_alloc.h"
34*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
35*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
36bc1f688bSRobert Mustacchi #include "dwarf_arange.h"
37bc1f688bSRobert Mustacchi #include "dwarf_global.h"  /* for _dwarf_fixup_* */
38*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
39bc1f688bSRobert Mustacchi 
40*4d9fdb46SRobert Mustacchi static void
free_aranges_chain(Dwarf_Debug dbg,Dwarf_Chain head)41*4d9fdb46SRobert Mustacchi free_aranges_chain(Dwarf_Debug dbg, Dwarf_Chain head)
42*4d9fdb46SRobert Mustacchi {
43*4d9fdb46SRobert Mustacchi     Dwarf_Chain cur = head;
44*4d9fdb46SRobert Mustacchi     Dwarf_Chain next = 0;
45*4d9fdb46SRobert Mustacchi 
46*4d9fdb46SRobert Mustacchi     if(!head) {
47*4d9fdb46SRobert Mustacchi         return;
48*4d9fdb46SRobert Mustacchi     }
49*4d9fdb46SRobert Mustacchi     next = head->ch_next;
50*4d9fdb46SRobert Mustacchi     for( ;cur; cur = next) {
51*4d9fdb46SRobert Mustacchi         void *item = cur->ch_item;
52*4d9fdb46SRobert Mustacchi         int  type = cur->ch_itemtype;
53*4d9fdb46SRobert Mustacchi 
54*4d9fdb46SRobert Mustacchi         next = cur->ch_next;
55*4d9fdb46SRobert Mustacchi         if (item && type) {
56*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,item,type);
57*4d9fdb46SRobert Mustacchi             cur->ch_item = 0;
58*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,cur,DW_DLA_CHAIN);
59*4d9fdb46SRobert Mustacchi         }
60*4d9fdb46SRobert Mustacchi     }
61*4d9fdb46SRobert Mustacchi }
62bc1f688bSRobert Mustacchi 
63bc1f688bSRobert Mustacchi /*  Common code for two user-visible routines to share.
64bc1f688bSRobert Mustacchi     Errors here result in memory leaks, but errors here
65bc1f688bSRobert Mustacchi     are serious (making aranges unusable) so we assume
66bc1f688bSRobert Mustacchi     callers will not repeat the error often or mind the leaks.
67bc1f688bSRobert Mustacchi */
68bc1f688bSRobert Mustacchi static int
dwarf_get_aranges_list(Dwarf_Debug dbg,Dwarf_Chain * chain_out,Dwarf_Signed * chain_count_out,Dwarf_Error * error)69bc1f688bSRobert Mustacchi dwarf_get_aranges_list(Dwarf_Debug dbg,
70bc1f688bSRobert Mustacchi     Dwarf_Chain  * chain_out,
71bc1f688bSRobert Mustacchi     Dwarf_Signed * chain_count_out,
72bc1f688bSRobert Mustacchi     Dwarf_Error  * error)
73bc1f688bSRobert Mustacchi {
74bc1f688bSRobert Mustacchi     /* Sweeps through the arange. */
75bc1f688bSRobert Mustacchi     Dwarf_Small *arange_ptr = 0;
76bc1f688bSRobert Mustacchi     Dwarf_Small *arange_ptr_start = 0;
77bc1f688bSRobert Mustacchi 
78bc1f688bSRobert Mustacchi     /*  Start of arange header.  Used for rounding offset of arange_ptr
79bc1f688bSRobert Mustacchi         to twice the tuple size.  Libdwarf requirement. */
80bc1f688bSRobert Mustacchi     Dwarf_Small *header_ptr = 0;
81bc1f688bSRobert Mustacchi 
82bc1f688bSRobert Mustacchi     /*  Version of .debug_aranges header. */
83*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned version = 0;
84bc1f688bSRobert Mustacchi 
85bc1f688bSRobert Mustacchi     /*  Offset of current set of aranges into .debug_info. */
86bc1f688bSRobert Mustacchi     Dwarf_Off info_offset = 0;
87bc1f688bSRobert Mustacchi     /*  Size in bytes of addresses in target. */
88bc1f688bSRobert Mustacchi     Dwarf_Small address_size = 0;
89bc1f688bSRobert Mustacchi     /*  Size in bytes of segment offsets in target. */
90bc1f688bSRobert Mustacchi     Dwarf_Small segment_size = 0;
91bc1f688bSRobert Mustacchi     /*  Count of total number of aranges. */
92*4d9fdb46SRobert Mustacchi     Dwarf_Signed arange_count = 0;
93bc1f688bSRobert Mustacchi     Dwarf_Arange arange = 0;
94*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned section_size = 0;
95*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr arange_end_section = 0;
96bc1f688bSRobert Mustacchi     /*  Used to chain Dwarf_Aranges structs. */
97bc1f688bSRobert Mustacchi     Dwarf_Chain curr_chain = NULL;
98bc1f688bSRobert Mustacchi     Dwarf_Chain prev_chain = NULL;
99bc1f688bSRobert Mustacchi     Dwarf_Chain head_chain = NULL;
100bc1f688bSRobert Mustacchi 
101*4d9fdb46SRobert Mustacchi     if (!dbg->de_debug_aranges.dss_size) {
102*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
103*4d9fdb46SRobert Mustacchi     }
104bc1f688bSRobert Mustacchi     arange_ptr = dbg->de_debug_aranges.dss_data;
105bc1f688bSRobert Mustacchi     arange_ptr_start = arange_ptr;
106*4d9fdb46SRobert Mustacchi     section_size = dbg->de_debug_aranges.dss_size;
107*4d9fdb46SRobert Mustacchi     arange_end_section = arange_ptr + section_size;
108*4d9fdb46SRobert Mustacchi 
109bc1f688bSRobert Mustacchi     do {
110*4d9fdb46SRobert Mustacchi         /*  Length of current set of aranges.
111*4d9fdb46SRobert Mustacchi             This is local length, which begins just
112*4d9fdb46SRobert Mustacchi             after the length field itself. */
113*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned area_length = 0;
114bc1f688bSRobert Mustacchi         Dwarf_Small remainder = 0;
115bc1f688bSRobert Mustacchi         Dwarf_Unsigned range_entry_size = 0;
116bc1f688bSRobert Mustacchi         int local_length_size;
117bc1f688bSRobert Mustacchi         int local_extension_size = 0;
118*4d9fdb46SRobert Mustacchi         Dwarf_Small *end_this_arange = 0;
119*4d9fdb46SRobert Mustacchi         int res = 0;
120*4d9fdb46SRobert Mustacchi 
121bc1f688bSRobert Mustacchi 
122bc1f688bSRobert Mustacchi         header_ptr = arange_ptr;
123*4d9fdb46SRobert Mustacchi         if (header_ptr >= arange_end_section) {
124*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
125*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR);
126*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
127*4d9fdb46SRobert Mustacchi         }
128*4d9fdb46SRobert Mustacchi         res = _dwarf_read_area_length_ck_wrapper(dbg,&area_length,
129*4d9fdb46SRobert Mustacchi             &arange_ptr,&local_length_size,&local_extension_size,
130*4d9fdb46SRobert Mustacchi             section_size,arange_end_section,error);
131*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
132*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
133*4d9fdb46SRobert Mustacchi             return res;
134*4d9fdb46SRobert Mustacchi         }
135*4d9fdb46SRobert Mustacchi         /*  arange_ptr has been incremented appropriately past
136*4d9fdb46SRobert Mustacchi             the length field by READ_AREA_LENGTH. */
137bc1f688bSRobert Mustacchi 
138*4d9fdb46SRobert Mustacchi         if (area_length >  dbg->de_debug_aranges.dss_size) {
139*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
140*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR);
141*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
142*4d9fdb46SRobert Mustacchi         }
143*4d9fdb46SRobert Mustacchi         if ((area_length + local_length_size + local_extension_size) >
144*4d9fdb46SRobert Mustacchi             dbg->de_debug_aranges.dss_size) {
145*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
146*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR);
147*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
148*4d9fdb46SRobert Mustacchi         }
149bc1f688bSRobert Mustacchi 
150*4d9fdb46SRobert Mustacchi         end_this_arange = arange_ptr + area_length;
151*4d9fdb46SRobert Mustacchi         if (end_this_arange > arange_end_section) {
152*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
153*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR);
154*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
155*4d9fdb46SRobert Mustacchi         }
156*4d9fdb46SRobert Mustacchi         if (!area_length) {
157*4d9fdb46SRobert Mustacchi             /*  We read 4 bytes of zero, so area-length zero.
158*4d9fdb46SRobert Mustacchi                 Keep scanning. First seen Nov 27, 2018
159*4d9fdb46SRobert Mustacchi                 in GNU-cc in windows dll. */
160*4d9fdb46SRobert Mustacchi             continue;
161*4d9fdb46SRobert Mustacchi         }
162bc1f688bSRobert Mustacchi 
163*4d9fdb46SRobert Mustacchi         res = _dwarf_read_unaligned_ck_wrapper(dbg,&version,
164*4d9fdb46SRobert Mustacchi             arange_ptr,DWARF_HALF_SIZE,end_this_arange,error);
165*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
166*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
167*4d9fdb46SRobert Mustacchi             return res;
168*4d9fdb46SRobert Mustacchi         }
169*4d9fdb46SRobert Mustacchi         arange_ptr += DWARF_HALF_SIZE;
170*4d9fdb46SRobert Mustacchi         if (arange_ptr >= end_this_arange) {
171*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
172*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR);
173*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
174*4d9fdb46SRobert Mustacchi         }
175*4d9fdb46SRobert Mustacchi         if (version != DW_ARANGES_VERSION2) {
176*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
177bc1f688bSRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
178bc1f688bSRobert Mustacchi             return (DW_DLV_ERROR);
179bc1f688bSRobert Mustacchi         }
180*4d9fdb46SRobert Mustacchi         res = _dwarf_read_unaligned_ck_wrapper(dbg,&info_offset,
181*4d9fdb46SRobert Mustacchi             arange_ptr,local_length_size,end_this_arange,error);
182*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
183*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
184*4d9fdb46SRobert Mustacchi             return res;
185*4d9fdb46SRobert Mustacchi         }
186bc1f688bSRobert Mustacchi 
187bc1f688bSRobert Mustacchi         arange_ptr += local_length_size;
188*4d9fdb46SRobert Mustacchi         if (arange_ptr >= end_this_arange) {
189*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
190*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR);
191*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
192*4d9fdb46SRobert Mustacchi         }
193*4d9fdb46SRobert Mustacchi         /* This applies to debug_info only, not to debug_types. */
194bc1f688bSRobert Mustacchi         if (info_offset >= dbg->de_debug_info.dss_size) {
195bc1f688bSRobert Mustacchi             FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset,
196bc1f688bSRobert Mustacchi                 "arange info offset.a");
197bc1f688bSRobert Mustacchi             if (info_offset >= dbg->de_debug_info.dss_size) {
198*4d9fdb46SRobert Mustacchi                 free_aranges_chain(dbg,head_chain);
199bc1f688bSRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
200bc1f688bSRobert Mustacchi                 return (DW_DLV_ERROR);
201bc1f688bSRobert Mustacchi             }
202bc1f688bSRobert Mustacchi         }
203bc1f688bSRobert Mustacchi 
204bc1f688bSRobert Mustacchi         address_size = *(Dwarf_Small *) arange_ptr;
205*4d9fdb46SRobert Mustacchi         if (address_size  > sizeof(Dwarf_Addr)) {
206*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
207*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ERROR);
208*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
209*4d9fdb46SRobert Mustacchi         }
210*4d9fdb46SRobert Mustacchi         if (address_size  ==  0) {
211*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
212*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ZERO);
213*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
214*4d9fdb46SRobert Mustacchi         }
215bc1f688bSRobert Mustacchi         /*  It is not an error if the sizes differ.
216bc1f688bSRobert Mustacchi             Unusual, but not an error. */
217bc1f688bSRobert Mustacchi         arange_ptr = arange_ptr + sizeof(Dwarf_Small);
218bc1f688bSRobert Mustacchi 
219*4d9fdb46SRobert Mustacchi         /*  The following deref means we better
220*4d9fdb46SRobert Mustacchi             check the pointer for off-end. */
221*4d9fdb46SRobert Mustacchi         if (arange_ptr >= end_this_arange) {
222*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
223*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
224*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
225*4d9fdb46SRobert Mustacchi         }
226*4d9fdb46SRobert Mustacchi 
227*4d9fdb46SRobert Mustacchi         /*  Even DWARF2 had a segment_size field here, meaning
228*4d9fdb46SRobert Mustacchi             size in bytes of a segment descriptor on the target
229*4d9fdb46SRobert Mustacchi             system. */
230bc1f688bSRobert Mustacchi         segment_size = *(Dwarf_Small *) arange_ptr;
231*4d9fdb46SRobert Mustacchi         if (segment_size > sizeof(Dwarf_Addr)) {
232*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
233bc1f688bSRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
234bc1f688bSRobert Mustacchi             return (DW_DLV_ERROR);
235bc1f688bSRobert Mustacchi         }
236*4d9fdb46SRobert Mustacchi         arange_ptr = arange_ptr + sizeof(Dwarf_Small);
237*4d9fdb46SRobert Mustacchi 
238*4d9fdb46SRobert Mustacchi         /* Code below will check for == end_this_arange as appropriate. */
239*4d9fdb46SRobert Mustacchi         if (arange_ptr > end_this_arange) {
240*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
241*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
242*4d9fdb46SRobert Mustacchi             return (DW_DLV_ERROR);
243*4d9fdb46SRobert Mustacchi         }
244bc1f688bSRobert Mustacchi 
245bc1f688bSRobert Mustacchi         range_entry_size = 2*address_size + segment_size;
246bc1f688bSRobert Mustacchi         /* Round arange_ptr offset to next multiple of address_size. */
247bc1f688bSRobert Mustacchi         remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) %
248bc1f688bSRobert Mustacchi             (range_entry_size);
249bc1f688bSRobert Mustacchi         if (remainder != 0) {
250bc1f688bSRobert Mustacchi             arange_ptr = arange_ptr + (2 * address_size) - remainder;
251bc1f688bSRobert Mustacchi         }
252*4d9fdb46SRobert Mustacchi 
253bc1f688bSRobert Mustacchi         do {
254bc1f688bSRobert Mustacchi             Dwarf_Addr range_address = 0;
255bc1f688bSRobert Mustacchi             Dwarf_Unsigned segment_selector = 0;
256bc1f688bSRobert Mustacchi             Dwarf_Unsigned range_length = 0;
257bc1f688bSRobert Mustacchi             /*  For segmented address spaces, the first field to
258*4d9fdb46SRobert Mustacchi                 read is a segment selector (new in DWARF4).
259*4d9fdb46SRobert Mustacchi                 The version number DID NOT CHANGE from 2, which
260*4d9fdb46SRobert Mustacchi                 is quite surprising.
261*4d9fdb46SRobert Mustacchi                 Also surprising since the segment_size
262*4d9fdb46SRobert Mustacchi                 was always there
263*4d9fdb46SRobert Mustacchi                 in the table header! */
264*4d9fdb46SRobert Mustacchi             /*  We want to test cu_version here but
265*4d9fdb46SRobert Mustacchi                 currently with no way to do that.
266*4d9fdb46SRobert Mustacchi                 So we just hope no one using
267*4d9fdb46SRobert Mustacchi                 segment_selectors, really. FIXME */
268*4d9fdb46SRobert Mustacchi             if (segment_size) {
269*4d9fdb46SRobert Mustacchi                 /*  Only applies if cu_version >= 4. */
270*4d9fdb46SRobert Mustacchi                 res = _dwarf_read_unaligned_ck_wrapper(dbg,
271*4d9fdb46SRobert Mustacchi                     &segment_selector,
272*4d9fdb46SRobert Mustacchi                     arange_ptr,segment_size,end_this_arange,error);
273*4d9fdb46SRobert Mustacchi                 if (res != DW_DLV_OK) {
274*4d9fdb46SRobert Mustacchi                     free_aranges_chain(dbg,head_chain);
275*4d9fdb46SRobert Mustacchi                     return res;
276*4d9fdb46SRobert Mustacchi                 }
277bc1f688bSRobert Mustacchi                 arange_ptr += address_size;
278bc1f688bSRobert Mustacchi             }
279bc1f688bSRobert Mustacchi 
280*4d9fdb46SRobert Mustacchi             res = _dwarf_read_unaligned_ck_wrapper(dbg,&range_address,
281*4d9fdb46SRobert Mustacchi                 arange_ptr,address_size,end_this_arange,error);
282*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
283*4d9fdb46SRobert Mustacchi                 free_aranges_chain(dbg,head_chain);
284*4d9fdb46SRobert Mustacchi                 return res;
285*4d9fdb46SRobert Mustacchi             }
286bc1f688bSRobert Mustacchi             arange_ptr += address_size;
287bc1f688bSRobert Mustacchi 
288*4d9fdb46SRobert Mustacchi             res = _dwarf_read_unaligned_ck_wrapper(dbg,&range_length,
289*4d9fdb46SRobert Mustacchi                 arange_ptr,address_size,end_this_arange,error);
290*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
291*4d9fdb46SRobert Mustacchi                 free_aranges_chain(dbg,head_chain);
292*4d9fdb46SRobert Mustacchi                 return res;
293*4d9fdb46SRobert Mustacchi             }
294*4d9fdb46SRobert Mustacchi 
295bc1f688bSRobert Mustacchi             arange_ptr += address_size;
296bc1f688bSRobert Mustacchi 
297*4d9fdb46SRobert Mustacchi             {
298*4d9fdb46SRobert Mustacchi                 /*  We used to suppress all-zero entries, but
299bc1f688bSRobert Mustacchi                     now we return all aranges entries so we show
300bc1f688bSRobert Mustacchi                     the entire content.  March 31, 2010. */
301bc1f688bSRobert Mustacchi 
302bc1f688bSRobert Mustacchi                 arange = (Dwarf_Arange)
303bc1f688bSRobert Mustacchi                     _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
304bc1f688bSRobert Mustacchi                 if (arange == NULL) {
305*4d9fdb46SRobert Mustacchi                     free_aranges_chain(dbg,head_chain);
306bc1f688bSRobert Mustacchi                     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
307bc1f688bSRobert Mustacchi                     return (DW_DLV_ERROR);
308bc1f688bSRobert Mustacchi                 }
309bc1f688bSRobert Mustacchi 
310bc1f688bSRobert Mustacchi                 arange->ar_segment_selector = segment_selector;
311bc1f688bSRobert Mustacchi                 arange->ar_segment_selector_size = segment_size;
312bc1f688bSRobert Mustacchi                 arange->ar_address = range_address;
313bc1f688bSRobert Mustacchi                 arange->ar_length = range_length;
314bc1f688bSRobert Mustacchi                 arange->ar_info_offset = info_offset;
315bc1f688bSRobert Mustacchi                 arange->ar_dbg = dbg;
316bc1f688bSRobert Mustacchi                 arange_count++;
317bc1f688bSRobert Mustacchi 
318bc1f688bSRobert Mustacchi                 curr_chain = (Dwarf_Chain)
319bc1f688bSRobert Mustacchi                     _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
320bc1f688bSRobert Mustacchi                 if (curr_chain == NULL) {
321*4d9fdb46SRobert Mustacchi                     free_aranges_chain(dbg,head_chain);
322bc1f688bSRobert Mustacchi                     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
323bc1f688bSRobert Mustacchi                     return (DW_DLV_ERROR);
324bc1f688bSRobert Mustacchi                 }
325bc1f688bSRobert Mustacchi 
326bc1f688bSRobert Mustacchi                 curr_chain->ch_item = arange;
327*4d9fdb46SRobert Mustacchi                 curr_chain->ch_itemtype = DW_DLA_ARANGE;
328bc1f688bSRobert Mustacchi                 if (head_chain == NULL)
329bc1f688bSRobert Mustacchi                     head_chain = prev_chain = curr_chain;
330bc1f688bSRobert Mustacchi                 else {
331bc1f688bSRobert Mustacchi                     prev_chain->ch_next = curr_chain;
332bc1f688bSRobert Mustacchi                     prev_chain = curr_chain;
333bc1f688bSRobert Mustacchi                 }
334bc1f688bSRobert Mustacchi             }
335bc1f688bSRobert Mustacchi             /*  The current set of ranges is terminated by
336bc1f688bSRobert Mustacchi                 range_address 0 and range_length 0, but that
337bc1f688bSRobert Mustacchi                 does not necessarily terminate the ranges for this CU!
338bc1f688bSRobert Mustacchi                 There can be multiple sets in that DWARF
339bc1f688bSRobert Mustacchi                 does not explicitly forbid multiple sets.
340bc1f688bSRobert Mustacchi                 DWARF2,3,4 section 7.20
341*4d9fdb46SRobert Mustacchi                 We stop short to avoid overrun of the end of the CU.  */
342bc1f688bSRobert Mustacchi 
343*4d9fdb46SRobert Mustacchi         } while (end_this_arange >= (arange_ptr + range_entry_size));
344bc1f688bSRobert Mustacchi 
345bc1f688bSRobert Mustacchi         /*  A compiler could emit some padding bytes here. dwarf2/3
346bc1f688bSRobert Mustacchi             (dwarf4 sec 7.20) does not clearly make extra padding
347bc1f688bSRobert Mustacchi             bytes illegal. */
348*4d9fdb46SRobert Mustacchi         if (end_this_arange < arange_ptr) {
349*4d9fdb46SRobert Mustacchi             Dwarf_Unsigned pad_count = arange_ptr - end_this_arange;
350bc1f688bSRobert Mustacchi             Dwarf_Unsigned offset = arange_ptr - arange_ptr_start;
351*4d9fdb46SRobert Mustacchi             dwarfstring aramsg;
352bc1f688bSRobert Mustacchi 
353*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&aramsg);
354*4d9fdb46SRobert Mustacchi             /* Safe. Length strictly limited. */
355*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&aramsg,
356*4d9fdb46SRobert Mustacchi                 "DW_DLE_ARANGE_LENGTH_BAD."
357*4d9fdb46SRobert Mustacchi                 " 0x%" DW_PR_XZEROS DW_PR_DUx,
358*4d9fdb46SRobert Mustacchi                 pad_count);
359*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&aramsg,
360*4d9fdb46SRobert Mustacchi                 " pad bytes at offset 0x%" DW_PR_XZEROS DW_PR_DUx
361*4d9fdb46SRobert Mustacchi                 " in .debug_aranges",
362*4d9fdb46SRobert Mustacchi                 offset);
363*4d9fdb46SRobert Mustacchi             dwarf_insert_harmless_error(dbg,
364*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&aramsg));
365*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&aramsg);
366*4d9fdb46SRobert Mustacchi         }
367*4d9fdb46SRobert Mustacchi         /*  For most compilers, arange_ptr == end_this_arange at
368*4d9fdb46SRobert Mustacchi             this point. But not if there were padding bytes */
369*4d9fdb46SRobert Mustacchi         arange_ptr = end_this_arange;
370*4d9fdb46SRobert Mustacchi     } while (arange_ptr < arange_end_section);
371*4d9fdb46SRobert Mustacchi 
372*4d9fdb46SRobert Mustacchi     if (arange_ptr != arange_end_section) {
373*4d9fdb46SRobert Mustacchi         free_aranges_chain(dbg,head_chain);
374bc1f688bSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
375bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
376bc1f688bSRobert Mustacchi     }
377bc1f688bSRobert Mustacchi     *chain_out = head_chain;
378bc1f688bSRobert Mustacchi     *chain_count_out = arange_count;
379bc1f688bSRobert Mustacchi     return DW_DLV_OK;
380bc1f688bSRobert Mustacchi }
381bc1f688bSRobert Mustacchi 
382bc1f688bSRobert Mustacchi /*
383bc1f688bSRobert Mustacchi     This function returns the count of the number of
384bc1f688bSRobert Mustacchi     aranges in the .debug_aranges section.  It sets
385bc1f688bSRobert Mustacchi     aranges to point to a block of Dwarf_Arange's
386bc1f688bSRobert Mustacchi     describing the arange's.  It returns DW_DLV_ERROR
387bc1f688bSRobert Mustacchi     on error.
388bc1f688bSRobert Mustacchi 
389bc1f688bSRobert Mustacchi     Must be identical in most aspects to
390bc1f688bSRobert Mustacchi         dwarf_get_aranges_addr_offsets!
391bc1f688bSRobert Mustacchi 
392bc1f688bSRobert Mustacchi */
393bc1f688bSRobert Mustacchi int
dwarf_get_aranges(Dwarf_Debug dbg,Dwarf_Arange ** aranges,Dwarf_Signed * returned_count,Dwarf_Error * error)394bc1f688bSRobert Mustacchi dwarf_get_aranges(Dwarf_Debug dbg,
395bc1f688bSRobert Mustacchi     Dwarf_Arange ** aranges,
396bc1f688bSRobert Mustacchi     Dwarf_Signed * returned_count, Dwarf_Error * error)
397bc1f688bSRobert Mustacchi {
398bc1f688bSRobert Mustacchi     /* Count of total number of aranges. */
399bc1f688bSRobert Mustacchi     Dwarf_Signed arange_count = 0;
400bc1f688bSRobert Mustacchi 
401bc1f688bSRobert Mustacchi     Dwarf_Arange *arange_block = 0;
402bc1f688bSRobert Mustacchi 
403bc1f688bSRobert Mustacchi     /* Used to chain Dwarf_Aranges structs. */
404bc1f688bSRobert Mustacchi     Dwarf_Chain curr_chain = NULL;
405bc1f688bSRobert Mustacchi     Dwarf_Chain prev_chain = NULL;
406bc1f688bSRobert Mustacchi     Dwarf_Chain head_chain = NULL;
407*4d9fdb46SRobert Mustacchi     Dwarf_Signed i = 0;
408bc1f688bSRobert Mustacchi     int res = DW_DLV_ERROR;
409bc1f688bSRobert Mustacchi 
410bc1f688bSRobert Mustacchi     /* ***** BEGIN CODE ***** */
411bc1f688bSRobert Mustacchi 
412bc1f688bSRobert Mustacchi     if (dbg == NULL) {
413bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
414bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
415bc1f688bSRobert Mustacchi     }
416bc1f688bSRobert Mustacchi 
417bc1f688bSRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error);
418bc1f688bSRobert Mustacchi     if (res != DW_DLV_OK) {
419bc1f688bSRobert Mustacchi         return res;
420bc1f688bSRobert Mustacchi     }
421*4d9fdb46SRobert Mustacchi     /*  aranges points in to info, so if info needs expanding
422*4d9fdb46SRobert Mustacchi         we have to load it. */
423*4d9fdb46SRobert Mustacchi     res = _dwarf_load_debug_info(dbg, error);
424*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
425*4d9fdb46SRobert Mustacchi         return res;
426*4d9fdb46SRobert Mustacchi     }
427bc1f688bSRobert Mustacchi 
428bc1f688bSRobert Mustacchi     res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
429bc1f688bSRobert Mustacchi     if (res != DW_DLV_OK) {
430*4d9fdb46SRobert Mustacchi         free_aranges_chain(dbg,head_chain);
431bc1f688bSRobert Mustacchi         return res;
432bc1f688bSRobert Mustacchi     }
433bc1f688bSRobert Mustacchi 
434bc1f688bSRobert Mustacchi     arange_block = (Dwarf_Arange *)
435bc1f688bSRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count);
436bc1f688bSRobert Mustacchi     if (arange_block == NULL) {
437bc1f688bSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
438*4d9fdb46SRobert Mustacchi         free_aranges_chain(dbg,head_chain);
439*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
440bc1f688bSRobert Mustacchi     }
441bc1f688bSRobert Mustacchi 
442*4d9fdb46SRobert Mustacchi     /* See also free_aranges_chain() above */
443bc1f688bSRobert Mustacchi     curr_chain = head_chain;
444bc1f688bSRobert Mustacchi     for (i = 0; i < arange_count; i++) {
445*4d9fdb46SRobert Mustacchi 
446*4d9fdb46SRobert Mustacchi         /*  Copies pointers. No dealloc of ch_item, */
447bc1f688bSRobert Mustacchi         *(arange_block + i) = curr_chain->ch_item;
448*4d9fdb46SRobert Mustacchi         curr_chain->ch_item = 0;
449bc1f688bSRobert Mustacchi         prev_chain = curr_chain;
450bc1f688bSRobert Mustacchi         curr_chain = curr_chain->ch_next;
451bc1f688bSRobert Mustacchi         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
452bc1f688bSRobert Mustacchi     }
453bc1f688bSRobert Mustacchi 
454bc1f688bSRobert Mustacchi     *aranges = arange_block;
455bc1f688bSRobert Mustacchi     *returned_count = (arange_count);
456bc1f688bSRobert Mustacchi     return DW_DLV_OK;
457bc1f688bSRobert Mustacchi }
458bc1f688bSRobert Mustacchi 
459bc1f688bSRobert Mustacchi /*
460bc1f688bSRobert Mustacchi     This function returns DW_DLV_OK if it succeeds
461bc1f688bSRobert Mustacchi     and DW_DLV_ERR or DW_DLV_OK otherwise.
462bc1f688bSRobert Mustacchi     count is set to the number of addresses in the
463bc1f688bSRobert Mustacchi     .debug_aranges section.
464bc1f688bSRobert Mustacchi     For each address, the corresponding element in
465bc1f688bSRobert Mustacchi     an array is set to the address itself(aranges) and
466bc1f688bSRobert Mustacchi     the section offset (offsets).
467bc1f688bSRobert Mustacchi     Must be identical in most aspects to
468bc1f688bSRobert Mustacchi         dwarf_get_aranges!
469bc1f688bSRobert Mustacchi */
470bc1f688bSRobert Mustacchi int
_dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,Dwarf_Addr ** addrs,Dwarf_Off ** offsets,Dwarf_Signed * count,Dwarf_Error * error)471bc1f688bSRobert Mustacchi _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,
472bc1f688bSRobert Mustacchi     Dwarf_Addr ** addrs,
473bc1f688bSRobert Mustacchi     Dwarf_Off ** offsets,
474bc1f688bSRobert Mustacchi     Dwarf_Signed * count,
475bc1f688bSRobert Mustacchi     Dwarf_Error * error)
476bc1f688bSRobert Mustacchi {
477*4d9fdb46SRobert Mustacchi     Dwarf_Signed i = 0;
478bc1f688bSRobert Mustacchi 
479bc1f688bSRobert Mustacchi     /* Used to chain Dwarf_Aranges structs. */
480bc1f688bSRobert Mustacchi     Dwarf_Chain curr_chain = NULL;
481bc1f688bSRobert Mustacchi     Dwarf_Chain prev_chain = NULL;
482bc1f688bSRobert Mustacchi     Dwarf_Chain head_chain = NULL;
483bc1f688bSRobert Mustacchi 
484bc1f688bSRobert Mustacchi     Dwarf_Signed arange_count = 0;
485bc1f688bSRobert Mustacchi     Dwarf_Addr *arange_addrs = 0;
486bc1f688bSRobert Mustacchi     Dwarf_Off *arange_offsets = 0;
487bc1f688bSRobert Mustacchi 
488bc1f688bSRobert Mustacchi     int res = DW_DLV_ERROR;
489bc1f688bSRobert Mustacchi 
490bc1f688bSRobert Mustacchi     /* ***** BEGIN CODE ***** */
491bc1f688bSRobert Mustacchi 
492bc1f688bSRobert Mustacchi     if (error != NULL)
493bc1f688bSRobert Mustacchi         *error = NULL;
494bc1f688bSRobert Mustacchi 
495bc1f688bSRobert Mustacchi     if (dbg == NULL) {
496bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
497bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
498bc1f688bSRobert Mustacchi     }
499bc1f688bSRobert Mustacchi 
500bc1f688bSRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_aranges,error);
501bc1f688bSRobert Mustacchi     if (res != DW_DLV_OK) {
502bc1f688bSRobert Mustacchi         return res;
503bc1f688bSRobert Mustacchi     }
504*4d9fdb46SRobert Mustacchi     /*  aranges points in to info, so if info needs expanding
505*4d9fdb46SRobert Mustacchi         we have to load it. */
506*4d9fdb46SRobert Mustacchi     res = _dwarf_load_debug_info(dbg, error);
507*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
508*4d9fdb46SRobert Mustacchi         return res;
509*4d9fdb46SRobert Mustacchi     }
510bc1f688bSRobert Mustacchi     res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
511bc1f688bSRobert Mustacchi     if (res != DW_DLV_OK) {
512bc1f688bSRobert Mustacchi         return res;
513bc1f688bSRobert Mustacchi     }
514bc1f688bSRobert Mustacchi     arange_addrs = (Dwarf_Addr *)
515bc1f688bSRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
516bc1f688bSRobert Mustacchi     if (arange_addrs == NULL) {
517bc1f688bSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
518bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
519bc1f688bSRobert Mustacchi     }
520bc1f688bSRobert Mustacchi     arange_offsets = (Dwarf_Off *)
521bc1f688bSRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
522bc1f688bSRobert Mustacchi     if (arange_offsets == NULL) {
523bc1f688bSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
524bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
525bc1f688bSRobert Mustacchi     }
526bc1f688bSRobert Mustacchi 
527bc1f688bSRobert Mustacchi     curr_chain = head_chain;
528bc1f688bSRobert Mustacchi     for (i = 0; i < arange_count; i++) {
529bc1f688bSRobert Mustacchi         Dwarf_Arange ar = curr_chain->ch_item;
530*4d9fdb46SRobert Mustacchi         int itemtype = curr_chain->ch_itemtype;
531bc1f688bSRobert Mustacchi 
532*4d9fdb46SRobert Mustacchi         curr_chain->ch_item = 0;
533bc1f688bSRobert Mustacchi         arange_addrs[i] = ar->ar_address;
534bc1f688bSRobert Mustacchi         arange_offsets[i] = ar->ar_info_offset;
535bc1f688bSRobert Mustacchi         prev_chain = curr_chain;
536bc1f688bSRobert Mustacchi         curr_chain = curr_chain->ch_next;
537*4d9fdb46SRobert Mustacchi         if (ar && itemtype) {
538*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg, ar, itemtype);
539*4d9fdb46SRobert Mustacchi         }
540bc1f688bSRobert Mustacchi         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
541bc1f688bSRobert Mustacchi     }
542bc1f688bSRobert Mustacchi     *count = arange_count;
543bc1f688bSRobert Mustacchi     *offsets = arange_offsets;
544bc1f688bSRobert Mustacchi     *addrs = arange_addrs;
545bc1f688bSRobert Mustacchi     return (DW_DLV_OK);
546bc1f688bSRobert Mustacchi }
547bc1f688bSRobert Mustacchi 
548bc1f688bSRobert Mustacchi 
549bc1f688bSRobert Mustacchi /*
550bc1f688bSRobert Mustacchi     This function takes a pointer to a block
551bc1f688bSRobert Mustacchi     of Dwarf_Arange's, and a count of the
552bc1f688bSRobert Mustacchi     length of the block.  It checks if the
553bc1f688bSRobert Mustacchi     given address is within the range of an
554bc1f688bSRobert Mustacchi     address range in the block.  If yes, it
555bc1f688bSRobert Mustacchi     returns the appropriate Dwarf_Arange.
556bc1f688bSRobert Mustacchi     Otherwise, it returns DW_DLV_ERROR.
557bc1f688bSRobert Mustacchi */
558bc1f688bSRobert Mustacchi int
dwarf_get_arange(Dwarf_Arange * aranges,Dwarf_Unsigned arange_count,Dwarf_Addr address,Dwarf_Arange * returned_arange,Dwarf_Error * error)559bc1f688bSRobert Mustacchi dwarf_get_arange(Dwarf_Arange * aranges,
560bc1f688bSRobert Mustacchi     Dwarf_Unsigned arange_count,
561bc1f688bSRobert Mustacchi     Dwarf_Addr address,
562bc1f688bSRobert Mustacchi     Dwarf_Arange * returned_arange, Dwarf_Error * error)
563bc1f688bSRobert Mustacchi {
564bc1f688bSRobert Mustacchi     Dwarf_Arange curr_arange = 0;
565bc1f688bSRobert Mustacchi     Dwarf_Unsigned i = 0;
566bc1f688bSRobert Mustacchi 
567bc1f688bSRobert Mustacchi     if (aranges == NULL) {
568bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL);
569bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
570bc1f688bSRobert Mustacchi     }
571bc1f688bSRobert Mustacchi     for (i = 0; i < arange_count; i++) {
572bc1f688bSRobert Mustacchi         curr_arange = *(aranges + i);
573bc1f688bSRobert Mustacchi         if (address >= curr_arange->ar_address &&
574bc1f688bSRobert Mustacchi             address <
575bc1f688bSRobert Mustacchi             curr_arange->ar_address + curr_arange->ar_length) {
576bc1f688bSRobert Mustacchi             *returned_arange = curr_arange;
577bc1f688bSRobert Mustacchi             return (DW_DLV_OK);
578bc1f688bSRobert Mustacchi         }
579bc1f688bSRobert Mustacchi     }
580bc1f688bSRobert Mustacchi 
581bc1f688bSRobert Mustacchi     return (DW_DLV_NO_ENTRY);
582bc1f688bSRobert Mustacchi }
583bc1f688bSRobert Mustacchi 
584bc1f688bSRobert Mustacchi 
585bc1f688bSRobert Mustacchi /*
586bc1f688bSRobert Mustacchi     This function takes an Dwarf_Arange,
587bc1f688bSRobert Mustacchi     and returns the offset of the first
588bc1f688bSRobert Mustacchi     die in the compilation-unit that the
589bc1f688bSRobert Mustacchi     arange belongs to.  Returns DW_DLV_ERROR
590bc1f688bSRobert Mustacchi     on error.
591*4d9fdb46SRobert Mustacchi 
592*4d9fdb46SRobert Mustacchi     For an arange, the cu_die can only be from debug_info,
593*4d9fdb46SRobert Mustacchi     not debug_types, it seems.
594bc1f688bSRobert Mustacchi */
595bc1f688bSRobert Mustacchi int
dwarf_get_cu_die_offset(Dwarf_Arange arange,Dwarf_Off * returned_offset,Dwarf_Error * error)596bc1f688bSRobert Mustacchi dwarf_get_cu_die_offset(Dwarf_Arange arange,
597bc1f688bSRobert Mustacchi     Dwarf_Off * returned_offset,
598bc1f688bSRobert Mustacchi     Dwarf_Error * error)
599bc1f688bSRobert Mustacchi {
600bc1f688bSRobert Mustacchi     Dwarf_Debug dbg = 0;
601bc1f688bSRobert Mustacchi     Dwarf_Off offset = 0;
602*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned headerlen = 0;
603*4d9fdb46SRobert Mustacchi     int cres = 0;
604bc1f688bSRobert Mustacchi 
605bc1f688bSRobert Mustacchi     if (arange == NULL) {
606bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
607bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
608bc1f688bSRobert Mustacchi     }
609bc1f688bSRobert Mustacchi     dbg = arange->ar_dbg;
610bc1f688bSRobert Mustacchi     offset = arange->ar_info_offset;
611*4d9fdb46SRobert Mustacchi     /* This applies to debug_info only, not to debug_types. */
612bc1f688bSRobert Mustacchi     if (!dbg->de_debug_info.dss_data) {
613bc1f688bSRobert Mustacchi         int res = _dwarf_load_debug_info(dbg, error);
614bc1f688bSRobert Mustacchi 
615bc1f688bSRobert Mustacchi         if (res != DW_DLV_OK) {
616bc1f688bSRobert Mustacchi             return res;
617bc1f688bSRobert Mustacchi         }
618bc1f688bSRobert Mustacchi     }
619*4d9fdb46SRobert Mustacchi 
620*4d9fdb46SRobert Mustacchi     cres = _dwarf_length_of_cu_header(dbg, offset,
621*4d9fdb46SRobert Mustacchi         true, &headerlen,error);
622*4d9fdb46SRobert Mustacchi     if (cres != DW_DLV_OK) {
623*4d9fdb46SRobert Mustacchi         return cres;
624*4d9fdb46SRobert Mustacchi     }
625*4d9fdb46SRobert Mustacchi     *returned_offset =  headerlen + offset;
626bc1f688bSRobert Mustacchi     return DW_DLV_OK;
627bc1f688bSRobert Mustacchi }
628bc1f688bSRobert Mustacchi 
629*4d9fdb46SRobert Mustacchi /*  This function takes an Dwarf_Arange,
630bc1f688bSRobert Mustacchi     and returns the offset of the CU header
631bc1f688bSRobert Mustacchi     in the compilation-unit that the
632bc1f688bSRobert Mustacchi     arange belongs to.  Returns DW_DLV_ERROR
633bc1f688bSRobert Mustacchi     on error.
634bc1f688bSRobert Mustacchi     Ensures .debug_info loaded so
635*4d9fdb46SRobert Mustacchi     the cu_offset is meaningful.  */
636bc1f688bSRobert Mustacchi int
dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,Dwarf_Off * cu_header_offset_returned,Dwarf_Error * error)637bc1f688bSRobert Mustacchi dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,
638bc1f688bSRobert Mustacchi     Dwarf_Off * cu_header_offset_returned,
639bc1f688bSRobert Mustacchi     Dwarf_Error * error)
640bc1f688bSRobert Mustacchi {
641bc1f688bSRobert Mustacchi     Dwarf_Debug dbg = 0;
642bc1f688bSRobert Mustacchi     if (arange == NULL) {
643bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
644bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
645bc1f688bSRobert Mustacchi     }
646bc1f688bSRobert Mustacchi     dbg = arange->ar_dbg;
647*4d9fdb46SRobert Mustacchi     /* This applies to debug_info only, not to debug_types. */
648bc1f688bSRobert Mustacchi     /*  Like dwarf_get_arange_info this ensures debug_info loaded:
649bc1f688bSRobert Mustacchi         the cu_header is in debug_info and will be used else
650bc1f688bSRobert Mustacchi         we would not call dwarf_get_arange_cu_header_offset. */
651bc1f688bSRobert Mustacchi     if (!dbg->de_debug_info.dss_data) {
652bc1f688bSRobert Mustacchi         int res = _dwarf_load_debug_info(dbg, error);
653bc1f688bSRobert Mustacchi         if (res != DW_DLV_OK) {
654bc1f688bSRobert Mustacchi             return res;
655bc1f688bSRobert Mustacchi         }
656bc1f688bSRobert Mustacchi     }
657bc1f688bSRobert Mustacchi     *cu_header_offset_returned = arange->ar_info_offset;
658bc1f688bSRobert Mustacchi     return DW_DLV_OK;
659bc1f688bSRobert Mustacchi }
660bc1f688bSRobert Mustacchi 
661bc1f688bSRobert Mustacchi 
662bc1f688bSRobert Mustacchi 
663bc1f688bSRobert Mustacchi 
664bc1f688bSRobert Mustacchi /*
665bc1f688bSRobert Mustacchi     This function takes a Dwarf_Arange, and returns
666bc1f688bSRobert Mustacchi     true if it is not NULL.  It also stores the start
667bc1f688bSRobert Mustacchi     address of the range in *start, the length of the
668bc1f688bSRobert Mustacchi     range in *length, and the offset of the first die
669bc1f688bSRobert Mustacchi     in the compilation-unit in *cu_die_offset.  It
670bc1f688bSRobert Mustacchi     returns false on error.
671bc1f688bSRobert Mustacchi     If cu_die_offset returned ensures .debug_info loaded so
672bc1f688bSRobert Mustacchi     the cu_die_offset is meaningful.
673bc1f688bSRobert Mustacchi */
674bc1f688bSRobert Mustacchi int
dwarf_get_arange_info(Dwarf_Arange arange,Dwarf_Addr * start,Dwarf_Unsigned * length,Dwarf_Off * cu_die_offset,Dwarf_Error * error)675bc1f688bSRobert Mustacchi dwarf_get_arange_info(Dwarf_Arange arange,
676bc1f688bSRobert Mustacchi     Dwarf_Addr * start,
677bc1f688bSRobert Mustacchi     Dwarf_Unsigned * length,
678bc1f688bSRobert Mustacchi     Dwarf_Off * cu_die_offset, Dwarf_Error * error)
679bc1f688bSRobert Mustacchi {
680bc1f688bSRobert Mustacchi     if (arange == NULL) {
681bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
682bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
683bc1f688bSRobert Mustacchi     }
684bc1f688bSRobert Mustacchi 
685bc1f688bSRobert Mustacchi     if (start != NULL)
686bc1f688bSRobert Mustacchi         *start = arange->ar_address;
687bc1f688bSRobert Mustacchi     if (length != NULL)
688bc1f688bSRobert Mustacchi         *length = arange->ar_length;
689bc1f688bSRobert Mustacchi     if (cu_die_offset != NULL) {
690bc1f688bSRobert Mustacchi         Dwarf_Debug dbg = arange->ar_dbg;
691*4d9fdb46SRobert Mustacchi         Dwarf_Off headerlen = 0;
692bc1f688bSRobert Mustacchi         Dwarf_Off offset = arange->ar_info_offset;
693*4d9fdb46SRobert Mustacchi         int cres = 0;
694bc1f688bSRobert Mustacchi 
695*4d9fdb46SRobert Mustacchi         /* This applies to debug_info only, not to debug_types. */
696bc1f688bSRobert Mustacchi         if (!dbg->de_debug_info.dss_data) {
697bc1f688bSRobert Mustacchi             int res = _dwarf_load_debug_info(dbg, error);
698bc1f688bSRobert Mustacchi             if (res != DW_DLV_OK) {
699bc1f688bSRobert Mustacchi                 return res;
700bc1f688bSRobert Mustacchi             }
701bc1f688bSRobert Mustacchi         }
702*4d9fdb46SRobert Mustacchi 
703*4d9fdb46SRobert Mustacchi         cres = _dwarf_length_of_cu_header(dbg, offset,
704*4d9fdb46SRobert Mustacchi             true, &headerlen,error);
705*4d9fdb46SRobert Mustacchi         if (cres != DW_DLV_OK) {
706*4d9fdb46SRobert Mustacchi             return cres;
707*4d9fdb46SRobert Mustacchi         }
708*4d9fdb46SRobert Mustacchi         *cu_die_offset = headerlen + offset;
709bc1f688bSRobert Mustacchi     }
710bc1f688bSRobert Mustacchi     return (DW_DLV_OK);
711bc1f688bSRobert Mustacchi }
712bc1f688bSRobert Mustacchi 
713bc1f688bSRobert Mustacchi 
714bc1f688bSRobert Mustacchi /* New for DWARF4, entries may have segment information.
715bc1f688bSRobert Mustacchi    *segment is only meaningful if *segment_entry_size is non-zero. */
716bc1f688bSRobert Mustacchi int
dwarf_get_arange_info_b(Dwarf_Arange arange,Dwarf_Unsigned * segment,Dwarf_Unsigned * segment_entry_size,Dwarf_Addr * start,Dwarf_Unsigned * length,Dwarf_Off * cu_die_offset,Dwarf_Error * error)717bc1f688bSRobert Mustacchi dwarf_get_arange_info_b(Dwarf_Arange arange,
718bc1f688bSRobert Mustacchi     Dwarf_Unsigned*  segment,
719bc1f688bSRobert Mustacchi     Dwarf_Unsigned*  segment_entry_size,
720bc1f688bSRobert Mustacchi     Dwarf_Addr    * start,
721bc1f688bSRobert Mustacchi     Dwarf_Unsigned* length,
722bc1f688bSRobert Mustacchi     Dwarf_Off     * cu_die_offset,
723bc1f688bSRobert Mustacchi     Dwarf_Error   * error)
724bc1f688bSRobert Mustacchi {
725bc1f688bSRobert Mustacchi     if (arange == NULL) {
726bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
727*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
728bc1f688bSRobert Mustacchi     }
729bc1f688bSRobert Mustacchi 
730bc1f688bSRobert Mustacchi     if (segment != NULL) {
731bc1f688bSRobert Mustacchi         *segment = arange->ar_segment_selector;
732bc1f688bSRobert Mustacchi     }
733bc1f688bSRobert Mustacchi     if (segment_entry_size != NULL) {
734bc1f688bSRobert Mustacchi         *segment_entry_size = arange->ar_segment_selector_size;
735bc1f688bSRobert Mustacchi     }
736bc1f688bSRobert Mustacchi     if (start != NULL)
737bc1f688bSRobert Mustacchi         *start = arange->ar_address;
738bc1f688bSRobert Mustacchi     if (length != NULL)
739bc1f688bSRobert Mustacchi         *length = arange->ar_length;
740bc1f688bSRobert Mustacchi     if (cu_die_offset != NULL) {
741bc1f688bSRobert Mustacchi         Dwarf_Debug dbg = arange->ar_dbg;
742bc1f688bSRobert Mustacchi         Dwarf_Off offset = arange->ar_info_offset;
743*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned headerlen = 0;
744*4d9fdb46SRobert Mustacchi         int cres = 0;
745bc1f688bSRobert Mustacchi 
746*4d9fdb46SRobert Mustacchi         /* This applies to debug_info only, not to debug_types. */
747bc1f688bSRobert Mustacchi         if (!dbg->de_debug_info.dss_data) {
748bc1f688bSRobert Mustacchi             int res = _dwarf_load_debug_info(dbg, error);
749bc1f688bSRobert Mustacchi             if (res != DW_DLV_OK) {
750bc1f688bSRobert Mustacchi                 return res;
751bc1f688bSRobert Mustacchi             }
752bc1f688bSRobert Mustacchi         }
753*4d9fdb46SRobert Mustacchi         cres = _dwarf_length_of_cu_header(dbg, offset,
754*4d9fdb46SRobert Mustacchi             true, &headerlen,error);
755*4d9fdb46SRobert Mustacchi         if (cres != DW_DLV_OK) {
756*4d9fdb46SRobert Mustacchi             return cres;
757*4d9fdb46SRobert Mustacchi         }
758*4d9fdb46SRobert Mustacchi         *cu_die_offset = offset + headerlen;
759*4d9fdb46SRobert Mustacchi 
760bc1f688bSRobert Mustacchi     }
761bc1f688bSRobert Mustacchi     return (DW_DLV_OK);
762bc1f688bSRobert Mustacchi }
763