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