xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_loclists.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
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_loc.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     loclists headers (not referring to Dwarf_Loc_Head_c
56*4d9fdb46SRobert Mustacchi     here), to clean up. */
57*4d9fdb46SRobert Mustacchi static void
free_loclists_chain(Dwarf_Debug dbg,Dwarf_Chain head)58*4d9fdb46SRobert Mustacchi free_loclists_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
counted_loc_descr(Dwarf_Debug dbg,Dwarf_Small * data,Dwarf_Small * enddata,Dwarf_Unsigned offset,Dwarf_Unsigned * loc_ops_overall_size,Dwarf_Unsigned * loc_ops_count_len,Dwarf_Unsigned * loc_ops_len,Dwarf_Small ** opsdata,Dwarf_Unsigned * opsoffset,Dwarf_Error * err)77*4d9fdb46SRobert Mustacchi counted_loc_descr(Dwarf_Debug dbg,
78*4d9fdb46SRobert Mustacchi     Dwarf_Small *data,
79*4d9fdb46SRobert Mustacchi     Dwarf_Small *enddata,
80*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
81*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *loc_ops_overall_size,
82*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *loc_ops_count_len,
83*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *loc_ops_len,
84*4d9fdb46SRobert Mustacchi     Dwarf_Small    **opsdata,
85*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *opsoffset,
86*4d9fdb46SRobert Mustacchi     Dwarf_Error *  err)
87*4d9fdb46SRobert Mustacchi {
88*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned ops_len = 0;
89*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned leblen = 0;
90*4d9fdb46SRobert Mustacchi     DECODE_LEB128_UWORD_LEN_CK(data,ops_len,leblen,
91*4d9fdb46SRobert Mustacchi         dbg,err,enddata);
92*4d9fdb46SRobert Mustacchi     *loc_ops_count_len = leblen;
93*4d9fdb46SRobert Mustacchi     *loc_ops_overall_size = ops_len+leblen;
94*4d9fdb46SRobert Mustacchi     *loc_ops_len = ops_len;
95*4d9fdb46SRobert Mustacchi     *opsdata = data;
96*4d9fdb46SRobert Mustacchi     *opsoffset = offset +leblen;
97*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
98*4d9fdb46SRobert Mustacchi }
99*4d9fdb46SRobert Mustacchi 
100*4d9fdb46SRobert Mustacchi static int
read_single_lle_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_Unsigned * opsblocksize,Dwarf_Unsigned * opsoffset,Dwarf_Small ** ops,Dwarf_Error * err)101*4d9fdb46SRobert Mustacchi read_single_lle_entry(Dwarf_Debug dbg,
102*4d9fdb46SRobert Mustacchi     Dwarf_Small    *data,
103*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned  dataoffset,
104*4d9fdb46SRobert Mustacchi     Dwarf_Small    *enddata,
105*4d9fdb46SRobert Mustacchi     unsigned        address_size,
106*4d9fdb46SRobert Mustacchi     unsigned       *bytes_count_out,
107*4d9fdb46SRobert Mustacchi     unsigned       *entry_kind,
108*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *entry_operand1,
109*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *entry_operand2,
110*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *opsblocksize, /* Just the  expr data */
111*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *opsoffset, /* Just the expr ops data */
112*4d9fdb46SRobert Mustacchi     Dwarf_Small   **ops, /*  pointer to expr ops ops */
113*4d9fdb46SRobert Mustacchi     Dwarf_Error* err)
114*4d9fdb46SRobert Mustacchi {
115*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count = 0;
116*4d9fdb46SRobert Mustacchi     unsigned int   leblen = 0;
117*4d9fdb46SRobert Mustacchi     unsigned int   code = 0;
118*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned val1 = 0;
119*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned val2 = 0;
120*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned loc_ops_overall_size = 0;
121*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned loc_ops_count_len = 0;
122*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned loc_ops_len = 0;
123*4d9fdb46SRobert Mustacchi     Dwarf_Small   *lopsdata = 0;
124*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned lopsoffset = 0;
125*4d9fdb46SRobert Mustacchi 
126*4d9fdb46SRobert Mustacchi     /*  Some of these have a  Counted Location Description
127*4d9fdb46SRobert Mustacchi         in them. */
128*4d9fdb46SRobert Mustacchi     code = *data;
129*4d9fdb46SRobert Mustacchi     ++data;
130*4d9fdb46SRobert Mustacchi     ++count;
131*4d9fdb46SRobert Mustacchi     switch(code) {
132*4d9fdb46SRobert Mustacchi     case DW_LLE_end_of_list: break;
133*4d9fdb46SRobert Mustacchi     case DW_LLE_base_addressx:{
134*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_LEN_CK(data,val1,leblen,
135*4d9fdb46SRobert Mustacchi             dbg,err,enddata);
136*4d9fdb46SRobert Mustacchi         count += leblen;
137*4d9fdb46SRobert Mustacchi         }
138*4d9fdb46SRobert Mustacchi         break;
139*4d9fdb46SRobert Mustacchi     case DW_LLE_startx_endx:
140*4d9fdb46SRobert Mustacchi     case DW_LLE_startx_length:
141*4d9fdb46SRobert Mustacchi     case DW_LLE_offset_pair: {
142*4d9fdb46SRobert Mustacchi         int res = 0;
143*4d9fdb46SRobert Mustacchi 
144*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_LEN_CK(data,val1,leblen,
145*4d9fdb46SRobert Mustacchi             dbg,err,enddata);
146*4d9fdb46SRobert Mustacchi         count += leblen;
147*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_LEN_CK(data,val2,leblen,
148*4d9fdb46SRobert Mustacchi             dbg,err,enddata);
149*4d9fdb46SRobert Mustacchi         count += leblen;
150*4d9fdb46SRobert Mustacchi         res = counted_loc_descr(dbg,data,enddata,
151*4d9fdb46SRobert Mustacchi             dataoffset,
152*4d9fdb46SRobert Mustacchi             &loc_ops_overall_size,
153*4d9fdb46SRobert Mustacchi             &loc_ops_count_len,
154*4d9fdb46SRobert Mustacchi             &loc_ops_len,
155*4d9fdb46SRobert Mustacchi             &lopsdata,
156*4d9fdb46SRobert Mustacchi             &lopsoffset,
157*4d9fdb46SRobert Mustacchi             err);
158*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
159*4d9fdb46SRobert Mustacchi             return res;
160*4d9fdb46SRobert Mustacchi         }
161*4d9fdb46SRobert Mustacchi         count += loc_ops_overall_size;
162*4d9fdb46SRobert Mustacchi         data  += loc_ops_overall_size;
163*4d9fdb46SRobert Mustacchi 
164*4d9fdb46SRobert Mustacchi         }
165*4d9fdb46SRobert Mustacchi         break;
166*4d9fdb46SRobert Mustacchi     case DW_LLE_default_location: {
167*4d9fdb46SRobert Mustacchi         int res = 0;
168*4d9fdb46SRobert Mustacchi 
169*4d9fdb46SRobert Mustacchi         res = counted_loc_descr(dbg,data,enddata,
170*4d9fdb46SRobert Mustacchi             dataoffset,
171*4d9fdb46SRobert Mustacchi             &loc_ops_overall_size,
172*4d9fdb46SRobert Mustacchi             &loc_ops_count_len,
173*4d9fdb46SRobert Mustacchi             &loc_ops_len,
174*4d9fdb46SRobert Mustacchi             &lopsdata,
175*4d9fdb46SRobert Mustacchi             &lopsoffset,
176*4d9fdb46SRobert Mustacchi             err);
177*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
178*4d9fdb46SRobert Mustacchi             return res;
179*4d9fdb46SRobert Mustacchi         }
180*4d9fdb46SRobert Mustacchi         data +=  loc_ops_overall_size;
181*4d9fdb46SRobert Mustacchi         count +=  loc_ops_overall_size;
182*4d9fdb46SRobert Mustacchi         }
183*4d9fdb46SRobert Mustacchi         break;
184*4d9fdb46SRobert Mustacchi     case DW_LLE_base_address: {
185*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned,
186*4d9fdb46SRobert Mustacchi             data,address_size,err,enddata);
187*4d9fdb46SRobert Mustacchi         data += address_size;
188*4d9fdb46SRobert Mustacchi         count += address_size;
189*4d9fdb46SRobert Mustacchi         }
190*4d9fdb46SRobert Mustacchi         break;
191*4d9fdb46SRobert Mustacchi     case DW_LLE_start_end: {
192*4d9fdb46SRobert Mustacchi         int res = 0;
193*4d9fdb46SRobert Mustacchi 
194*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned,
195*4d9fdb46SRobert Mustacchi             data,address_size,err,enddata);
196*4d9fdb46SRobert Mustacchi         data += address_size;
197*4d9fdb46SRobert Mustacchi         count += address_size;
198*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg,val2, Dwarf_Unsigned,
199*4d9fdb46SRobert Mustacchi             data,address_size,err,enddata);
200*4d9fdb46SRobert Mustacchi         data += address_size;
201*4d9fdb46SRobert Mustacchi         count += address_size;
202*4d9fdb46SRobert Mustacchi         res = counted_loc_descr(dbg,data,enddata,
203*4d9fdb46SRobert Mustacchi             dataoffset,
204*4d9fdb46SRobert Mustacchi             &loc_ops_overall_size,
205*4d9fdb46SRobert Mustacchi             &loc_ops_count_len,
206*4d9fdb46SRobert Mustacchi             &loc_ops_len,
207*4d9fdb46SRobert Mustacchi             &lopsdata,
208*4d9fdb46SRobert Mustacchi             &lopsoffset,
209*4d9fdb46SRobert Mustacchi             err);
210*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
211*4d9fdb46SRobert Mustacchi             return res;
212*4d9fdb46SRobert Mustacchi         }
213*4d9fdb46SRobert Mustacchi         count += loc_ops_overall_size;
214*4d9fdb46SRobert Mustacchi         data +=  loc_ops_overall_size;
215*4d9fdb46SRobert Mustacchi         }
216*4d9fdb46SRobert Mustacchi         break;
217*4d9fdb46SRobert Mustacchi     case DW_LLE_start_length: {
218*4d9fdb46SRobert Mustacchi         int res = 0;
219*4d9fdb46SRobert Mustacchi 
220*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned,
221*4d9fdb46SRobert Mustacchi             data,address_size,err,enddata);
222*4d9fdb46SRobert Mustacchi         data += address_size;
223*4d9fdb46SRobert Mustacchi         count += address_size;
224*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_LEN_CK(data,val2,leblen,
225*4d9fdb46SRobert Mustacchi             dbg,err,enddata);
226*4d9fdb46SRobert Mustacchi         count += leblen;
227*4d9fdb46SRobert Mustacchi         res = counted_loc_descr(dbg,data,enddata,
228*4d9fdb46SRobert Mustacchi             dataoffset,
229*4d9fdb46SRobert Mustacchi             &loc_ops_overall_size,
230*4d9fdb46SRobert Mustacchi             &loc_ops_count_len,
231*4d9fdb46SRobert Mustacchi             &loc_ops_len,
232*4d9fdb46SRobert Mustacchi             &lopsdata,
233*4d9fdb46SRobert Mustacchi             &lopsoffset,
234*4d9fdb46SRobert Mustacchi             err);
235*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
236*4d9fdb46SRobert Mustacchi             return res;
237*4d9fdb46SRobert Mustacchi         }
238*4d9fdb46SRobert Mustacchi         count += loc_ops_overall_size;
239*4d9fdb46SRobert Mustacchi         data +=  loc_ops_overall_size;
240*4d9fdb46SRobert Mustacchi         }
241*4d9fdb46SRobert Mustacchi         break;
242*4d9fdb46SRobert Mustacchi     default: {
243*4d9fdb46SRobert Mustacchi         dwarfstring m;
244*4d9fdb46SRobert Mustacchi 
245*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
246*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
247*4d9fdb46SRobert Mustacchi             "DW_DLE_LOCLISTS_ERROR: "
248*4d9fdb46SRobert Mustacchi             "The loclists entry at .debug_loclists"
249*4d9fdb46SRobert Mustacchi             " offset 0x%x" ,dataoffset);
250*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
251*4d9fdb46SRobert Mustacchi             " has code 0x%x which is unknown",code);
252*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg,err,DW_DLE_LOCLISTS_ERROR,
253*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
254*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
255*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
256*4d9fdb46SRobert Mustacchi         }
257*4d9fdb46SRobert Mustacchi         break;
258*4d9fdb46SRobert Mustacchi     }
259*4d9fdb46SRobert Mustacchi     *bytes_count_out = count;
260*4d9fdb46SRobert Mustacchi     *entry_kind      = code;
261*4d9fdb46SRobert Mustacchi     *entry_operand1  = val1;
262*4d9fdb46SRobert Mustacchi     *entry_operand2  = val2;
263*4d9fdb46SRobert Mustacchi     *opsblocksize    = loc_ops_len;
264*4d9fdb46SRobert Mustacchi     *opsoffset = lopsoffset;
265*4d9fdb46SRobert Mustacchi     *ops       = lopsdata;
266*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
267*4d9fdb46SRobert Mustacchi }
268*4d9fdb46SRobert Mustacchi 
269*4d9fdb46SRobert Mustacchi /*  Reads the header. Determines the
270*4d9fdb46SRobert Mustacchi     various offsets, including offset
271*4d9fdb46SRobert Mustacchi     of the next header. Does no memory
272*4d9fdb46SRobert Mustacchi     allocations here. */
273*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_Loclists_Context buildhere,Dwarf_Unsigned * next_offset,Dwarf_Error * error)274*4d9fdb46SRobert Mustacchi internal_read_header(Dwarf_Debug dbg,
275*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned contextnum,
276*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned sectionlength,
277*4d9fdb46SRobert Mustacchi     Dwarf_Small *data,
278*4d9fdb46SRobert Mustacchi     Dwarf_Small *end_data,
279*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
280*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context  buildhere,
281*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *next_offset,
282*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
283*4d9fdb46SRobert Mustacchi {
284*4d9fdb46SRobert Mustacchi     Dwarf_Small *startdata = data;
285*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned arealen = 0;
286*4d9fdb46SRobert Mustacchi     int length_size = 0;
287*4d9fdb46SRobert Mustacchi     int exten_size = 0;
288*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned version = 0;
289*4d9fdb46SRobert Mustacchi     unsigned address_size = 0;
290*4d9fdb46SRobert Mustacchi     unsigned segment_selector_size=  0;
291*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset_entry_count = 0;
292*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned localoff = 0;
293*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned lists_len = 0;
294*4d9fdb46SRobert Mustacchi 
295*4d9fdb46SRobert Mustacchi     READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned,
296*4d9fdb46SRobert Mustacchi         data,length_size,exten_size,
297*4d9fdb46SRobert Mustacchi         error,
298*4d9fdb46SRobert Mustacchi         sectionlength,end_data);
299*4d9fdb46SRobert Mustacchi     if (arealen > sectionlength) {
300*4d9fdb46SRobert Mustacchi         dwarfstring m;
301*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
302*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
303*4d9fdb46SRobert Mustacchi             "DW_DLE_SECTION_SIZE_ERROR: A .debug_loclists "
304*4d9fdb46SRobert Mustacchi             "area size of 0x%x ",arealen);
305*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
306*4d9fdb46SRobert Mustacchi             "at offset 0x%x ",offset);
307*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
308*4d9fdb46SRobert Mustacchi             "is larger than the entire section size of "
309*4d9fdb46SRobert Mustacchi             "0x%x. Corrupt DWARF.",sectionlength);
310*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg,error,DW_DLE_SECTION_SIZE_ERROR,
311*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
312*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
313*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
314*4d9fdb46SRobert Mustacchi     }
315*4d9fdb46SRobert Mustacchi 
316*4d9fdb46SRobert Mustacchi     buildhere->lc_length = arealen +length_size+exten_size;
317*4d9fdb46SRobert Mustacchi     buildhere->lc_dbg = dbg;
318*4d9fdb46SRobert Mustacchi     buildhere->lc_index = contextnum;
319*4d9fdb46SRobert Mustacchi     buildhere->lc_header_offset = offset;
320*4d9fdb46SRobert Mustacchi     buildhere->lc_offset_size = length_size;
321*4d9fdb46SRobert Mustacchi     buildhere->lc_extension_size = exten_size;
322*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,version,Dwarf_Unsigned,data,
323*4d9fdb46SRobert Mustacchi         SIZEOFT16,error,end_data);
324*4d9fdb46SRobert Mustacchi     if (version != DW_CU_VERSION5) {
325*4d9fdb46SRobert Mustacchi         dwarfstring m;
326*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
327*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
328*4d9fdb46SRobert Mustacchi             "DW_DLE_VERSION_STAMP_ERROR: The version should be 5 "
329*4d9fdb46SRobert Mustacchi             "but we find %u instead.",version);
330*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg,error,DW_DLE_VERSION_STAMP_ERROR,
331*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
332*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
333*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
334*4d9fdb46SRobert Mustacchi     }
335*4d9fdb46SRobert Mustacchi     buildhere->lc_version = version;
336*4d9fdb46SRobert Mustacchi     data += SIZEOFT16;
337*4d9fdb46SRobert Mustacchi 
338*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,address_size,unsigned,data,
339*4d9fdb46SRobert Mustacchi         SIZEOFT8,error,end_data);
340*4d9fdb46SRobert Mustacchi     if (version != DW_CU_VERSION5) {
341*4d9fdb46SRobert Mustacchi         dwarfstring m;
342*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
343*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
344*4d9fdb46SRobert Mustacchi             "DW_DLE_VERSION_STAMP_ERROR: The version should be 5 "
345*4d9fdb46SRobert Mustacchi             "but we find %u instead.",version);
346*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg,error,DW_DLE_VERSION_STAMP_ERROR,
347*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
348*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
349*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
350*4d9fdb46SRobert Mustacchi     }
351*4d9fdb46SRobert Mustacchi     if (address_size != 4 && address_size != 8 &&
352*4d9fdb46SRobert Mustacchi         address_size != 2) {
353*4d9fdb46SRobert Mustacchi         dwarfstring m;
354*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
355*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
356*4d9fdb46SRobert Mustacchi             " DW_DLE_ADDRESS_SIZE_ERROR: The address size "
357*4d9fdb46SRobert Mustacchi             "of %u is not supported.",address_size);
358*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR,
359*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
360*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
361*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
362*4d9fdb46SRobert Mustacchi     }
363*4d9fdb46SRobert Mustacchi     buildhere->lc_address_size = address_size;
364*4d9fdb46SRobert Mustacchi     data++;
365*4d9fdb46SRobert Mustacchi 
366*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,segment_selector_size,unsigned,data,
367*4d9fdb46SRobert Mustacchi         SIZEOFT8,error,end_data);
368*4d9fdb46SRobert Mustacchi     buildhere->lc_segment_selector_size = segment_selector_size;
369*4d9fdb46SRobert Mustacchi     data++;
370*4d9fdb46SRobert Mustacchi 
371*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,offset_entry_count,Dwarf_Unsigned,data,
372*4d9fdb46SRobert Mustacchi         SIZEOFT32,error,end_data);
373*4d9fdb46SRobert Mustacchi     buildhere->lc_offset_entry_count = offset_entry_count;
374*4d9fdb46SRobert Mustacchi     data += SIZEOFT32;
375*4d9fdb46SRobert Mustacchi     if (offset_entry_count ){
376*4d9fdb46SRobert Mustacchi         buildhere->lc_offsets_array = data;
377*4d9fdb46SRobert Mustacchi     }
378*4d9fdb46SRobert Mustacchi     localoff = data - startdata;
379*4d9fdb46SRobert Mustacchi     lists_len = address_size *offset_entry_count;
380*4d9fdb46SRobert Mustacchi 
381*4d9fdb46SRobert Mustacchi     data += lists_len;
382*4d9fdb46SRobert Mustacchi 
383*4d9fdb46SRobert Mustacchi     buildhere->lc_offsets_off_in_sect = offset+localoff;
384*4d9fdb46SRobert Mustacchi     buildhere->lc_first_loclist_offset = offset+localoff+
385*4d9fdb46SRobert Mustacchi         lists_len;
386*4d9fdb46SRobert Mustacchi     buildhere->lc_loclists_header = startdata;
387*4d9fdb46SRobert Mustacchi     buildhere->lc_endaddr = startdata +buildhere->lc_length;
388*4d9fdb46SRobert Mustacchi     buildhere->lc_past_last_loclist_offset =
389*4d9fdb46SRobert Mustacchi         buildhere->lc_header_offset +buildhere->lc_length;
390*4d9fdb46SRobert Mustacchi     *next_offset =  buildhere->lc_past_last_loclist_offset;
391*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
392*4d9fdb46SRobert Mustacchi }
393*4d9fdb46SRobert Mustacchi 
394*4d9fdb46SRobert Mustacchi 
395*4d9fdb46SRobert Mustacchi /*  We return a pointer to an array of contexts
396*4d9fdb46SRobert Mustacchi     (not context pointers through *cxt if
397*4d9fdb46SRobert Mustacchi     we succeed and are returning DW_DLV_OK.
398*4d9fdb46SRobert Mustacchi     We never return DW_DLV_NO_ENTRY here. */
399*4d9fdb46SRobert Mustacchi static int
internal_load_loclists_contexts(Dwarf_Debug dbg,Dwarf_Loclists_Context ** cxt,Dwarf_Unsigned * count,Dwarf_Error * error)400*4d9fdb46SRobert Mustacchi internal_load_loclists_contexts(Dwarf_Debug dbg,
401*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context **cxt,
402*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *count,
403*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
404*4d9fdb46SRobert Mustacchi {
405*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset = 0;
406*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned nextoffset = 0;
407*4d9fdb46SRobert Mustacchi     Dwarf_Small  * data = dbg->de_debug_loclists.dss_data;
408*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned section_size = dbg->de_debug_loclists.dss_size;
409*4d9fdb46SRobert Mustacchi     Dwarf_Small  * startdata = data;
410*4d9fdb46SRobert Mustacchi     Dwarf_Small  * end_data = data +section_size;
411*4d9fdb46SRobert Mustacchi     Dwarf_Chain curr_chain = 0;
412*4d9fdb46SRobert Mustacchi     Dwarf_Chain prev_chain = 0;
413*4d9fdb46SRobert Mustacchi     Dwarf_Chain head_chain = 0;
414*4d9fdb46SRobert Mustacchi     int res = 0;
415*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned chainlength = 0;
416*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context *fullarray = 0;
417*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
418*4d9fdb46SRobert Mustacchi 
419*4d9fdb46SRobert Mustacchi     for( ; data < end_data ; ) {
420*4d9fdb46SRobert Mustacchi         Dwarf_Loclists_Context newcontext = 0;
421*4d9fdb46SRobert Mustacchi 
422*4d9fdb46SRobert Mustacchi         /* sizeof the context struct, not sizeof a pointer */
423*4d9fdb46SRobert Mustacchi         newcontext = malloc(sizeof(*newcontext));
424*4d9fdb46SRobert Mustacchi         if (!newcontext) {
425*4d9fdb46SRobert Mustacchi             free_loclists_chain(dbg,head_chain);
426*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg,error,
427*4d9fdb46SRobert Mustacchi                 DW_DLE_ALLOC_FAIL,
428*4d9fdb46SRobert Mustacchi                 "DW_DLE_ALLOC_FAIL: Allocation of "
429*4d9fdb46SRobert Mustacchi                 "Loclists_Context failed");
430*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
431*4d9fdb46SRobert Mustacchi         }
432*4d9fdb46SRobert Mustacchi         memset(newcontext,0,sizeof(*newcontext));
433*4d9fdb46SRobert Mustacchi         res = internal_read_header(dbg,chainlength,
434*4d9fdb46SRobert Mustacchi             section_size,
435*4d9fdb46SRobert Mustacchi             data,end_data,offset,
436*4d9fdb46SRobert Mustacchi             newcontext,&nextoffset,error);
437*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_ERROR) {
438*4d9fdb46SRobert Mustacchi             free(newcontext);
439*4d9fdb46SRobert Mustacchi             free_loclists_chain(dbg,head_chain);
440*4d9fdb46SRobert Mustacchi         }
441*4d9fdb46SRobert Mustacchi         curr_chain = (Dwarf_Chain)
442*4d9fdb46SRobert Mustacchi             _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
443*4d9fdb46SRobert Mustacchi         if (curr_chain == NULL) {
444*4d9fdb46SRobert Mustacchi             free_loclists_chain(dbg,head_chain);
445*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
446*4d9fdb46SRobert Mustacchi                 "DW_DLE_ALLOC_FAIL: allocating Loclists_Context"
447*4d9fdb46SRobert Mustacchi                 " chain entry");
448*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
449*4d9fdb46SRobert Mustacchi         }
450*4d9fdb46SRobert Mustacchi         curr_chain->ch_item = newcontext;
451*4d9fdb46SRobert Mustacchi         ++chainlength;
452*4d9fdb46SRobert Mustacchi         if (head_chain == NULL) {
453*4d9fdb46SRobert Mustacchi             head_chain = prev_chain = curr_chain;
454*4d9fdb46SRobert Mustacchi         } else {
455*4d9fdb46SRobert Mustacchi             prev_chain->ch_next = curr_chain;
456*4d9fdb46SRobert Mustacchi             prev_chain = curr_chain;
457*4d9fdb46SRobert Mustacchi         }
458*4d9fdb46SRobert Mustacchi         data = startdata+nextoffset;
459*4d9fdb46SRobert Mustacchi         offset = nextoffset;
460*4d9fdb46SRobert Mustacchi     }
461*4d9fdb46SRobert Mustacchi     fullarray= (Dwarf_Loclists_Context *)malloc(
462*4d9fdb46SRobert Mustacchi         chainlength *sizeof(Dwarf_Loclists_Context /*pointer*/));
463*4d9fdb46SRobert Mustacchi     if (!fullarray) {
464*4d9fdb46SRobert Mustacchi         free_loclists_chain(dbg,head_chain);
465*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg,error,
466*4d9fdb46SRobert Mustacchi             DW_DLE_ALLOC_FAIL,"Allocation of "
467*4d9fdb46SRobert Mustacchi             "Loclists_Context pointer array failed");
468*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
469*4d9fdb46SRobert Mustacchi     }
470*4d9fdb46SRobert Mustacchi     curr_chain = head_chain;
471*4d9fdb46SRobert Mustacchi     for( i = 0; i < chainlength; ++i) {
472*4d9fdb46SRobert Mustacchi         fullarray[i] = (Dwarf_Loclists_Context)curr_chain->ch_item;
473*4d9fdb46SRobert Mustacchi         curr_chain->ch_item = 0;
474*4d9fdb46SRobert Mustacchi         prev_chain = curr_chain;
475*4d9fdb46SRobert Mustacchi         curr_chain = curr_chain->ch_next;
476*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
477*4d9fdb46SRobert Mustacchi     }
478*4d9fdb46SRobert Mustacchi     /*  ASSERT: the chain is entirely dealloc'd
479*4d9fdb46SRobert Mustacchi         and the array of pointers points to
480*4d9fdb46SRobert Mustacchi         individually malloc'd Dwarf_Loclists_Context_s */
481*4d9fdb46SRobert Mustacchi     *cxt = fullarray;
482*4d9fdb46SRobert Mustacchi     *count = chainlength;
483*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
484*4d9fdb46SRobert Mustacchi }
485*4d9fdb46SRobert Mustacchi 
486*4d9fdb46SRobert Mustacchi 
487*4d9fdb46SRobert Mustacchi 
488*4d9fdb46SRobert Mustacchi /*  Used by dwarfdump to print raw loclists data.
489*4d9fdb46SRobert Mustacchi     Loads all the .debug_loclists[.dwo]  headers and
490*4d9fdb46SRobert Mustacchi     returns DW_DLV_NO_ENTRY if the section
491*4d9fdb46SRobert Mustacchi     is missing or empty.
492*4d9fdb46SRobert Mustacchi     Intended to be done quite early and
493*4d9fdb46SRobert Mustacchi     done exactly once.
494*4d9fdb46SRobert Mustacchi     Harmless to do more than once.
495*4d9fdb46SRobert Mustacchi     With DW_DLV_OK it returns the number of
496*4d9fdb46SRobert Mustacchi     loclists headers in the section through
497*4d9fdb46SRobert Mustacchi     loclists_count. */
dwarf_load_loclists(Dwarf_Debug dbg,Dwarf_Unsigned * loclists_count,Dwarf_Error * error)498*4d9fdb46SRobert Mustacchi int dwarf_load_loclists(
499*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg,
500*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *loclists_count,
501*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
502*4d9fdb46SRobert Mustacchi {
503*4d9fdb46SRobert Mustacchi     int res = DW_DLV_ERROR;
504*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context *cxt = 0;
505*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count = 0;
506*4d9fdb46SRobert Mustacchi 
507*4d9fdb46SRobert Mustacchi     if (dbg->de_loclists_context) {
508*4d9fdb46SRobert Mustacchi         if (loclists_count) {
509*4d9fdb46SRobert Mustacchi             *loclists_count = dbg->de_loclists_context_count;
510*4d9fdb46SRobert Mustacchi         }
511*4d9fdb46SRobert Mustacchi     }
512*4d9fdb46SRobert Mustacchi     if (!dbg->de_debug_loclists.dss_size) {
513*4d9fdb46SRobert Mustacchi         /* nothing there. */
514*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
515*4d9fdb46SRobert Mustacchi     }
516*4d9fdb46SRobert Mustacchi     if (!dbg->de_debug_loclists.dss_data) {
517*4d9fdb46SRobert Mustacchi         res = _dwarf_load_section(dbg, &dbg->de_debug_loclists,
518*4d9fdb46SRobert Mustacchi             error);
519*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
520*4d9fdb46SRobert Mustacchi             return res;
521*4d9fdb46SRobert Mustacchi         }
522*4d9fdb46SRobert Mustacchi     }
523*4d9fdb46SRobert Mustacchi     res = internal_load_loclists_contexts(dbg,&cxt,&count,error);
524*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
525*4d9fdb46SRobert Mustacchi         return res;
526*4d9fdb46SRobert Mustacchi     }
527*4d9fdb46SRobert Mustacchi     dbg->de_loclists_context = cxt;
528*4d9fdb46SRobert Mustacchi     dbg->de_loclists_context_count = count;
529*4d9fdb46SRobert Mustacchi     if (loclists_count) {
530*4d9fdb46SRobert Mustacchi         *loclists_count = count;
531*4d9fdb46SRobert Mustacchi     }
532*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
533*4d9fdb46SRobert Mustacchi }
534*4d9fdb46SRobert Mustacchi 
535*4d9fdb46SRobert Mustacchi /*  Frees the memory in use in all loclists contexts.
536*4d9fdb46SRobert Mustacchi     Done by dwarf_finish()  */
537*4d9fdb46SRobert Mustacchi void
_dwarf_dealloc_loclists_context(Dwarf_Debug dbg)538*4d9fdb46SRobert Mustacchi _dwarf_dealloc_loclists_context(Dwarf_Debug dbg)
539*4d9fdb46SRobert Mustacchi {
540*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
541*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context * loccon = 0;
542*4d9fdb46SRobert Mustacchi 
543*4d9fdb46SRobert Mustacchi     if (!dbg->de_loclists_context) {
544*4d9fdb46SRobert Mustacchi         return;
545*4d9fdb46SRobert Mustacchi     }
546*4d9fdb46SRobert Mustacchi     loccon = dbg->de_loclists_context;
547*4d9fdb46SRobert Mustacchi     for( ; i < dbg->de_loclists_context_count; ++i,++loccon) {
548*4d9fdb46SRobert Mustacchi         Dwarf_Loclists_Context con = *loccon;
549*4d9fdb46SRobert Mustacchi         con->lc_offsets_array = 0;
550*4d9fdb46SRobert Mustacchi         con->lc_offset_entry_count = 0;
551*4d9fdb46SRobert Mustacchi         free(con);
552*4d9fdb46SRobert Mustacchi     }
553*4d9fdb46SRobert Mustacchi     free(dbg->de_loclists_context);
554*4d9fdb46SRobert Mustacchi     dbg->de_loclists_context = 0;
555*4d9fdb46SRobert Mustacchi     dbg->de_loclists_context_count = 0;
556*4d9fdb46SRobert Mustacchi }
557*4d9fdb46SRobert Mustacchi 
558*4d9fdb46SRobert Mustacchi /*  Used by dwarfdump to print raw loclists data. */
559*4d9fdb46SRobert Mustacchi int
dwarf_get_loclist_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)560*4d9fdb46SRobert Mustacchi dwarf_get_loclist_offset_index_value(
561*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg,
562*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned context_index,
563*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offsetentry_index,
564*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * offset_value_out,
565*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * global_offset_value_out,
566*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
567*4d9fdb46SRobert Mustacchi {
568*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context con = 0;
569*4d9fdb46SRobert Mustacchi     unsigned offset_len = 0;
570*4d9fdb46SRobert Mustacchi     Dwarf_Small *offsetptr = 0;
571*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned targetoffset = 0;
572*4d9fdb46SRobert Mustacchi 
573*4d9fdb46SRobert Mustacchi     if (!dbg->de_loclists_context_count) {
574*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
575*4d9fdb46SRobert Mustacchi     }
576*4d9fdb46SRobert Mustacchi     if (context_index >= dbg->de_loclists_context_count) {
577*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
578*4d9fdb46SRobert Mustacchi     }
579*4d9fdb46SRobert Mustacchi     con = dbg->de_loclists_context[context_index];
580*4d9fdb46SRobert Mustacchi 
581*4d9fdb46SRobert Mustacchi     if (offsetentry_index >= con->lc_offset_entry_count) {
582*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
583*4d9fdb46SRobert Mustacchi     }
584*4d9fdb46SRobert Mustacchi     offset_len = con->lc_offset_size;
585*4d9fdb46SRobert Mustacchi     offsetptr = con->lc_offsets_array +
586*4d9fdb46SRobert Mustacchi         (offsetentry_index*offset_len);
587*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,targetoffset,Dwarf_Unsigned,
588*4d9fdb46SRobert Mustacchi         offsetptr,
589*4d9fdb46SRobert Mustacchi         offset_len,error,con->lc_endaddr);
590*4d9fdb46SRobert Mustacchi     if (offset_value_out) {
591*4d9fdb46SRobert Mustacchi         *offset_value_out = targetoffset;
592*4d9fdb46SRobert Mustacchi     }
593*4d9fdb46SRobert Mustacchi     if (global_offset_value_out) {
594*4d9fdb46SRobert Mustacchi         *global_offset_value_out = targetoffset +
595*4d9fdb46SRobert Mustacchi             con->lc_offsets_off_in_sect;
596*4d9fdb46SRobert Mustacchi     }
597*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
598*4d9fdb46SRobert Mustacchi }
599*4d9fdb46SRobert Mustacchi 
600*4d9fdb46SRobert Mustacchi /*  Used by dwarfdump to print basic data from the
601*4d9fdb46SRobert Mustacchi     data generated to look at a specific loclist
602*4d9fdb46SRobert Mustacchi     as returned by  dwarf_loclists_index_get_rle_head()
603*4d9fdb46SRobert Mustacchi     or dwarf_loclists_offset_get_rle_head. */
dwarf_get_loclist_head_basics(Dwarf_Loc_Head_c head,Dwarf_Small * lkind,Dwarf_Unsigned * lle_count,Dwarf_Unsigned * lle_version,Dwarf_Unsigned * loclists_index_returned,Dwarf_Unsigned * bytes_total_in_lle,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 * loclists_base_present,Dwarf_Unsigned * loclists_base,Dwarf_Bool * loclists_base_address_present,Dwarf_Unsigned * loclists_base_address,Dwarf_Bool * loclists_debug_addr_base_present,Dwarf_Unsigned * loclists_debug_addr_base,Dwarf_Unsigned * loclists_offset_lle_set,UNUSEDARG Dwarf_Error * error)604*4d9fdb46SRobert Mustacchi int dwarf_get_loclist_head_basics(
605*4d9fdb46SRobert Mustacchi     Dwarf_Loc_Head_c head,
606*4d9fdb46SRobert Mustacchi     Dwarf_Small    * lkind,
607*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * lle_count,
608*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * lle_version,
609*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * loclists_index_returned,
610*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * bytes_total_in_lle,
611*4d9fdb46SRobert Mustacchi     Dwarf_Half     * offset_size,
612*4d9fdb46SRobert Mustacchi     Dwarf_Half     * address_size,
613*4d9fdb46SRobert Mustacchi     Dwarf_Half     * segment_selector_size,
614*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * overall_offset_of_this_context,
615*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * total_length_of_this_context,
616*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * offset_table_offset,
617*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * offset_table_entrycount,
618*4d9fdb46SRobert Mustacchi     Dwarf_Bool     * loclists_base_present,
619*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * loclists_base,
620*4d9fdb46SRobert Mustacchi     Dwarf_Bool     * loclists_base_address_present,
621*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * loclists_base_address,
622*4d9fdb46SRobert Mustacchi     Dwarf_Bool     * loclists_debug_addr_base_present,
623*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * loclists_debug_addr_base,
624*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * loclists_offset_lle_set,
625*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error *error)
626*4d9fdb46SRobert Mustacchi {
627*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context loccontext = 0;
628*4d9fdb46SRobert Mustacchi     *lkind = head->ll_kind;
629*4d9fdb46SRobert Mustacchi     *lle_count = head->ll_locdesc_count;
630*4d9fdb46SRobert Mustacchi     *lle_version = head->ll_cuversion;
631*4d9fdb46SRobert Mustacchi     *loclists_index_returned = head->ll_index;
632*4d9fdb46SRobert Mustacchi     *bytes_total_in_lle = head->ll_bytes_total;
633*4d9fdb46SRobert Mustacchi     *offset_size = head->ll_offset_size;
634*4d9fdb46SRobert Mustacchi     *address_size = head->ll_address_size;
635*4d9fdb46SRobert Mustacchi     *segment_selector_size = head->ll_segment_selector_size;
636*4d9fdb46SRobert Mustacchi     /*  If a dwarf_expression, no ll_loccontext */
637*4d9fdb46SRobert Mustacchi     loccontext = head->ll_localcontext;
638*4d9fdb46SRobert Mustacchi     if (loccontext) {
639*4d9fdb46SRobert Mustacchi         *overall_offset_of_this_context =
640*4d9fdb46SRobert Mustacchi             loccontext->lc_header_offset;
641*4d9fdb46SRobert Mustacchi         *total_length_of_this_context = loccontext->lc_length;
642*4d9fdb46SRobert Mustacchi         *offset_table_offset =  loccontext->lc_offsets_off_in_sect;
643*4d9fdb46SRobert Mustacchi         *offset_table_entrycount = loccontext->lc_offset_entry_count;
644*4d9fdb46SRobert Mustacchi     }
645*4d9fdb46SRobert Mustacchi     *loclists_base_present = head->ll_at_loclists_base_present;
646*4d9fdb46SRobert Mustacchi     *loclists_base= head->ll_at_loclists_base;
647*4d9fdb46SRobert Mustacchi 
648*4d9fdb46SRobert Mustacchi     *loclists_base_address_present = head->ll_cu_base_address_present;
649*4d9fdb46SRobert Mustacchi     *loclists_base_address= head->ll_cu_base_address;
650*4d9fdb46SRobert Mustacchi 
651*4d9fdb46SRobert Mustacchi     *loclists_debug_addr_base_present = head->ll_cu_addr_base_present;
652*4d9fdb46SRobert Mustacchi     *loclists_debug_addr_base  = head->ll_cu_addr_base;
653*4d9fdb46SRobert Mustacchi     *loclists_offset_lle_set = head->ll_llearea_offset;
654*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
655*4d9fdb46SRobert Mustacchi }
656*4d9fdb46SRobert Mustacchi 
657*4d9fdb46SRobert Mustacchi /*  Used by dwarfdump to print raw loclists data.
658*4d9fdb46SRobert Mustacchi     Enables printing of details about the Range List Table
659*4d9fdb46SRobert Mustacchi     Headers, one header per call. Index starting at 0.
660*4d9fdb46SRobert Mustacchi     Returns DW_DLV_NO_ENTRY if index is too high for the table.
661*4d9fdb46SRobert Mustacchi     A .debug_loclists section may contain any number
662*4d9fdb46SRobert Mustacchi     of Range List Table Headers with their details.  */
dwarf_get_loclist_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_loclistentry,Dwarf_Unsigned * offset_past_last_loclistentry,UNUSEDARG Dwarf_Error * error)663*4d9fdb46SRobert Mustacchi int dwarf_get_loclist_context_basics(
664*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg,
665*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned context_index,
666*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * header_offset,
667*4d9fdb46SRobert Mustacchi     Dwarf_Small    * offset_size,
668*4d9fdb46SRobert Mustacchi     Dwarf_Small    * extension_size,
669*4d9fdb46SRobert Mustacchi     unsigned       * version, /* 5 */
670*4d9fdb46SRobert Mustacchi     Dwarf_Small    * address_size,
671*4d9fdb46SRobert Mustacchi     Dwarf_Small    * segment_selector_size,
672*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * offset_entry_count,
673*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * offset_of_offset_array,
674*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * offset_of_first_loclistentry,
675*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * offset_past_last_loclistentry,
676*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error *error)
677*4d9fdb46SRobert Mustacchi {
678*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context con = 0;
679*4d9fdb46SRobert Mustacchi     if (!dbg->de_loclists_context_count) {
680*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
681*4d9fdb46SRobert Mustacchi     }
682*4d9fdb46SRobert Mustacchi     if (context_index >= dbg->de_loclists_context_count) {
683*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
684*4d9fdb46SRobert Mustacchi     }
685*4d9fdb46SRobert Mustacchi     con = dbg->de_loclists_context[context_index];
686*4d9fdb46SRobert Mustacchi 
687*4d9fdb46SRobert Mustacchi     if (header_offset) {
688*4d9fdb46SRobert Mustacchi         *header_offset = con->lc_header_offset;
689*4d9fdb46SRobert Mustacchi     }
690*4d9fdb46SRobert Mustacchi     if (offset_size) {
691*4d9fdb46SRobert Mustacchi         *offset_size = con->lc_offset_size;
692*4d9fdb46SRobert Mustacchi     }
693*4d9fdb46SRobert Mustacchi     if (offset_size) {
694*4d9fdb46SRobert Mustacchi         *extension_size = con->lc_extension_size;
695*4d9fdb46SRobert Mustacchi     }
696*4d9fdb46SRobert Mustacchi     if (version) {
697*4d9fdb46SRobert Mustacchi         *version = con->lc_version;
698*4d9fdb46SRobert Mustacchi     }
699*4d9fdb46SRobert Mustacchi     if (address_size) {
700*4d9fdb46SRobert Mustacchi         *address_size = con->lc_address_size;
701*4d9fdb46SRobert Mustacchi     }
702*4d9fdb46SRobert Mustacchi     if (segment_selector_size) {
703*4d9fdb46SRobert Mustacchi         *segment_selector_size = con->lc_segment_selector_size;
704*4d9fdb46SRobert Mustacchi     }
705*4d9fdb46SRobert Mustacchi     if (offset_entry_count) {
706*4d9fdb46SRobert Mustacchi         *offset_entry_count = con->lc_offset_entry_count;
707*4d9fdb46SRobert Mustacchi     }
708*4d9fdb46SRobert Mustacchi     if (offset_of_offset_array) {
709*4d9fdb46SRobert Mustacchi         *offset_of_offset_array = con->lc_offsets_off_in_sect;
710*4d9fdb46SRobert Mustacchi     }
711*4d9fdb46SRobert Mustacchi     if (offset_of_first_loclistentry) {
712*4d9fdb46SRobert Mustacchi         *offset_of_first_loclistentry = con->lc_first_loclist_offset;
713*4d9fdb46SRobert Mustacchi     }
714*4d9fdb46SRobert Mustacchi     if (offset_past_last_loclistentry) {
715*4d9fdb46SRobert Mustacchi         *offset_past_last_loclistentry =
716*4d9fdb46SRobert Mustacchi             con->lc_past_last_loclist_offset;
717*4d9fdb46SRobert Mustacchi     }
718*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
719*4d9fdb46SRobert Mustacchi }
720*4d9fdb46SRobert Mustacchi 
721*4d9fdb46SRobert Mustacchi /*  Used by dwarfdump to print raw loclists data.
722*4d9fdb46SRobert Mustacchi     entry offset is offset_of_first_loclistentry.
723*4d9fdb46SRobert Mustacchi     Stop when the returned *next_entry_offset
724*4d9fdb46SRobert Mustacchi     is == offset_past_last_loclistentry (from
725*4d9fdb46SRobert Mustacchi     dwarf_get_loclist_context_plus).
726*4d9fdb46SRobert Mustacchi     This only makes sense within those loclists
727*4d9fdb46SRobert Mustacchi     This retrieves raw detail from the section,
728*4d9fdb46SRobert Mustacchi     no base values or anything are added.
729*4d9fdb46SRobert Mustacchi     So this returns raw individual entries
730*4d9fdb46SRobert Mustacchi     for a single loclist header, meaning a
731*4d9fdb46SRobert Mustacchi     a single Dwarf_Loclists_Context.  */
dwarf_get_loclist_lle(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_Unsigned * expr_ops_blocksize,Dwarf_Unsigned * expr_ops_offset,Dwarf_Small ** expr_opsdata,Dwarf_Error * err)732*4d9fdb46SRobert Mustacchi int dwarf_get_loclist_lle(
733*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg,
734*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned contextnumber,
735*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned entry_offset,
736*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned endoffset,
737*4d9fdb46SRobert Mustacchi     unsigned *entrylen,
738*4d9fdb46SRobert Mustacchi     unsigned *entry_kind,
739*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *entry_operand1,
740*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *entry_operand2,
741*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *expr_ops_blocksize,
742*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *expr_ops_offset,
743*4d9fdb46SRobert Mustacchi     Dwarf_Small   **expr_opsdata,
744*4d9fdb46SRobert Mustacchi     Dwarf_Error *err)
745*4d9fdb46SRobert Mustacchi {
746*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context con = 0;
747*4d9fdb46SRobert Mustacchi     Dwarf_Small *data = 0;
748*4d9fdb46SRobert Mustacchi     Dwarf_Small *enddata = 0;
749*4d9fdb46SRobert Mustacchi     int res = 0;
750*4d9fdb46SRobert Mustacchi     unsigned address_size = 0;
751*4d9fdb46SRobert Mustacchi 
752*4d9fdb46SRobert Mustacchi 
753*4d9fdb46SRobert Mustacchi     if (!dbg->de_loclists_context_count) {
754*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
755*4d9fdb46SRobert Mustacchi     }
756*4d9fdb46SRobert Mustacchi     data = dbg->de_debug_loclists.dss_data +
757*4d9fdb46SRobert Mustacchi         entry_offset;
758*4d9fdb46SRobert Mustacchi     enddata = dbg->de_debug_loclists.dss_data +
759*4d9fdb46SRobert Mustacchi         endoffset;
760*4d9fdb46SRobert Mustacchi     if (contextnumber >= dbg->de_loclists_context_count) {
761*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
762*4d9fdb46SRobert Mustacchi     }
763*4d9fdb46SRobert Mustacchi     con = dbg->de_loclists_context[contextnumber];
764*4d9fdb46SRobert Mustacchi     address_size = con->lc_address_size;
765*4d9fdb46SRobert Mustacchi     res = read_single_lle_entry(dbg,
766*4d9fdb46SRobert Mustacchi         data,entry_offset,enddata,
767*4d9fdb46SRobert Mustacchi         address_size, entrylen,
768*4d9fdb46SRobert Mustacchi         entry_kind, entry_operand1, entry_operand2,
769*4d9fdb46SRobert Mustacchi         expr_ops_blocksize,
770*4d9fdb46SRobert Mustacchi         expr_ops_offset,
771*4d9fdb46SRobert Mustacchi         expr_opsdata,
772*4d9fdb46SRobert Mustacchi         err);
773*4d9fdb46SRobert Mustacchi     return res;
774*4d9fdb46SRobert Mustacchi }
775*4d9fdb46SRobert Mustacchi 
776*4d9fdb46SRobert Mustacchi 
777*4d9fdb46SRobert Mustacchi static int
_dwarf_which_loclists_context(Dwarf_Debug dbg,Dwarf_CU_Context ctx,Dwarf_Unsigned loclist_offset,Dwarf_Unsigned * index,Dwarf_Error * error)778*4d9fdb46SRobert Mustacchi _dwarf_which_loclists_context(Dwarf_Debug dbg,
779*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context ctx,
780*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned loclist_offset,
781*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *index,
782*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
783*4d9fdb46SRobert Mustacchi {
784*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned          count = 0;
785*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context *array = 0;
786*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned          i = 0;
787*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context  rcx = 0;
788*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned          rcxoff = 0;
789*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned          rcxend = 0;
790*4d9fdb46SRobert Mustacchi 
791*4d9fdb46SRobert Mustacchi     array = dbg->de_loclists_context;
792*4d9fdb46SRobert Mustacchi     count = dbg->de_loclists_context_count;
793*4d9fdb46SRobert Mustacchi     if (!array) {
794*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
795*4d9fdb46SRobert Mustacchi     }
796*4d9fdb46SRobert Mustacchi     rcx = array[i];
797*4d9fdb46SRobert Mustacchi     rcxoff = rcx->lc_header_offset;
798*4d9fdb46SRobert Mustacchi     rcxend = rcxoff + rcx->lc_length;
799*4d9fdb46SRobert Mustacchi     if (!ctx->cc_loclists_base_present) {
800*4d9fdb46SRobert Mustacchi         /* We look at the location of each loclist context
801*4d9fdb46SRobert Mustacchi             to find one with the offset the DIE gave us. */
802*4d9fdb46SRobert Mustacchi         for ( i = 0 ; i < count; ++i) {
803*4d9fdb46SRobert Mustacchi             rcx = array[i];
804*4d9fdb46SRobert Mustacchi             rcxoff = rcx->lc_header_offset;
805*4d9fdb46SRobert Mustacchi             rcxend = rcxoff +
806*4d9fdb46SRobert Mustacchi                 rcx->lc_length;
807*4d9fdb46SRobert Mustacchi             rcxend = rcxoff +
808*4d9fdb46SRobert Mustacchi                 rcx->lc_length;
809*4d9fdb46SRobert Mustacchi             if (loclist_offset < rcxoff){
810*4d9fdb46SRobert Mustacchi                 continue;
811*4d9fdb46SRobert Mustacchi             }
812*4d9fdb46SRobert Mustacchi             if (loclist_offset < rcxend ){
813*4d9fdb46SRobert Mustacchi                 *index = i;
814*4d9fdb46SRobert Mustacchi                 return DW_DLV_OK;
815*4d9fdb46SRobert Mustacchi             }
816*4d9fdb46SRobert Mustacchi         }
817*4d9fdb46SRobert Mustacchi         {
818*4d9fdb46SRobert Mustacchi             dwarfstring m;
819*4d9fdb46SRobert Mustacchi 
820*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&m);
821*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
822*4d9fdb46SRobert Mustacchi                 "DW_DLE_LOCLISTS_ERROR: loclist ran off end "
823*4d9fdb46SRobert Mustacchi                 " finding target offset of"
824*4d9fdb46SRobert Mustacchi                 " 0x%" DW_PR_XZEROS DW_PR_DUx ,loclist_offset);
825*4d9fdb46SRobert Mustacchi             dwarfstring_append(&m,
826*4d9fdb46SRobert Mustacchi                 " Not found anywhere in .debug_loclists "
827*4d9fdb46SRobert Mustacchi                 "data. Corrupted data?");
828*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg,error,
829*4d9fdb46SRobert Mustacchi                 DW_DLE_LOCLISTS_ERROR,
830*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&m));
831*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&m);
832*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
833*4d9fdb46SRobert Mustacchi         }
834*4d9fdb46SRobert Mustacchi     } else {
835*4d9fdb46SRobert Mustacchi         /*  We have a DW_AT_loclists_base (lc_loclists_base),
836*4d9fdb46SRobert Mustacchi             let's use it. */
837*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned lookfor = 0;;
838*4d9fdb46SRobert Mustacchi 
839*4d9fdb46SRobert Mustacchi         lookfor = ctx->cc_loclists_base;
840*4d9fdb46SRobert Mustacchi         for ( i = 0 ; i < count; ++i) {
841*4d9fdb46SRobert Mustacchi             dwarfstring m;
842*4d9fdb46SRobert Mustacchi 
843*4d9fdb46SRobert Mustacchi             rcx = array[i];
844*4d9fdb46SRobert Mustacchi             if (rcx->lc_offsets_off_in_sect == lookfor){
845*4d9fdb46SRobert Mustacchi                 *index = i;
846*4d9fdb46SRobert Mustacchi                 return DW_DLV_OK;
847*4d9fdb46SRobert Mustacchi             }
848*4d9fdb46SRobert Mustacchi             if (rcx->lc_offsets_off_in_sect < lookfor){
849*4d9fdb46SRobert Mustacchi                 continue;
850*4d9fdb46SRobert Mustacchi             }
851*4d9fdb46SRobert Mustacchi 
852*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&m);
853*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
854*4d9fdb46SRobert Mustacchi                 "DW_DLE_LOCLISTS_ERROR: loclists base of "
855*4d9fdb46SRobert Mustacchi                 " 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor);
856*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
857*4d9fdb46SRobert Mustacchi                 " was not found though we are now at base "
858*4d9fdb46SRobert Mustacchi                 " 0x%" DW_PR_XZEROS DW_PR_DUx ,
859*4d9fdb46SRobert Mustacchi                 rcx->lc_offsets_off_in_sect);
860*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg,error,
861*4d9fdb46SRobert Mustacchi                 DW_DLE_LOCLISTS_ERROR,
862*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&m));
863*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&m);
864*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
865*4d9fdb46SRobert Mustacchi         }
866*4d9fdb46SRobert Mustacchi         {
867*4d9fdb46SRobert Mustacchi             dwarfstring m;
868*4d9fdb46SRobert Mustacchi 
869*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&m);
870*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
871*4d9fdb46SRobert Mustacchi                 "DW_DLE_LOCLISTS_ERROR: loclist base of "
872*4d9fdb46SRobert Mustacchi                 " 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor);
873*4d9fdb46SRobert Mustacchi             dwarfstring_append(&m,
874*4d9fdb46SRobert Mustacchi                 " was not found anywhere in .debug_loclists "
875*4d9fdb46SRobert Mustacchi                 "data. Corrupted data?");
876*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg,error,
877*4d9fdb46SRobert Mustacchi                 DW_DLE_LOCLISTS_ERROR,
878*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&m));
879*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&m);
880*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
881*4d9fdb46SRobert Mustacchi         }
882*4d9fdb46SRobert Mustacchi     }
883*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
884*4d9fdb46SRobert Mustacchi }
885*4d9fdb46SRobert Mustacchi #if 0
886*4d9fdb46SRobert Mustacchi int
887*4d9fdb46SRobert Mustacchi dwarf_dealloc_loclists_head(Dwarf_Loc_Head_c h)
888*4d9fdb46SRobert Mustacchi {
889*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = h->ll_dbg;
890*4d9fdb46SRobert Mustacchi 
891*4d9fdb46SRobert Mustacchi     dwarf_dealloc(dbg,h,DW_DLA_LOCLISTS_HEAD);
892*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
893*4d9fdb46SRobert Mustacchi }
894*4d9fdb46SRobert Mustacchi #endif
895*4d9fdb46SRobert Mustacchi 
896*4d9fdb46SRobert Mustacchi /*  Caller will eventually free as appropriate. */
897*4d9fdb46SRobert Mustacchi static int
alloc_rle_and_append_to_list(Dwarf_Debug dbg,Dwarf_Loc_Head_c rctx,Dwarf_Locdesc_c * e_out,Dwarf_Error * error)898*4d9fdb46SRobert Mustacchi alloc_rle_and_append_to_list(Dwarf_Debug dbg,
899*4d9fdb46SRobert Mustacchi     Dwarf_Loc_Head_c rctx,
900*4d9fdb46SRobert Mustacchi     Dwarf_Locdesc_c *e_out,
901*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
902*4d9fdb46SRobert Mustacchi {
903*4d9fdb46SRobert Mustacchi     Dwarf_Locdesc_c e = 0;
904*4d9fdb46SRobert Mustacchi 
905*4d9fdb46SRobert Mustacchi     e = malloc(sizeof(struct Dwarf_Locdesc_c_s));
906*4d9fdb46SRobert Mustacchi     if (!e) {
907*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
908*4d9fdb46SRobert Mustacchi             "DW_DLE_ALLOC_FAIL: Out of memory in "
909*4d9fdb46SRobert Mustacchi             "building list of loclists entries on a DIE.");
910*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
911*4d9fdb46SRobert Mustacchi     }
912*4d9fdb46SRobert Mustacchi     memset(e,0,sizeof(struct Dwarf_Locdesc_c_s));
913*4d9fdb46SRobert Mustacchi     if (rctx->ll_first) {
914*4d9fdb46SRobert Mustacchi         rctx->ll_last->ld_next = e;
915*4d9fdb46SRobert Mustacchi         rctx->ll_last = e;
916*4d9fdb46SRobert Mustacchi     } else {
917*4d9fdb46SRobert Mustacchi         rctx->ll_first = e;
918*4d9fdb46SRobert Mustacchi         rctx->ll_last = e;
919*4d9fdb46SRobert Mustacchi     }
920*4d9fdb46SRobert Mustacchi     rctx->ll_locdesc_count++;
921*4d9fdb46SRobert Mustacchi     *e_out = e;
922*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
923*4d9fdb46SRobert Mustacchi }
924*4d9fdb46SRobert Mustacchi 
925*4d9fdb46SRobert Mustacchi /*  Read the group of loclists entries, and
926*4d9fdb46SRobert Mustacchi     finally build an array of Dwarf_Locdesc_c
927*4d9fdb46SRobert Mustacchi     records. Attach to rctx here.
928*4d9fdb46SRobert Mustacchi     Since on error the caller will destruct the rctx
929*4d9fdb46SRobert Mustacchi     and we ensure to attach allocations there
930*4d9fdb46SRobert Mustacchi     the caller will destruct the allocations here
931*4d9fdb46SRobert Mustacchi     in case we return DW_DLV_ERROR*/
932*4d9fdb46SRobert Mustacchi static int
build_array_of_lle(Dwarf_Debug dbg,Dwarf_Loc_Head_c rctx,Dwarf_Error * error)933*4d9fdb46SRobert Mustacchi build_array_of_lle(Dwarf_Debug dbg,
934*4d9fdb46SRobert Mustacchi     Dwarf_Loc_Head_c rctx,
935*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
936*4d9fdb46SRobert Mustacchi {
937*4d9fdb46SRobert Mustacchi     int res = 0;
938*4d9fdb46SRobert Mustacchi     Dwarf_Small   *data         = rctx->ll_llepointer;
939*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned dataoffset   = rctx->ll_llearea_offset;
940*4d9fdb46SRobert Mustacchi     Dwarf_Small   *enddata      = rctx->ll_end_data_area;
941*4d9fdb46SRobert Mustacchi     unsigned int   offset_size  = rctx->ll_offset_size;
942*4d9fdb46SRobert Mustacchi     unsigned int   address_size = rctx->ll_address_size;
943*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned bytescounttotal= 0;
944*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned latestbaseaddr = 0;
945*4d9fdb46SRobert Mustacchi     unsigned int   foundbaseaddr  = FALSE;
946*4d9fdb46SRobert Mustacchi     int            done           = FALSE;
947*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned locdesc_index  = 0;
948*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i              = 0;
949*4d9fdb46SRobert Mustacchi 
950*4d9fdb46SRobert Mustacchi     if (rctx->ll_cu_base_address_present) {
951*4d9fdb46SRobert Mustacchi         /*  The CU DIE had DW_AT_low_pc
952*4d9fdb46SRobert Mustacchi             and it is a base address. */
953*4d9fdb46SRobert Mustacchi         latestbaseaddr = rctx->ll_cu_base_address;
954*4d9fdb46SRobert Mustacchi         foundbaseaddr  = TRUE;
955*4d9fdb46SRobert Mustacchi     }
956*4d9fdb46SRobert Mustacchi     for( ; !done  ;++locdesc_index ) {
957*4d9fdb46SRobert Mustacchi         unsigned entrylen = 0;
958*4d9fdb46SRobert Mustacchi         unsigned code = 0;
959*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned val1 = 0;
960*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned val2 = 0;
961*4d9fdb46SRobert Mustacchi         Dwarf_Addr addr1= 0;
962*4d9fdb46SRobert Mustacchi         Dwarf_Addr addr2 = 0;
963*4d9fdb46SRobert Mustacchi         Dwarf_Locdesc_c e = 0;
964*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned opsblocksize  = 0;
965*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned opsoffset  = 0;
966*4d9fdb46SRobert Mustacchi         Dwarf_Small *ops = 0;
967*4d9fdb46SRobert Mustacchi         Dwarf_Block_c eops;
968*4d9fdb46SRobert Mustacchi 
969*4d9fdb46SRobert Mustacchi         memset(&eops,0,sizeof(eops));
970*4d9fdb46SRobert Mustacchi         res = read_single_lle_entry(dbg,
971*4d9fdb46SRobert Mustacchi             data,dataoffset, enddata,
972*4d9fdb46SRobert Mustacchi             address_size,&entrylen,
973*4d9fdb46SRobert Mustacchi             &code,&val1, &val2,
974*4d9fdb46SRobert Mustacchi             &opsblocksize,&opsoffset,&ops,
975*4d9fdb46SRobert Mustacchi             error);
976*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
977*4d9fdb46SRobert Mustacchi             return res;
978*4d9fdb46SRobert Mustacchi         }
979*4d9fdb46SRobert Mustacchi         res = alloc_rle_and_append_to_list(dbg,rctx,&e,error);
980*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
981*4d9fdb46SRobert Mustacchi             return res;
982*4d9fdb46SRobert Mustacchi         }
983*4d9fdb46SRobert Mustacchi         eops.bl_len =opsblocksize;
984*4d9fdb46SRobert Mustacchi         eops.bl_data = ops;
985*4d9fdb46SRobert Mustacchi         eops.bl_kind = rctx->ll_kind;
986*4d9fdb46SRobert Mustacchi         eops.bl_section_offset = opsoffset;
987*4d9fdb46SRobert Mustacchi         eops.bl_locdesc_offset = dataoffset;
988*4d9fdb46SRobert Mustacchi         e->ld_kind = rctx->ll_kind;
989*4d9fdb46SRobert Mustacchi         e->ld_lle_value = code,
990*4d9fdb46SRobert Mustacchi         e->ld_entrylen = entrylen;
991*4d9fdb46SRobert Mustacchi         e->ld_rawlow = val1;
992*4d9fdb46SRobert Mustacchi         e->ld_rawhigh = val2;
993*4d9fdb46SRobert Mustacchi         e->ld_opsblock = eops;
994*4d9fdb46SRobert Mustacchi         bytescounttotal += entrylen;
995*4d9fdb46SRobert Mustacchi         data += entrylen;
996*4d9fdb46SRobert Mustacchi         if (code == DW_LLE_end_of_list) {
997*4d9fdb46SRobert Mustacchi             done = TRUE;
998*4d9fdb46SRobert Mustacchi             break;
999*4d9fdb46SRobert Mustacchi         }
1000*4d9fdb46SRobert Mustacchi         /*  Here we create the cooked values from
1001*4d9fdb46SRobert Mustacchi             the raw values and other data. */
1002*4d9fdb46SRobert Mustacchi         switch(code) {
1003*4d9fdb46SRobert Mustacchi         case DW_LLE_base_addressx:
1004*4d9fdb46SRobert Mustacchi             foundbaseaddr = TRUE;
1005*4d9fdb46SRobert Mustacchi             res = _dwarf_extract_address_from_debug_addr(
1006*4d9fdb46SRobert Mustacchi                 dbg,rctx->ll_context,val1,
1007*4d9fdb46SRobert Mustacchi                 &addr1,error);
1008*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
1009*4d9fdb46SRobert Mustacchi                 return res;
1010*4d9fdb46SRobert Mustacchi             }
1011*4d9fdb46SRobert Mustacchi             e->ld_lopc = addr1;
1012*4d9fdb46SRobert Mustacchi             latestbaseaddr = addr1;
1013*4d9fdb46SRobert Mustacchi             break;
1014*4d9fdb46SRobert Mustacchi         case DW_LLE_startx_endx:
1015*4d9fdb46SRobert Mustacchi             res = _dwarf_extract_address_from_debug_addr(
1016*4d9fdb46SRobert Mustacchi                 dbg,rctx->ll_context,val1,
1017*4d9fdb46SRobert Mustacchi                 &addr1,error);
1018*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
1019*4d9fdb46SRobert Mustacchi                 return res;
1020*4d9fdb46SRobert Mustacchi             }
1021*4d9fdb46SRobert Mustacchi             res = _dwarf_extract_address_from_debug_addr(
1022*4d9fdb46SRobert Mustacchi                 dbg,rctx->ll_context,val2,
1023*4d9fdb46SRobert Mustacchi                 &addr2,error);
1024*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
1025*4d9fdb46SRobert Mustacchi                 return res;
1026*4d9fdb46SRobert Mustacchi             }
1027*4d9fdb46SRobert Mustacchi             e->ld_lopc = addr1;
1028*4d9fdb46SRobert Mustacchi             e->ld_highpc = addr2;
1029*4d9fdb46SRobert Mustacchi             break;
1030*4d9fdb46SRobert Mustacchi         case DW_LLE_startx_length:
1031*4d9fdb46SRobert Mustacchi             res = _dwarf_extract_address_from_debug_addr(
1032*4d9fdb46SRobert Mustacchi                 dbg,rctx->ll_context,val1,
1033*4d9fdb46SRobert Mustacchi                 &addr1,error);
1034*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
1035*4d9fdb46SRobert Mustacchi                 return res;
1036*4d9fdb46SRobert Mustacchi             }
1037*4d9fdb46SRobert Mustacchi             e->ld_lopc = addr1;
1038*4d9fdb46SRobert Mustacchi             e->ld_highpc = val2+addr1;
1039*4d9fdb46SRobert Mustacchi             break;
1040*4d9fdb46SRobert Mustacchi         case DW_LLE_offset_pair:
1041*4d9fdb46SRobert Mustacchi             if(foundbaseaddr) {
1042*4d9fdb46SRobert Mustacchi                 e->ld_lopc = val1+latestbaseaddr;
1043*4d9fdb46SRobert Mustacchi                 e->ld_highpc = val2+latestbaseaddr;
1044*4d9fdb46SRobert Mustacchi             } else {
1045*4d9fdb46SRobert Mustacchi                 e->ld_lopc = val1+rctx->ll_cu_base_address;
1046*4d9fdb46SRobert Mustacchi                 e->ld_highpc = val2+rctx->ll_cu_base_address;
1047*4d9fdb46SRobert Mustacchi             }
1048*4d9fdb46SRobert Mustacchi             break;
1049*4d9fdb46SRobert Mustacchi         case DW_LLE_base_address:
1050*4d9fdb46SRobert Mustacchi             foundbaseaddr = TRUE;
1051*4d9fdb46SRobert Mustacchi             latestbaseaddr = val1;
1052*4d9fdb46SRobert Mustacchi             e->ld_lopc = val1;
1053*4d9fdb46SRobert Mustacchi             break;
1054*4d9fdb46SRobert Mustacchi         case DW_LLE_start_end:
1055*4d9fdb46SRobert Mustacchi             e->ld_lopc = val1;
1056*4d9fdb46SRobert Mustacchi             e->ld_highpc = val2;
1057*4d9fdb46SRobert Mustacchi             break;
1058*4d9fdb46SRobert Mustacchi         case DW_LLE_start_length:
1059*4d9fdb46SRobert Mustacchi             e->ld_lopc = val1;
1060*4d9fdb46SRobert Mustacchi             e->ld_highpc = val2+val1;
1061*4d9fdb46SRobert Mustacchi             break;
1062*4d9fdb46SRobert Mustacchi         default: {
1063*4d9fdb46SRobert Mustacchi             dwarfstring m;
1064*4d9fdb46SRobert Mustacchi 
1065*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&m);
1066*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
1067*4d9fdb46SRobert Mustacchi                 " DW_DLE_LOCLISTS_ERROR: "
1068*4d9fdb46SRobert Mustacchi                 " The .debug_loclists "
1069*4d9fdb46SRobert Mustacchi                 " loclist code 0x%x is unknown, "
1070*4d9fdb46SRobert Mustacchi                 " DWARF5 is corrupted.",code);
1071*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg, error,
1072*4d9fdb46SRobert Mustacchi                 DW_DLE_LOCLISTS_ERROR,
1073*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&m));
1074*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&m);
1075*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1076*4d9fdb46SRobert Mustacchi         }
1077*4d9fdb46SRobert Mustacchi         }
1078*4d9fdb46SRobert Mustacchi     }
1079*4d9fdb46SRobert Mustacchi     if (rctx->ll_locdesc_count > 0) {
1080*4d9fdb46SRobert Mustacchi         Dwarf_Locdesc_c array = 0;
1081*4d9fdb46SRobert Mustacchi         Dwarf_Locdesc_c cur = 0;
1082*4d9fdb46SRobert Mustacchi         Dwarf_Locdesc_c prev = 0;
1083*4d9fdb46SRobert Mustacchi 
1084*4d9fdb46SRobert Mustacchi         /* array of structs. */
1085*4d9fdb46SRobert Mustacchi         array = (Dwarf_Locdesc_c)_dwarf_get_alloc(dbg,
1086*4d9fdb46SRobert Mustacchi             DW_DLA_LOCDESC_C, rctx->ll_locdesc_count);
1087*4d9fdb46SRobert Mustacchi         if (!array) {
1088*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
1089*4d9fdb46SRobert Mustacchi                 "DW_DLE_ALLOC_FAIL: Out of memory in "
1090*4d9fdb46SRobert Mustacchi                 "copying list of locdescs into array ");
1091*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1092*4d9fdb46SRobert Mustacchi         }
1093*4d9fdb46SRobert Mustacchi         rctx->ll_locdesc = array;
1094*4d9fdb46SRobert Mustacchi         cur = rctx->ll_first;
1095*4d9fdb46SRobert Mustacchi         for (i = 0  ; i < rctx->ll_locdesc_count; ++i) {
1096*4d9fdb46SRobert Mustacchi             prev = cur;
1097*4d9fdb46SRobert Mustacchi             array[i] = *cur;
1098*4d9fdb46SRobert Mustacchi             cur = cur->ld_next;
1099*4d9fdb46SRobert Mustacchi             free(prev);
1100*4d9fdb46SRobert Mustacchi         }
1101*4d9fdb46SRobert Mustacchi         rctx->ll_first = 0;
1102*4d9fdb46SRobert Mustacchi         rctx->ll_last = 0;
1103*4d9fdb46SRobert Mustacchi     }
1104*4d9fdb46SRobert Mustacchi     for (i = 0; i < rctx->ll_locdesc_count; ++i) {
1105*4d9fdb46SRobert Mustacchi         Dwarf_Locdesc_c ldc = rctx->ll_locdesc + i;
1106*4d9fdb46SRobert Mustacchi 
1107*4d9fdb46SRobert Mustacchi         res = _dwarf_fill_in_locdesc_op_c(dbg,
1108*4d9fdb46SRobert Mustacchi             i,
1109*4d9fdb46SRobert Mustacchi             rctx,
1110*4d9fdb46SRobert Mustacchi             &ldc->ld_opsblock,
1111*4d9fdb46SRobert Mustacchi             address_size, offset_size,
1112*4d9fdb46SRobert Mustacchi             rctx->ll_cuversion,
1113*4d9fdb46SRobert Mustacchi             ldc->ld_lopc, ldc->ld_highpc,
1114*4d9fdb46SRobert Mustacchi             ldc->ld_lle_value,
1115*4d9fdb46SRobert Mustacchi             error);
1116*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
1117*4d9fdb46SRobert Mustacchi             return res;
1118*4d9fdb46SRobert Mustacchi         }
1119*4d9fdb46SRobert Mustacchi     }
1120*4d9fdb46SRobert Mustacchi     rctx->ll_bytes_total = bytescounttotal;
1121*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1122*4d9fdb46SRobert Mustacchi }
1123*4d9fdb46SRobert Mustacchi 
1124*4d9fdb46SRobert Mustacchi /*  Build a head with all the relevent Entries
1125*4d9fdb46SRobert Mustacchi     attached, all the locdescs and for each such,
1126*4d9fdb46SRobert Mustacchi     all its expression operators.
1127*4d9fdb46SRobert Mustacchi */
1128*4d9fdb46SRobert Mustacchi int
_dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,Dwarf_Attribute attr,Dwarf_Loc_Head_c llhead,Dwarf_Error * error)1129*4d9fdb46SRobert Mustacchi _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
1130*4d9fdb46SRobert Mustacchi     Dwarf_Attribute attr,
1131*4d9fdb46SRobert Mustacchi     Dwarf_Loc_Head_c llhead,
1132*4d9fdb46SRobert Mustacchi     Dwarf_Error         *error)
1133*4d9fdb46SRobert Mustacchi {
1134*4d9fdb46SRobert Mustacchi     int res = 0;
1135*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned loclists_contextnum = 0;
1136*4d9fdb46SRobert Mustacchi     Dwarf_Small *table_base = 0;
1137*4d9fdb46SRobert Mustacchi     Dwarf_Small *table_entry = 0;
1138*4d9fdb46SRobert Mustacchi     Dwarf_Small *enddata = 0;
1139*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context *array = 0;
1140*4d9fdb46SRobert Mustacchi     Dwarf_Loclists_Context rctx = 0;
1141*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned entrycount = 0;
1142*4d9fdb46SRobert Mustacchi     unsigned offsetsize = 0;
1143*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned lle_global_offset = 0;
1144*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context ctx = 0;
1145*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset_in_loclists = 0;
1146*4d9fdb46SRobert Mustacchi     Dwarf_Bool is_loclistx = FALSE;
1147*4d9fdb46SRobert Mustacchi     int theform = llhead->ll_attrform;
1148*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned attr_val = 0;
1149*4d9fdb46SRobert Mustacchi 
1150*4d9fdb46SRobert Mustacchi     ctx = attr->ar_cu_context;
1151*4d9fdb46SRobert Mustacchi     array = dbg->de_loclists_context;
1152*4d9fdb46SRobert Mustacchi     if ( theform == DW_FORM_sec_offset) {
1153*4d9fdb46SRobert Mustacchi         /*  DW_FORM_sec_offset is not formudata , often
1154*4d9fdb46SRobert Mustacchi             seen in in DW5 DW_AT_location etc */
1155*4d9fdb46SRobert Mustacchi         res = dwarf_global_formref(attr, &attr_val,error);
1156*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
1157*4d9fdb46SRobert Mustacchi             return res;
1158*4d9fdb46SRobert Mustacchi         }
1159*4d9fdb46SRobert Mustacchi         offset_in_loclists = attr_val;
1160*4d9fdb46SRobert Mustacchi     } else {
1161*4d9fdb46SRobert Mustacchi         if (theform == DW_FORM_loclistx) {
1162*4d9fdb46SRobert Mustacchi             is_loclistx = TRUE;
1163*4d9fdb46SRobert Mustacchi         }
1164*4d9fdb46SRobert Mustacchi         res = dwarf_formudata(attr,&attr_val,error);
1165*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
1166*4d9fdb46SRobert Mustacchi             return res;
1167*4d9fdb46SRobert Mustacchi         }
1168*4d9fdb46SRobert Mustacchi         /*  the context cc_loclists_base gives the offset
1169*4d9fdb46SRobert Mustacchi             of the array. of offsets (if cc_loclists_base_present) */
1170*4d9fdb46SRobert Mustacchi                 offset_in_loclists = attr_val;
1171*4d9fdb46SRobert Mustacchi         if (is_loclistx) {
1172*4d9fdb46SRobert Mustacchi             if (ctx->cc_loclists_base_present) {
1173*4d9fdb46SRobert Mustacchi                 offset_in_loclists = ctx->cc_loclists_base;
1174*4d9fdb46SRobert Mustacchi             } else {
1175*4d9fdb46SRobert Mustacchi                 /* FIXME: check in tied file for a cc_loclists_base */
1176*4d9fdb46SRobert Mustacchi                 dwarfstring m;
1177*4d9fdb46SRobert Mustacchi 
1178*4d9fdb46SRobert Mustacchi                 dwarfstring_constructor(&m);
1179*4d9fdb46SRobert Mustacchi                 dwarfstring_append_printf_u(&m,
1180*4d9fdb46SRobert Mustacchi                     "DW_DLE_LOCLISTS_ERROR: loclists table index of"
1181*4d9fdb46SRobert Mustacchi                     " %u"  ,attr_val);
1182*4d9fdb46SRobert Mustacchi                 dwarfstring_append(&m,
1183*4d9fdb46SRobert Mustacchi                     " is unusable unless it is in a tied file."
1184*4d9fdb46SRobert Mustacchi                     " libdwarf is incomplete. FIXME");
1185*4d9fdb46SRobert Mustacchi                 _dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
1186*4d9fdb46SRobert Mustacchi                     dwarfstring_string(&m));
1187*4d9fdb46SRobert Mustacchi                 dwarfstring_destructor(&m);
1188*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1189*4d9fdb46SRobert Mustacchi             }
1190*4d9fdb46SRobert Mustacchi         } else {
1191*4d9fdb46SRobert Mustacchi             offset_in_loclists = attr_val;
1192*4d9fdb46SRobert Mustacchi         }
1193*4d9fdb46SRobert Mustacchi     }
1194*4d9fdb46SRobert Mustacchi     res = _dwarf_which_loclists_context(dbg,ctx,
1195*4d9fdb46SRobert Mustacchi         offset_in_loclists,
1196*4d9fdb46SRobert Mustacchi         &loclists_contextnum,error);
1197*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1198*4d9fdb46SRobert Mustacchi         return res;
1199*4d9fdb46SRobert Mustacchi     }
1200*4d9fdb46SRobert Mustacchi     rctx = array[loclists_contextnum];
1201*4d9fdb46SRobert Mustacchi     table_base = rctx->lc_offsets_array;
1202*4d9fdb46SRobert Mustacchi     entrycount = rctx->lc_offset_entry_count;
1203*4d9fdb46SRobert Mustacchi     offsetsize = rctx->lc_offset_size;
1204*4d9fdb46SRobert Mustacchi     enddata = rctx->lc_endaddr;
1205*4d9fdb46SRobert Mustacchi 
1206*4d9fdb46SRobert Mustacchi     if (is_loclistx && attr_val >= entrycount) {
1207*4d9fdb46SRobert Mustacchi         dwarfstring m;
1208*4d9fdb46SRobert Mustacchi 
1209*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
1210*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
1211*4d9fdb46SRobert Mustacchi             "DW_DLE_LOCLISTS_ERROR: loclists table index of"
1212*4d9fdb46SRobert Mustacchi             " %u"  ,attr_val);
1213*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
1214*4d9fdb46SRobert Mustacchi             " too large for table of %u "
1215*4d9fdb46SRobert Mustacchi             "entries.",entrycount);
1216*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg,error,
1217*4d9fdb46SRobert Mustacchi             DW_DLE_LOCLISTS_ERROR,
1218*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
1219*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
1220*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1221*4d9fdb46SRobert Mustacchi     }
1222*4d9fdb46SRobert Mustacchi     llhead->ll_localcontext = rctx;
1223*4d9fdb46SRobert Mustacchi     llhead->ll_index = loclists_contextnum;
1224*4d9fdb46SRobert Mustacchi     llhead->ll_cuversion = rctx->lc_version;
1225*4d9fdb46SRobert Mustacchi     llhead->ll_offset_size = offsetsize;
1226*4d9fdb46SRobert Mustacchi     llhead->ll_address_size  = rctx->lc_address_size;
1227*4d9fdb46SRobert Mustacchi     llhead->ll_segment_selector_size =
1228*4d9fdb46SRobert Mustacchi         rctx->lc_segment_selector_size;
1229*4d9fdb46SRobert Mustacchi 
1230*4d9fdb46SRobert Mustacchi     if (is_loclistx) {
1231*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned table_entryval = 0;
1232*4d9fdb46SRobert Mustacchi 
1233*4d9fdb46SRobert Mustacchi         table_entry = attr_val*offsetsize + table_base;
1234*4d9fdb46SRobert Mustacchi         /*  No malloc here yet so no leak if the macro returns
1235*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR */
1236*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg,table_entryval, Dwarf_Unsigned,
1237*4d9fdb46SRobert Mustacchi             table_entry,offsetsize,error,enddata);
1238*4d9fdb46SRobert Mustacchi         lle_global_offset = rctx->lc_offsets_off_in_sect +
1239*4d9fdb46SRobert Mustacchi             table_entryval;
1240*4d9fdb46SRobert Mustacchi     } else {
1241*4d9fdb46SRobert Mustacchi         lle_global_offset = attr_val;
1242*4d9fdb46SRobert Mustacchi     }
1243*4d9fdb46SRobert Mustacchi 
1244*4d9fdb46SRobert Mustacchi     llhead->ll_llepointer = rctx->lc_offsets_array +
1245*4d9fdb46SRobert Mustacchi         rctx->lc_offset_entry_count*offsetsize;
1246*4d9fdb46SRobert Mustacchi     llhead->ll_end_data_area = enddata;
1247*4d9fdb46SRobert Mustacchi 
1248*4d9fdb46SRobert Mustacchi     llhead->ll_llearea_offset = lle_global_offset;
1249*4d9fdb46SRobert Mustacchi     llhead->ll_llepointer = lle_global_offset +
1250*4d9fdb46SRobert Mustacchi         dbg->de_debug_loclists.dss_data;
1251*4d9fdb46SRobert Mustacchi 
1252*4d9fdb46SRobert Mustacchi     res = build_array_of_lle(dbg,llhead,error);
1253*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1254*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,llhead,DW_DLA_LOCLISTS_HEAD);
1255*4d9fdb46SRobert Mustacchi         return res;
1256*4d9fdb46SRobert Mustacchi     }
1257*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1258*4d9fdb46SRobert Mustacchi }
1259*4d9fdb46SRobert Mustacchi 
1260*4d9fdb46SRobert Mustacchi 
1261*4d9fdb46SRobert Mustacchi int
dwarf_get_loclists_entry_fields(Dwarf_Loc_Head_c head,Dwarf_Unsigned entrynum,unsigned * entrylen,unsigned * code,Dwarf_Unsigned * raw1,Dwarf_Unsigned * raw2,Dwarf_Unsigned * cooked1,Dwarf_Unsigned * cooked2,UNUSEDARG Dwarf_Error * err)1262*4d9fdb46SRobert Mustacchi dwarf_get_loclists_entry_fields(
1263*4d9fdb46SRobert Mustacchi     Dwarf_Loc_Head_c head,
1264*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned entrynum,
1265*4d9fdb46SRobert Mustacchi     unsigned *entrylen,
1266*4d9fdb46SRobert Mustacchi     unsigned *code,
1267*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *raw1,
1268*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *raw2,
1269*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *cooked1,
1270*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *cooked2,
1271*4d9fdb46SRobert Mustacchi     /*  FIXME not right for loclists or their loc exprs */
1272*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error *err)
1273*4d9fdb46SRobert Mustacchi {
1274*4d9fdb46SRobert Mustacchi     Dwarf_Locdesc_c e = 0;
1275*4d9fdb46SRobert Mustacchi 
1276*4d9fdb46SRobert Mustacchi     if (entrynum >= head->ll_locdesc_count) {
1277*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
1278*4d9fdb46SRobert Mustacchi     }
1279*4d9fdb46SRobert Mustacchi     e = head->ll_locdesc + entrynum;
1280*4d9fdb46SRobert Mustacchi     *entrylen  = e->ld_entrylen;
1281*4d9fdb46SRobert Mustacchi     *code      = e->ld_lle_value;
1282*4d9fdb46SRobert Mustacchi     *raw1      = e->ld_rawlow;
1283*4d9fdb46SRobert Mustacchi     *raw2      = e->ld_rawhigh;
1284*4d9fdb46SRobert Mustacchi     *cooked1   = e->ld_lopc;
1285*4d9fdb46SRobert Mustacchi     *cooked2   = e->ld_highpc;
1286*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1287*4d9fdb46SRobert Mustacchi }
1288*4d9fdb46SRobert Mustacchi 
1289*4d9fdb46SRobert Mustacchi /*  Deals with both fully and partially build head */
1290*4d9fdb46SRobert Mustacchi void
_dwarf_free_loclists_head(Dwarf_Loc_Head_c head)1291*4d9fdb46SRobert Mustacchi _dwarf_free_loclists_head(Dwarf_Loc_Head_c head)
1292*4d9fdb46SRobert Mustacchi {
1293*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = head->ll_dbg;
1294*4d9fdb46SRobert Mustacchi 
1295*4d9fdb46SRobert Mustacchi     if (head->ll_first) {
1296*4d9fdb46SRobert Mustacchi         /* partially built head. */
1297*4d9fdb46SRobert Mustacchi         /*  ASSERT: ll_loclists is NULL */
1298*4d9fdb46SRobert Mustacchi         Dwarf_Locdesc_c cur = head->ll_first;
1299*4d9fdb46SRobert Mustacchi         Dwarf_Locdesc_c next = 0;
1300*4d9fdb46SRobert Mustacchi 
1301*4d9fdb46SRobert Mustacchi         for ( ; cur ; cur = next) {
1302*4d9fdb46SRobert Mustacchi             next = cur->ld_next;
1303*4d9fdb46SRobert Mustacchi             free(cur);
1304*4d9fdb46SRobert Mustacchi         }
1305*4d9fdb46SRobert Mustacchi         head->ll_first = 0;
1306*4d9fdb46SRobert Mustacchi         head->ll_last = 0;
1307*4d9fdb46SRobert Mustacchi         head->ll_locdesc_count = 0;
1308*4d9fdb46SRobert Mustacchi     } else {
1309*4d9fdb46SRobert Mustacchi         Dwarf_Locdesc_c desc = head->ll_locdesc;
1310*4d9fdb46SRobert Mustacchi         /*  ASSERT: ll_first and ll_last are NULL */
1311*4d9fdb46SRobert Mustacchi         /* fully built head. */
1312*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned listlen = head->ll_locdesc_count;
1313*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned i = 0;
1314*4d9fdb46SRobert Mustacchi         for ( ; i < listlen; ++i) {
1315*4d9fdb46SRobert Mustacchi             Dwarf_Loc_Expr_Op loc = desc[i].ld_s;
1316*4d9fdb46SRobert Mustacchi             if(loc) {
1317*4d9fdb46SRobert Mustacchi                 dwarf_dealloc(dbg,loc,DW_DLA_LOC_BLOCK_C);
1318*4d9fdb46SRobert Mustacchi             }
1319*4d9fdb46SRobert Mustacchi         }
1320*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,head->ll_locdesc,DW_DLA_LOCDESC_C);
1321*4d9fdb46SRobert Mustacchi         head->ll_locdesc = 0;
1322*4d9fdb46SRobert Mustacchi         head->ll_locdesc_count = 0;
1323*4d9fdb46SRobert Mustacchi     }
1324*4d9fdb46SRobert Mustacchi }
1325*4d9fdb46SRobert Mustacchi 
1326*4d9fdb46SRobert Mustacchi void
_dwarf_loclists_head_destructor(void * head)1327*4d9fdb46SRobert Mustacchi _dwarf_loclists_head_destructor(void *head)
1328*4d9fdb46SRobert Mustacchi {
1329*4d9fdb46SRobert Mustacchi     Dwarf_Loc_Head_c h = head;
1330*4d9fdb46SRobert Mustacchi 
1331*4d9fdb46SRobert Mustacchi     _dwarf_free_loclists_head(h);
1332*4d9fdb46SRobert Mustacchi }
1333