1*4d9fdb46SRobert Mustacchi /*
2*4d9fdb46SRobert Mustacchi Copyright (c) 2020, David Anderson
3*4d9fdb46SRobert Mustacchi All rights reserved.
4*4d9fdb46SRobert Mustacchi
5*4d9fdb46SRobert Mustacchi Redistribution and use in source and binary forms, with
6*4d9fdb46SRobert Mustacchi or without modification, are permitted provided that the
7*4d9fdb46SRobert Mustacchi following conditions are met:
8*4d9fdb46SRobert Mustacchi
9*4d9fdb46SRobert Mustacchi Redistributions of source code must retain the above
10*4d9fdb46SRobert Mustacchi copyright notice, this list of conditions and the following
11*4d9fdb46SRobert Mustacchi disclaimer.
12*4d9fdb46SRobert Mustacchi
13*4d9fdb46SRobert Mustacchi Redistributions in binary form must reproduce the above
14*4d9fdb46SRobert Mustacchi copyright notice, this list of conditions and the following
15*4d9fdb46SRobert Mustacchi disclaimer in the documentation and/or other materials
16*4d9fdb46SRobert Mustacchi provided with the distribution.
17*4d9fdb46SRobert Mustacchi
18*4d9fdb46SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19*4d9fdb46SRobert Mustacchi CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20*4d9fdb46SRobert Mustacchi INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*4d9fdb46SRobert Mustacchi OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*4d9fdb46SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23*4d9fdb46SRobert Mustacchi CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*4d9fdb46SRobert Mustacchi SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25*4d9fdb46SRobert Mustacchi NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26*4d9fdb46SRobert Mustacchi LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*4d9fdb46SRobert Mustacchi HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*4d9fdb46SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29*4d9fdb46SRobert Mustacchi OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30*4d9fdb46SRobert Mustacchi EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*4d9fdb46SRobert Mustacchi */
32*4d9fdb46SRobert Mustacchi
33*4d9fdb46SRobert Mustacchi #include "config.h"
34*4d9fdb46SRobert Mustacchi #include <stdio.h>
35*4d9fdb46SRobert Mustacchi #include <stdlib.h>
36*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
37*4d9fdb46SRobert Mustacchi #include <stdlib.h>
38*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
39*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
40*4d9fdb46SRobert Mustacchi #include "dwarf_alloc.h"
41*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
42*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
43*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
44*4d9fdb46SRobert Mustacchi #include "dwarf_rnglists.h"
45*4d9fdb46SRobert Mustacchi
46*4d9fdb46SRobert Mustacchi #define SIZEOFT8 1
47*4d9fdb46SRobert Mustacchi #define SIZEOFT16 2
48*4d9fdb46SRobert Mustacchi #define SIZEOFT32 4
49*4d9fdb46SRobert Mustacchi #define SIZEOFT64 8
50*4d9fdb46SRobert Mustacchi #define TRUE 1
51*4d9fdb46SRobert Mustacchi #define FALSE 0
52*4d9fdb46SRobert Mustacchi
53*4d9fdb46SRobert Mustacchi
54*4d9fdb46SRobert Mustacchi /* Used in case of error reading the
55*4d9fdb46SRobert Mustacchi rnglists headers (not referring to Dwarf_Rnglists_Head
56*4d9fdb46SRobert Mustacchi here), to clean up. */
57*4d9fdb46SRobert Mustacchi static void
free_rnglists_chain(Dwarf_Debug dbg,Dwarf_Chain head)58*4d9fdb46SRobert Mustacchi free_rnglists_chain(Dwarf_Debug dbg, Dwarf_Chain head)
59*4d9fdb46SRobert Mustacchi {
60*4d9fdb46SRobert Mustacchi Dwarf_Chain cur = head;
61*4d9fdb46SRobert Mustacchi Dwarf_Chain next = 0;
62*4d9fdb46SRobert Mustacchi
63*4d9fdb46SRobert Mustacchi if(!head) {
64*4d9fdb46SRobert Mustacchi return;
65*4d9fdb46SRobert Mustacchi }
66*4d9fdb46SRobert Mustacchi for( ;cur; cur = next) {
67*4d9fdb46SRobert Mustacchi next = cur->ch_next;
68*4d9fdb46SRobert Mustacchi if (cur->ch_item) {
69*4d9fdb46SRobert Mustacchi free(cur->ch_item);
70*4d9fdb46SRobert Mustacchi cur->ch_item = 0;
71*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,cur,DW_DLA_CHAIN);
72*4d9fdb46SRobert Mustacchi }
73*4d9fdb46SRobert Mustacchi }
74*4d9fdb46SRobert Mustacchi }
75*4d9fdb46SRobert Mustacchi
76*4d9fdb46SRobert Mustacchi static int
read_single_rle_entry(Dwarf_Debug dbg,Dwarf_Small * data,Dwarf_Unsigned dataoffset,Dwarf_Small * enddata,unsigned address_size,unsigned * bytes_count_out,unsigned * entry_kind,Dwarf_Unsigned * entry_operand1,Dwarf_Unsigned * entry_operand2,Dwarf_Error * err)77*4d9fdb46SRobert Mustacchi read_single_rle_entry(Dwarf_Debug dbg,
78*4d9fdb46SRobert Mustacchi Dwarf_Small *data,
79*4d9fdb46SRobert Mustacchi Dwarf_Unsigned dataoffset,
80*4d9fdb46SRobert Mustacchi Dwarf_Small *enddata,
81*4d9fdb46SRobert Mustacchi unsigned address_size,
82*4d9fdb46SRobert Mustacchi unsigned *bytes_count_out,
83*4d9fdb46SRobert Mustacchi unsigned *entry_kind,
84*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *entry_operand1,
85*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *entry_operand2,
86*4d9fdb46SRobert Mustacchi Dwarf_Error* err)
87*4d9fdb46SRobert Mustacchi {
88*4d9fdb46SRobert Mustacchi Dwarf_Unsigned count = 0;
89*4d9fdb46SRobert Mustacchi unsigned leblen = 0;
90*4d9fdb46SRobert Mustacchi unsigned code = 0;
91*4d9fdb46SRobert Mustacchi Dwarf_Unsigned val1 = 0;
92*4d9fdb46SRobert Mustacchi Dwarf_Unsigned val2 = 0;
93*4d9fdb46SRobert Mustacchi
94*4d9fdb46SRobert Mustacchi code = *data;
95*4d9fdb46SRobert Mustacchi ++data;
96*4d9fdb46SRobert Mustacchi ++count;
97*4d9fdb46SRobert Mustacchi switch(code) {
98*4d9fdb46SRobert Mustacchi case DW_RLE_end_of_list: break;
99*4d9fdb46SRobert Mustacchi case DW_RLE_base_addressx:{
100*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_LEN_CK(data,val1,leblen,
101*4d9fdb46SRobert Mustacchi dbg,err,enddata);
102*4d9fdb46SRobert Mustacchi count += leblen;
103*4d9fdb46SRobert Mustacchi }
104*4d9fdb46SRobert Mustacchi break;
105*4d9fdb46SRobert Mustacchi case DW_RLE_startx_endx:
106*4d9fdb46SRobert Mustacchi case DW_RLE_startx_length:
107*4d9fdb46SRobert Mustacchi case DW_RLE_offset_pair: {
108*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_LEN_CK(data,val1,leblen,
109*4d9fdb46SRobert Mustacchi dbg,err,enddata);
110*4d9fdb46SRobert Mustacchi count += leblen;
111*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_LEN_CK(data,val2,leblen,
112*4d9fdb46SRobert Mustacchi dbg,err,enddata);
113*4d9fdb46SRobert Mustacchi count += leblen;
114*4d9fdb46SRobert Mustacchi }
115*4d9fdb46SRobert Mustacchi break;
116*4d9fdb46SRobert Mustacchi case DW_RLE_base_address: {
117*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned,
118*4d9fdb46SRobert Mustacchi data,address_size,err,enddata);
119*4d9fdb46SRobert Mustacchi data += address_size;
120*4d9fdb46SRobert Mustacchi count += address_size;
121*4d9fdb46SRobert Mustacchi }
122*4d9fdb46SRobert Mustacchi break;
123*4d9fdb46SRobert Mustacchi case DW_RLE_start_end: {
124*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned,
125*4d9fdb46SRobert Mustacchi data,address_size,err,enddata);
126*4d9fdb46SRobert Mustacchi data += address_size;
127*4d9fdb46SRobert Mustacchi count += address_size;
128*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,val2, Dwarf_Unsigned,
129*4d9fdb46SRobert Mustacchi data,address_size,err,enddata);
130*4d9fdb46SRobert Mustacchi data += address_size;
131*4d9fdb46SRobert Mustacchi count += address_size;
132*4d9fdb46SRobert Mustacchi }
133*4d9fdb46SRobert Mustacchi break;
134*4d9fdb46SRobert Mustacchi case DW_RLE_start_length: {
135*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned,
136*4d9fdb46SRobert Mustacchi data,address_size,err,enddata);
137*4d9fdb46SRobert Mustacchi data += address_size;
138*4d9fdb46SRobert Mustacchi count += address_size;
139*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_LEN_CK(data,val2,leblen,
140*4d9fdb46SRobert Mustacchi dbg,err,enddata);
141*4d9fdb46SRobert Mustacchi count += leblen;
142*4d9fdb46SRobert Mustacchi }
143*4d9fdb46SRobert Mustacchi break;
144*4d9fdb46SRobert Mustacchi default: {
145*4d9fdb46SRobert Mustacchi dwarfstring m;
146*4d9fdb46SRobert Mustacchi
147*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
148*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
149*4d9fdb46SRobert Mustacchi "DW_DLE_RNGLISTS_ERROR: "
150*4d9fdb46SRobert Mustacchi "The rangelists entry at .debug_rnglists"
151*4d9fdb46SRobert Mustacchi " offset 0x%x" ,dataoffset);
152*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
153*4d9fdb46SRobert Mustacchi " has code 0x%x which is unknown",code);
154*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,err,DW_DLE_RNGLISTS_ERROR,
155*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
156*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
157*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
158*4d9fdb46SRobert Mustacchi }
159*4d9fdb46SRobert Mustacchi break;
160*4d9fdb46SRobert Mustacchi }
161*4d9fdb46SRobert Mustacchi *bytes_count_out = count;
162*4d9fdb46SRobert Mustacchi *entry_kind = code;
163*4d9fdb46SRobert Mustacchi *entry_operand1 = val1;
164*4d9fdb46SRobert Mustacchi *entry_operand2 = val2;
165*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
166*4d9fdb46SRobert Mustacchi }
167*4d9fdb46SRobert Mustacchi
168*4d9fdb46SRobert Mustacchi /* Reads the header. Determines the
169*4d9fdb46SRobert Mustacchi various offsets, including offset
170*4d9fdb46SRobert Mustacchi of the next header. Does no memory
171*4d9fdb46SRobert Mustacchi allocations here. */
172*4d9fdb46SRobert Mustacchi static int
internal_read_header(Dwarf_Debug dbg,Dwarf_Unsigned contextnum,Dwarf_Unsigned sectionlength,Dwarf_Small * data,Dwarf_Small * end_data,Dwarf_Unsigned offset,Dwarf_Rnglists_Context buildhere,Dwarf_Unsigned * next_offset,Dwarf_Error * error)173*4d9fdb46SRobert Mustacchi internal_read_header(Dwarf_Debug dbg,
174*4d9fdb46SRobert Mustacchi Dwarf_Unsigned contextnum,
175*4d9fdb46SRobert Mustacchi Dwarf_Unsigned sectionlength,
176*4d9fdb46SRobert Mustacchi Dwarf_Small *data,
177*4d9fdb46SRobert Mustacchi Dwarf_Small *end_data,
178*4d9fdb46SRobert Mustacchi Dwarf_Unsigned offset,
179*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context buildhere,
180*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *next_offset,
181*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
182*4d9fdb46SRobert Mustacchi {
183*4d9fdb46SRobert Mustacchi Dwarf_Small *startdata = data;
184*4d9fdb46SRobert Mustacchi Dwarf_Unsigned arealen = 0;
185*4d9fdb46SRobert Mustacchi int length_size = 0;
186*4d9fdb46SRobert Mustacchi int exten_size = 0;
187*4d9fdb46SRobert Mustacchi Dwarf_Unsigned version = 0;
188*4d9fdb46SRobert Mustacchi unsigned address_size = 0;
189*4d9fdb46SRobert Mustacchi unsigned segment_selector_size= 0;
190*4d9fdb46SRobert Mustacchi Dwarf_Unsigned offset_entry_count = 0;
191*4d9fdb46SRobert Mustacchi Dwarf_Unsigned localoff = 0;
192*4d9fdb46SRobert Mustacchi Dwarf_Unsigned lists_len = 0;
193*4d9fdb46SRobert Mustacchi
194*4d9fdb46SRobert Mustacchi READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned,
195*4d9fdb46SRobert Mustacchi data,length_size,exten_size,
196*4d9fdb46SRobert Mustacchi error,
197*4d9fdb46SRobert Mustacchi sectionlength,end_data);
198*4d9fdb46SRobert Mustacchi if (arealen > sectionlength) {
199*4d9fdb46SRobert Mustacchi dwarfstring m;
200*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
201*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
202*4d9fdb46SRobert Mustacchi "DW_DLE_SECTION_SIZE_ERROR: A .debug_rnglists "
203*4d9fdb46SRobert Mustacchi "area size of 0x%x ",arealen);
204*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
205*4d9fdb46SRobert Mustacchi "at offset 0x%x ",offset);
206*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
207*4d9fdb46SRobert Mustacchi "is larger than the entire section size of "
208*4d9fdb46SRobert Mustacchi "0x%x. Corrupt DWARF.",sectionlength);
209*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,DW_DLE_SECTION_SIZE_ERROR,
210*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
211*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
212*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
213*4d9fdb46SRobert Mustacchi }
214*4d9fdb46SRobert Mustacchi
215*4d9fdb46SRobert Mustacchi buildhere->rc_length = arealen +length_size+exten_size;
216*4d9fdb46SRobert Mustacchi buildhere->rc_dbg = dbg;
217*4d9fdb46SRobert Mustacchi buildhere->rc_index = contextnum;
218*4d9fdb46SRobert Mustacchi buildhere->rc_header_offset = offset;
219*4d9fdb46SRobert Mustacchi buildhere->rc_offset_size = length_size;
220*4d9fdb46SRobert Mustacchi buildhere->rc_extension_size = exten_size;
221*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,version,Dwarf_Unsigned,data,
222*4d9fdb46SRobert Mustacchi SIZEOFT16,error,end_data);
223*4d9fdb46SRobert Mustacchi if (version != DW_CU_VERSION5) {
224*4d9fdb46SRobert Mustacchi dwarfstring m;
225*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
226*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
227*4d9fdb46SRobert Mustacchi "DW_DLE_VERSION_STAMP_ERROR: The version should be 5 "
228*4d9fdb46SRobert Mustacchi "but we find %u instead.",version);
229*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,DW_DLE_VERSION_STAMP_ERROR,
230*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
231*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
232*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
233*4d9fdb46SRobert Mustacchi }
234*4d9fdb46SRobert Mustacchi buildhere->rc_version = version;
235*4d9fdb46SRobert Mustacchi data += SIZEOFT16;
236*4d9fdb46SRobert Mustacchi
237*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,address_size,unsigned,data,
238*4d9fdb46SRobert Mustacchi SIZEOFT8,error,end_data);
239*4d9fdb46SRobert Mustacchi if (version != DW_CU_VERSION5) {
240*4d9fdb46SRobert Mustacchi dwarfstring m;
241*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
242*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
243*4d9fdb46SRobert Mustacchi "DW_DLE_VERSION_STAMP_ERROR: The version should be 5 "
244*4d9fdb46SRobert Mustacchi "but we find %u instead.",version);
245*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,DW_DLE_VERSION_STAMP_ERROR,
246*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
247*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
248*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
249*4d9fdb46SRobert Mustacchi }
250*4d9fdb46SRobert Mustacchi if (address_size != 4 && address_size != 8 &&
251*4d9fdb46SRobert Mustacchi address_size != 2) {
252*4d9fdb46SRobert Mustacchi dwarfstring m;
253*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
254*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
255*4d9fdb46SRobert Mustacchi " DW_DLE_ADDRESS_SIZE_ERROR: The address size "
256*4d9fdb46SRobert Mustacchi "of %u is not supported.",address_size);
257*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR,
258*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
259*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
260*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
261*4d9fdb46SRobert Mustacchi }
262*4d9fdb46SRobert Mustacchi buildhere->rc_address_size = address_size;
263*4d9fdb46SRobert Mustacchi data++;
264*4d9fdb46SRobert Mustacchi
265*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,segment_selector_size,unsigned,data,
266*4d9fdb46SRobert Mustacchi SIZEOFT8,error,end_data);
267*4d9fdb46SRobert Mustacchi buildhere->rc_segment_selector_size = segment_selector_size;
268*4d9fdb46SRobert Mustacchi data++;
269*4d9fdb46SRobert Mustacchi
270*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,offset_entry_count,Dwarf_Unsigned,data,
271*4d9fdb46SRobert Mustacchi SIZEOFT32,error,end_data);
272*4d9fdb46SRobert Mustacchi buildhere->rc_offset_entry_count = offset_entry_count;
273*4d9fdb46SRobert Mustacchi data += SIZEOFT32;
274*4d9fdb46SRobert Mustacchi if (offset_entry_count ){
275*4d9fdb46SRobert Mustacchi buildhere->rc_offsets_array = data;
276*4d9fdb46SRobert Mustacchi }
277*4d9fdb46SRobert Mustacchi localoff = data - startdata;
278*4d9fdb46SRobert Mustacchi lists_len = address_size *offset_entry_count;
279*4d9fdb46SRobert Mustacchi
280*4d9fdb46SRobert Mustacchi data += lists_len;
281*4d9fdb46SRobert Mustacchi
282*4d9fdb46SRobert Mustacchi buildhere->rc_offsets_off_in_sect = offset+localoff;
283*4d9fdb46SRobert Mustacchi buildhere->rc_first_rnglist_offset = offset+localoff+
284*4d9fdb46SRobert Mustacchi lists_len;
285*4d9fdb46SRobert Mustacchi buildhere->rc_rnglists_header = startdata;
286*4d9fdb46SRobert Mustacchi buildhere->rc_endaddr = startdata +buildhere->rc_length;
287*4d9fdb46SRobert Mustacchi buildhere->rc_past_last_rnglist_offset =
288*4d9fdb46SRobert Mustacchi buildhere->rc_header_offset +buildhere->rc_length;
289*4d9fdb46SRobert Mustacchi *next_offset = buildhere->rc_past_last_rnglist_offset;
290*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
291*4d9fdb46SRobert Mustacchi }
292*4d9fdb46SRobert Mustacchi
293*4d9fdb46SRobert Mustacchi
294*4d9fdb46SRobert Mustacchi /* We return a pointer to an array of contexts
295*4d9fdb46SRobert Mustacchi (not context pointers through *cxt if
296*4d9fdb46SRobert Mustacchi we succeed and are returning DW_DLV_OK.
297*4d9fdb46SRobert Mustacchi We never return DW_DLV_NO_ENTRY here. */
298*4d9fdb46SRobert Mustacchi static int
internal_load_rnglists_contexts(Dwarf_Debug dbg,Dwarf_Rnglists_Context ** cxt,Dwarf_Unsigned * count,Dwarf_Error * error)299*4d9fdb46SRobert Mustacchi internal_load_rnglists_contexts(Dwarf_Debug dbg,
300*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context **cxt,
301*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *count,
302*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
303*4d9fdb46SRobert Mustacchi {
304*4d9fdb46SRobert Mustacchi Dwarf_Unsigned offset = 0;
305*4d9fdb46SRobert Mustacchi Dwarf_Unsigned nextoffset = 0;
306*4d9fdb46SRobert Mustacchi Dwarf_Small * data = dbg->de_debug_rnglists.dss_data;
307*4d9fdb46SRobert Mustacchi Dwarf_Unsigned section_size = dbg->de_debug_rnglists.dss_size;
308*4d9fdb46SRobert Mustacchi Dwarf_Small * startdata = data;
309*4d9fdb46SRobert Mustacchi Dwarf_Small * end_data = data +section_size;
310*4d9fdb46SRobert Mustacchi Dwarf_Chain curr_chain = 0;
311*4d9fdb46SRobert Mustacchi Dwarf_Chain prev_chain = 0;
312*4d9fdb46SRobert Mustacchi Dwarf_Chain head_chain = 0;
313*4d9fdb46SRobert Mustacchi int res = 0;
314*4d9fdb46SRobert Mustacchi Dwarf_Unsigned chainlength = 0;
315*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context *fullarray = 0;
316*4d9fdb46SRobert Mustacchi Dwarf_Unsigned i = 0;
317*4d9fdb46SRobert Mustacchi
318*4d9fdb46SRobert Mustacchi for( ; data < end_data ; ) {
319*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context newcontext = 0;
320*4d9fdb46SRobert Mustacchi
321*4d9fdb46SRobert Mustacchi /* sizeof the context struct, not sizeof a pointer */
322*4d9fdb46SRobert Mustacchi newcontext = malloc(sizeof(*newcontext));
323*4d9fdb46SRobert Mustacchi if (!newcontext) {
324*4d9fdb46SRobert Mustacchi free_rnglists_chain(dbg,head_chain);
325*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,
326*4d9fdb46SRobert Mustacchi DW_DLE_ALLOC_FAIL,
327*4d9fdb46SRobert Mustacchi "DW_DLE_ALLOC_FAIL: Allocation of "
328*4d9fdb46SRobert Mustacchi "Rnglists_Context failed");
329*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
330*4d9fdb46SRobert Mustacchi }
331*4d9fdb46SRobert Mustacchi memset(newcontext,0,sizeof(*newcontext));
332*4d9fdb46SRobert Mustacchi res = internal_read_header(dbg,chainlength,
333*4d9fdb46SRobert Mustacchi section_size,
334*4d9fdb46SRobert Mustacchi data,end_data,offset,
335*4d9fdb46SRobert Mustacchi newcontext,&nextoffset,error);
336*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
337*4d9fdb46SRobert Mustacchi free(newcontext);
338*4d9fdb46SRobert Mustacchi free_rnglists_chain(dbg,head_chain);
339*4d9fdb46SRobert Mustacchi }
340*4d9fdb46SRobert Mustacchi curr_chain = (Dwarf_Chain)
341*4d9fdb46SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
342*4d9fdb46SRobert Mustacchi if (curr_chain == NULL) {
343*4d9fdb46SRobert Mustacchi free_rnglists_chain(dbg,head_chain);
344*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
345*4d9fdb46SRobert Mustacchi "DW_DLE_ALLOC_FAIL: allocating Rnglists_Context"
346*4d9fdb46SRobert Mustacchi " chain entry");
347*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
348*4d9fdb46SRobert Mustacchi }
349*4d9fdb46SRobert Mustacchi curr_chain->ch_item = newcontext;
350*4d9fdb46SRobert Mustacchi ++chainlength;
351*4d9fdb46SRobert Mustacchi if (head_chain == NULL) {
352*4d9fdb46SRobert Mustacchi head_chain = prev_chain = curr_chain;
353*4d9fdb46SRobert Mustacchi } else {
354*4d9fdb46SRobert Mustacchi prev_chain->ch_next = curr_chain;
355*4d9fdb46SRobert Mustacchi prev_chain = curr_chain;
356*4d9fdb46SRobert Mustacchi }
357*4d9fdb46SRobert Mustacchi data = startdata+nextoffset;
358*4d9fdb46SRobert Mustacchi offset = nextoffset;
359*4d9fdb46SRobert Mustacchi }
360*4d9fdb46SRobert Mustacchi fullarray= (Dwarf_Rnglists_Context *)malloc(
361*4d9fdb46SRobert Mustacchi chainlength *sizeof(Dwarf_Rnglists_Context /*pointer*/));
362*4d9fdb46SRobert Mustacchi if (!fullarray) {
363*4d9fdb46SRobert Mustacchi free_rnglists_chain(dbg,head_chain);
364*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,
365*4d9fdb46SRobert Mustacchi DW_DLE_ALLOC_FAIL,"Allocation of "
366*4d9fdb46SRobert Mustacchi "Rnglists_Context pointer array failed");
367*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
368*4d9fdb46SRobert Mustacchi }
369*4d9fdb46SRobert Mustacchi curr_chain = head_chain;
370*4d9fdb46SRobert Mustacchi for( i = 0; i < chainlength; ++i) {
371*4d9fdb46SRobert Mustacchi fullarray[i] = (Dwarf_Rnglists_Context)curr_chain->ch_item;
372*4d9fdb46SRobert Mustacchi curr_chain->ch_item = 0;
373*4d9fdb46SRobert Mustacchi prev_chain = curr_chain;
374*4d9fdb46SRobert Mustacchi curr_chain = curr_chain->ch_next;
375*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
376*4d9fdb46SRobert Mustacchi }
377*4d9fdb46SRobert Mustacchi /* ASSERT: the chain is entirely dealloc'd
378*4d9fdb46SRobert Mustacchi and the array of pointers points to
379*4d9fdb46SRobert Mustacchi individually malloc'd Dwarf_Rnglists_Context_s */
380*4d9fdb46SRobert Mustacchi *cxt = fullarray;
381*4d9fdb46SRobert Mustacchi *count = chainlength;
382*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
383*4d9fdb46SRobert Mustacchi }
384*4d9fdb46SRobert Mustacchi
385*4d9fdb46SRobert Mustacchi
386*4d9fdb46SRobert Mustacchi
387*4d9fdb46SRobert Mustacchi /* Used by dwarfdump to print raw rnglists data.
388*4d9fdb46SRobert Mustacchi Loads all the .debug_rnglists[.dwo] headers and
389*4d9fdb46SRobert Mustacchi returns DW_DLV_NO_ENTRY if the section
390*4d9fdb46SRobert Mustacchi is missing or empty.
391*4d9fdb46SRobert Mustacchi Intended to be done quite early and
392*4d9fdb46SRobert Mustacchi done exactly once.
393*4d9fdb46SRobert Mustacchi Harmless to do more than once.
394*4d9fdb46SRobert Mustacchi With DW_DLV_OK it returns the number of
395*4d9fdb46SRobert Mustacchi rnglists headers in the section through
396*4d9fdb46SRobert Mustacchi rnglists_count. */
dwarf_load_rnglists(Dwarf_Debug dbg,Dwarf_Unsigned * rnglists_count,UNUSEDARG Dwarf_Error * error)397*4d9fdb46SRobert Mustacchi int dwarf_load_rnglists(
398*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg,
399*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *rnglists_count,
400*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error *error)
401*4d9fdb46SRobert Mustacchi {
402*4d9fdb46SRobert Mustacchi int res = DW_DLV_ERROR;
403*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context *cxt = 0;
404*4d9fdb46SRobert Mustacchi Dwarf_Unsigned count = 0;
405*4d9fdb46SRobert Mustacchi
406*4d9fdb46SRobert Mustacchi if (dbg->de_rnglists_context) {
407*4d9fdb46SRobert Mustacchi if (rnglists_count) {
408*4d9fdb46SRobert Mustacchi *rnglists_count = dbg->de_rnglists_context_count;
409*4d9fdb46SRobert Mustacchi }
410*4d9fdb46SRobert Mustacchi }
411*4d9fdb46SRobert Mustacchi if (!dbg->de_debug_rnglists.dss_size) {
412*4d9fdb46SRobert Mustacchi /* nothing there. */
413*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
414*4d9fdb46SRobert Mustacchi }
415*4d9fdb46SRobert Mustacchi if (!dbg->de_debug_rnglists.dss_data) {
416*4d9fdb46SRobert Mustacchi res = _dwarf_load_section(dbg, &dbg->de_debug_rnglists,
417*4d9fdb46SRobert Mustacchi error);
418*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
419*4d9fdb46SRobert Mustacchi return res;
420*4d9fdb46SRobert Mustacchi }
421*4d9fdb46SRobert Mustacchi }
422*4d9fdb46SRobert Mustacchi res = internal_load_rnglists_contexts(dbg,&cxt,&count,error);
423*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
424*4d9fdb46SRobert Mustacchi return res;
425*4d9fdb46SRobert Mustacchi }
426*4d9fdb46SRobert Mustacchi dbg->de_rnglists_context = cxt;
427*4d9fdb46SRobert Mustacchi dbg->de_rnglists_context_count = count;
428*4d9fdb46SRobert Mustacchi if (rnglists_count) {
429*4d9fdb46SRobert Mustacchi *rnglists_count = count;
430*4d9fdb46SRobert Mustacchi }
431*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
432*4d9fdb46SRobert Mustacchi }
433*4d9fdb46SRobert Mustacchi
434*4d9fdb46SRobert Mustacchi /* Frees the memory in use in all rnglists contexts.
435*4d9fdb46SRobert Mustacchi Done by dwarf_finish() */
436*4d9fdb46SRobert Mustacchi void
_dwarf_dealloc_rnglists_context(Dwarf_Debug dbg)437*4d9fdb46SRobert Mustacchi _dwarf_dealloc_rnglists_context(Dwarf_Debug dbg)
438*4d9fdb46SRobert Mustacchi {
439*4d9fdb46SRobert Mustacchi Dwarf_Unsigned i = 0;
440*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context * rngcon = 0;
441*4d9fdb46SRobert Mustacchi
442*4d9fdb46SRobert Mustacchi if (!dbg->de_rnglists_context) {
443*4d9fdb46SRobert Mustacchi return;
444*4d9fdb46SRobert Mustacchi }
445*4d9fdb46SRobert Mustacchi rngcon = dbg->de_rnglists_context;
446*4d9fdb46SRobert Mustacchi for( ; i < dbg->de_rnglists_context_count; ++i,++rngcon) {
447*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context con = *rngcon;
448*4d9fdb46SRobert Mustacchi con->rc_offsets_array = 0;
449*4d9fdb46SRobert Mustacchi con->rc_offset_entry_count = 0;
450*4d9fdb46SRobert Mustacchi free(con);
451*4d9fdb46SRobert Mustacchi }
452*4d9fdb46SRobert Mustacchi free(dbg->de_rnglists_context);
453*4d9fdb46SRobert Mustacchi dbg->de_rnglists_context = 0;
454*4d9fdb46SRobert Mustacchi dbg->de_rnglists_context_count = 0;
455*4d9fdb46SRobert Mustacchi }
456*4d9fdb46SRobert Mustacchi
457*4d9fdb46SRobert Mustacchi /* Used by dwarfdump to print raw rnglists data. */
458*4d9fdb46SRobert Mustacchi int
dwarf_get_rnglist_offset_index_value(Dwarf_Debug dbg,Dwarf_Unsigned context_index,Dwarf_Unsigned offsetentry_index,Dwarf_Unsigned * offset_value_out,Dwarf_Unsigned * global_offset_value_out,Dwarf_Error * error)459*4d9fdb46SRobert Mustacchi dwarf_get_rnglist_offset_index_value(
460*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg,
461*4d9fdb46SRobert Mustacchi Dwarf_Unsigned context_index,
462*4d9fdb46SRobert Mustacchi Dwarf_Unsigned offsetentry_index,
463*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * offset_value_out,
464*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * global_offset_value_out,
465*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
466*4d9fdb46SRobert Mustacchi {
467*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context con = 0;
468*4d9fdb46SRobert Mustacchi unsigned offset_len = 0;
469*4d9fdb46SRobert Mustacchi Dwarf_Small *offsetptr = 0;
470*4d9fdb46SRobert Mustacchi Dwarf_Unsigned targetoffset = 0;
471*4d9fdb46SRobert Mustacchi
472*4d9fdb46SRobert Mustacchi if (!dbg->de_rnglists_context_count) {
473*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
474*4d9fdb46SRobert Mustacchi }
475*4d9fdb46SRobert Mustacchi if (context_index >= dbg->de_rnglists_context_count) {
476*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
477*4d9fdb46SRobert Mustacchi }
478*4d9fdb46SRobert Mustacchi con = dbg->de_rnglists_context[context_index];
479*4d9fdb46SRobert Mustacchi
480*4d9fdb46SRobert Mustacchi if (offsetentry_index >= con->rc_offset_entry_count) {
481*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
482*4d9fdb46SRobert Mustacchi }
483*4d9fdb46SRobert Mustacchi offset_len = con->rc_offset_size;
484*4d9fdb46SRobert Mustacchi offsetptr = con->rc_offsets_array +
485*4d9fdb46SRobert Mustacchi (offsetentry_index*offset_len);
486*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,targetoffset,Dwarf_Unsigned,
487*4d9fdb46SRobert Mustacchi offsetptr,
488*4d9fdb46SRobert Mustacchi offset_len,error,con->rc_endaddr);
489*4d9fdb46SRobert Mustacchi if (offset_value_out) {
490*4d9fdb46SRobert Mustacchi *offset_value_out = targetoffset;
491*4d9fdb46SRobert Mustacchi }
492*4d9fdb46SRobert Mustacchi if (global_offset_value_out) {
493*4d9fdb46SRobert Mustacchi *global_offset_value_out = targetoffset +
494*4d9fdb46SRobert Mustacchi con->rc_offsets_off_in_sect;
495*4d9fdb46SRobert Mustacchi }
496*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
497*4d9fdb46SRobert Mustacchi }
498*4d9fdb46SRobert Mustacchi
499*4d9fdb46SRobert Mustacchi /* Used by dwarfdump to print basic data from the
500*4d9fdb46SRobert Mustacchi data generated to look at a specific rangelist
501*4d9fdb46SRobert Mustacchi as returned by dwarf_rnglists_index_get_rle_head()
502*4d9fdb46SRobert Mustacchi or dwarf_rnglists_offset_get_rle_head. */
dwarf_get_rnglist_head_basics(Dwarf_Rnglists_Head head,Dwarf_Unsigned * rle_count,Dwarf_Unsigned * rle_version,Dwarf_Unsigned * rnglists_index_returned,Dwarf_Unsigned * bytes_total_in_rle,Dwarf_Half * offset_size,Dwarf_Half * address_size,Dwarf_Half * segment_selector_size,Dwarf_Unsigned * overall_offset_of_this_context,Dwarf_Unsigned * total_length_of_this_context,Dwarf_Unsigned * offset_table_offset,Dwarf_Unsigned * offset_table_entrycount,Dwarf_Bool * rnglists_base_present,Dwarf_Unsigned * rnglists_base,Dwarf_Bool * rnglists_base_address_present,Dwarf_Unsigned * rnglists_base_address,Dwarf_Bool * rnglists_debug_addr_base_present,Dwarf_Unsigned * rnglists_debug_addr_base,UNUSEDARG Dwarf_Error * error)503*4d9fdb46SRobert Mustacchi int dwarf_get_rnglist_head_basics(
504*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Head head,
505*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * rle_count,
506*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * rle_version,
507*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * rnglists_index_returned,
508*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * bytes_total_in_rle,
509*4d9fdb46SRobert Mustacchi Dwarf_Half * offset_size,
510*4d9fdb46SRobert Mustacchi Dwarf_Half * address_size,
511*4d9fdb46SRobert Mustacchi Dwarf_Half * segment_selector_size,
512*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * overall_offset_of_this_context,
513*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * total_length_of_this_context,
514*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * offset_table_offset,
515*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * offset_table_entrycount,
516*4d9fdb46SRobert Mustacchi Dwarf_Bool * rnglists_base_present,
517*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * rnglists_base,
518*4d9fdb46SRobert Mustacchi Dwarf_Bool * rnglists_base_address_present,
519*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * rnglists_base_address,
520*4d9fdb46SRobert Mustacchi Dwarf_Bool * rnglists_debug_addr_base_present,
521*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * rnglists_debug_addr_base,
522*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error *error)
523*4d9fdb46SRobert Mustacchi {
524*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context rngcontext = 0;
525*4d9fdb46SRobert Mustacchi *rle_count = head->rh_count;
526*4d9fdb46SRobert Mustacchi *rle_version = head->rh_version;
527*4d9fdb46SRobert Mustacchi *rnglists_index_returned = head->rh_index;
528*4d9fdb46SRobert Mustacchi *bytes_total_in_rle = head->rh_bytes_total;
529*4d9fdb46SRobert Mustacchi *offset_size = head->rh_offset_size;
530*4d9fdb46SRobert Mustacchi *address_size = head->rh_address_size;
531*4d9fdb46SRobert Mustacchi *segment_selector_size = head->rh_segment_selector_size;
532*4d9fdb46SRobert Mustacchi rngcontext = head->rh_localcontext;
533*4d9fdb46SRobert Mustacchi if (rngcontext) {
534*4d9fdb46SRobert Mustacchi *overall_offset_of_this_context = rngcontext->rc_header_offset;
535*4d9fdb46SRobert Mustacchi *total_length_of_this_context = rngcontext->rc_length;
536*4d9fdb46SRobert Mustacchi *offset_table_offset = rngcontext->rc_offsets_off_in_sect;
537*4d9fdb46SRobert Mustacchi *offset_table_entrycount = rngcontext->rc_offset_entry_count;
538*4d9fdb46SRobert Mustacchi }
539*4d9fdb46SRobert Mustacchi *rnglists_base_present = head->rh_at_rnglists_base_present;
540*4d9fdb46SRobert Mustacchi *rnglists_base= head->rh_at_rnglists_base;
541*4d9fdb46SRobert Mustacchi
542*4d9fdb46SRobert Mustacchi *rnglists_base_address_present = head->rh_cu_base_address_present;
543*4d9fdb46SRobert Mustacchi *rnglists_base_address= head->rh_cu_base_address;
544*4d9fdb46SRobert Mustacchi
545*4d9fdb46SRobert Mustacchi *rnglists_debug_addr_base_present = head->rh_cu_addr_base_present;
546*4d9fdb46SRobert Mustacchi *rnglists_debug_addr_base = head->rh_cu_addr_base;
547*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
548*4d9fdb46SRobert Mustacchi }
549*4d9fdb46SRobert Mustacchi
550*4d9fdb46SRobert Mustacchi /* Used by dwarfdump to print raw rnglists data.
551*4d9fdb46SRobert Mustacchi Enables printing of details about the Range List Table
552*4d9fdb46SRobert Mustacchi Headers, one header per call. Index starting at 0.
553*4d9fdb46SRobert Mustacchi Returns DW_DLV_NO_ENTRY if index is too high for the table.
554*4d9fdb46SRobert Mustacchi A .debug_rnglists section may contain any number
555*4d9fdb46SRobert Mustacchi of Range List Table Headers with their details. */
dwarf_get_rnglist_context_basics(Dwarf_Debug dbg,Dwarf_Unsigned context_index,Dwarf_Unsigned * header_offset,Dwarf_Small * offset_size,Dwarf_Small * extension_size,unsigned * version,Dwarf_Small * address_size,Dwarf_Small * segment_selector_size,Dwarf_Unsigned * offset_entry_count,Dwarf_Unsigned * offset_of_offset_array,Dwarf_Unsigned * offset_of_first_rangeentry,Dwarf_Unsigned * offset_past_last_rangeentry,UNUSEDARG Dwarf_Error * error)556*4d9fdb46SRobert Mustacchi int dwarf_get_rnglist_context_basics(
557*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg,
558*4d9fdb46SRobert Mustacchi Dwarf_Unsigned context_index,
559*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * header_offset,
560*4d9fdb46SRobert Mustacchi Dwarf_Small * offset_size,
561*4d9fdb46SRobert Mustacchi Dwarf_Small * extension_size,
562*4d9fdb46SRobert Mustacchi unsigned * version, /* 5 */
563*4d9fdb46SRobert Mustacchi Dwarf_Small * address_size,
564*4d9fdb46SRobert Mustacchi Dwarf_Small * segment_selector_size,
565*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * offset_entry_count,
566*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * offset_of_offset_array,
567*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * offset_of_first_rangeentry,
568*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * offset_past_last_rangeentry,
569*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error *error)
570*4d9fdb46SRobert Mustacchi {
571*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context con = 0;
572*4d9fdb46SRobert Mustacchi if (!dbg->de_rnglists_context_count) {
573*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
574*4d9fdb46SRobert Mustacchi }
575*4d9fdb46SRobert Mustacchi if (context_index >= dbg->de_rnglists_context_count) {
576*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
577*4d9fdb46SRobert Mustacchi }
578*4d9fdb46SRobert Mustacchi con = dbg->de_rnglists_context[context_index];
579*4d9fdb46SRobert Mustacchi
580*4d9fdb46SRobert Mustacchi if (header_offset) {
581*4d9fdb46SRobert Mustacchi *header_offset = con->rc_header_offset;
582*4d9fdb46SRobert Mustacchi }
583*4d9fdb46SRobert Mustacchi if (offset_size) {
584*4d9fdb46SRobert Mustacchi *offset_size = con->rc_offset_size;
585*4d9fdb46SRobert Mustacchi }
586*4d9fdb46SRobert Mustacchi if (offset_size) {
587*4d9fdb46SRobert Mustacchi *extension_size = con->rc_extension_size;
588*4d9fdb46SRobert Mustacchi }
589*4d9fdb46SRobert Mustacchi if (version) {
590*4d9fdb46SRobert Mustacchi *version = con->rc_version;
591*4d9fdb46SRobert Mustacchi }
592*4d9fdb46SRobert Mustacchi if (address_size) {
593*4d9fdb46SRobert Mustacchi *address_size = con->rc_address_size;
594*4d9fdb46SRobert Mustacchi }
595*4d9fdb46SRobert Mustacchi if (segment_selector_size) {
596*4d9fdb46SRobert Mustacchi *segment_selector_size = con->rc_segment_selector_size;
597*4d9fdb46SRobert Mustacchi }
598*4d9fdb46SRobert Mustacchi if (offset_entry_count) {
599*4d9fdb46SRobert Mustacchi *offset_entry_count = con->rc_offset_entry_count;
600*4d9fdb46SRobert Mustacchi }
601*4d9fdb46SRobert Mustacchi if (offset_of_offset_array) {
602*4d9fdb46SRobert Mustacchi *offset_of_offset_array = con->rc_offsets_off_in_sect;
603*4d9fdb46SRobert Mustacchi }
604*4d9fdb46SRobert Mustacchi if (offset_of_first_rangeentry) {
605*4d9fdb46SRobert Mustacchi *offset_of_first_rangeentry = con->rc_first_rnglist_offset;
606*4d9fdb46SRobert Mustacchi }
607*4d9fdb46SRobert Mustacchi if (offset_past_last_rangeentry) {
608*4d9fdb46SRobert Mustacchi *offset_past_last_rangeentry =
609*4d9fdb46SRobert Mustacchi con->rc_past_last_rnglist_offset;
610*4d9fdb46SRobert Mustacchi }
611*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
612*4d9fdb46SRobert Mustacchi }
613*4d9fdb46SRobert Mustacchi
614*4d9fdb46SRobert Mustacchi /* Used by dwarfdump to print raw rnglists data.
615*4d9fdb46SRobert Mustacchi entry offset is offset_of_first_rangeentry.
616*4d9fdb46SRobert Mustacchi Stop when the returned *next_entry_offset
617*4d9fdb46SRobert Mustacchi is == offset_past_last_rangentry (from
618*4d9fdb46SRobert Mustacchi dwarf_get_rnglist_context_plus).
619*4d9fdb46SRobert Mustacchi This only makes sense within those ranges.
620*4d9fdb46SRobert Mustacchi This retrieves raw detail from the section,
621*4d9fdb46SRobert Mustacchi no base values or anything are added.
622*4d9fdb46SRobert Mustacchi So this returns raw individual entries
623*4d9fdb46SRobert Mustacchi for a single rnglist header, meaning a
624*4d9fdb46SRobert Mustacchi a single Dwarf_Rnglists_Context. */
dwarf_get_rnglist_rle(Dwarf_Debug dbg,Dwarf_Unsigned contextnumber,Dwarf_Unsigned entry_offset,Dwarf_Unsigned endoffset,unsigned * entrylen,unsigned * entry_kind,Dwarf_Unsigned * entry_operand1,Dwarf_Unsigned * entry_operand2,Dwarf_Error * err)625*4d9fdb46SRobert Mustacchi int dwarf_get_rnglist_rle(
626*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg,
627*4d9fdb46SRobert Mustacchi Dwarf_Unsigned contextnumber,
628*4d9fdb46SRobert Mustacchi Dwarf_Unsigned entry_offset,
629*4d9fdb46SRobert Mustacchi Dwarf_Unsigned endoffset,
630*4d9fdb46SRobert Mustacchi unsigned *entrylen,
631*4d9fdb46SRobert Mustacchi unsigned *entry_kind,
632*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *entry_operand1,
633*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *entry_operand2,
634*4d9fdb46SRobert Mustacchi Dwarf_Error *err)
635*4d9fdb46SRobert Mustacchi {
636*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context con = 0;
637*4d9fdb46SRobert Mustacchi Dwarf_Small *data = 0;
638*4d9fdb46SRobert Mustacchi Dwarf_Small *enddata = 0;
639*4d9fdb46SRobert Mustacchi int res = 0;
640*4d9fdb46SRobert Mustacchi unsigned address_size = 0;
641*4d9fdb46SRobert Mustacchi
642*4d9fdb46SRobert Mustacchi if (!dbg->de_rnglists_context_count) {
643*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
644*4d9fdb46SRobert Mustacchi }
645*4d9fdb46SRobert Mustacchi data = dbg->de_debug_rnglists.dss_data +
646*4d9fdb46SRobert Mustacchi entry_offset;
647*4d9fdb46SRobert Mustacchi enddata = dbg->de_debug_rnglists.dss_data +
648*4d9fdb46SRobert Mustacchi endoffset;
649*4d9fdb46SRobert Mustacchi if (contextnumber >= dbg->de_rnglists_context_count) {
650*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
651*4d9fdb46SRobert Mustacchi }
652*4d9fdb46SRobert Mustacchi
653*4d9fdb46SRobert Mustacchi con = dbg->de_rnglists_context[contextnumber];
654*4d9fdb46SRobert Mustacchi address_size = con->rc_address_size;
655*4d9fdb46SRobert Mustacchi
656*4d9fdb46SRobert Mustacchi res = read_single_rle_entry(dbg,
657*4d9fdb46SRobert Mustacchi data,entry_offset,enddata,
658*4d9fdb46SRobert Mustacchi address_size,entrylen,
659*4d9fdb46SRobert Mustacchi entry_kind, entry_operand1, entry_operand2,
660*4d9fdb46SRobert Mustacchi err);
661*4d9fdb46SRobert Mustacchi return res;
662*4d9fdb46SRobert Mustacchi }
663*4d9fdb46SRobert Mustacchi
664*4d9fdb46SRobert Mustacchi
665*4d9fdb46SRobert Mustacchi static int
_dwarf_which_rnglists_context(Dwarf_Debug dbg,Dwarf_CU_Context ctx,Dwarf_Unsigned rnglist_offset,Dwarf_Unsigned * index,Dwarf_Error * error)666*4d9fdb46SRobert Mustacchi _dwarf_which_rnglists_context(Dwarf_Debug dbg,
667*4d9fdb46SRobert Mustacchi Dwarf_CU_Context ctx,
668*4d9fdb46SRobert Mustacchi Dwarf_Unsigned rnglist_offset,
669*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *index,
670*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
671*4d9fdb46SRobert Mustacchi {
672*4d9fdb46SRobert Mustacchi Dwarf_Unsigned count;
673*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context *array;
674*4d9fdb46SRobert Mustacchi Dwarf_Unsigned i = 0;
675*4d9fdb46SRobert Mustacchi
676*4d9fdb46SRobert Mustacchi array = dbg->de_rnglists_context;
677*4d9fdb46SRobert Mustacchi count = dbg->de_rnglists_context_count;
678*4d9fdb46SRobert Mustacchi /* Using the slow way, a simple linear search. */
679*4d9fdb46SRobert Mustacchi if (!ctx->cc_rnglists_base_present) {
680*4d9fdb46SRobert Mustacchi /* We look at the location of each rnglist context
681*4d9fdb46SRobert Mustacchi to find one with the offset the DIE gave us. */
682*4d9fdb46SRobert Mustacchi for ( i = 0 ; i < count; ++i) {
683*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context rcx = array[i];
684*4d9fdb46SRobert Mustacchi Dwarf_Unsigned rcxoff = rcx->rc_header_offset;
685*4d9fdb46SRobert Mustacchi Dwarf_Unsigned rcxend = rcxoff +
686*4d9fdb46SRobert Mustacchi rcx->rc_length;
687*4d9fdb46SRobert Mustacchi
688*4d9fdb46SRobert Mustacchi if (rnglist_offset < rcxoff){
689*4d9fdb46SRobert Mustacchi continue;
690*4d9fdb46SRobert Mustacchi }
691*4d9fdb46SRobert Mustacchi if (rnglist_offset < rcxend ){
692*4d9fdb46SRobert Mustacchi *index = i;
693*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
694*4d9fdb46SRobert Mustacchi }
695*4d9fdb46SRobert Mustacchi }
696*4d9fdb46SRobert Mustacchi {
697*4d9fdb46SRobert Mustacchi dwarfstring m;
698*4d9fdb46SRobert Mustacchi
699*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
700*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
701*4d9fdb46SRobert Mustacchi "DW_DLE_RNGLISTS_ERROR: rnglist ran off end "
702*4d9fdb46SRobert Mustacchi " finding target offset of"
703*4d9fdb46SRobert Mustacchi " 0x%" DW_PR_XZEROS DW_PR_DUx ,rnglist_offset);
704*4d9fdb46SRobert Mustacchi dwarfstring_append(&m,
705*4d9fdb46SRobert Mustacchi " Not found anywhere in .debug_rnglists "
706*4d9fdb46SRobert Mustacchi "data. Corrupted data?");
707*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,
708*4d9fdb46SRobert Mustacchi DW_DLE_RNGLISTS_ERROR,
709*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
710*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
711*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
712*4d9fdb46SRobert Mustacchi }
713*4d9fdb46SRobert Mustacchi } else {
714*4d9fdb46SRobert Mustacchi /* We have a DW_AT_rnglists_base (cc_rangelists_base),
715*4d9fdb46SRobert Mustacchi let's use it. */
716*4d9fdb46SRobert Mustacchi Dwarf_Unsigned lookfor = 0;;
717*4d9fdb46SRobert Mustacchi
718*4d9fdb46SRobert Mustacchi lookfor = ctx->cc_rnglists_base;
719*4d9fdb46SRobert Mustacchi for ( i = 0 ; i < count; ++i) {
720*4d9fdb46SRobert Mustacchi dwarfstring m;
721*4d9fdb46SRobert Mustacchi
722*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context rcx = array[i];
723*4d9fdb46SRobert Mustacchi if (rcx->rc_offsets_off_in_sect == lookfor){
724*4d9fdb46SRobert Mustacchi *index = i;
725*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
726*4d9fdb46SRobert Mustacchi }
727*4d9fdb46SRobert Mustacchi if (rcx->rc_offsets_off_in_sect < lookfor){
728*4d9fdb46SRobert Mustacchi continue;
729*4d9fdb46SRobert Mustacchi }
730*4d9fdb46SRobert Mustacchi
731*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
732*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
733*4d9fdb46SRobert Mustacchi "DW_DLE_RNGLISTS_ERROR: rnglists base of "
734*4d9fdb46SRobert Mustacchi " 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor);
735*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
736*4d9fdb46SRobert Mustacchi " was not found though we are now at base "
737*4d9fdb46SRobert Mustacchi " 0x%" DW_PR_XZEROS DW_PR_DUx ,
738*4d9fdb46SRobert Mustacchi rcx->rc_offsets_off_in_sect);
739*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,
740*4d9fdb46SRobert Mustacchi DW_DLE_RNGLISTS_ERROR,
741*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
742*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
743*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
744*4d9fdb46SRobert Mustacchi }
745*4d9fdb46SRobert Mustacchi {
746*4d9fdb46SRobert Mustacchi dwarfstring m;
747*4d9fdb46SRobert Mustacchi
748*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
749*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
750*4d9fdb46SRobert Mustacchi "DW_DLE_RNGLISTS_ERROR: rnglist base of "
751*4d9fdb46SRobert Mustacchi " 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor);
752*4d9fdb46SRobert Mustacchi dwarfstring_append(&m,
753*4d9fdb46SRobert Mustacchi " was not found anywhere in .debug_rnglists "
754*4d9fdb46SRobert Mustacchi "data. Corrupted data?");
755*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,
756*4d9fdb46SRobert Mustacchi DW_DLE_RNGLISTS_ERROR,
757*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
758*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
759*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
760*4d9fdb46SRobert Mustacchi }
761*4d9fdb46SRobert Mustacchi }
762*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
763*4d9fdb46SRobert Mustacchi }
764*4d9fdb46SRobert Mustacchi
765*4d9fdb46SRobert Mustacchi int
dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head h)766*4d9fdb46SRobert Mustacchi dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head h)
767*4d9fdb46SRobert Mustacchi {
768*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg = h->rh_dbg;
769*4d9fdb46SRobert Mustacchi
770*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,h,DW_DLA_RNGLISTS_HEAD);
771*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
772*4d9fdb46SRobert Mustacchi }
773*4d9fdb46SRobert Mustacchi
774*4d9fdb46SRobert Mustacchi /* Caller will eventually free as appropriate. */
775*4d9fdb46SRobert Mustacchi static int
alloc_rle_and_append_to_list(Dwarf_Debug dbg,Dwarf_Rnglists_Head rctx,Dwarf_Rnglists_Entry * e_out,Dwarf_Error * error)776*4d9fdb46SRobert Mustacchi alloc_rle_and_append_to_list(Dwarf_Debug dbg,
777*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Head rctx,
778*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Entry *e_out,
779*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
780*4d9fdb46SRobert Mustacchi {
781*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Entry e = 0;
782*4d9fdb46SRobert Mustacchi
783*4d9fdb46SRobert Mustacchi e = malloc(sizeof(struct Dwarf_Rnglists_Entry_s));
784*4d9fdb46SRobert Mustacchi if (!e) {
785*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
786*4d9fdb46SRobert Mustacchi "DW_DLE_ALLOC_FAIL: Out of memory in "
787*4d9fdb46SRobert Mustacchi "building list of rnglists entries on a DIE.");
788*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
789*4d9fdb46SRobert Mustacchi }
790*4d9fdb46SRobert Mustacchi memset(e,0,sizeof(struct Dwarf_Rnglists_Entry_s));
791*4d9fdb46SRobert Mustacchi if (rctx->rh_first) {
792*4d9fdb46SRobert Mustacchi rctx->rh_last->rle_next = e;
793*4d9fdb46SRobert Mustacchi rctx->rh_last = e;
794*4d9fdb46SRobert Mustacchi } else {
795*4d9fdb46SRobert Mustacchi rctx->rh_first = e;
796*4d9fdb46SRobert Mustacchi rctx->rh_last = e;
797*4d9fdb46SRobert Mustacchi }
798*4d9fdb46SRobert Mustacchi rctx->rh_count++;
799*4d9fdb46SRobert Mustacchi *e_out = e;
800*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
801*4d9fdb46SRobert Mustacchi }
802*4d9fdb46SRobert Mustacchi
803*4d9fdb46SRobert Mustacchi /* Read the group of rangelists entries, and
804*4d9fdb46SRobert Mustacchi finally build an array of Dwarf_Rnglists_Entry
805*4d9fdb46SRobert Mustacchi records. Attach to rctx here.
806*4d9fdb46SRobert Mustacchi Since on error the caller will destruct the rctx
807*4d9fdb46SRobert Mustacchi and we ensure to attach allocations there
808*4d9fdb46SRobert Mustacchi the caller will destruct the allocations here
809*4d9fdb46SRobert Mustacchi in case we return DW_DLV_ERROR*/
810*4d9fdb46SRobert Mustacchi static int
build_array_of_rle(Dwarf_Debug dbg,Dwarf_Rnglists_Head rctx,Dwarf_Error * error)811*4d9fdb46SRobert Mustacchi build_array_of_rle(Dwarf_Debug dbg,
812*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Head rctx,
813*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
814*4d9fdb46SRobert Mustacchi {
815*4d9fdb46SRobert Mustacchi int res = 0;
816*4d9fdb46SRobert Mustacchi Dwarf_Small * data = rctx->rh_rlepointer;
817*4d9fdb46SRobert Mustacchi Dwarf_Unsigned dataoffset = rctx->rh_rlearea_offset;
818*4d9fdb46SRobert Mustacchi Dwarf_Small *enddata = rctx->rh_end_data_area;
819*4d9fdb46SRobert Mustacchi unsigned address_size = rctx->rh_address_size;
820*4d9fdb46SRobert Mustacchi Dwarf_Unsigned bytescounttotal= 0;
821*4d9fdb46SRobert Mustacchi Dwarf_Unsigned latestbaseaddr = 0;
822*4d9fdb46SRobert Mustacchi unsigned foundbaseaddr = FALSE;
823*4d9fdb46SRobert Mustacchi int done = FALSE;
824*4d9fdb46SRobert Mustacchi
825*4d9fdb46SRobert Mustacchi if (rctx->rh_cu_base_address_present) {
826*4d9fdb46SRobert Mustacchi /* The CU DIE had DW_AT_low_pc
827*4d9fdb46SRobert Mustacchi and it is a base address. */
828*4d9fdb46SRobert Mustacchi latestbaseaddr = rctx->rh_cu_base_address;
829*4d9fdb46SRobert Mustacchi foundbaseaddr = TRUE;
830*4d9fdb46SRobert Mustacchi }
831*4d9fdb46SRobert Mustacchi for( ; !done ; ) {
832*4d9fdb46SRobert Mustacchi unsigned entrylen = 0;
833*4d9fdb46SRobert Mustacchi unsigned code = 0;
834*4d9fdb46SRobert Mustacchi Dwarf_Unsigned val1 = 0;
835*4d9fdb46SRobert Mustacchi Dwarf_Unsigned val2 = 0;
836*4d9fdb46SRobert Mustacchi Dwarf_Addr addr1= 0;
837*4d9fdb46SRobert Mustacchi Dwarf_Addr addr2 = 0;
838*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Entry e = 0;
839*4d9fdb46SRobert Mustacchi
840*4d9fdb46SRobert Mustacchi res = read_single_rle_entry(dbg,
841*4d9fdb46SRobert Mustacchi data,dataoffset, enddata,
842*4d9fdb46SRobert Mustacchi address_size,&entrylen,
843*4d9fdb46SRobert Mustacchi &code,&val1, &val2,error);
844*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
845*4d9fdb46SRobert Mustacchi return res;
846*4d9fdb46SRobert Mustacchi }
847*4d9fdb46SRobert Mustacchi res = alloc_rle_and_append_to_list(dbg,rctx,&e,error);
848*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
849*4d9fdb46SRobert Mustacchi return res;
850*4d9fdb46SRobert Mustacchi }
851*4d9fdb46SRobert Mustacchi e->rle_code = code,
852*4d9fdb46SRobert Mustacchi e->rle_entrylen = entrylen;
853*4d9fdb46SRobert Mustacchi e->rle_raw1 = val1;
854*4d9fdb46SRobert Mustacchi e->rle_raw2 = val2;
855*4d9fdb46SRobert Mustacchi bytescounttotal += entrylen;
856*4d9fdb46SRobert Mustacchi data += entrylen;
857*4d9fdb46SRobert Mustacchi if (code == DW_RLE_end_of_list) {
858*4d9fdb46SRobert Mustacchi done = TRUE;
859*4d9fdb46SRobert Mustacchi break;
860*4d9fdb46SRobert Mustacchi }
861*4d9fdb46SRobert Mustacchi switch(code) {
862*4d9fdb46SRobert Mustacchi case DW_RLE_base_addressx:
863*4d9fdb46SRobert Mustacchi foundbaseaddr = TRUE;
864*4d9fdb46SRobert Mustacchi res = _dwarf_extract_address_from_debug_addr(
865*4d9fdb46SRobert Mustacchi dbg,rctx->rh_context,val1,
866*4d9fdb46SRobert Mustacchi &addr1,error);
867*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
868*4d9fdb46SRobert Mustacchi return res;
869*4d9fdb46SRobert Mustacchi }
870*4d9fdb46SRobert Mustacchi e->rle_cooked1 = addr1;
871*4d9fdb46SRobert Mustacchi latestbaseaddr = addr1;
872*4d9fdb46SRobert Mustacchi break;
873*4d9fdb46SRobert Mustacchi case DW_RLE_startx_endx:
874*4d9fdb46SRobert Mustacchi res = _dwarf_extract_address_from_debug_addr(
875*4d9fdb46SRobert Mustacchi dbg,rctx->rh_context,val1,
876*4d9fdb46SRobert Mustacchi &addr1,error);
877*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
878*4d9fdb46SRobert Mustacchi return res;
879*4d9fdb46SRobert Mustacchi }
880*4d9fdb46SRobert Mustacchi res = _dwarf_extract_address_from_debug_addr(
881*4d9fdb46SRobert Mustacchi dbg,rctx->rh_context,val2,
882*4d9fdb46SRobert Mustacchi &addr2,error);
883*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
884*4d9fdb46SRobert Mustacchi return res;
885*4d9fdb46SRobert Mustacchi }
886*4d9fdb46SRobert Mustacchi e->rle_cooked1 = addr1;
887*4d9fdb46SRobert Mustacchi e->rle_cooked2 = addr2;
888*4d9fdb46SRobert Mustacchi break;
889*4d9fdb46SRobert Mustacchi case DW_RLE_startx_length:
890*4d9fdb46SRobert Mustacchi res = _dwarf_extract_address_from_debug_addr(
891*4d9fdb46SRobert Mustacchi dbg,rctx->rh_context,val1,
892*4d9fdb46SRobert Mustacchi &addr1,error);
893*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
894*4d9fdb46SRobert Mustacchi return res;
895*4d9fdb46SRobert Mustacchi }
896*4d9fdb46SRobert Mustacchi e->rle_cooked1 = addr1;
897*4d9fdb46SRobert Mustacchi e->rle_cooked2 = val2+addr1;
898*4d9fdb46SRobert Mustacchi break;
899*4d9fdb46SRobert Mustacchi case DW_RLE_offset_pair:
900*4d9fdb46SRobert Mustacchi if(foundbaseaddr) {
901*4d9fdb46SRobert Mustacchi e->rle_cooked1 = val1+latestbaseaddr;
902*4d9fdb46SRobert Mustacchi e->rle_cooked2 = val2+latestbaseaddr;
903*4d9fdb46SRobert Mustacchi } else {
904*4d9fdb46SRobert Mustacchi e->rle_cooked1 = val1+rctx->rh_cu_base_address;
905*4d9fdb46SRobert Mustacchi e->rle_cooked2 = val2+rctx->rh_cu_base_address;
906*4d9fdb46SRobert Mustacchi }
907*4d9fdb46SRobert Mustacchi break;
908*4d9fdb46SRobert Mustacchi case DW_RLE_base_address:
909*4d9fdb46SRobert Mustacchi foundbaseaddr = TRUE;
910*4d9fdb46SRobert Mustacchi latestbaseaddr = val1;
911*4d9fdb46SRobert Mustacchi e->rle_cooked1 = val1;
912*4d9fdb46SRobert Mustacchi break;
913*4d9fdb46SRobert Mustacchi case DW_RLE_start_end:
914*4d9fdb46SRobert Mustacchi e->rle_cooked1 = val1;
915*4d9fdb46SRobert Mustacchi e->rle_cooked2 = val2;
916*4d9fdb46SRobert Mustacchi break;
917*4d9fdb46SRobert Mustacchi case DW_RLE_start_length:
918*4d9fdb46SRobert Mustacchi e->rle_cooked1 = val1;
919*4d9fdb46SRobert Mustacchi e->rle_cooked2 = val2+val1;
920*4d9fdb46SRobert Mustacchi break;
921*4d9fdb46SRobert Mustacchi default: {
922*4d9fdb46SRobert Mustacchi dwarfstring m;
923*4d9fdb46SRobert Mustacchi
924*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
925*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
926*4d9fdb46SRobert Mustacchi " DW_DLE_RNGLISTS_ERROR: "
927*4d9fdb46SRobert Mustacchi " The .debug_rnglists "
928*4d9fdb46SRobert Mustacchi " rangelist code 0x%x is unknown, "
929*4d9fdb46SRobert Mustacchi " DWARF5 is corrupted.",code);
930*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error,
931*4d9fdb46SRobert Mustacchi DW_DLE_RNGLISTS_ERROR,
932*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
933*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
934*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
935*4d9fdb46SRobert Mustacchi }
936*4d9fdb46SRobert Mustacchi }
937*4d9fdb46SRobert Mustacchi }
938*4d9fdb46SRobert Mustacchi if (rctx->rh_count > 0) {
939*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Entry* array = 0;
940*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Entry cur = 0;
941*4d9fdb46SRobert Mustacchi Dwarf_Unsigned i = 0;
942*4d9fdb46SRobert Mustacchi
943*4d9fdb46SRobert Mustacchi /* Creating an array of pointers. */
944*4d9fdb46SRobert Mustacchi array = (Dwarf_Rnglists_Entry*)malloc(
945*4d9fdb46SRobert Mustacchi rctx->rh_count *sizeof(Dwarf_Rnglists_Entry));
946*4d9fdb46SRobert Mustacchi if (!array) {
947*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
948*4d9fdb46SRobert Mustacchi "DW_DLE_ALLOC_FAIL: Out of memory in "
949*4d9fdb46SRobert Mustacchi "turning list of rnglists entries on a DIE"
950*4d9fdb46SRobert Mustacchi "into a pointer array");
951*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
952*4d9fdb46SRobert Mustacchi }
953*4d9fdb46SRobert Mustacchi cur = rctx->rh_first;
954*4d9fdb46SRobert Mustacchi for ( ; i < rctx->rh_count; ++i) {
955*4d9fdb46SRobert Mustacchi array[i] = cur;
956*4d9fdb46SRobert Mustacchi cur = cur->rle_next;
957*4d9fdb46SRobert Mustacchi }
958*4d9fdb46SRobert Mustacchi rctx->rh_rnglists = array;
959*4d9fdb46SRobert Mustacchi rctx->rh_first = 0;
960*4d9fdb46SRobert Mustacchi rctx->rh_last = 0;
961*4d9fdb46SRobert Mustacchi }
962*4d9fdb46SRobert Mustacchi rctx->rh_bytes_total = bytescounttotal;
963*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
964*4d9fdb46SRobert Mustacchi }
965*4d9fdb46SRobert Mustacchi
966*4d9fdb46SRobert Mustacchi /* Build a head with all the relevent Entries
967*4d9fdb46SRobert Mustacchi attached.
968*4d9fdb46SRobert Mustacchi */
969*4d9fdb46SRobert Mustacchi int
dwarf_rnglists_get_rle_head(Dwarf_Attribute attr,Dwarf_Half theform,Dwarf_Unsigned attr_val,Dwarf_Rnglists_Head * head_out,Dwarf_Unsigned * entries_count_out,Dwarf_Unsigned * global_offset_of_rle_set,Dwarf_Error * error)970*4d9fdb46SRobert Mustacchi dwarf_rnglists_get_rle_head(
971*4d9fdb46SRobert Mustacchi Dwarf_Attribute attr,
972*4d9fdb46SRobert Mustacchi Dwarf_Half theform,
973*4d9fdb46SRobert Mustacchi Dwarf_Unsigned attr_val,
974*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Head *head_out,
975*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *entries_count_out,
976*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *global_offset_of_rle_set,
977*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
978*4d9fdb46SRobert Mustacchi {
979*4d9fdb46SRobert Mustacchi int res = 0;
980*4d9fdb46SRobert Mustacchi Dwarf_Unsigned rnglists_contextnum = 0;
981*4d9fdb46SRobert Mustacchi Dwarf_Small *table_base = 0;
982*4d9fdb46SRobert Mustacchi Dwarf_Small *table_entry = 0;
983*4d9fdb46SRobert Mustacchi Dwarf_Small *enddata = 0;
984*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context *array = 0;
985*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Context rctx = 0;
986*4d9fdb46SRobert Mustacchi Dwarf_Unsigned entrycount = 0;
987*4d9fdb46SRobert Mustacchi unsigned offsetsize = 0;
988*4d9fdb46SRobert Mustacchi Dwarf_Unsigned rle_global_offset = 0;
989*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Head lhead = 0;
990*4d9fdb46SRobert Mustacchi Dwarf_CU_Context ctx = 0;
991*4d9fdb46SRobert Mustacchi struct Dwarf_Rnglists_Head_s shead;
992*4d9fdb46SRobert Mustacchi Dwarf_Unsigned offset_in_rnglists = 0;
993*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg = 0;
994*4d9fdb46SRobert Mustacchi Dwarf_Bool is_rnglistx = FALSE;
995*4d9fdb46SRobert Mustacchi
996*4d9fdb46SRobert Mustacchi memset(&shead,0,sizeof(shead));
997*4d9fdb46SRobert Mustacchi ctx = attr->ar_cu_context;
998*4d9fdb46SRobert Mustacchi dbg = ctx->cc_dbg;
999*4d9fdb46SRobert Mustacchi array = dbg->de_rnglists_context;
1000*4d9fdb46SRobert Mustacchi if (theform == DW_FORM_rnglistx) {
1001*4d9fdb46SRobert Mustacchi is_rnglistx = TRUE;
1002*4d9fdb46SRobert Mustacchi }
1003*4d9fdb46SRobert Mustacchi /* ASSERT: the 3 pointers just set are non-null */
1004*4d9fdb46SRobert Mustacchi /* the context cc_rnglists_base gives the offset
1005*4d9fdb46SRobert Mustacchi of the array. of offsets (if cc_rnglists_base_present) */
1006*4d9fdb46SRobert Mustacchi offset_in_rnglists = attr_val;
1007*4d9fdb46SRobert Mustacchi if (is_rnglistx) {
1008*4d9fdb46SRobert Mustacchi if (ctx->cc_rnglists_base_present) {
1009*4d9fdb46SRobert Mustacchi offset_in_rnglists = ctx->cc_rnglists_base;
1010*4d9fdb46SRobert Mustacchi
1011*4d9fdb46SRobert Mustacchi } else {
1012*4d9fdb46SRobert Mustacchi /* FIXME: check in tied file for a cc_rnglists_base */
1013*4d9fdb46SRobert Mustacchi dwarfstring m;
1014*4d9fdb46SRobert Mustacchi
1015*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
1016*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
1017*4d9fdb46SRobert Mustacchi "DW_DLE_RNGLISTS_ERROR: rnglists table index of"
1018*4d9fdb46SRobert Mustacchi " %u" ,attr_val);
1019*4d9fdb46SRobert Mustacchi dwarfstring_append(&m,
1020*4d9fdb46SRobert Mustacchi " is unusable unless it is in a tied file."
1021*4d9fdb46SRobert Mustacchi " libdwarf is incomplete. FIXME");
1022*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR,
1023*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
1024*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
1025*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
1026*4d9fdb46SRobert Mustacchi }
1027*4d9fdb46SRobert Mustacchi } else {
1028*4d9fdb46SRobert Mustacchi offset_in_rnglists = attr_val;
1029*4d9fdb46SRobert Mustacchi }
1030*4d9fdb46SRobert Mustacchi res = _dwarf_which_rnglists_context(dbg,ctx,
1031*4d9fdb46SRobert Mustacchi offset_in_rnglists,
1032*4d9fdb46SRobert Mustacchi &rnglists_contextnum,error);
1033*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1034*4d9fdb46SRobert Mustacchi return res;
1035*4d9fdb46SRobert Mustacchi }
1036*4d9fdb46SRobert Mustacchi rctx = array[rnglists_contextnum];
1037*4d9fdb46SRobert Mustacchi table_base = rctx->rc_offsets_array;
1038*4d9fdb46SRobert Mustacchi entrycount = rctx->rc_offset_entry_count;
1039*4d9fdb46SRobert Mustacchi offsetsize = rctx->rc_offset_size;
1040*4d9fdb46SRobert Mustacchi enddata = rctx->rc_endaddr;
1041*4d9fdb46SRobert Mustacchi
1042*4d9fdb46SRobert Mustacchi if (is_rnglistx && attr_val >= entrycount) {
1043*4d9fdb46SRobert Mustacchi dwarfstring m;
1044*4d9fdb46SRobert Mustacchi
1045*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
1046*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
1047*4d9fdb46SRobert Mustacchi "DW_DLE_RNGLISTS_ERROR: rnglists table index of"
1048*4d9fdb46SRobert Mustacchi " %u" ,attr_val);
1049*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
1050*4d9fdb46SRobert Mustacchi " too large for table of %u "
1051*4d9fdb46SRobert Mustacchi "entries.",entrycount);
1052*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg,error,
1053*4d9fdb46SRobert Mustacchi DW_DLE_RNGLISTS_ERROR,
1054*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
1055*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
1056*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
1057*4d9fdb46SRobert Mustacchi }
1058*4d9fdb46SRobert Mustacchi shead.rh_context = ctx;
1059*4d9fdb46SRobert Mustacchi shead.rh_localcontext = rctx;
1060*4d9fdb46SRobert Mustacchi shead.rh_index = rnglists_contextnum;
1061*4d9fdb46SRobert Mustacchi shead.rh_version = rctx->rc_version;
1062*4d9fdb46SRobert Mustacchi shead.rh_offset_size = offsetsize;
1063*4d9fdb46SRobert Mustacchi shead.rh_address_size = rctx->rc_address_size;
1064*4d9fdb46SRobert Mustacchi shead.rh_segment_selector_size =
1065*4d9fdb46SRobert Mustacchi rctx->rc_segment_selector_size;
1066*4d9fdb46SRobert Mustacchi
1067*4d9fdb46SRobert Mustacchi /* DW_AT_rnglists_base from CU */
1068*4d9fdb46SRobert Mustacchi shead.rh_at_rnglists_base_present =
1069*4d9fdb46SRobert Mustacchi ctx->cc_rnglists_base_present;
1070*4d9fdb46SRobert Mustacchi shead.rh_at_rnglists_base = ctx->cc_rnglists_base;
1071*4d9fdb46SRobert Mustacchi
1072*4d9fdb46SRobert Mustacchi /* DW_AT_low_pc, if present. From CU */
1073*4d9fdb46SRobert Mustacchi shead.rh_cu_base_address_present = ctx->cc_low_pc_present;
1074*4d9fdb46SRobert Mustacchi shead.rh_cu_base_address = ctx->cc_low_pc;
1075*4d9fdb46SRobert Mustacchi
1076*4d9fdb46SRobert Mustacchi /* base address DW_AT_addr_base of our part of
1077*4d9fdb46SRobert Mustacchi .debug_addr, from CU */
1078*4d9fdb46SRobert Mustacchi shead.rh_cu_addr_base = ctx->cc_addr_base;
1079*4d9fdb46SRobert Mustacchi shead.rh_cu_addr_base_present = ctx->cc_addr_base_present;
1080*4d9fdb46SRobert Mustacchi if (is_rnglistx) {
1081*4d9fdb46SRobert Mustacchi Dwarf_Unsigned table_entryval = 0;
1082*4d9fdb46SRobert Mustacchi
1083*4d9fdb46SRobert Mustacchi table_entry = attr_val*offsetsize + table_base;
1084*4d9fdb46SRobert Mustacchi /* No malloc here yet so no leak if the macro returns
1085*4d9fdb46SRobert Mustacchi DW_DLV_ERROR */
1086*4d9fdb46SRobert Mustacchi READ_UNALIGNED_CK(dbg,table_entryval, Dwarf_Unsigned,
1087*4d9fdb46SRobert Mustacchi table_entry,offsetsize,error,enddata);
1088*4d9fdb46SRobert Mustacchi rle_global_offset = rctx->rc_offsets_off_in_sect +
1089*4d9fdb46SRobert Mustacchi table_entryval;
1090*4d9fdb46SRobert Mustacchi } else {
1091*4d9fdb46SRobert Mustacchi rle_global_offset = attr_val;
1092*4d9fdb46SRobert Mustacchi }
1093*4d9fdb46SRobert Mustacchi
1094*4d9fdb46SRobert Mustacchi shead.rh_rlepointer = rctx->rc_offsets_array +
1095*4d9fdb46SRobert Mustacchi rctx->rc_offset_entry_count*offsetsize;
1096*4d9fdb46SRobert Mustacchi shead.rh_end_data_area = enddata;
1097*4d9fdb46SRobert Mustacchi
1098*4d9fdb46SRobert Mustacchi shead.rh_rlearea_offset = rle_global_offset;
1099*4d9fdb46SRobert Mustacchi shead.rh_rlepointer = rle_global_offset +
1100*4d9fdb46SRobert Mustacchi dbg->de_debug_rnglists.dss_data;
1101*4d9fdb46SRobert Mustacchi lhead = (Dwarf_Rnglists_Head)
1102*4d9fdb46SRobert Mustacchi _dwarf_get_alloc(dbg,DW_DLA_RNGLISTS_HEAD,1);
1103*4d9fdb46SRobert Mustacchi if (!lhead) {
1104*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
1105*4d9fdb46SRobert Mustacchi "Allocating a Dwarf_Rnglists_Head struct fails"
1106*4d9fdb46SRobert Mustacchi " in libdwarf function dwarf_rnglists_index_get_rle_head()");
1107*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
1108*4d9fdb46SRobert Mustacchi }
1109*4d9fdb46SRobert Mustacchi shead.rh_dbg = dbg;
1110*4d9fdb46SRobert Mustacchi *lhead = shead;
1111*4d9fdb46SRobert Mustacchi res = build_array_of_rle(dbg,lhead,error);
1112*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1113*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,lhead,DW_DLA_RNGLISTS_HEAD);
1114*4d9fdb46SRobert Mustacchi return res;
1115*4d9fdb46SRobert Mustacchi }
1116*4d9fdb46SRobert Mustacchi if(global_offset_of_rle_set) {
1117*4d9fdb46SRobert Mustacchi *global_offset_of_rle_set = rle_global_offset;
1118*4d9fdb46SRobert Mustacchi }
1119*4d9fdb46SRobert Mustacchi /* Caller needs the head pointer else there will be leaks. */
1120*4d9fdb46SRobert Mustacchi *head_out = lhead;
1121*4d9fdb46SRobert Mustacchi if (entries_count_out) {
1122*4d9fdb46SRobert Mustacchi *entries_count_out = lhead->rh_count;
1123*4d9fdb46SRobert Mustacchi }
1124*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
1125*4d9fdb46SRobert Mustacchi }
1126*4d9fdb46SRobert Mustacchi
1127*4d9fdb46SRobert Mustacchi int
dwarf_get_rnglists_entry_fields(Dwarf_Rnglists_Head head,Dwarf_Unsigned entrynum,unsigned * entrylen,unsigned * code,Dwarf_Unsigned * raw1,Dwarf_Unsigned * raw2,Dwarf_Unsigned * cooked1,Dwarf_Unsigned * cooked2,UNUSEDARG Dwarf_Error * err)1128*4d9fdb46SRobert Mustacchi dwarf_get_rnglists_entry_fields(
1129*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Head head,
1130*4d9fdb46SRobert Mustacchi Dwarf_Unsigned entrynum,
1131*4d9fdb46SRobert Mustacchi unsigned *entrylen,
1132*4d9fdb46SRobert Mustacchi unsigned *code,
1133*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *raw1,
1134*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *raw2,
1135*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *cooked1,
1136*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *cooked2,
1137*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error *err)
1138*4d9fdb46SRobert Mustacchi {
1139*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Entry e = 0;
1140*4d9fdb46SRobert Mustacchi
1141*4d9fdb46SRobert Mustacchi if (entrynum >= head->rh_count) {
1142*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
1143*4d9fdb46SRobert Mustacchi }
1144*4d9fdb46SRobert Mustacchi e = head->rh_rnglists[entrynum];
1145*4d9fdb46SRobert Mustacchi *entrylen = e->rle_entrylen;
1146*4d9fdb46SRobert Mustacchi *code = e->rle_code;
1147*4d9fdb46SRobert Mustacchi *raw1 = e->rle_raw1;
1148*4d9fdb46SRobert Mustacchi *raw2 = e->rle_raw2;
1149*4d9fdb46SRobert Mustacchi *cooked1 = e->rle_cooked1;
1150*4d9fdb46SRobert Mustacchi *cooked2 = e->rle_cooked2;
1151*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
1152*4d9fdb46SRobert Mustacchi }
1153*4d9fdb46SRobert Mustacchi
1154*4d9fdb46SRobert Mustacchi /* Deals with both fully and partially build head */
1155*4d9fdb46SRobert Mustacchi static void
_dwarf_free_rnglists_head(Dwarf_Rnglists_Head head)1156*4d9fdb46SRobert Mustacchi _dwarf_free_rnglists_head(Dwarf_Rnglists_Head head)
1157*4d9fdb46SRobert Mustacchi {
1158*4d9fdb46SRobert Mustacchi if (head->rh_first) {
1159*4d9fdb46SRobert Mustacchi /* partially built head. */
1160*4d9fdb46SRobert Mustacchi /* ASSERT: rh_rnglists is NULL */
1161*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Entry cur = head->rh_first;
1162*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Entry next = 0;
1163*4d9fdb46SRobert Mustacchi
1164*4d9fdb46SRobert Mustacchi for ( ; cur ; cur = next) {
1165*4d9fdb46SRobert Mustacchi next = cur->rle_next;
1166*4d9fdb46SRobert Mustacchi free(cur);
1167*4d9fdb46SRobert Mustacchi }
1168*4d9fdb46SRobert Mustacchi head->rh_first = 0;
1169*4d9fdb46SRobert Mustacchi head->rh_last = 0;
1170*4d9fdb46SRobert Mustacchi head->rh_count = 0;
1171*4d9fdb46SRobert Mustacchi } else {
1172*4d9fdb46SRobert Mustacchi /* ASSERT: rh_first and rh_last are NULL */
1173*4d9fdb46SRobert Mustacchi /* fully built head. */
1174*4d9fdb46SRobert Mustacchi Dwarf_Unsigned i = 0;
1175*4d9fdb46SRobert Mustacchi
1176*4d9fdb46SRobert Mustacchi /* Deal with the array form. */
1177*4d9fdb46SRobert Mustacchi for( ; i < head->rh_count; ++i) {
1178*4d9fdb46SRobert Mustacchi free(head->rh_rnglists[i]);
1179*4d9fdb46SRobert Mustacchi }
1180*4d9fdb46SRobert Mustacchi free(head->rh_rnglists);
1181*4d9fdb46SRobert Mustacchi head->rh_rnglists = 0;
1182*4d9fdb46SRobert Mustacchi }
1183*4d9fdb46SRobert Mustacchi }
1184*4d9fdb46SRobert Mustacchi
1185*4d9fdb46SRobert Mustacchi void
_dwarf_rnglists_head_destructor(void * head)1186*4d9fdb46SRobert Mustacchi _dwarf_rnglists_head_destructor(void *head)
1187*4d9fdb46SRobert Mustacchi {
1188*4d9fdb46SRobert Mustacchi Dwarf_Rnglists_Head h = head;
1189*4d9fdb46SRobert Mustacchi
1190*4d9fdb46SRobert Mustacchi _dwarf_free_rnglists_head(h);
1191*4d9fdb46SRobert Mustacchi }
1192