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