xref: /titanic_51/usr/src/lib/libdwarf/common/dwarf_arange.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
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
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
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
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
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
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
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
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
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