1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi
3*7fd79137SRobert Mustacchi Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
4*7fd79137SRobert Mustacchi Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5*7fd79137SRobert Mustacchi
6*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it
7*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License
8*7fd79137SRobert Mustacchi as published by the Free Software Foundation.
9*7fd79137SRobert Mustacchi
10*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but
11*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of
12*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*7fd79137SRobert Mustacchi
14*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is
15*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement
16*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or
17*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if
18*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with
19*7fd79137SRobert Mustacchi other software, or any other product whatsoever.
20*7fd79137SRobert Mustacchi
21*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public
22*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software
23*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*7fd79137SRobert Mustacchi USA.
25*7fd79137SRobert Mustacchi
26*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27*7fd79137SRobert Mustacchi Mountain View, CA 94043, or:
28*7fd79137SRobert Mustacchi
29*7fd79137SRobert Mustacchi http://www.sgi.com
30*7fd79137SRobert Mustacchi
31*7fd79137SRobert Mustacchi For further information regarding this notice, see:
32*7fd79137SRobert Mustacchi
33*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*7fd79137SRobert Mustacchi
35*7fd79137SRobert Mustacchi */
36*7fd79137SRobert Mustacchi /* The address of the Free Software Foundation is
37*7fd79137SRobert Mustacchi Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*7fd79137SRobert Mustacchi Boston, MA 02110-1301, USA.
39*7fd79137SRobert Mustacchi SGI has moved from the Crittenden Lane address.
40*7fd79137SRobert Mustacchi */
41*7fd79137SRobert Mustacchi
42*7fd79137SRobert Mustacchi
43*7fd79137SRobert Mustacchi
44*7fd79137SRobert Mustacchi
45*7fd79137SRobert Mustacchi
46*7fd79137SRobert Mustacchi
47*7fd79137SRobert Mustacchi #include "config.h"
48*7fd79137SRobert Mustacchi #include "dwarf_incl.h"
49*7fd79137SRobert Mustacchi #include <stdio.h>
50*7fd79137SRobert Mustacchi #include "dwarf_arange.h"
51*7fd79137SRobert Mustacchi #include "dwarf_global.h" /* for _dwarf_fixup_* */
52*7fd79137SRobert Mustacchi
53*7fd79137SRobert Mustacchi
54*7fd79137SRobert Mustacchi /* Common code for two user-visible routines to share.
55*7fd79137SRobert Mustacchi Errors here result in memory leaks, but errors here
56*7fd79137SRobert Mustacchi are serious (making aranges unusable) so we assume
57*7fd79137SRobert Mustacchi callers will not repeat the error often or mind the leaks.
58*7fd79137SRobert Mustacchi */
59*7fd79137SRobert Mustacchi static int
dwarf_get_aranges_list(Dwarf_Debug dbg,Dwarf_Chain * chain_out,Dwarf_Signed * chain_count_out,Dwarf_Error * error)60*7fd79137SRobert Mustacchi dwarf_get_aranges_list(Dwarf_Debug dbg,
61*7fd79137SRobert Mustacchi Dwarf_Chain * chain_out,
62*7fd79137SRobert Mustacchi Dwarf_Signed * chain_count_out,
63*7fd79137SRobert Mustacchi Dwarf_Error * error)
64*7fd79137SRobert Mustacchi {
65*7fd79137SRobert Mustacchi /* Sweeps through the arange. */
66*7fd79137SRobert Mustacchi Dwarf_Small *arange_ptr = 0;
67*7fd79137SRobert Mustacchi Dwarf_Small *arange_ptr_start = 0;
68*7fd79137SRobert Mustacchi
69*7fd79137SRobert Mustacchi /* Start of arange header. Used for rounding offset of arange_ptr
70*7fd79137SRobert Mustacchi to twice the tuple size. Libdwarf requirement. */
71*7fd79137SRobert Mustacchi Dwarf_Small *header_ptr = 0;
72*7fd79137SRobert Mustacchi
73*7fd79137SRobert Mustacchi /* Version of .debug_aranges header. */
74*7fd79137SRobert Mustacchi Dwarf_Half version = 0;
75*7fd79137SRobert Mustacchi
76*7fd79137SRobert Mustacchi /* Offset of current set of aranges into .debug_info. */
77*7fd79137SRobert Mustacchi Dwarf_Off info_offset = 0;
78*7fd79137SRobert Mustacchi
79*7fd79137SRobert Mustacchi /* Size in bytes of addresses in target. */
80*7fd79137SRobert Mustacchi Dwarf_Small address_size = 0;
81*7fd79137SRobert Mustacchi
82*7fd79137SRobert Mustacchi /* Size in bytes of segment offsets in target. */
83*7fd79137SRobert Mustacchi Dwarf_Small segment_size = 0;
84*7fd79137SRobert Mustacchi
85*7fd79137SRobert Mustacchi /* Count of total number of aranges. */
86*7fd79137SRobert Mustacchi Dwarf_Unsigned arange_count = 0;
87*7fd79137SRobert Mustacchi
88*7fd79137SRobert Mustacchi Dwarf_Arange arange = 0;
89*7fd79137SRobert Mustacchi
90*7fd79137SRobert Mustacchi /* Used to chain Dwarf_Aranges structs. */
91*7fd79137SRobert Mustacchi Dwarf_Chain curr_chain = NULL;
92*7fd79137SRobert Mustacchi Dwarf_Chain prev_chain = NULL;
93*7fd79137SRobert Mustacchi Dwarf_Chain head_chain = NULL;
94*7fd79137SRobert Mustacchi
95*7fd79137SRobert Mustacchi arange_ptr = dbg->de_debug_aranges.dss_data;
96*7fd79137SRobert Mustacchi arange_ptr_start = arange_ptr;
97*7fd79137SRobert Mustacchi do {
98*7fd79137SRobert Mustacchi /* Length of current set of aranges. */
99*7fd79137SRobert Mustacchi Dwarf_Unsigned length = 0;
100*7fd79137SRobert Mustacchi Dwarf_Small remainder = 0;
101*7fd79137SRobert Mustacchi Dwarf_Small *arange_ptr_past_end = 0;
102*7fd79137SRobert Mustacchi Dwarf_Unsigned range_entry_size = 0;
103*7fd79137SRobert Mustacchi
104*7fd79137SRobert Mustacchi int local_length_size;
105*7fd79137SRobert Mustacchi
106*7fd79137SRobert Mustacchi /*REFERENCED*/ /* Not used in this instance of the macro */
107*7fd79137SRobert Mustacchi int local_extension_size = 0;
108*7fd79137SRobert Mustacchi
109*7fd79137SRobert Mustacchi header_ptr = arange_ptr;
110*7fd79137SRobert Mustacchi
111*7fd79137SRobert Mustacchi /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */
112*7fd79137SRobert Mustacchi READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
113*7fd79137SRobert Mustacchi arange_ptr, local_length_size,
114*7fd79137SRobert Mustacchi local_extension_size);
115*7fd79137SRobert Mustacchi arange_ptr_past_end = arange_ptr + length;
116*7fd79137SRobert Mustacchi
117*7fd79137SRobert Mustacchi
118*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, version, Dwarf_Half,
119*7fd79137SRobert Mustacchi arange_ptr, sizeof(Dwarf_Half));
120*7fd79137SRobert Mustacchi arange_ptr += sizeof(Dwarf_Half);
121*7fd79137SRobert Mustacchi length = length - sizeof(Dwarf_Half);
122*7fd79137SRobert Mustacchi if (version != CURRENT_VERSION_STAMP) {
123*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
124*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
125*7fd79137SRobert Mustacchi }
126*7fd79137SRobert Mustacchi
127*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, info_offset, Dwarf_Off,
128*7fd79137SRobert Mustacchi arange_ptr, local_length_size);
129*7fd79137SRobert Mustacchi arange_ptr += local_length_size;
130*7fd79137SRobert Mustacchi length = length - local_length_size;
131*7fd79137SRobert Mustacchi if (info_offset >= dbg->de_debug_info.dss_size) {
132*7fd79137SRobert Mustacchi FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset,
133*7fd79137SRobert Mustacchi "arange info offset.a");
134*7fd79137SRobert Mustacchi if (info_offset >= dbg->de_debug_info.dss_size) {
135*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
136*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
137*7fd79137SRobert Mustacchi }
138*7fd79137SRobert Mustacchi }
139*7fd79137SRobert Mustacchi
140*7fd79137SRobert Mustacchi address_size = *(Dwarf_Small *) arange_ptr;
141*7fd79137SRobert Mustacchi /* It is not an error if the sizes differ.
142*7fd79137SRobert Mustacchi Unusual, but not an error. */
143*7fd79137SRobert Mustacchi arange_ptr = arange_ptr + sizeof(Dwarf_Small);
144*7fd79137SRobert Mustacchi length = length - sizeof(Dwarf_Small);
145*7fd79137SRobert Mustacchi
146*7fd79137SRobert Mustacchi segment_size = *(Dwarf_Small *) arange_ptr;
147*7fd79137SRobert Mustacchi arange_ptr = arange_ptr + sizeof(Dwarf_Small);
148*7fd79137SRobert Mustacchi length = length - sizeof(Dwarf_Small);
149*7fd79137SRobert Mustacchi if (segment_size != 0) {
150*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
151*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
152*7fd79137SRobert Mustacchi }
153*7fd79137SRobert Mustacchi
154*7fd79137SRobert Mustacchi range_entry_size = 2*address_size + segment_size;
155*7fd79137SRobert Mustacchi /* Round arange_ptr offset to next multiple of address_size. */
156*7fd79137SRobert Mustacchi remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) %
157*7fd79137SRobert Mustacchi (range_entry_size);
158*7fd79137SRobert Mustacchi if (remainder != 0) {
159*7fd79137SRobert Mustacchi arange_ptr = arange_ptr + (2 * address_size) - remainder;
160*7fd79137SRobert Mustacchi length = length - ((2 * address_size) - remainder);
161*7fd79137SRobert Mustacchi }
162*7fd79137SRobert Mustacchi do {
163*7fd79137SRobert Mustacchi Dwarf_Addr range_address = 0;
164*7fd79137SRobert Mustacchi Dwarf_Unsigned segment_selector = 0;
165*7fd79137SRobert Mustacchi Dwarf_Unsigned range_length = 0;
166*7fd79137SRobert Mustacchi /* For segmented address spaces, the first field to
167*7fd79137SRobert Mustacchi read is a segment selector (new in DWARF4) */
168*7fd79137SRobert Mustacchi if(version == 4 && segment_size != 0) {
169*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, segment_selector, Dwarf_Unsigned,
170*7fd79137SRobert Mustacchi arange_ptr, segment_size);
171*7fd79137SRobert Mustacchi arange_ptr += address_size;
172*7fd79137SRobert Mustacchi length = length - address_size;
173*7fd79137SRobert Mustacchi }
174*7fd79137SRobert Mustacchi
175*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, range_address, Dwarf_Addr,
176*7fd79137SRobert Mustacchi arange_ptr, address_size);
177*7fd79137SRobert Mustacchi arange_ptr += address_size;
178*7fd79137SRobert Mustacchi length = length - address_size;
179*7fd79137SRobert Mustacchi
180*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned,
181*7fd79137SRobert Mustacchi arange_ptr, address_size);
182*7fd79137SRobert Mustacchi arange_ptr += address_size;
183*7fd79137SRobert Mustacchi length = length - address_size;
184*7fd79137SRobert Mustacchi
185*7fd79137SRobert Mustacchi { /* We used to suppress all-zero entries, but
186*7fd79137SRobert Mustacchi now we return all aranges entries so we show
187*7fd79137SRobert Mustacchi the entire content. March 31, 2010. */
188*7fd79137SRobert Mustacchi
189*7fd79137SRobert Mustacchi arange = (Dwarf_Arange)
190*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
191*7fd79137SRobert Mustacchi if (arange == NULL) {
192*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
193*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
194*7fd79137SRobert Mustacchi }
195*7fd79137SRobert Mustacchi
196*7fd79137SRobert Mustacchi arange->ar_segment_selector = segment_selector;
197*7fd79137SRobert Mustacchi arange->ar_segment_selector_size = segment_size;
198*7fd79137SRobert Mustacchi arange->ar_address = range_address;
199*7fd79137SRobert Mustacchi arange->ar_length = range_length;
200*7fd79137SRobert Mustacchi arange->ar_info_offset = info_offset;
201*7fd79137SRobert Mustacchi arange->ar_dbg = dbg;
202*7fd79137SRobert Mustacchi arange_count++;
203*7fd79137SRobert Mustacchi
204*7fd79137SRobert Mustacchi curr_chain = (Dwarf_Chain)
205*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
206*7fd79137SRobert Mustacchi if (curr_chain == NULL) {
207*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
208*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
209*7fd79137SRobert Mustacchi }
210*7fd79137SRobert Mustacchi
211*7fd79137SRobert Mustacchi curr_chain->ch_item = arange;
212*7fd79137SRobert Mustacchi if (head_chain == NULL)
213*7fd79137SRobert Mustacchi head_chain = prev_chain = curr_chain;
214*7fd79137SRobert Mustacchi else {
215*7fd79137SRobert Mustacchi prev_chain->ch_next = curr_chain;
216*7fd79137SRobert Mustacchi prev_chain = curr_chain;
217*7fd79137SRobert Mustacchi }
218*7fd79137SRobert Mustacchi }
219*7fd79137SRobert Mustacchi /* The current set of ranges is terminated by
220*7fd79137SRobert Mustacchi range_address 0 and range_length 0, but that
221*7fd79137SRobert Mustacchi does not necessarily terminate the ranges for this CU!
222*7fd79137SRobert Mustacchi There can be multiple sets in that DWARF
223*7fd79137SRobert Mustacchi does not explicitly forbid multiple sets.
224*7fd79137SRobert Mustacchi DWARF2,3,4 section 7.20
225*7fd79137SRobert Mustacchi We stop short to avoid overrun of the end of the CU.
226*7fd79137SRobert Mustacchi */
227*7fd79137SRobert Mustacchi
228*7fd79137SRobert Mustacchi } while (arange_ptr_past_end >= (arange_ptr + range_entry_size));
229*7fd79137SRobert Mustacchi
230*7fd79137SRobert Mustacchi /* A compiler could emit some padding bytes here. dwarf2/3
231*7fd79137SRobert Mustacchi (dwarf4 sec 7.20) does not clearly make extra padding
232*7fd79137SRobert Mustacchi bytes illegal. */
233*7fd79137SRobert Mustacchi if (arange_ptr_past_end < arange_ptr) {
234*7fd79137SRobert Mustacchi char buf[200];
235*7fd79137SRobert Mustacchi Dwarf_Unsigned pad_count = arange_ptr - arange_ptr_past_end;
236*7fd79137SRobert Mustacchi Dwarf_Unsigned offset = arange_ptr - arange_ptr_start;
237*7fd79137SRobert Mustacchi snprintf(buf,sizeof(buf),"DW_DLE_ARANGE_LENGTH_BAD."
238*7fd79137SRobert Mustacchi " 0x%" DW_PR_DUx
239*7fd79137SRobert Mustacchi " pad bytes at offset 0x%" DW_PR_DUx
240*7fd79137SRobert Mustacchi " in .debug_aranges",
241*7fd79137SRobert Mustacchi pad_count, offset);
242*7fd79137SRobert Mustacchi dwarf_insert_harmless_error(dbg,buf);
243*7fd79137SRobert Mustacchi }
244*7fd79137SRobert Mustacchi /* For most compilers, arange_ptr == arange_ptr_past_end at
245*7fd79137SRobert Mustacchi this point. But not if there were padding bytes */
246*7fd79137SRobert Mustacchi arange_ptr = arange_ptr_past_end;
247*7fd79137SRobert Mustacchi } while (arange_ptr <
248*7fd79137SRobert Mustacchi dbg->de_debug_aranges.dss_data + dbg->de_debug_aranges.dss_size);
249*7fd79137SRobert Mustacchi
250*7fd79137SRobert Mustacchi if (arange_ptr !=
251*7fd79137SRobert Mustacchi dbg->de_debug_aranges.dss_data + dbg->de_debug_aranges.dss_size) {
252*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
253*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
254*7fd79137SRobert Mustacchi }
255*7fd79137SRobert Mustacchi *chain_out = head_chain;
256*7fd79137SRobert Mustacchi *chain_count_out = arange_count;
257*7fd79137SRobert Mustacchi return DW_DLV_OK;
258*7fd79137SRobert Mustacchi }
259*7fd79137SRobert Mustacchi
260*7fd79137SRobert Mustacchi /*
261*7fd79137SRobert Mustacchi This function returns the count of the number of
262*7fd79137SRobert Mustacchi aranges in the .debug_aranges section. It sets
263*7fd79137SRobert Mustacchi aranges to point to a block of Dwarf_Arange's
264*7fd79137SRobert Mustacchi describing the arange's. It returns DW_DLV_ERROR
265*7fd79137SRobert Mustacchi on error.
266*7fd79137SRobert Mustacchi
267*7fd79137SRobert Mustacchi Must be identical in most aspects to
268*7fd79137SRobert Mustacchi dwarf_get_aranges_addr_offsets!
269*7fd79137SRobert Mustacchi
270*7fd79137SRobert Mustacchi */
271*7fd79137SRobert Mustacchi int
dwarf_get_aranges(Dwarf_Debug dbg,Dwarf_Arange ** aranges,Dwarf_Signed * returned_count,Dwarf_Error * error)272*7fd79137SRobert Mustacchi dwarf_get_aranges(Dwarf_Debug dbg,
273*7fd79137SRobert Mustacchi Dwarf_Arange ** aranges,
274*7fd79137SRobert Mustacchi Dwarf_Signed * returned_count, Dwarf_Error * error)
275*7fd79137SRobert Mustacchi {
276*7fd79137SRobert Mustacchi /* Count of total number of aranges. */
277*7fd79137SRobert Mustacchi Dwarf_Signed arange_count = 0;
278*7fd79137SRobert Mustacchi
279*7fd79137SRobert Mustacchi Dwarf_Arange *arange_block = 0;
280*7fd79137SRobert Mustacchi
281*7fd79137SRobert Mustacchi /* Used to chain Dwarf_Aranges structs. */
282*7fd79137SRobert Mustacchi Dwarf_Chain curr_chain = NULL;
283*7fd79137SRobert Mustacchi Dwarf_Chain prev_chain = NULL;
284*7fd79137SRobert Mustacchi Dwarf_Chain head_chain = NULL;
285*7fd79137SRobert Mustacchi Dwarf_Unsigned i = 0;
286*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR;
287*7fd79137SRobert Mustacchi
288*7fd79137SRobert Mustacchi /* ***** BEGIN CODE ***** */
289*7fd79137SRobert Mustacchi
290*7fd79137SRobert Mustacchi if (dbg == NULL) {
291*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
292*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
293*7fd79137SRobert Mustacchi }
294*7fd79137SRobert Mustacchi
295*7fd79137SRobert Mustacchi res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error);
296*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
297*7fd79137SRobert Mustacchi return res;
298*7fd79137SRobert Mustacchi }
299*7fd79137SRobert Mustacchi
300*7fd79137SRobert Mustacchi res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
301*7fd79137SRobert Mustacchi if(res != DW_DLV_OK) {
302*7fd79137SRobert Mustacchi return res;
303*7fd79137SRobert Mustacchi }
304*7fd79137SRobert Mustacchi
305*7fd79137SRobert Mustacchi arange_block = (Dwarf_Arange *)
306*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count);
307*7fd79137SRobert Mustacchi if (arange_block == NULL) {
308*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
309*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
310*7fd79137SRobert Mustacchi }
311*7fd79137SRobert Mustacchi
312*7fd79137SRobert Mustacchi curr_chain = head_chain;
313*7fd79137SRobert Mustacchi for (i = 0; i < arange_count; i++) {
314*7fd79137SRobert Mustacchi *(arange_block + i) = curr_chain->ch_item;
315*7fd79137SRobert Mustacchi prev_chain = curr_chain;
316*7fd79137SRobert Mustacchi curr_chain = curr_chain->ch_next;
317*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
318*7fd79137SRobert Mustacchi }
319*7fd79137SRobert Mustacchi
320*7fd79137SRobert Mustacchi *aranges = arange_block;
321*7fd79137SRobert Mustacchi *returned_count = (arange_count);
322*7fd79137SRobert Mustacchi return DW_DLV_OK;
323*7fd79137SRobert Mustacchi }
324*7fd79137SRobert Mustacchi
325*7fd79137SRobert Mustacchi /*
326*7fd79137SRobert Mustacchi This function returns DW_DLV_OK if it succeeds
327*7fd79137SRobert Mustacchi and DW_DLV_ERR or DW_DLV_OK otherwise.
328*7fd79137SRobert Mustacchi count is set to the number of addresses in the
329*7fd79137SRobert Mustacchi .debug_aranges section.
330*7fd79137SRobert Mustacchi For each address, the corresponding element in
331*7fd79137SRobert Mustacchi an array is set to the address itself(aranges) and
332*7fd79137SRobert Mustacchi the section offset (offsets).
333*7fd79137SRobert Mustacchi Must be identical in most aspects to
334*7fd79137SRobert Mustacchi dwarf_get_aranges!
335*7fd79137SRobert Mustacchi */
336*7fd79137SRobert Mustacchi int
_dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,Dwarf_Addr ** addrs,Dwarf_Off ** offsets,Dwarf_Signed * count,Dwarf_Error * error)337*7fd79137SRobert Mustacchi _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,
338*7fd79137SRobert Mustacchi Dwarf_Addr ** addrs,
339*7fd79137SRobert Mustacchi Dwarf_Off ** offsets,
340*7fd79137SRobert Mustacchi Dwarf_Signed * count,
341*7fd79137SRobert Mustacchi Dwarf_Error * error)
342*7fd79137SRobert Mustacchi {
343*7fd79137SRobert Mustacchi Dwarf_Unsigned i = 0;
344*7fd79137SRobert Mustacchi
345*7fd79137SRobert Mustacchi /* Used to chain Dwarf_Aranges structs. */
346*7fd79137SRobert Mustacchi Dwarf_Chain curr_chain = NULL;
347*7fd79137SRobert Mustacchi Dwarf_Chain prev_chain = NULL;
348*7fd79137SRobert Mustacchi Dwarf_Chain head_chain = NULL;
349*7fd79137SRobert Mustacchi
350*7fd79137SRobert Mustacchi Dwarf_Signed arange_count = 0;
351*7fd79137SRobert Mustacchi Dwarf_Addr *arange_addrs = 0;
352*7fd79137SRobert Mustacchi Dwarf_Off *arange_offsets = 0;
353*7fd79137SRobert Mustacchi
354*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR;
355*7fd79137SRobert Mustacchi
356*7fd79137SRobert Mustacchi /* ***** BEGIN CODE ***** */
357*7fd79137SRobert Mustacchi
358*7fd79137SRobert Mustacchi if (error != NULL)
359*7fd79137SRobert Mustacchi *error = NULL;
360*7fd79137SRobert Mustacchi
361*7fd79137SRobert Mustacchi if (dbg == NULL) {
362*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
363*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
364*7fd79137SRobert Mustacchi }
365*7fd79137SRobert Mustacchi
366*7fd79137SRobert Mustacchi res = _dwarf_load_section(dbg, &dbg->de_debug_aranges,error);
367*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
368*7fd79137SRobert Mustacchi return res;
369*7fd79137SRobert Mustacchi }
370*7fd79137SRobert Mustacchi
371*7fd79137SRobert Mustacchi res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
372*7fd79137SRobert Mustacchi if(res != DW_DLV_OK) {
373*7fd79137SRobert Mustacchi return res;
374*7fd79137SRobert Mustacchi }
375*7fd79137SRobert Mustacchi
376*7fd79137SRobert Mustacchi arange_addrs = (Dwarf_Addr *)
377*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
378*7fd79137SRobert Mustacchi if (arange_addrs == NULL) {
379*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
380*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
381*7fd79137SRobert Mustacchi }
382*7fd79137SRobert Mustacchi arange_offsets = (Dwarf_Off *)
383*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
384*7fd79137SRobert Mustacchi if (arange_offsets == NULL) {
385*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
386*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
387*7fd79137SRobert Mustacchi }
388*7fd79137SRobert Mustacchi
389*7fd79137SRobert Mustacchi curr_chain = head_chain;
390*7fd79137SRobert Mustacchi for (i = 0; i < arange_count; i++) {
391*7fd79137SRobert Mustacchi Dwarf_Arange ar = curr_chain->ch_item;
392*7fd79137SRobert Mustacchi
393*7fd79137SRobert Mustacchi arange_addrs[i] = ar->ar_address;
394*7fd79137SRobert Mustacchi arange_offsets[i] = ar->ar_info_offset;
395*7fd79137SRobert Mustacchi prev_chain = curr_chain;
396*7fd79137SRobert Mustacchi curr_chain = curr_chain->ch_next;
397*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
398*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
399*7fd79137SRobert Mustacchi }
400*7fd79137SRobert Mustacchi *count = arange_count;
401*7fd79137SRobert Mustacchi *offsets = arange_offsets;
402*7fd79137SRobert Mustacchi *addrs = arange_addrs;
403*7fd79137SRobert Mustacchi return (DW_DLV_OK);
404*7fd79137SRobert Mustacchi }
405*7fd79137SRobert Mustacchi
406*7fd79137SRobert Mustacchi
407*7fd79137SRobert Mustacchi /*
408*7fd79137SRobert Mustacchi This function takes a pointer to a block
409*7fd79137SRobert Mustacchi of Dwarf_Arange's, and a count of the
410*7fd79137SRobert Mustacchi length of the block. It checks if the
411*7fd79137SRobert Mustacchi given address is within the range of an
412*7fd79137SRobert Mustacchi address range in the block. If yes, it
413*7fd79137SRobert Mustacchi returns the appropriate Dwarf_Arange.
414*7fd79137SRobert Mustacchi Otherwise, it returns DW_DLV_ERROR.
415*7fd79137SRobert Mustacchi */
416*7fd79137SRobert Mustacchi int
dwarf_get_arange(Dwarf_Arange * aranges,Dwarf_Unsigned arange_count,Dwarf_Addr address,Dwarf_Arange * returned_arange,Dwarf_Error * error)417*7fd79137SRobert Mustacchi dwarf_get_arange(Dwarf_Arange * aranges,
418*7fd79137SRobert Mustacchi Dwarf_Unsigned arange_count,
419*7fd79137SRobert Mustacchi Dwarf_Addr address,
420*7fd79137SRobert Mustacchi Dwarf_Arange * returned_arange, Dwarf_Error * error)
421*7fd79137SRobert Mustacchi {
422*7fd79137SRobert Mustacchi Dwarf_Arange curr_arange = 0;
423*7fd79137SRobert Mustacchi Dwarf_Unsigned i = 0;
424*7fd79137SRobert Mustacchi
425*7fd79137SRobert Mustacchi if (aranges == NULL) {
426*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL);
427*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
428*7fd79137SRobert Mustacchi }
429*7fd79137SRobert Mustacchi for (i = 0; i < arange_count; i++) {
430*7fd79137SRobert Mustacchi curr_arange = *(aranges + i);
431*7fd79137SRobert Mustacchi if (address >= curr_arange->ar_address &&
432*7fd79137SRobert Mustacchi address <
433*7fd79137SRobert Mustacchi curr_arange->ar_address + curr_arange->ar_length) {
434*7fd79137SRobert Mustacchi *returned_arange = curr_arange;
435*7fd79137SRobert Mustacchi return (DW_DLV_OK);
436*7fd79137SRobert Mustacchi }
437*7fd79137SRobert Mustacchi }
438*7fd79137SRobert Mustacchi
439*7fd79137SRobert Mustacchi return (DW_DLV_NO_ENTRY);
440*7fd79137SRobert Mustacchi }
441*7fd79137SRobert Mustacchi
442*7fd79137SRobert Mustacchi
443*7fd79137SRobert Mustacchi /*
444*7fd79137SRobert Mustacchi This function takes an Dwarf_Arange,
445*7fd79137SRobert Mustacchi and returns the offset of the first
446*7fd79137SRobert Mustacchi die in the compilation-unit that the
447*7fd79137SRobert Mustacchi arange belongs to. Returns DW_DLV_ERROR
448*7fd79137SRobert Mustacchi on error.
449*7fd79137SRobert Mustacchi */
450*7fd79137SRobert Mustacchi int
dwarf_get_cu_die_offset(Dwarf_Arange arange,Dwarf_Off * returned_offset,Dwarf_Error * error)451*7fd79137SRobert Mustacchi dwarf_get_cu_die_offset(Dwarf_Arange arange,
452*7fd79137SRobert Mustacchi Dwarf_Off * returned_offset,
453*7fd79137SRobert Mustacchi Dwarf_Error * error)
454*7fd79137SRobert Mustacchi {
455*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
456*7fd79137SRobert Mustacchi Dwarf_Off offset = 0;
457*7fd79137SRobert Mustacchi
458*7fd79137SRobert Mustacchi if (arange == NULL) {
459*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
460*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
461*7fd79137SRobert Mustacchi }
462*7fd79137SRobert Mustacchi dbg = arange->ar_dbg;
463*7fd79137SRobert Mustacchi offset = arange->ar_info_offset;
464*7fd79137SRobert Mustacchi if (!dbg->de_debug_info.dss_data) {
465*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error);
466*7fd79137SRobert Mustacchi
467*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
468*7fd79137SRobert Mustacchi return res;
469*7fd79137SRobert Mustacchi }
470*7fd79137SRobert Mustacchi }
471*7fd79137SRobert Mustacchi *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset);
472*7fd79137SRobert Mustacchi return DW_DLV_OK;
473*7fd79137SRobert Mustacchi }
474*7fd79137SRobert Mustacchi
475*7fd79137SRobert Mustacchi /*
476*7fd79137SRobert Mustacchi This function takes an Dwarf_Arange,
477*7fd79137SRobert Mustacchi and returns the offset of the CU header
478*7fd79137SRobert Mustacchi in the compilation-unit that the
479*7fd79137SRobert Mustacchi arange belongs to. Returns DW_DLV_ERROR
480*7fd79137SRobert Mustacchi on error.
481*7fd79137SRobert Mustacchi Ensures .debug_info loaded so
482*7fd79137SRobert Mustacchi the cu_offset is meaningful.
483*7fd79137SRobert Mustacchi */
484*7fd79137SRobert Mustacchi int
dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,Dwarf_Off * cu_header_offset_returned,Dwarf_Error * error)485*7fd79137SRobert Mustacchi dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,
486*7fd79137SRobert Mustacchi Dwarf_Off * cu_header_offset_returned,
487*7fd79137SRobert Mustacchi Dwarf_Error * error)
488*7fd79137SRobert Mustacchi {
489*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
490*7fd79137SRobert Mustacchi if (arange == NULL) {
491*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
492*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
493*7fd79137SRobert Mustacchi }
494*7fd79137SRobert Mustacchi dbg = arange->ar_dbg;
495*7fd79137SRobert Mustacchi /* Like dwarf_get_arange_info this ensures debug_info loaded:
496*7fd79137SRobert Mustacchi the cu_header is in debug_info and will be used else
497*7fd79137SRobert Mustacchi we would not call dwarf_get_arange_cu_header_offset. */
498*7fd79137SRobert Mustacchi if (!dbg->de_debug_info.dss_data) {
499*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error);
500*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
501*7fd79137SRobert Mustacchi return res;
502*7fd79137SRobert Mustacchi }
503*7fd79137SRobert Mustacchi }
504*7fd79137SRobert Mustacchi *cu_header_offset_returned = arange->ar_info_offset;
505*7fd79137SRobert Mustacchi return DW_DLV_OK;
506*7fd79137SRobert Mustacchi }
507*7fd79137SRobert Mustacchi
508*7fd79137SRobert Mustacchi
509*7fd79137SRobert Mustacchi
510*7fd79137SRobert Mustacchi
511*7fd79137SRobert Mustacchi /*
512*7fd79137SRobert Mustacchi This function takes a Dwarf_Arange, and returns
513*7fd79137SRobert Mustacchi true if it is not NULL. It also stores the start
514*7fd79137SRobert Mustacchi address of the range in *start, the length of the
515*7fd79137SRobert Mustacchi range in *length, and the offset of the first die
516*7fd79137SRobert Mustacchi in the compilation-unit in *cu_die_offset. It
517*7fd79137SRobert Mustacchi returns false on error.
518*7fd79137SRobert Mustacchi If cu_die_offset returned ensures .debug_info loaded so
519*7fd79137SRobert Mustacchi the cu_die_offset is meaningful.
520*7fd79137SRobert Mustacchi */
521*7fd79137SRobert Mustacchi int
dwarf_get_arange_info(Dwarf_Arange arange,Dwarf_Addr * start,Dwarf_Unsigned * length,Dwarf_Off * cu_die_offset,Dwarf_Error * error)522*7fd79137SRobert Mustacchi dwarf_get_arange_info(Dwarf_Arange arange,
523*7fd79137SRobert Mustacchi Dwarf_Addr * start,
524*7fd79137SRobert Mustacchi Dwarf_Unsigned * length,
525*7fd79137SRobert Mustacchi Dwarf_Off * cu_die_offset, Dwarf_Error * error)
526*7fd79137SRobert Mustacchi {
527*7fd79137SRobert Mustacchi if (arange == NULL) {
528*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
529*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
530*7fd79137SRobert Mustacchi }
531*7fd79137SRobert Mustacchi
532*7fd79137SRobert Mustacchi if (start != NULL)
533*7fd79137SRobert Mustacchi *start = arange->ar_address;
534*7fd79137SRobert Mustacchi if (length != NULL)
535*7fd79137SRobert Mustacchi *length = arange->ar_length;
536*7fd79137SRobert Mustacchi if (cu_die_offset != NULL) {
537*7fd79137SRobert Mustacchi Dwarf_Debug dbg = arange->ar_dbg;
538*7fd79137SRobert Mustacchi Dwarf_Off offset = arange->ar_info_offset;
539*7fd79137SRobert Mustacchi
540*7fd79137SRobert Mustacchi if (!dbg->de_debug_info.dss_data) {
541*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error);
542*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
543*7fd79137SRobert Mustacchi return res;
544*7fd79137SRobert Mustacchi }
545*7fd79137SRobert Mustacchi }
546*7fd79137SRobert Mustacchi *cu_die_offset =
547*7fd79137SRobert Mustacchi offset + _dwarf_length_of_cu_header(dbg, offset);
548*7fd79137SRobert Mustacchi }
549*7fd79137SRobert Mustacchi return (DW_DLV_OK);
550*7fd79137SRobert Mustacchi }
551*7fd79137SRobert Mustacchi
552*7fd79137SRobert Mustacchi
553*7fd79137SRobert Mustacchi /* New for DWARF4, entries may have segment information.
554*7fd79137SRobert Mustacchi *segment is only meaningful if *segment_entry_size is non-zero. */
555*7fd79137SRobert 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)556*7fd79137SRobert Mustacchi dwarf_get_arange_info_b(Dwarf_Arange arange,
557*7fd79137SRobert Mustacchi Dwarf_Unsigned* segment,
558*7fd79137SRobert Mustacchi Dwarf_Unsigned* segment_entry_size,
559*7fd79137SRobert Mustacchi Dwarf_Addr * start,
560*7fd79137SRobert Mustacchi Dwarf_Unsigned* length,
561*7fd79137SRobert Mustacchi Dwarf_Off * cu_die_offset,
562*7fd79137SRobert Mustacchi Dwarf_Error * error)
563*7fd79137SRobert Mustacchi {
564*7fd79137SRobert Mustacchi if (arange == NULL) {
565*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
566*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
567*7fd79137SRobert Mustacchi }
568*7fd79137SRobert Mustacchi
569*7fd79137SRobert Mustacchi if(segment != NULL) {
570*7fd79137SRobert Mustacchi *segment = arange->ar_segment_selector;
571*7fd79137SRobert Mustacchi }
572*7fd79137SRobert Mustacchi if(segment_entry_size != NULL) {
573*7fd79137SRobert Mustacchi *segment_entry_size = arange->ar_segment_selector_size;
574*7fd79137SRobert Mustacchi }
575*7fd79137SRobert Mustacchi if (start != NULL)
576*7fd79137SRobert Mustacchi *start = arange->ar_address;
577*7fd79137SRobert Mustacchi if (length != NULL)
578*7fd79137SRobert Mustacchi *length = arange->ar_length;
579*7fd79137SRobert Mustacchi if (cu_die_offset != NULL) {
580*7fd79137SRobert Mustacchi Dwarf_Debug dbg = arange->ar_dbg;
581*7fd79137SRobert Mustacchi Dwarf_Off offset = arange->ar_info_offset;
582*7fd79137SRobert Mustacchi
583*7fd79137SRobert Mustacchi if (!dbg->de_debug_info.dss_data) {
584*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error);
585*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
586*7fd79137SRobert Mustacchi return res;
587*7fd79137SRobert Mustacchi }
588*7fd79137SRobert Mustacchi }
589*7fd79137SRobert Mustacchi *cu_die_offset =
590*7fd79137SRobert Mustacchi offset + _dwarf_length_of_cu_header(dbg, offset);
591*7fd79137SRobert Mustacchi }
592*7fd79137SRobert Mustacchi return (DW_DLV_OK);
593*7fd79137SRobert Mustacchi }
594