149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe 
307dc1947SRichard Lowe   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 
749d3bc91SRichard Lowe 
849d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
9*4d9fdb46SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
1049d3bc91SRichard Lowe   as published by the Free Software Foundation.
1149d3bc91SRichard Lowe 
1249d3bc91SRichard Lowe   This program is distributed in the hope that it would be useful, but
1349d3bc91SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
14*4d9fdb46SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1549d3bc91SRichard Lowe 
1649d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
17*4d9fdb46SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
18*4d9fdb46SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
1949d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
20*4d9fdb46SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
21*4d9fdb46SRobert Mustacchi   other software, or any other product whatsoever.
2249d3bc91SRichard Lowe 
23*4d9fdb46SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
24*4d9fdb46SRobert Mustacchi   License along with this program; if not, write the Free Software
2507dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2649d3bc91SRichard Lowe   USA.
2749d3bc91SRichard Lowe 
2807dc1947SRichard Lowe */
2907dc1947SRichard Lowe 
3049d3bc91SRichard Lowe #include "config.h"
3149d3bc91SRichard Lowe #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"
3649d3bc91SRichard Lowe #include "dwarf_arange.h"
37*4d9fdb46SRobert Mustacchi #include "dwarf_global.h"  /* for _dwarf_fixup_* */
38*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
3949d3bc91SRichard Lowe 
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 }
6249d3bc91SRichard Lowe 
63*4d9fdb46SRobert Mustacchi /*  Common code for two user-visible routines to share.
64*4d9fdb46SRobert Mustacchi     Errors here result in memory leaks, but errors here
65*4d9fdb46SRobert Mustacchi     are serious (making aranges unusable) so we assume
66*4d9fdb46SRobert Mustacchi     callers will not repeat the error often or mind the leaks.
6749d3bc91SRichard Lowe */
6807dc1947SRichard Lowe static int
dwarf_get_aranges_list(Dwarf_Debug dbg,Dwarf_Chain * chain_out,Dwarf_Signed * chain_count_out,Dwarf_Error * error)6907dc1947SRichard Lowe dwarf_get_aranges_list(Dwarf_Debug dbg,
7007dc1947SRichard Lowe     Dwarf_Chain  * chain_out,
7107dc1947SRichard Lowe     Dwarf_Signed * chain_count_out,
7207dc1947SRichard Lowe     Dwarf_Error  * error)
7349d3bc91SRichard Lowe {
7407dc1947SRichard Lowe     /* Sweeps through the arange. */
7507dc1947SRichard Lowe     Dwarf_Small *arange_ptr = 0;
7607dc1947SRichard Lowe     Dwarf_Small *arange_ptr_start = 0;
7749d3bc91SRichard Lowe 
78*4d9fdb46SRobert Mustacchi     /*  Start of arange header.  Used for rounding offset of arange_ptr
79*4d9fdb46SRobert Mustacchi         to twice the tuple size.  Libdwarf requirement. */
8007dc1947SRichard Lowe     Dwarf_Small *header_ptr = 0;
8149d3bc91SRichard Lowe 
82*4d9fdb46SRobert Mustacchi     /*  Version of .debug_aranges header. */
83*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned version = 0;
8449d3bc91SRichard Lowe 
85*4d9fdb46SRobert Mustacchi     /*  Offset of current set of aranges into .debug_info. */
8607dc1947SRichard Lowe     Dwarf_Off info_offset = 0;
87*4d9fdb46SRobert Mustacchi     /*  Size in bytes of addresses in target. */
8807dc1947SRichard Lowe     Dwarf_Small address_size = 0;
89*4d9fdb46SRobert Mustacchi     /*  Size in bytes of segment offsets in target. */
9007dc1947SRichard Lowe     Dwarf_Small segment_size = 0;
91*4d9fdb46SRobert Mustacchi     /*  Count of total number of aranges. */
92*4d9fdb46SRobert Mustacchi     Dwarf_Signed arange_count = 0;
9307dc1947SRichard Lowe     Dwarf_Arange arange = 0;
94*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned section_size = 0;
95*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr arange_end_section = 0;
96*4d9fdb46SRobert Mustacchi     /*  Used to chain Dwarf_Aranges structs. */
9707dc1947SRichard Lowe     Dwarf_Chain curr_chain = NULL;
9807dc1947SRichard Lowe     Dwarf_Chain prev_chain = NULL;
9907dc1947SRichard Lowe     Dwarf_Chain head_chain = NULL;
10049d3bc91SRichard Lowe 
101*4d9fdb46SRobert Mustacchi     if (!dbg->de_debug_aranges.dss_size) {
102*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
103*4d9fdb46SRobert Mustacchi     }
10407dc1947SRichard Lowe     arange_ptr = dbg->de_debug_aranges.dss_data;
10507dc1947SRichard Lowe     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 
10907dc1947SRichard Lowe     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;
11407dc1947SRichard Lowe         Dwarf_Small remainder = 0;
11507dc1947SRichard Lowe         Dwarf_Unsigned range_entry_size = 0;
11607dc1947SRichard Lowe         int local_length_size;
11707dc1947SRichard Lowe         int local_extension_size = 0;
118*4d9fdb46SRobert Mustacchi         Dwarf_Small *end_this_arange = 0;
119*4d9fdb46SRobert Mustacchi         int res = 0;
120*4d9fdb46SRobert Mustacchi 
12107dc1947SRichard Lowe 
12207dc1947SRichard Lowe         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. */
13707dc1947SRichard Lowe 
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         }
14949d3bc91SRichard Lowe 
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         }
16249d3bc91SRichard Lowe 
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);
17707dc1947SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
17807dc1947SRichard Lowe             return (DW_DLV_ERROR);
17907dc1947SRichard Lowe         }
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         }
18607dc1947SRichard Lowe 
18707dc1947SRichard Lowe         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. */
19407dc1947SRichard Lowe         if (info_offset >= dbg->de_debug_info.dss_size) {
19507dc1947SRichard Lowe             FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset,
19607dc1947SRichard Lowe                 "arange info offset.a");
19707dc1947SRichard Lowe             if (info_offset >= dbg->de_debug_info.dss_size) {
198*4d9fdb46SRobert Mustacchi                 free_aranges_chain(dbg,head_chain);
19907dc1947SRichard Lowe                 _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
20007dc1947SRichard Lowe                 return (DW_DLV_ERROR);
20107dc1947SRichard Lowe             }
20207dc1947SRichard Lowe         }
20307dc1947SRichard Lowe 
20407dc1947SRichard Lowe         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         }
215*4d9fdb46SRobert Mustacchi         /*  It is not an error if the sizes differ.
216*4d9fdb46SRobert Mustacchi             Unusual, but not an error. */
21707dc1947SRichard Lowe         arange_ptr = arange_ptr + sizeof(Dwarf_Small);
21807dc1947SRichard Lowe 
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. */
23007dc1947SRichard Lowe         segment_size = *(Dwarf_Small *) arange_ptr;
231*4d9fdb46SRobert Mustacchi         if (segment_size > sizeof(Dwarf_Addr)) {
232*4d9fdb46SRobert Mustacchi             free_aranges_chain(dbg,head_chain);
23307dc1947SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
23407dc1947SRichard Lowe             return (DW_DLV_ERROR);
23507dc1947SRichard Lowe         }
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         }
24407dc1947SRichard Lowe 
24507dc1947SRichard Lowe         range_entry_size = 2*address_size + segment_size;
24607dc1947SRichard Lowe         /* Round arange_ptr offset to next multiple of address_size. */
24707dc1947SRichard Lowe         remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) %
24807dc1947SRichard Lowe             (range_entry_size);
24907dc1947SRichard Lowe         if (remainder != 0) {
25007dc1947SRichard Lowe             arange_ptr = arange_ptr + (2 * address_size) - remainder;
25107dc1947SRichard Lowe         }
252*4d9fdb46SRobert Mustacchi 
25307dc1947SRichard Lowe         do {
25407dc1947SRichard Lowe             Dwarf_Addr range_address = 0;
25507dc1947SRichard Lowe             Dwarf_Unsigned segment_selector = 0;
25607dc1947SRichard Lowe             Dwarf_Unsigned range_length = 0;
257*4d9fdb46SRobert 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                 }
27707dc1947SRichard Lowe                 arange_ptr += address_size;
27807dc1947SRichard Lowe             }
27907dc1947SRichard Lowe 
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             }
28607dc1947SRichard Lowe             arange_ptr += address_size;
28707dc1947SRichard Lowe 
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 
29507dc1947SRichard Lowe             arange_ptr += address_size;
29607dc1947SRichard Lowe 
297*4d9fdb46SRobert Mustacchi             {
298*4d9fdb46SRobert Mustacchi                 /*  We used to suppress all-zero entries, but
299*4d9fdb46SRobert Mustacchi                     now we return all aranges entries so we show
300*4d9fdb46SRobert Mustacchi                     the entire content.  March 31, 2010. */
30107dc1947SRichard Lowe 
30207dc1947SRichard Lowe                 arange = (Dwarf_Arange)
30307dc1947SRichard Lowe                     _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
30407dc1947SRichard Lowe                 if (arange == NULL) {
305*4d9fdb46SRobert Mustacchi                     free_aranges_chain(dbg,head_chain);
30607dc1947SRichard Lowe                     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
30707dc1947SRichard Lowe                     return (DW_DLV_ERROR);
30807dc1947SRichard Lowe                 }
30907dc1947SRichard Lowe 
31007dc1947SRichard Lowe                 arange->ar_segment_selector = segment_selector;
31107dc1947SRichard Lowe                 arange->ar_segment_selector_size = segment_size;
31207dc1947SRichard Lowe                 arange->ar_address = range_address;
31307dc1947SRichard Lowe                 arange->ar_length = range_length;
31407dc1947SRichard Lowe                 arange->ar_info_offset = info_offset;
31507dc1947SRichard Lowe                 arange->ar_dbg = dbg;
31607dc1947SRichard Lowe                 arange_count++;
31707dc1947SRichard Lowe 
31807dc1947SRichard Lowe                 curr_chain = (Dwarf_Chain)
31907dc1947SRichard Lowe                     _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
32007dc1947SRichard Lowe                 if (curr_chain == NULL) {
321*4d9fdb46SRobert Mustacchi                     free_aranges_chain(dbg,head_chain);
32207dc1947SRichard Lowe                     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
32307dc1947SRichard Lowe                     return (DW_DLV_ERROR);
32407dc1947SRichard Lowe                 }
32507dc1947SRichard Lowe 
32607dc1947SRichard Lowe                 curr_chain->ch_item = arange;
327*4d9fdb46SRobert Mustacchi                 curr_chain->ch_itemtype = DW_DLA_ARANGE;
32807dc1947SRichard Lowe                 if (head_chain == NULL)
32907dc1947SRichard Lowe                     head_chain = prev_chain = curr_chain;
33007dc1947SRichard Lowe                 else {
33107dc1947SRichard Lowe                     prev_chain->ch_next = curr_chain;
33207dc1947SRichard Lowe                     prev_chain = curr_chain;
33307dc1947SRichard Lowe                 }
33407dc1947SRichard Lowe             }
335*4d9fdb46SRobert Mustacchi             /*  The current set of ranges is terminated by
336*4d9fdb46SRobert Mustacchi                 range_address 0 and range_length 0, but that
337*4d9fdb46SRobert Mustacchi                 does not necessarily terminate the ranges for this CU!
338*4d9fdb46SRobert Mustacchi                 There can be multiple sets in that DWARF
339*4d9fdb46SRobert Mustacchi                 does not explicitly forbid multiple sets.
340*4d9fdb46SRobert Mustacchi                 DWARF2,3,4 section 7.20
341*4d9fdb46SRobert Mustacchi                 We stop short to avoid overrun of the end of the CU.  */
342*4d9fdb46SRobert Mustacchi 
343*4d9fdb46SRobert Mustacchi         } while (end_this_arange >= (arange_ptr + range_entry_size));
344*4d9fdb46SRobert Mustacchi 
345*4d9fdb46SRobert Mustacchi         /*  A compiler could emit some padding bytes here. dwarf2/3
346*4d9fdb46SRobert Mustacchi             (dwarf4 sec 7.20) does not clearly make extra padding
347*4d9fdb46SRobert Mustacchi             bytes illegal. */
348*4d9fdb46SRobert Mustacchi         if (end_this_arange < arange_ptr) {
349*4d9fdb46SRobert Mustacchi             Dwarf_Unsigned pad_count = arange_ptr - end_this_arange;
35007dc1947SRichard Lowe             Dwarf_Unsigned offset = arange_ptr - arange_ptr_start;
351*4d9fdb46SRobert Mustacchi             dwarfstring aramsg;
352*4d9fdb46SRobert 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
36107dc1947SRichard Lowe                 " 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);
36607dc1947SRichard Lowe         }
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);
37407dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
37507dc1947SRichard Lowe         return (DW_DLV_ERROR);
37607dc1947SRichard Lowe     }
37707dc1947SRichard Lowe     *chain_out = head_chain;
37807dc1947SRichard Lowe     *chain_count_out = arange_count;
37907dc1947SRichard Lowe     return DW_DLV_OK;
38007dc1947SRichard Lowe }
38107dc1947SRichard Lowe 
38207dc1947SRichard Lowe /*
38307dc1947SRichard Lowe     This function returns the count of the number of
38407dc1947SRichard Lowe     aranges in the .debug_aranges section.  It sets
385*4d9fdb46SRobert Mustacchi     aranges to point to a block of Dwarf_Arange's
38607dc1947SRichard Lowe     describing the arange's.  It returns DW_DLV_ERROR
38707dc1947SRichard Lowe     on error.
38807dc1947SRichard Lowe 
38907dc1947SRichard Lowe     Must be identical in most aspects to
39007dc1947SRichard Lowe         dwarf_get_aranges_addr_offsets!
39107dc1947SRichard Lowe 
39207dc1947SRichard Lowe */
39307dc1947SRichard Lowe int
dwarf_get_aranges(Dwarf_Debug dbg,Dwarf_Arange ** aranges,Dwarf_Signed * returned_count,Dwarf_Error * error)39407dc1947SRichard Lowe dwarf_get_aranges(Dwarf_Debug dbg,
39507dc1947SRichard Lowe     Dwarf_Arange ** aranges,
39607dc1947SRichard Lowe     Dwarf_Signed * returned_count, Dwarf_Error * error)
39707dc1947SRichard Lowe {
39807dc1947SRichard Lowe     /* Count of total number of aranges. */
39907dc1947SRichard Lowe     Dwarf_Signed arange_count = 0;
40007dc1947SRichard Lowe 
40107dc1947SRichard Lowe     Dwarf_Arange *arange_block = 0;
40207dc1947SRichard Lowe 
40307dc1947SRichard Lowe     /* Used to chain Dwarf_Aranges structs. */
40407dc1947SRichard Lowe     Dwarf_Chain curr_chain = NULL;
40507dc1947SRichard Lowe     Dwarf_Chain prev_chain = NULL;
40607dc1947SRichard Lowe     Dwarf_Chain head_chain = NULL;
407*4d9fdb46SRobert Mustacchi     Dwarf_Signed i = 0;
40807dc1947SRichard Lowe     int res = DW_DLV_ERROR;
40949d3bc91SRichard Lowe 
41049d3bc91SRichard Lowe     /* ***** BEGIN CODE ***** */
41149d3bc91SRichard Lowe 
41249d3bc91SRichard Lowe     if (dbg == NULL) {
41307dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
41407dc1947SRichard Lowe         return (DW_DLV_ERROR);
41549d3bc91SRichard Lowe     }
41649d3bc91SRichard Lowe 
41707dc1947SRichard Lowe     res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error);
41849d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
41949d3bc91SRichard Lowe         return res;
42049d3bc91SRichard Lowe     }
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     }
42749d3bc91SRichard Lowe 
42807dc1947SRichard Lowe     res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
429*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
430*4d9fdb46SRobert Mustacchi         free_aranges_chain(dbg,head_chain);
43107dc1947SRichard Lowe         return res;
43249d3bc91SRichard Lowe     }
43349d3bc91SRichard Lowe 
43449d3bc91SRichard Lowe     arange_block = (Dwarf_Arange *)
43507dc1947SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count);
43649d3bc91SRichard Lowe     if (arange_block == NULL) {
43707dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
438*4d9fdb46SRobert Mustacchi         free_aranges_chain(dbg,head_chain);
439*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
44049d3bc91SRichard Lowe     }
44149d3bc91SRichard Lowe 
442*4d9fdb46SRobert Mustacchi     /* See also free_aranges_chain() above */
44349d3bc91SRichard Lowe     curr_chain = head_chain;
44449d3bc91SRichard Lowe     for (i = 0; i < arange_count; i++) {
445*4d9fdb46SRobert Mustacchi 
446*4d9fdb46SRobert Mustacchi         /*  Copies pointers. No dealloc of ch_item, */
44707dc1947SRichard Lowe         *(arange_block + i) = curr_chain->ch_item;
448*4d9fdb46SRobert Mustacchi         curr_chain->ch_item = 0;
44907dc1947SRichard Lowe         prev_chain = curr_chain;
45007dc1947SRichard Lowe         curr_chain = curr_chain->ch_next;
45107dc1947SRichard Lowe         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
45249d3bc91SRichard Lowe     }
45349d3bc91SRichard Lowe 
45449d3bc91SRichard Lowe     *aranges = arange_block;
45549d3bc91SRichard Lowe     *returned_count = (arange_count);
45649d3bc91SRichard Lowe     return DW_DLV_OK;
45749d3bc91SRichard Lowe }
45849d3bc91SRichard Lowe 
45949d3bc91SRichard Lowe /*
46049d3bc91SRichard Lowe     This function returns DW_DLV_OK if it succeeds
46149d3bc91SRichard Lowe     and DW_DLV_ERR or DW_DLV_OK otherwise.
46249d3bc91SRichard Lowe     count is set to the number of addresses in the
463*4d9fdb46SRobert Mustacchi     .debug_aranges section.
46449d3bc91SRichard Lowe     For each address, the corresponding element in
46549d3bc91SRichard Lowe     an array is set to the address itself(aranges) and
46649d3bc91SRichard Lowe     the section offset (offsets).
46749d3bc91SRichard Lowe     Must be identical in most aspects to
46807dc1947SRichard Lowe         dwarf_get_aranges!
46949d3bc91SRichard Lowe */
47049d3bc91SRichard Lowe int
_dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,Dwarf_Addr ** addrs,Dwarf_Off ** offsets,Dwarf_Signed * count,Dwarf_Error * error)47149d3bc91SRichard Lowe _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,
47207dc1947SRichard Lowe     Dwarf_Addr ** addrs,
47307dc1947SRichard Lowe     Dwarf_Off ** offsets,
47407dc1947SRichard Lowe     Dwarf_Signed * count,
47507dc1947SRichard Lowe     Dwarf_Error * error)
47649d3bc91SRichard Lowe {
477*4d9fdb46SRobert Mustacchi     Dwarf_Signed i = 0;
47849d3bc91SRichard Lowe 
47949d3bc91SRichard Lowe     /* Used to chain Dwarf_Aranges structs. */
48007dc1947SRichard Lowe     Dwarf_Chain curr_chain = NULL;
48107dc1947SRichard Lowe     Dwarf_Chain prev_chain = NULL;
48207dc1947SRichard Lowe     Dwarf_Chain head_chain = NULL;
48349d3bc91SRichard Lowe 
48407dc1947SRichard Lowe     Dwarf_Signed arange_count = 0;
48507dc1947SRichard Lowe     Dwarf_Addr *arange_addrs = 0;
48607dc1947SRichard Lowe     Dwarf_Off *arange_offsets = 0;
48749d3bc91SRichard Lowe 
48807dc1947SRichard Lowe     int res = DW_DLV_ERROR;
48949d3bc91SRichard Lowe 
49049d3bc91SRichard Lowe     /* ***** BEGIN CODE ***** */
49149d3bc91SRichard Lowe 
49249d3bc91SRichard Lowe     if (error != NULL)
49307dc1947SRichard Lowe         *error = NULL;
49449d3bc91SRichard Lowe 
49549d3bc91SRichard Lowe     if (dbg == NULL) {
49607dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
49707dc1947SRichard Lowe         return (DW_DLV_ERROR);
49849d3bc91SRichard Lowe     }
49949d3bc91SRichard Lowe 
50007dc1947SRichard Lowe     res = _dwarf_load_section(dbg, &dbg->de_debug_aranges,error);
50149d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
50249d3bc91SRichard Lowe         return res;
50349d3bc91SRichard Lowe     }
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     }
51007dc1947SRichard Lowe     res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
511*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
51207dc1947SRichard Lowe         return res;
51349d3bc91SRichard Lowe     }
51449d3bc91SRichard Lowe     arange_addrs = (Dwarf_Addr *)
51507dc1947SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
51649d3bc91SRichard Lowe     if (arange_addrs == NULL) {
51707dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
51807dc1947SRichard Lowe         return (DW_DLV_ERROR);
51949d3bc91SRichard Lowe     }
52049d3bc91SRichard Lowe     arange_offsets = (Dwarf_Off *)
52107dc1947SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
52249d3bc91SRichard Lowe     if (arange_offsets == NULL) {
52307dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
52407dc1947SRichard Lowe         return (DW_DLV_ERROR);
52549d3bc91SRichard Lowe     }
52649d3bc91SRichard Lowe 
52749d3bc91SRichard Lowe     curr_chain = head_chain;
52849d3bc91SRichard Lowe     for (i = 0; i < arange_count; i++) {
52907dc1947SRichard Lowe         Dwarf_Arange ar = curr_chain->ch_item;
530*4d9fdb46SRobert Mustacchi         int itemtype = curr_chain->ch_itemtype;
53107dc1947SRichard Lowe 
532*4d9fdb46SRobert Mustacchi         curr_chain->ch_item = 0;
53307dc1947SRichard Lowe         arange_addrs[i] = ar->ar_address;
53407dc1947SRichard Lowe         arange_offsets[i] = ar->ar_info_offset;
53507dc1947SRichard Lowe         prev_chain = curr_chain;
53607dc1947SRichard Lowe         curr_chain = curr_chain->ch_next;
537*4d9fdb46SRobert Mustacchi         if (ar && itemtype) {
538*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg, ar, itemtype);
539*4d9fdb46SRobert Mustacchi         }
54007dc1947SRichard Lowe         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
54149d3bc91SRichard Lowe     }
54249d3bc91SRichard Lowe     *count = arange_count;
54349d3bc91SRichard Lowe     *offsets = arange_offsets;
54449d3bc91SRichard Lowe     *addrs = arange_addrs;
54549d3bc91SRichard Lowe     return (DW_DLV_OK);
54649d3bc91SRichard Lowe }
54749d3bc91SRichard Lowe 
54849d3bc91SRichard Lowe 
54949d3bc91SRichard Lowe /*
55049d3bc91SRichard Lowe     This function takes a pointer to a block
55149d3bc91SRichard Lowe     of Dwarf_Arange's, and a count of the
55249d3bc91SRichard Lowe     length of the block.  It checks if the
55349d3bc91SRichard Lowe     given address is within the range of an
55449d3bc91SRichard Lowe     address range in the block.  If yes, it
55549d3bc91SRichard Lowe     returns the appropriate Dwarf_Arange.
55649d3bc91SRichard Lowe     Otherwise, it returns DW_DLV_ERROR.
55749d3bc91SRichard Lowe */
55849d3bc91SRichard Lowe int
dwarf_get_arange(Dwarf_Arange * aranges,Dwarf_Unsigned arange_count,Dwarf_Addr address,Dwarf_Arange * returned_arange,Dwarf_Error * error)55949d3bc91SRichard Lowe dwarf_get_arange(Dwarf_Arange * aranges,
56007dc1947SRichard Lowe     Dwarf_Unsigned arange_count,
56107dc1947SRichard Lowe     Dwarf_Addr address,
56207dc1947SRichard Lowe     Dwarf_Arange * returned_arange, Dwarf_Error * error)
56349d3bc91SRichard Lowe {
56407dc1947SRichard Lowe     Dwarf_Arange curr_arange = 0;
56507dc1947SRichard Lowe     Dwarf_Unsigned i = 0;
56649d3bc91SRichard Lowe 
56749d3bc91SRichard Lowe     if (aranges == NULL) {
56807dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL);
56907dc1947SRichard Lowe         return (DW_DLV_ERROR);
57049d3bc91SRichard Lowe     }
57149d3bc91SRichard Lowe     for (i = 0; i < arange_count; i++) {
57207dc1947SRichard Lowe         curr_arange = *(aranges + i);
57307dc1947SRichard Lowe         if (address >= curr_arange->ar_address &&
57407dc1947SRichard Lowe             address <
57507dc1947SRichard Lowe             curr_arange->ar_address + curr_arange->ar_length) {
57607dc1947SRichard Lowe             *returned_arange = curr_arange;
57707dc1947SRichard Lowe             return (DW_DLV_OK);
57807dc1947SRichard Lowe         }
57949d3bc91SRichard Lowe     }
58049d3bc91SRichard Lowe 
58149d3bc91SRichard Lowe     return (DW_DLV_NO_ENTRY);
58249d3bc91SRichard Lowe }
58349d3bc91SRichard Lowe 
58449d3bc91SRichard Lowe 
58549d3bc91SRichard Lowe /*
58649d3bc91SRichard Lowe     This function takes an Dwarf_Arange,
58749d3bc91SRichard Lowe     and returns the offset of the first
58849d3bc91SRichard Lowe     die in the compilation-unit that the
58949d3bc91SRichard Lowe     arange belongs to.  Returns DW_DLV_ERROR
59049d3bc91SRichard Lowe     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.
59449d3bc91SRichard Lowe */
59549d3bc91SRichard Lowe int
dwarf_get_cu_die_offset(Dwarf_Arange arange,Dwarf_Off * returned_offset,Dwarf_Error * error)59649d3bc91SRichard Lowe dwarf_get_cu_die_offset(Dwarf_Arange arange,
59707dc1947SRichard Lowe     Dwarf_Off * returned_offset,
59807dc1947SRichard Lowe     Dwarf_Error * error)
59949d3bc91SRichard Lowe {
60007dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
60107dc1947SRichard Lowe     Dwarf_Off offset = 0;
602*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned headerlen = 0;
603*4d9fdb46SRobert Mustacchi     int cres = 0;
60449d3bc91SRichard Lowe 
60549d3bc91SRichard Lowe     if (arange == NULL) {
60607dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
60707dc1947SRichard Lowe         return (DW_DLV_ERROR);
60849d3bc91SRichard Lowe     }
60949d3bc91SRichard Lowe     dbg = arange->ar_dbg;
61049d3bc91SRichard Lowe     offset = arange->ar_info_offset;
611*4d9fdb46SRobert Mustacchi     /* This applies to debug_info only, not to debug_types. */
61207dc1947SRichard Lowe     if (!dbg->de_debug_info.dss_data) {
61307dc1947SRichard Lowe         int res = _dwarf_load_debug_info(dbg, error);
61407dc1947SRichard Lowe 
61507dc1947SRichard Lowe         if (res != DW_DLV_OK) {
61607dc1947SRichard Lowe             return res;
61749d3bc91SRichard Lowe         }
61849d3bc91SRichard Lowe     }
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;
62649d3bc91SRichard Lowe     return DW_DLV_OK;
62749d3bc91SRichard Lowe }
62849d3bc91SRichard Lowe 
629*4d9fdb46SRobert Mustacchi /*  This function takes an Dwarf_Arange,
63049d3bc91SRichard Lowe     and returns the offset of the CU header
63149d3bc91SRichard Lowe     in the compilation-unit that the
63249d3bc91SRichard Lowe     arange belongs to.  Returns DW_DLV_ERROR
633*4d9fdb46SRobert Mustacchi     on error.
63407dc1947SRichard Lowe     Ensures .debug_info loaded so
635*4d9fdb46SRobert Mustacchi     the cu_offset is meaningful.  */
63649d3bc91SRichard Lowe int
dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,Dwarf_Off * cu_header_offset_returned,Dwarf_Error * error)63749d3bc91SRichard Lowe dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,
63807dc1947SRichard Lowe     Dwarf_Off * cu_header_offset_returned,
63907dc1947SRichard Lowe     Dwarf_Error * error)
64049d3bc91SRichard Lowe {
64107dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
64249d3bc91SRichard Lowe     if (arange == NULL) {
64307dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
64407dc1947SRichard Lowe         return (DW_DLV_ERROR);
64507dc1947SRichard Lowe     }
64607dc1947SRichard Lowe     dbg = arange->ar_dbg;
647*4d9fdb46SRobert Mustacchi     /* This applies to debug_info only, not to debug_types. */
648*4d9fdb46SRobert Mustacchi     /*  Like dwarf_get_arange_info this ensures debug_info loaded:
649*4d9fdb46SRobert Mustacchi         the cu_header is in debug_info and will be used else
650*4d9fdb46SRobert Mustacchi         we would not call dwarf_get_arange_cu_header_offset. */
65107dc1947SRichard Lowe     if (!dbg->de_debug_info.dss_data) {
65207dc1947SRichard Lowe         int res = _dwarf_load_debug_info(dbg, error);
65307dc1947SRichard Lowe         if (res != DW_DLV_OK) {
654*4d9fdb46SRobert Mustacchi             return res;
65507dc1947SRichard Lowe         }
65649d3bc91SRichard Lowe     }
65749d3bc91SRichard Lowe     *cu_header_offset_returned = arange->ar_info_offset;
65849d3bc91SRichard Lowe     return DW_DLV_OK;
65949d3bc91SRichard Lowe }
66049d3bc91SRichard Lowe 
66149d3bc91SRichard Lowe 
66249d3bc91SRichard Lowe 
66307dc1947SRichard Lowe 
66449d3bc91SRichard Lowe /*
66549d3bc91SRichard Lowe     This function takes a Dwarf_Arange, and returns
66649d3bc91SRichard Lowe     true if it is not NULL.  It also stores the start
66749d3bc91SRichard Lowe     address of the range in *start, the length of the
66849d3bc91SRichard Lowe     range in *length, and the offset of the first die
66949d3bc91SRichard Lowe     in the compilation-unit in *cu_die_offset.  It
67049d3bc91SRichard Lowe     returns false on error.
67107dc1947SRichard Lowe     If cu_die_offset returned ensures .debug_info loaded so
67207dc1947SRichard Lowe     the cu_die_offset is meaningful.
67349d3bc91SRichard Lowe */
67449d3bc91SRichard Lowe int
dwarf_get_arange_info(Dwarf_Arange arange,Dwarf_Addr * start,Dwarf_Unsigned * length,Dwarf_Off * cu_die_offset,Dwarf_Error * error)67549d3bc91SRichard Lowe dwarf_get_arange_info(Dwarf_Arange arange,
67607dc1947SRichard Lowe     Dwarf_Addr * start,
67707dc1947SRichard Lowe     Dwarf_Unsigned * length,
67807dc1947SRichard Lowe     Dwarf_Off * cu_die_offset, Dwarf_Error * error)
67949d3bc91SRichard Lowe {
68049d3bc91SRichard Lowe     if (arange == NULL) {
68107dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
68207dc1947SRichard Lowe         return (DW_DLV_ERROR);
68349d3bc91SRichard Lowe     }
68449d3bc91SRichard Lowe 
68549d3bc91SRichard Lowe     if (start != NULL)
68607dc1947SRichard Lowe         *start = arange->ar_address;
68749d3bc91SRichard Lowe     if (length != NULL)
68807dc1947SRichard Lowe         *length = arange->ar_length;
68949d3bc91SRichard Lowe     if (cu_die_offset != NULL) {
69007dc1947SRichard Lowe         Dwarf_Debug dbg = arange->ar_dbg;
691*4d9fdb46SRobert Mustacchi         Dwarf_Off headerlen = 0;
69207dc1947SRichard Lowe         Dwarf_Off offset = arange->ar_info_offset;
693*4d9fdb46SRobert Mustacchi         int cres = 0;
69407dc1947SRichard Lowe 
695*4d9fdb46SRobert Mustacchi         /* This applies to debug_info only, not to debug_types. */
69607dc1947SRichard Lowe         if (!dbg->de_debug_info.dss_data) {
69707dc1947SRichard Lowe             int res = _dwarf_load_debug_info(dbg, error);
69807dc1947SRichard Lowe             if (res != DW_DLV_OK) {
69907dc1947SRichard Lowe                 return res;
70007dc1947SRichard Lowe             }
70149d3bc91SRichard Lowe         }
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;
70949d3bc91SRichard Lowe     }
71049d3bc91SRichard Lowe     return (DW_DLV_OK);
71149d3bc91SRichard Lowe }
71207dc1947SRichard Lowe 
71307dc1947SRichard Lowe 
714*4d9fdb46SRobert Mustacchi /* New for DWARF4, entries may have segment information.
71507dc1947SRichard Lowe    *segment is only meaningful if *segment_entry_size is non-zero. */
716*4d9fdb46SRobert 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)71707dc1947SRichard Lowe dwarf_get_arange_info_b(Dwarf_Arange arange,
71807dc1947SRichard Lowe     Dwarf_Unsigned*  segment,
71907dc1947SRichard Lowe     Dwarf_Unsigned*  segment_entry_size,
72007dc1947SRichard Lowe     Dwarf_Addr    * start,
72107dc1947SRichard Lowe     Dwarf_Unsigned* length,
722*4d9fdb46SRobert Mustacchi     Dwarf_Off     * cu_die_offset,
72307dc1947SRichard Lowe     Dwarf_Error   * error)
724*4d9fdb46SRobert Mustacchi {
72507dc1947SRichard Lowe     if (arange == NULL) {
72607dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
727*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
72807dc1947SRichard Lowe     }
729*4d9fdb46SRobert Mustacchi 
730*4d9fdb46SRobert Mustacchi     if (segment != NULL) {
731*4d9fdb46SRobert Mustacchi         *segment = arange->ar_segment_selector;
73207dc1947SRichard Lowe     }
733*4d9fdb46SRobert Mustacchi     if (segment_entry_size != NULL) {
734*4d9fdb46SRobert Mustacchi         *segment_entry_size = arange->ar_segment_selector_size;
73507dc1947SRichard Lowe     }
73607dc1947SRichard Lowe     if (start != NULL)
73707dc1947SRichard Lowe         *start = arange->ar_address;
73807dc1947SRichard Lowe     if (length != NULL)
73907dc1947SRichard Lowe         *length = arange->ar_length;
74007dc1947SRichard Lowe     if (cu_die_offset != NULL) {
74107dc1947SRichard Lowe         Dwarf_Debug dbg = arange->ar_dbg;
74207dc1947SRichard Lowe         Dwarf_Off offset = arange->ar_info_offset;
743*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned headerlen = 0;
744*4d9fdb46SRobert Mustacchi         int cres = 0;
74507dc1947SRichard Lowe 
746*4d9fdb46SRobert Mustacchi         /* This applies to debug_info only, not to debug_types. */
74707dc1947SRichard Lowe         if (!dbg->de_debug_info.dss_data) {
74807dc1947SRichard Lowe             int res = _dwarf_load_debug_info(dbg, error);
74907dc1947SRichard Lowe             if (res != DW_DLV_OK) {
75007dc1947SRichard Lowe                 return res;
75107dc1947SRichard Lowe             }
75207dc1947SRichard Lowe         }
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 
76007dc1947SRichard Lowe     }
76107dc1947SRichard Lowe     return (DW_DLV_OK);
762*4d9fdb46SRobert Mustacchi }
763