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