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