1 /*
2 Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
3 Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved.
4 Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved.
5
6 This program is free software; you can redistribute it
7 and/or modify it under the terms of version 2.1 of the
8 GNU Lesser General Public License as published by the Free
9 Software Foundation.
10
11 This program is distributed in the hope that it would be
12 useful, but WITHOUT ANY WARRANTY; without even the implied
13 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE.
15
16 Further, this software is distributed without any warranty
17 that it is free of the rightful claim of any third person
18 regarding infringement or the like. Any license provided
19 herein, whether implied or otherwise, applies only to this
20 software file. Patent licenses, if any, provided herein
21 do not apply to combinations of this program with other
22 software, or any other product whatsoever.
23
24 You should have received a copy of the GNU Lesser General
25 Public License along with this program; if not, write the
26 Free Software Foundation, Inc., 51 Franklin Street - Fifth
27 Floor, Boston MA 02110-1301, USA.
28
29 */
30
31 #include "config.h"
32 #include <stdio.h> /* for debugging only. */
33 #ifdef HAVE_STDINT_H
34 #include <stdint.h> /* For uintptr_t */
35 #endif /* HAVE_STDINT_H */
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h> /* For uintptr_t */
38 #endif /* HAVE_STDLIB_H */
39 #include "dwarf_incl.h"
40 #include "dwarf_alloc.h"
41 #include "dwarf_error.h"
42 #include "dwarf_util.h"
43 #include "dwarf_loc.h"
44 #include "dwarfstring.h"
45
46 #define TRUE 1
47 #define FALSE 0
48
49 static int _dwarf_read_loc_section_dwo(Dwarf_Debug dbg,
50 Dwarf_Block_c * return_block,
51 Dwarf_Addr * lowpc,
52 Dwarf_Addr * highpc,
53 Dwarf_Bool * at_end,
54 Dwarf_Half * lle_op,
55 Dwarf_Off sec_offset,
56 Dwarf_Half address_size,
57 Dwarf_Half lkind,
58 Dwarf_Error *error);
59
60
61 static void
_dwarf_lkind_name(unsigned lkind,dwarfstring * m)62 _dwarf_lkind_name(unsigned lkind, dwarfstring *m)
63 {
64 switch(lkind) {
65 case DW_LKIND_expression:
66 dwarfstring_append(m,"DW_LKIND_expression");
67 return;
68 case DW_LKIND_loclist:
69 dwarfstring_append(m,"DW_LKIND_loclist");
70 return;
71 case DW_LKIND_GNU_exp_list:
72 dwarfstring_append(m,"DW_LKIND_GNU_exp_list");
73 return;
74 case DW_LKIND_loclists:
75 dwarfstring_append(m,"DW_LKIND_loclists");
76 return;
77 case DW_LKIND_unknown:
78 dwarfstring_append(m,"DW_LKIND_unknown");
79 return;
80 }
81 dwarfstring_append_printf_u(m,
82 "<DW_LKIND location kind is unknown and has value %u>.",
83 lkind);
84 }
85
86
87 static int
determine_location_lkind(unsigned int version,unsigned int form,UNUSEDARG unsigned int attribute,Dwarf_Bool is_dwo)88 determine_location_lkind(unsigned int version,
89 unsigned int form,
90 UNUSEDARG unsigned int attribute,
91 Dwarf_Bool is_dwo)
92 {
93 switch(form) {
94 case DW_FORM_exprloc: /* only defined for
95 DW_CFA_def_cfa_expression */
96 case DW_FORM_block:
97 case DW_FORM_block1:
98 case DW_FORM_block2:
99 case DW_FORM_block4:
100 return DW_LKIND_expression;
101 break;
102 case DW_FORM_data4:
103 case DW_FORM_data8:
104 if (version > 1 && version < 4) {
105 return DW_LKIND_loclist;
106 }
107 break;
108 case DW_FORM_sec_offset:
109 if (version == 5 ) {
110 return DW_LKIND_loclists;
111 }
112 if (version == 4 && is_dwo ) {
113 return DW_LKIND_GNU_exp_list;
114 }
115 return DW_LKIND_loclist;
116 break;
117 case DW_FORM_loclistx:
118 if (version == 5 ) {
119 return DW_LKIND_loclists;
120 }
121 break;
122 default:
123 break;
124 }
125 return DW_LKIND_unknown;
126 }
127
128 static void
_dwarf_free_op_chain(Dwarf_Debug dbg,Dwarf_Loc_Chain headloc)129 _dwarf_free_op_chain(Dwarf_Debug dbg,
130 Dwarf_Loc_Chain headloc)
131 {
132 Dwarf_Loc_Chain cur = headloc;
133
134 while (cur) {
135 Dwarf_Loc_Chain next = cur->lc_next;
136 dwarf_dealloc(dbg, cur, DW_DLA_LOC_CHAIN);
137 cur = next;
138 }
139 }
140 /* Given a Dwarf_Block that represents a location expression,
141 this function returns a pointer to a Dwarf_Locdesc struct
142 that has its ld_cents field set to the number of location
143 operators in the block, and its ld_s field pointing to a
144 contiguous block of Dwarf_Loc structs. However, the
145 ld_lopc and ld_hipc values are uninitialized. Returns
146 DW_DLV_ERROR on error.
147
148 Created for DWARF2 this really does not work well
149 as later DWARF needs the newer interface.
150 You want Dwarf_Locdesc_c opaque struct, not what this
151 function provides.
152
153 This function assumes that the length of
154 the block is greater than 0. Zero length location expressions
155 to represent variables that have been optimized away are
156 handled in the calling function.
157
158 address_size, offset_size, and version_stamp are
159 per-CU, not per-object or per dbg.
160 We cannot use dbg directly to get those values.
161
162 Use for DWARF 2,3,4 only to avoid updating to
163 later interfaces. Not for experimental
164 dwarf4 dwo either.
165 Better to switch to a newer interface.
166 */
167 static int
_dwarf_get_locdesc(Dwarf_Debug dbg,Dwarf_Block_c * loc_block,Dwarf_Half address_size,Dwarf_Half offset_size,Dwarf_Small version_stamp,Dwarf_Addr lowpc,Dwarf_Addr highpc,Dwarf_Small * section_end,Dwarf_Locdesc ** locdesc_out,Dwarf_Error * error)168 _dwarf_get_locdesc(Dwarf_Debug dbg,
169 Dwarf_Block_c * loc_block,
170 Dwarf_Half address_size,
171 Dwarf_Half offset_size,
172 Dwarf_Small version_stamp,
173 Dwarf_Addr lowpc,
174 Dwarf_Addr highpc,
175 Dwarf_Small * section_end,
176 Dwarf_Locdesc ** locdesc_out,
177 Dwarf_Error * error)
178 {
179 /* Offset of current operator from start of block. */
180 Dwarf_Unsigned offset = 0;
181
182 /* Used to chain the Dwarf_Loc_Chain_s structs. */
183 Dwarf_Loc_Chain new_loc = NULL;
184 Dwarf_Loc_Chain prev_loc = NULL;
185 Dwarf_Loc_Chain head_loc = NULL;
186 /* Count of the number of location operators. */
187 Dwarf_Unsigned op_count = 0;
188
189 /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */
190 Dwarf_Loc *block_loc = 0;
191
192 /* Dwarf_Locdesc pointer to be returned. */
193 Dwarf_Locdesc *locdesc = 0;
194
195 Dwarf_Unsigned i = 0;
196 int res = 0;
197
198 /* ***** BEGIN CODE ***** */
199
200 offset = 0;
201 op_count = 0;
202
203
204 res = _dwarf_loc_block_sanity_check(dbg,loc_block,error);
205 if (res != DW_DLV_OK) {
206 return res;
207 }
208
209 /* OLD loop getting Loc operators. No DWARF5 */
210 while (offset <= loc_block->bl_len) {
211 Dwarf_Unsigned nextoffset = 0;
212 struct Dwarf_Loc_Expr_Op_s temp_loc;
213
214 res = _dwarf_read_loc_expr_op(dbg,loc_block,
215 op_count,
216 version_stamp,
217 offset_size,
218 address_size,
219 offset,
220 section_end,
221 &nextoffset,
222 &temp_loc,
223 error);
224 if (res == DW_DLV_ERROR) {
225 _dwarf_free_op_chain(dbg, head_loc);
226 return res;
227 }
228 if (res == DW_DLV_NO_ENTRY) {
229 /* Normal end. */
230 break;
231 }
232 op_count++;
233 new_loc =
234 (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg,
235 DW_DLA_LOC_CHAIN, 1);
236 if (new_loc == NULL) {
237 dwarfstring m;
238
239 _dwarf_free_op_chain(dbg, head_loc);
240 dwarfstring_constructor(&m);
241 dwarfstring_append_printf_u(&m,
242 " DW_DLE_ALLOC_FAIL: out of memory"
243 " allocating location"
244 " expression operator chain entry %u.",
245 op_count);
246 _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
247 dwarfstring_string(&m));
248 dwarfstring_destructor(&m);
249 return DW_DLV_ERROR;
250 }
251
252 /* Copying only the fields needed by DWARF 2,3,4 */
253 new_loc->lc_atom = temp_loc.lr_atom;
254 new_loc->lc_opnumber= temp_loc.lr_opnumber;
255 new_loc->lc_number = temp_loc.lr_number;
256 new_loc->lc_number2 = temp_loc.lr_number2;
257 new_loc->lc_number3 = temp_loc.lr_number3;
258 new_loc->lc_raw1 = temp_loc.lr_raw1;
259 new_loc->lc_raw2 = temp_loc.lr_raw2;
260 new_loc->lc_raw3 = temp_loc.lr_raw3;
261 new_loc->lc_offset = temp_loc.lr_offset;
262 offset = nextoffset;
263
264 if (head_loc == NULL)
265 head_loc = prev_loc = new_loc;
266 else {
267 prev_loc->lc_next = new_loc;
268 prev_loc = new_loc;
269 }
270 }
271
272 block_loc =
273 (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK,
274 op_count);
275 if (block_loc == NULL) {
276 _dwarf_free_op_chain(dbg, head_loc);
277 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
278 return DW_DLV_ERROR;
279 }
280
281 new_loc = head_loc;
282 for (i = 0; i < op_count; i++) {
283 /* Copying only the fields needed by DWARF 2,3,4
284 the struct is public and must never be changed. */
285 (block_loc + i)->lr_atom = new_loc->lc_atom;
286 (block_loc + i)->lr_number = new_loc->lc_number;
287 (block_loc + i)->lr_number2 = new_loc->lc_number2;
288 (block_loc + i)->lr_offset = new_loc->lc_offset;
289 prev_loc = new_loc;
290 new_loc = prev_loc->lc_next;
291 dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
292 }
293
294 locdesc =
295 (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
296 if (locdesc == NULL) {
297 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
298 return DW_DLV_ERROR;
299 }
300
301 locdesc->ld_cents = op_count;
302 locdesc->ld_s = block_loc;
303 locdesc->ld_section_offset = loc_block->bl_section_offset;
304 locdesc->ld_lopc = lowpc;
305 locdesc->ld_hipc = highpc;
306 locdesc->ld_from_loclist = 1;
307 *locdesc_out = locdesc;
308 return DW_DLV_OK;
309 }
310
311 /* Using a loclist offset to get the in-memory
312 address of .debug_loc data to read, returns the loclist
313 'header' info in return_block.
314 */
315
316 #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
317
318
319 static int
_dwarf_read_loc_section(Dwarf_Debug dbg,Dwarf_Block_c * return_block,Dwarf_Addr * lowpc,Dwarf_Addr * hipc,Dwarf_Half * lle_val,Dwarf_Off sec_offset,Dwarf_Half address_size,UNUSEDARG unsigned lkind,Dwarf_Error * error)320 _dwarf_read_loc_section(Dwarf_Debug dbg,
321 Dwarf_Block_c * return_block,
322 Dwarf_Addr * lowpc,
323 Dwarf_Addr * hipc,
324 Dwarf_Half * lle_val,
325 Dwarf_Off sec_offset,
326 Dwarf_Half address_size,
327 UNUSEDARG unsigned lkind,
328 Dwarf_Error * error)
329 {
330 Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset;
331 Dwarf_Small *loc_section_end =
332 dbg->de_debug_loc.dss_data + dbg->de_debug_loc.dss_size;
333
334 /* start_addr and end_addr are actually offsets
335 of the applicable base address of the CU.
336 They are address-size. */
337 Dwarf_Addr start_addr = 0;
338 Dwarf_Addr end_addr = 0;
339 Dwarf_Half exprblock_size = 0;
340 Dwarf_Unsigned exprblock_off =
341 2 * address_size + DWARF_HALF_SIZE;
342
343 if (sec_offset >= dbg->de_debug_loc.dss_size) {
344 /* We're at the end. No more present. */
345 return DW_DLV_NO_ENTRY;
346 }
347
348 /* If it goes past end, error */
349 if (exprblock_off > dbg->de_debug_loc.dss_size) {
350 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
351 return DW_DLV_ERROR;
352 }
353
354
355 READ_UNALIGNED_CK(dbg, start_addr, Dwarf_Addr, beg, address_size,
356 error,loc_section_end);
357 READ_UNALIGNED_CK(dbg, end_addr, Dwarf_Addr,
358 beg + address_size, address_size,
359 error,loc_section_end);
360 if (start_addr == 0 && end_addr == 0) {
361 /* If start_addr and end_addr are 0, it's the end and no
362 exprblock_size field follows. */
363 exprblock_size = 0;
364 exprblock_off -= DWARF_HALF_SIZE;
365 *lle_val = DW_LLE_end_of_list;
366 } else if (start_addr == MAX_ADDR) {
367 /* End address is a base address, no exprblock_size field here
368 either */
369 exprblock_size = 0;
370 exprblock_off -= DWARF_HALF_SIZE;
371 *lle_val = DW_LLE_base_address;
372 } else {
373 /* Here we note the address and length of the
374 expression operators, DW_OP_reg0 etc */
375 READ_UNALIGNED_CK(dbg, exprblock_size, Dwarf_Half,
376 beg + 2 * address_size, DWARF_HALF_SIZE,
377 error,loc_section_end);
378 /* exprblock_size can be zero, means no expression */
379 if ( exprblock_size >= dbg->de_debug_loc.dss_size) {
380 _dwarf_error(dbg, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
381 return DW_DLV_ERROR;
382 }
383 if ((sec_offset +exprblock_off + exprblock_size) >
384 dbg->de_debug_loc.dss_size) {
385 _dwarf_error(dbg, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
386 return DW_DLV_ERROR;
387 }
388 *lle_val = DW_LLE_start_end;
389 }
390 *lowpc = start_addr;
391 *hipc = end_addr;
392
393 return_block->bl_len = exprblock_size;
394 return_block->bl_kind = DW_LKIND_loclist;
395 return_block->bl_data = beg + exprblock_off;
396 return_block->bl_section_offset =
397 ((Dwarf_Small *) return_block->bl_data) -
398 dbg->de_debug_loc.dss_data;
399 return DW_DLV_OK;
400 }
401
402 static int
_dwarf_get_loclist_lle_count_dwo(Dwarf_Debug dbg,Dwarf_Off loclist_offset,Dwarf_Half address_size,unsigned lkind,int * loclist_count,Dwarf_Error * error)403 _dwarf_get_loclist_lle_count_dwo(Dwarf_Debug dbg,
404 Dwarf_Off loclist_offset,
405 Dwarf_Half address_size,
406 unsigned lkind,
407 int *loclist_count,
408 Dwarf_Error * error)
409 {
410 int count = 0;
411 Dwarf_Off offset = loclist_offset;
412
413 for (;;) {
414 Dwarf_Block_c b;
415 Dwarf_Bool at_end = FALSE;
416 Dwarf_Addr lowpc = 0;
417 Dwarf_Addr highpc = 0;
418 Dwarf_Half lle_op = 0;
419 int res = _dwarf_read_loc_section_dwo(dbg, &b,
420 &lowpc,
421 &highpc,
422 &at_end,
423 &lle_op,
424 offset,
425 address_size,
426 lkind,
427 error);
428 if (res != DW_DLV_OK) {
429 return res;
430 }
431 if (at_end) {
432 count++;
433 break;
434 }
435 offset = b.bl_len + b.bl_section_offset;
436 count++;
437 }
438 *loclist_count = count;
439 return DW_DLV_OK;
440 }
441
442 static int
_dwarf_get_loclist_lle_count(Dwarf_Debug dbg,Dwarf_Off loclist_offset,Dwarf_Half address_size,unsigned lkind,int * loclist_count,Dwarf_Error * error)443 _dwarf_get_loclist_lle_count(Dwarf_Debug dbg,
444 Dwarf_Off loclist_offset,
445 Dwarf_Half address_size,
446 unsigned lkind,
447 int *loclist_count,
448 Dwarf_Error * error)
449 {
450 int count = 0;
451 Dwarf_Off offset = loclist_offset;
452
453
454 for (;;) {
455 Dwarf_Block_c b;
456 Dwarf_Addr lowpc = 0;
457 Dwarf_Addr highpc = 0;
458 Dwarf_Half lle_val = 0;
459
460 int res = _dwarf_read_loc_section(dbg, &b,
461 &lowpc, &highpc,
462 &lle_val,
463 offset, address_size,lkind,error);
464 if (res != DW_DLV_OK) {
465 return res;
466 }
467 offset = b.bl_len + b.bl_section_offset;
468 if (lowpc == 0 && highpc == 0) {
469 break;
470 }
471 count++;
472 }
473 *loclist_count = count;
474 return DW_DLV_OK;
475 }
476
477 /* Helper routine to avoid code duplication.
478 */
479 static int
_dwarf_setup_loc(Dwarf_Attribute attr,Dwarf_Debug * dbg_ret,Dwarf_CU_Context * cucontext_ret,Dwarf_Half * form_ret,Dwarf_Error * error)480 _dwarf_setup_loc(Dwarf_Attribute attr,
481 Dwarf_Debug * dbg_ret,
482 Dwarf_CU_Context *cucontext_ret,
483 Dwarf_Half *form_ret,
484 Dwarf_Error *error)
485 {
486 Dwarf_Debug dbg = 0;
487 Dwarf_Half form = 0;
488 int blkres = DW_DLV_ERROR;
489
490 if (!attr) {
491 _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
492 return (DW_DLV_ERROR);
493 }
494 if (attr->ar_cu_context == NULL) {
495 _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
496 return (DW_DLV_ERROR);
497 }
498 *cucontext_ret = attr->ar_cu_context;
499
500 dbg = attr->ar_cu_context->cc_dbg;
501 if (dbg == NULL) {
502 _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
503 return (DW_DLV_ERROR);
504 }
505 *dbg_ret = dbg;
506 blkres = dwarf_whatform(attr, &form, error);
507 if (blkres != DW_DLV_OK) {
508 _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
509 return blkres;
510 }
511 *form_ret = form;
512 return DW_DLV_OK;
513 }
514
515 /* Helper routine to avoid code duplication.
516 */
517 static int
_dwarf_get_loclist_header_start(Dwarf_Debug dbg,Dwarf_Attribute attr,Dwarf_Unsigned * loclist_offset_out,Dwarf_Error * error)518 _dwarf_get_loclist_header_start(Dwarf_Debug dbg,
519 Dwarf_Attribute attr,
520 Dwarf_Unsigned * loclist_offset_out,
521 Dwarf_Error * error)
522 {
523 Dwarf_Unsigned loc_sec_size = 0;
524 Dwarf_Unsigned loclist_offset = 0;
525
526 int blkres = dwarf_global_formref(attr, &loclist_offset, error);
527 if (blkres != DW_DLV_OK) {
528 return blkres;
529 }
530 if (!dbg->de_debug_loc.dss_data) {
531 int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
532 if (secload != DW_DLV_OK) {
533 return secload;
534 }
535 if (!dbg->de_debug_loc.dss_size) {
536 return (DW_DLV_NO_ENTRY);
537 }
538 }
539 loc_sec_size = dbg->de_debug_loc.dss_size;
540 if (loclist_offset >= loc_sec_size) {
541 _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD);
542 return DW_DLV_ERROR;
543 }
544
545 {
546 int fisres = 0;
547 Dwarf_Unsigned fissoff = 0;
548 Dwarf_Unsigned size = 0;
549 fisres = _dwarf_get_fission_addition_die(attr->ar_die,
550 DW_SECT_LOCLISTS,
551 &fissoff, &size,error);
552 if(fisres != DW_DLV_OK) {
553 return fisres;
554 }
555 if (fissoff >= loc_sec_size) {
556 _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD);
557 return DW_DLV_ERROR;
558 }
559 loclist_offset += fissoff;
560 if (loclist_offset >= loc_sec_size) {
561 _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD);
562 return DW_DLV_ERROR;
563 }
564 }
565 *loclist_offset_out = loclist_offset;
566 return DW_DLV_OK;
567 }
568
569 /* When llbuf (see dwarf_loclist_n) is partially set up
570 and an error is encountered, tear it down as it
571 won't be used.
572 */
573 static void
_dwarf_cleanup_llbuf(Dwarf_Debug dbg,Dwarf_Locdesc ** llbuf,int count)574 _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count)
575 {
576 int i;
577 for (i = 0; i < count; ++i) {
578 dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
579 dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
580 }
581 dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
582 }
583
584 static int
context_is_cu_not_tu(Dwarf_CU_Context context,Dwarf_Bool * r)585 context_is_cu_not_tu(Dwarf_CU_Context context,
586 Dwarf_Bool *r)
587 {
588 int ut = context->cc_unit_type;
589
590 if (ut == DW_UT_type || ut == DW_UT_split_type ) {
591 *r =FALSE;
592 return DW_DLV_OK;
593 }
594 *r = TRUE;
595 return DW_DLV_OK;
596 }
597
598 /* Handles simple location entries and loclists.
599 Returns all the Locdesc's thru llbuf.
600
601 Will not work properly for DWARF5 and may not
602 work for some recent versions of gcc or llvm emitting
603 DWARF4 with location extensions.
604
605 Does not work for .debug_loc.dwo
606 */
607 int
dwarf_loclist_n(Dwarf_Attribute attr,Dwarf_Locdesc *** llbuf_out,Dwarf_Signed * listlen_out,Dwarf_Error * error)608 dwarf_loclist_n(Dwarf_Attribute attr,
609 Dwarf_Locdesc *** llbuf_out,
610 Dwarf_Signed * listlen_out, Dwarf_Error * error)
611 {
612 Dwarf_Debug dbg = 0;
613
614 /* Dwarf_Attribute that describes the DW_AT_location in die, if
615 present. */
616 Dwarf_Attribute loc_attr = attr;
617
618 /* Dwarf_Block that describes a single location expression. */
619 Dwarf_Block_c loc_block;
620
621 /* A pointer to the current Dwarf_Locdesc read. */
622 Dwarf_Locdesc *locdesc = 0;
623
624 Dwarf_Half form = 0;
625 Dwarf_Addr lowpc = 0;
626 Dwarf_Addr highpc = 0;
627 Dwarf_Signed listlen = 0;
628 Dwarf_Locdesc **llbuf = 0;
629 Dwarf_CU_Context cucontext = 0;
630 unsigned address_size = 0;
631 int cuvstamp = 0;
632 Dwarf_Bool is_cu = FALSE;
633 Dwarf_Half attrnum = 0;
634 int is_dwo = FALSE;
635 unsigned lkind = 0;
636
637 int blkres = DW_DLV_ERROR;
638 int setup_res = DW_DLV_ERROR;
639 Dwarf_Small * info_section_end = 0;
640
641 /* ***** BEGIN CODE ***** */
642 setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
643 if (setup_res != DW_DLV_OK) {
644 return setup_res;
645 }
646 info_section_end = _dwarf_calculate_info_section_end_ptr(cucontext);
647 cuvstamp = cucontext->cc_version_stamp;
648 address_size = cucontext->cc_address_size;
649 /* If this is a form_block then it's a location expression. If it's
650 DW_FORM_data4 or DW_FORM_data8 in DWARF2 or DWARF3
651 (or in DWARF4 or 5 a DW_FORM_sec_offset) it's a loclist offset */
652 if (cuvstamp == DW_CU_VERSION5) {
653 /* Use a newer interface. */
654 _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR);
655 return (DW_DLV_ERROR);
656 }
657 attrnum = attr->ar_attribute;
658 lkind = determine_location_lkind(cuvstamp,form, attrnum, is_dwo);
659 if (lkind == DW_LKIND_unknown ||
660 lkind == DW_LKIND_GNU_exp_list ||
661 lkind == DW_LKIND_loclists ) {
662 /* We cannot handle this here. */
663 _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR);
664 return (DW_DLV_ERROR);
665 }
666
667 if (lkind == DW_LKIND_loclist ) {
668 /* A reference to .debug_loc, with an offset in .debug_loc of a
669 loclist */
670 Dwarf_Small *loc_section_end = 0;
671 Dwarf_Unsigned loclist_offset = 0;
672 int off_res = DW_DLV_ERROR;
673 int count_res = DW_DLV_ERROR;
674 int loclist_count = 0;
675 int lli = 0;
676
677 setup_res = context_is_cu_not_tu(cucontext,&is_cu);
678 if(setup_res != DW_DLV_OK) {
679 return setup_res;
680 }
681
682 off_res = _dwarf_get_loclist_header_start(dbg,
683 attr, &loclist_offset, error);
684 if (off_res != DW_DLV_OK) {
685 return off_res;
686 }
687 count_res = _dwarf_get_loclist_lle_count(dbg, loclist_offset,
688 address_size,lkind, &loclist_count, error);
689 listlen = loclist_count;
690 if (count_res != DW_DLV_OK) {
691 return count_res;
692 }
693 if (loclist_count == 0) {
694 return DW_DLV_NO_ENTRY;
695 }
696
697 llbuf = (Dwarf_Locdesc **)
698 _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
699 if (!llbuf) {
700 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
701 return (DW_DLV_ERROR);
702 }
703
704 for (lli = 0; lli < loclist_count; ++lli) {
705 int lres = 0;
706 Dwarf_Half ll_op = 0;
707
708 blkres = _dwarf_read_loc_section(dbg,
709 &loc_block,
710 &lowpc,
711 &highpc,
712 &ll_op,
713 loclist_offset,
714 address_size,lkind,
715 error);
716 if (blkres != DW_DLV_OK) {
717 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
718 return (blkres);
719 }
720 loc_section_end = dbg->de_debug_loc.dss_data+
721 dbg->de_debug_loc.dss_size;
722 lres = _dwarf_get_locdesc(dbg,
723 &loc_block,
724 address_size,
725 cucontext->cc_length_size,
726 cucontext->cc_version_stamp,
727 lowpc, highpc,
728 loc_section_end,
729 &locdesc,
730 error);
731 if (lres != DW_DLV_OK) {
732 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
733 /* low level error already set: let it be passed back */
734 return lres;
735 }
736 llbuf[lli] = locdesc;
737
738 /* Now get to next loclist entry offset. */
739 loclist_offset = loc_block.bl_section_offset +
740 loc_block.bl_len;
741 }
742 } else { /* DW_LKIND_expression */
743 if( form == DW_FORM_exprloc) {
744 blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len,
745 &loc_block.bl_data,error);
746 if(blkres != DW_DLV_OK) {
747 return blkres;
748 }
749 loc_block.bl_kind = lkind;
750 loc_block.bl_section_offset =
751 (char *)loc_block.bl_data -
752 (char *)dbg->de_debug_info.dss_data;
753 } else {
754 Dwarf_Block *tblock = 0;
755 blkres = dwarf_formblock(loc_attr, &tblock, error);
756 if (blkres != DW_DLV_OK) {
757 return (blkres);
758 }
759 loc_block.bl_len = tblock->bl_len;
760 loc_block.bl_data = tblock->bl_data;
761 loc_block.bl_kind = lkind;
762 loc_block.bl_section_offset = tblock->bl_section_offset;
763 loc_block.bl_locdesc_offset = 0; /* not relevent */
764 /* We copied tblock contents to the stack var,
765 so can dealloc
766 tblock now. Avoids leaks. */
767 dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
768 }
769 listlen = 1; /* One by definition of a location entry. */
770 lowpc = 0; /* HACK, but with bl_kind we do not need */
771 highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
772
773 /* An empty location description (block length 0) means the
774 code generator emitted no variable, the variable was not
775 generated, it was unused or perhaps never tested
776 after being set.
777 Dwarf2, section 2.4.1 In other words, it is not an
778 error, and we don't test for block length 0
779 specially here. */
780 blkres = _dwarf_get_locdesc(dbg, &loc_block,
781 address_size,
782 cucontext->cc_length_size,
783 cucontext->cc_version_stamp,
784 lowpc, highpc,
785 info_section_end,
786 &locdesc,
787 error);
788 if (blkres != DW_DLV_OK) {
789 /* low level error already set: let it be passed back */
790 return blkres;
791 }
792 llbuf = (Dwarf_Locdesc **)
793 _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
794 if (!llbuf) {
795 /* Free the locdesc we allocated but won't use. */
796 dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
797 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
798 return (DW_DLV_ERROR);
799 }
800 llbuf[0] = locdesc;
801 }
802
803 *llbuf_out = llbuf;
804 *listlen_out = listlen;
805 return (DW_DLV_OK);
806 }
807
808 /* Handles only a location expression.
809 If called on a loclist, just returns one of those.
810 Cannot not handle a real loclist.
811 It returns the location expression as a loclist with
812 a single entry.
813 See dwarf_loclist_n() which handles any number
814 of location list entries.
815
816 This is the original definition, and it simply
817 does not work for loclists.
818 Nor does it work on DWARF4 nor on some
819 versions of gcc generating DWARF4.
820 Kept for compatibility.
821 */
822 int
dwarf_loclist(Dwarf_Attribute attr,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)823 dwarf_loclist(Dwarf_Attribute attr,
824 Dwarf_Locdesc ** llbuf,
825 Dwarf_Signed * listlen, Dwarf_Error * error)
826 {
827 Dwarf_Debug dbg = 0;
828
829 /* Dwarf_Attribute that describes the DW_AT_location in die, if
830 present. */
831 Dwarf_Attribute loc_attr = attr;
832
833 /* Dwarf_Block that describes a single location expression. */
834 Dwarf_Block_c loc_block;
835
836 /* A pointer to the current Dwarf_Locdesc read. */
837 Dwarf_Locdesc *locdesc = 0;
838 int is_dwo = FALSE;
839 Dwarf_Small *info_section_end = 0;
840 Dwarf_Half form = 0;
841 Dwarf_Addr lowpc = 0;
842 Dwarf_Addr highpc = 0;
843 Dwarf_CU_Context cucontext = 0;
844 unsigned address_size = 0;
845 unsigned lkind = 0;
846 int blkres = DW_DLV_ERROR;
847 int setup_res = DW_DLV_ERROR;
848 int cuvstamp = 0;
849 unsigned attrnum = 0;
850
851 /* ***** BEGIN CODE ***** */
852 setup_res = _dwarf_setup_loc(attr, &dbg, &cucontext, &form, error);
853 if (setup_res != DW_DLV_OK) {
854 return setup_res;
855 }
856 info_section_end = _dwarf_calculate_info_section_end_ptr(cucontext);
857 memset(&loc_block,0,sizeof(loc_block));
858 cuvstamp = cucontext->cc_version_stamp;
859 address_size = cucontext->cc_address_size;
860 attrnum = attr->ar_attribute;
861 lkind = determine_location_lkind(cuvstamp,form, attrnum, is_dwo);
862 if (lkind == DW_LKIND_unknown ||
863 lkind == DW_LKIND_GNU_exp_list ||
864 lkind == DW_LKIND_loclists ) {
865 /* We cannot handle this here. */
866 _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR);
867 return (DW_DLV_ERROR);
868 }
869
870 /* If this is a form_block then it's a location expression. If it's
871 DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
872 if (lkind == DW_LKIND_loclist) {
873 /* A reference to .debug_loc, with an offset in .debug_loc of a
874 loclist. */
875 Dwarf_Unsigned loclist_offset = 0;
876 int off_res = DW_DLV_ERROR;
877 Dwarf_Half ll_op = 0;
878
879 off_res = _dwarf_get_loclist_header_start(dbg,
880 attr, &loclist_offset,
881 error);
882 if (off_res != DW_DLV_OK) {
883 return off_res;
884 }
885
886 /* With dwarf_loclist, just read a single entry */
887 blkres = _dwarf_read_loc_section(dbg, &loc_block,
888 &lowpc,
889 &highpc,
890 &ll_op,
891 loclist_offset,
892 address_size,
893 lkind,
894 error);
895 if (blkres != DW_DLV_OK) {
896 return (blkres);
897 }
898 } else { /* DW_LKIND_expression */
899 if( form == DW_FORM_exprloc) {
900 blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len,
901 &loc_block.bl_data,error);
902 if(blkres != DW_DLV_OK) {
903 return blkres;
904 }
905 loc_block.bl_kind = lkind;
906 loc_block.bl_section_offset =
907 (char *)loc_block.bl_data -
908 (char *)dbg->de_debug_info.dss_data;
909 } else {
910 Dwarf_Block *tblock = 0;
911
912 /* If DWARF5 this will surely fail, get an error. */
913 blkres = dwarf_formblock(loc_attr, &tblock, error);
914 if (blkres != DW_DLV_OK) {
915 return (blkres);
916 }
917 loc_block.bl_len = tblock->bl_len;
918 loc_block.bl_data = tblock->bl_data;
919 loc_block.bl_kind = tblock->bl_from_loclist;
920 /* ASSERT: lkind == loc_block.bl_kind */
921 loc_block.bl_section_offset = tblock->bl_section_offset;
922 /* We copied tblock contents to the stack
923 var, so can dealloc tblock now.
924 Avoids leaks. */
925 dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
926 }
927 /* Because we set bl_kind we don't really
928 need this hack any more */
929 lowpc = 0; /* HACK */
930 highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
931 }
932
933 /* An empty location description (block length 0) means
934 the code
935 generator emitted no variable, the variable was not
936 generated, it was unused or perhaps never tested after
937 being set. Dwarf2, section 2.4.1 In other words,
938 it is not an error, and we don't test for block
939 length 0 specially here. See *dwarf_loclist_n()
940 which handles the general case, this case handles
941 only a single location expression. */
942 blkres = _dwarf_get_locdesc(dbg, &loc_block,
943 address_size, cucontext->cc_length_size,
944 cucontext->cc_version_stamp, lowpc, highpc,
945 info_section_end, &locdesc, error);
946 if (blkres != DW_DLV_OK) {
947 /* low level error already set: let it be passed back
948 */ return blkres;
949 }
950
951 *llbuf = locdesc;
952 *listlen = 1;
953 return (DW_DLV_OK);
954 }
955
956
957
958 /* Handles only a location expression.
959 It returns the location expression as a loclist with
960 a single entry.
961
962 Usable to access dwarf expressions from any source, but
963 specifically from
964 DW_CFA_def_cfa_expression
965 DW_CFA_expression
966 DW_CFA_val_expression
967
968 expression_in must point to a valid dwarf expression
969 set of bytes of length expression_length. Not
970 a DW_FORM_block*, just the expression bytes.
971
972 If the address_size != de_pointer_size this will not work
973 right.
974 See dwarf_loclist_from_expr_b() for a better interface.
975 */
976 int
dwarf_loclist_from_expr(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)977 dwarf_loclist_from_expr(Dwarf_Debug dbg,
978 Dwarf_Ptr expression_in,
979 Dwarf_Unsigned expression_length,
980 Dwarf_Locdesc ** llbuf,
981 Dwarf_Signed * listlen, Dwarf_Error * error)
982 {
983 int res = 0;
984 Dwarf_Half addr_size = dbg->de_pointer_size;
985 res = dwarf_loclist_from_expr_a(dbg,expression_in,
986 expression_length, addr_size,llbuf,listlen,error);
987 return res;
988 }
989
990 /* New April 27 2009. Adding addr_size argument for the rare
991 cases where an object has CUs with a different address_size.
992
993 As of 2012 we have yet another version, dwarf_loclist_from_expr_b()
994 with the version_stamp and offset size (length size) passed in.
995 */
996 int
dwarf_loclist_from_expr_a(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Half addr_size,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)997 dwarf_loclist_from_expr_a(Dwarf_Debug dbg,
998 Dwarf_Ptr expression_in,
999 Dwarf_Unsigned expression_length,
1000 Dwarf_Half addr_size,
1001 Dwarf_Locdesc ** llbuf,
1002 Dwarf_Signed * listlen,
1003 Dwarf_Error * error)
1004 {
1005 int res;
1006 Dwarf_Debug_InfoTypes info_reading = &dbg->de_info_reading;
1007 Dwarf_CU_Context current_cu_context =
1008 info_reading->de_cu_context;
1009 Dwarf_Small version_stamp = DW_CU_VERSION2;
1010 Dwarf_Half offset_size = dbg->de_length_size;
1011
1012 if (current_cu_context) {
1013 /* This is ugly. It is not necessarily right. Due to
1014 oddity in DW_OP_GNU_implicit_pointer, see its
1015 implementation above.
1016 For correctness, use dwarf_loclist_from_expr_b()
1017 instead of dwarf_loclist_from_expr_a(). */
1018 version_stamp = current_cu_context->cc_version_stamp;
1019 offset_size = current_cu_context->cc_length_size;
1020 if (version_stamp < 2) {
1021 /* This is probably totally silly. */
1022 version_stamp = DW_CU_VERSION2;
1023 }
1024 }
1025 res = dwarf_loclist_from_expr_b(dbg,
1026 expression_in,
1027 expression_length,
1028 addr_size,
1029 offset_size,
1030 version_stamp, /* CU context DWARF version */
1031 llbuf,
1032 listlen,
1033 error);
1034 return res;
1035 }
1036 /* New November 13 2012. Adding
1037 DWARF version number argument.
1038 */
1039 int
dwarf_loclist_from_expr_b(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Half addr_size,Dwarf_Half offset_size,Dwarf_Small dwarf_version,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)1040 dwarf_loclist_from_expr_b(Dwarf_Debug dbg,
1041 Dwarf_Ptr expression_in,
1042 Dwarf_Unsigned expression_length,
1043 Dwarf_Half addr_size,
1044 Dwarf_Half offset_size,
1045 Dwarf_Small dwarf_version,
1046 Dwarf_Locdesc ** llbuf,
1047 Dwarf_Signed * listlen,
1048 Dwarf_Error * error)
1049 {
1050 /* Dwarf_Block that describes a single location expression. */
1051 Dwarf_Block_c loc_block;
1052
1053 /* A pointer to the current Dwarf_Locdesc read. */
1054 Dwarf_Locdesc *locdesc = 0;
1055 Dwarf_Addr lowpc = 0;
1056 Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL);
1057 Dwarf_Small version_stamp = dwarf_version;
1058 int res = 0;
1059 /* We do not know what the end is in this interface. */
1060 Dwarf_Small *section_start = 0;
1061 Dwarf_Unsigned section_size = 0;
1062 Dwarf_Small *section_end = 0;
1063 const char *section_name = 0;
1064
1065 res = _dwarf_what_section_are_we(dbg,
1066 expression_in,§ion_name,§ion_start,
1067 §ion_size,§ion_end,error);
1068 if (res != DW_DLV_OK) {
1069 _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN);
1070 return DW_DLV_ERROR;
1071 }
1072
1073 memset(&loc_block,0,sizeof(loc_block));
1074 loc_block.bl_len = expression_length;
1075 loc_block.bl_data = expression_in;
1076 loc_block.bl_kind = DW_LKIND_expression;
1077 loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
1078
1079 /* An empty location description (block length 0) means the code
1080 generator emitted no variable, the variable was not generated,
1081 it was unused or perhaps never tested after being set. Dwarf2,
1082 section 2.4.1 In other words, it is not an error, and we don't
1083 test for block length 0 specially here. */
1084 /* We need the DWARF version to get a locdesc! */
1085 res = _dwarf_get_locdesc(dbg, &loc_block,
1086 addr_size,
1087 offset_size,
1088 version_stamp,
1089 lowpc, highpc,
1090 section_end,
1091 &locdesc,
1092 error);
1093 if (res != DW_DLV_OK) {
1094 /* low level error already set: let it be passed back */
1095 return res;
1096 }
1097
1098 *llbuf = locdesc;
1099 *listlen = 1;
1100 return DW_DLV_OK;
1101 }
1102
1103 /* Usable to read a single loclist or to read a block of them
1104 or to read an entire section's loclists.
1105
1106 It's BROKEN because it's not safe to read a loclist entry
1107 when we do not know the address size (in any object where
1108 address size can vary by compilation unit).
1109
1110 It also does not recognize split dwarf or DWARF4
1111 or DWARF5 adequately.
1112
1113 Use get_locdesc_entry_c() instead.
1114 */
1115 /*ARGSUSED*/ int
dwarf_get_loclist_entry(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Addr * hipc_offset,Dwarf_Addr * lopc_offset,Dwarf_Ptr * data,Dwarf_Unsigned * entry_len,Dwarf_Unsigned * next_entry,Dwarf_Error * error)1116 dwarf_get_loclist_entry(Dwarf_Debug dbg,
1117 Dwarf_Unsigned offset,
1118 Dwarf_Addr * hipc_offset,
1119 Dwarf_Addr * lopc_offset,
1120 Dwarf_Ptr * data,
1121 Dwarf_Unsigned * entry_len,
1122 Dwarf_Unsigned * next_entry,
1123 Dwarf_Error * error)
1124 {
1125 Dwarf_Block_c b;
1126 Dwarf_Addr lowpc = 0;
1127 Dwarf_Addr highpc = 0;
1128 Dwarf_Half address_size = 0;
1129 int res = DW_DLV_ERROR;
1130 Dwarf_Half ll_op = 0;
1131
1132 if (!dbg->de_debug_loc.dss_data) {
1133 int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
1134 if (secload != DW_DLV_OK) {
1135 return secload;
1136 }
1137 }
1138
1139 /* FIXME: DO NOT USE the call. address_size is not necessarily
1140 the same in every frame. */
1141 address_size = dbg->de_pointer_size;
1142 res = _dwarf_read_loc_section(dbg,
1143 &b, &lowpc, &highpc,
1144 &ll_op,offset,
1145 address_size,DW_LKIND_loclist,error);
1146 if (res != DW_DLV_OK) {
1147 return res;
1148 }
1149 *hipc_offset = highpc;
1150 *lopc_offset = lowpc;
1151 *entry_len = b.bl_len;
1152 *data = b.bl_data;
1153 *next_entry = b.bl_len + b.bl_section_offset;
1154 return DW_DLV_OK;
1155 }
1156
1157 /* ============== the October 2015 interfaces. */
1158 int
_dwarf_loc_block_sanity_check(Dwarf_Debug dbg,Dwarf_Block_c * loc_block,Dwarf_Error * error)1159 _dwarf_loc_block_sanity_check(Dwarf_Debug dbg,
1160 Dwarf_Block_c *loc_block,Dwarf_Error* error)
1161 {
1162 unsigned lkind = loc_block->bl_kind;
1163 if (lkind == DW_LKIND_loclist) {
1164 Dwarf_Small *loc_ptr = 0;
1165 Dwarf_Unsigned loc_len = 0;
1166 Dwarf_Small *end_ptr = 0;
1167
1168 loc_ptr = loc_block->bl_data;
1169 loc_len = loc_block->bl_len;
1170 end_ptr = dbg->de_debug_loc.dss_size +
1171 dbg->de_debug_loc.dss_data;
1172 if ((loc_ptr +loc_len) > end_ptr) {
1173 dwarfstring m;
1174
1175 dwarfstring_constructor(&m);
1176 dwarfstring_append(&m,
1177 "DW_DLE_DEBUG_LOC_SECTION_SHORT kind: ");
1178 _dwarf_lkind_name(lkind, &m);
1179 _dwarf_error_string(dbg,error,
1180 DW_DLE_DEBUG_LOC_SECTION_SHORT,
1181 dwarfstring_string(&m));
1182 dwarfstring_destructor(&m);
1183 return DW_DLV_ERROR;
1184 }
1185 return DW_DLV_OK;
1186 }
1187 if (lkind == DW_LKIND_loclists) {
1188 Dwarf_Small *loc_ptr = 0;
1189 Dwarf_Unsigned loc_len = 0;
1190 Dwarf_Small *end_ptr = 0;
1191
1192 loc_ptr = loc_block->bl_data;
1193 loc_len = loc_block->bl_len;
1194 end_ptr = dbg->de_debug_loclists.dss_size +
1195 dbg->de_debug_loclists.dss_data;
1196 if ((loc_ptr +loc_len) > end_ptr) {
1197 dwarfstring m;
1198
1199 dwarfstring_constructor(&m);
1200 dwarfstring_append(&m,
1201 "DW_DLE_DEBUG_LOC_SECTION_SHORT "
1202 "(the .debug_loclists section is short), kind: ");
1203 _dwarf_lkind_name(lkind, &m);
1204 _dwarf_error_string(dbg,error,
1205 DW_DLE_DEBUG_LOC_SECTION_SHORT,
1206 dwarfstring_string(&m));
1207 dwarfstring_destructor(&m);
1208 return DW_DLV_ERROR;
1209 }
1210 }
1211 return DW_DLV_OK;
1212 }
1213
1214 /* Sets locdesc operator list information in locdesc.
1215 Sets the locdesc values (rawlow, rawhigh etc).
1216 This synthesizes the ld_lle_value of the locdesc
1217 if it's not already provided.
1218 Not passing in locdesc pointer, the locdesc_index suffices
1219 to index to the relevant locdesc pointer.
1220 See also dwarf_loclists.c: build_array_of_lle*/
1221 int
_dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg,Dwarf_Unsigned locdesc_index,Dwarf_Loc_Head_c loc_head,Dwarf_Block_c * loc_block,Dwarf_Half address_size,Dwarf_Half offset_size,Dwarf_Small version_stamp,Dwarf_Addr lowpc,Dwarf_Addr highpc,Dwarf_Half lle_op,Dwarf_Error * error)1222 _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg,
1223 Dwarf_Unsigned locdesc_index,
1224 Dwarf_Loc_Head_c loc_head,
1225 Dwarf_Block_c * loc_block,
1226 Dwarf_Half address_size,
1227 Dwarf_Half offset_size,
1228 Dwarf_Small version_stamp,
1229 Dwarf_Addr lowpc,
1230 Dwarf_Addr highpc,
1231 Dwarf_Half lle_op,
1232 Dwarf_Error * error)
1233 {
1234 /* Offset of current operator from start of block. */
1235 Dwarf_Unsigned offset = 0;
1236
1237 /* Chain the DW_OPerator structs. */
1238 Dwarf_Loc_Chain new_loc = NULL;
1239 Dwarf_Loc_Chain prev_loc = NULL;
1240 Dwarf_Loc_Chain head_loc = NULL;
1241
1242 Dwarf_Unsigned op_count = 0;
1243
1244 /* Contiguous block of Dwarf_Loc_Expr_Op_s
1245 for Dwarf_Locdesc. */
1246 Dwarf_Loc_Expr_Op block_loc = 0;
1247
1248 Dwarf_Locdesc_c locdesc = loc_head->ll_locdesc + locdesc_index;
1249 Dwarf_Unsigned i = 0;
1250 int res = 0;
1251 Dwarf_Small *section_start = 0;
1252 Dwarf_Unsigned section_size = 0;
1253 Dwarf_Small *section_end = 0;
1254 const char *section_name = 0;
1255 Dwarf_Small *blockdataptr = 0;
1256 unsigned lkind = loc_head->ll_kind;
1257
1258 /* ***** BEGIN CODE ***** */
1259 blockdataptr = loc_block->bl_data;
1260 if (!blockdataptr || !loc_block->bl_len) {
1261 /* an empty block has no operations so
1262 no section or tests need be done.. */
1263 } else {
1264 res = _dwarf_what_section_are_we(dbg,
1265 blockdataptr,§ion_name,§ion_start,
1266 §ion_size,§ion_end,error);
1267 if (res != DW_DLV_OK) {
1268 _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN);
1269 return DW_DLV_ERROR;
1270 }
1271 res = _dwarf_loc_block_sanity_check(dbg,loc_block,error);
1272 if (res != DW_DLV_OK) {
1273 return res;
1274 }
1275 }
1276 /* New loop getting Loc operators. Non DWO */
1277 while (offset <= loc_block->bl_len) {
1278 Dwarf_Unsigned nextoffset = 0;
1279 struct Dwarf_Loc_Expr_Op_s temp_loc;
1280
1281 /* This call is ok even if bl_data NULL and bl_len 0 */
1282 res = _dwarf_read_loc_expr_op(dbg,loc_block,
1283 op_count,
1284 version_stamp,
1285 offset_size,
1286 address_size,
1287 offset,
1288 section_end,
1289 &nextoffset,
1290 &temp_loc,
1291 error);
1292 if (res == DW_DLV_ERROR) {
1293 return res;
1294 }
1295 if (res == DW_DLV_NO_ENTRY) {
1296 /* Normal end.
1297 Also the end for an empty loc_block. */
1298 break;
1299 }
1300 op_count++;
1301 new_loc =
1302 (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN, 1);
1303 if (new_loc == NULL) {
1304 _dwarf_free_op_chain(dbg,head_loc);
1305 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1306 return DW_DLV_ERROR;
1307 }
1308
1309 /* Copying all the fields. DWARF 2,3,4,5. */
1310 new_loc->lc_atom = temp_loc.lr_atom;
1311 new_loc->lc_opnumber= temp_loc.lr_opnumber;
1312 new_loc->lc_raw1 = temp_loc.lr_number;
1313 new_loc->lc_raw2 = temp_loc.lr_number2;
1314 new_loc->lc_raw3 = temp_loc.lr_number3;
1315 new_loc->lc_number = temp_loc.lr_number;
1316 new_loc->lc_number2 = temp_loc.lr_number2;
1317 new_loc->lc_number3 = temp_loc.lr_number3;
1318 new_loc->lc_offset = temp_loc.lr_offset;
1319 if (head_loc == NULL)
1320 head_loc = prev_loc = new_loc;
1321 else {
1322 prev_loc->lc_next = new_loc;
1323 prev_loc = new_loc;
1324 }
1325 offset = nextoffset;
1326 }
1327 block_loc =
1328 (Dwarf_Loc_Expr_Op ) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK_C,
1329 op_count);
1330 new_loc = head_loc;
1331 if (block_loc == NULL) {
1332 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1333 for (i = 0; i < op_count; i++) {
1334 prev_loc = new_loc;
1335 new_loc = prev_loc->lc_next;
1336 dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
1337 }
1338 return DW_DLV_ERROR;
1339 }
1340
1341 /* op_count could be zero. */
1342 new_loc = head_loc;
1343 for (i = 0; i < op_count; i++) {
1344 /* Copying only the fields needed by DWARF 2,3,4 */
1345 (block_loc + i)->lr_atom = new_loc->lc_atom;
1346 (block_loc + i)->lr_raw1 = new_loc->lc_raw1;
1347 (block_loc + i)->lr_raw2 = new_loc->lc_raw2;
1348 (block_loc + i)->lr_raw3 = new_loc->lc_raw3;
1349 (block_loc + i)->lr_number = new_loc->lc_number;
1350 (block_loc + i)->lr_number2 = new_loc->lc_number2;
1351 (block_loc + i)->lr_number3 = new_loc->lc_number3;
1352 (block_loc + i)->lr_offset = new_loc->lc_offset;
1353 (block_loc + i)->lr_opnumber = new_loc->lc_opnumber;
1354 prev_loc = new_loc;
1355 new_loc = prev_loc->lc_next;
1356 dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
1357 }
1358 /* Synthesizing the DW_LLE values for the old loclist
1359 versions. */
1360 if (loc_head->ll_kind == DW_LKIND_loclist) {
1361 /* Meaningless for a DW_LKIND_expression */
1362 if(highpc == 0 && lowpc == 0) {
1363 locdesc->ld_lle_value = DW_LLE_end_of_list;
1364 } else if(lowpc == MAX_ADDR) {
1365 locdesc->ld_lle_value = DW_LLE_base_address;
1366 } else {
1367 locdesc->ld_lle_value = DW_LLE_offset_pair;
1368 }
1369 } else if (DW_LKIND_GNU_exp_list){
1370 /* DW_LKIND_GNU_exp_list */
1371 locdesc->ld_lle_value = lle_op;
1372 }
1373 locdesc->ld_cents = op_count;
1374 locdesc->ld_s = block_loc;
1375 locdesc->ld_kind = lkind;
1376 locdesc->ld_section_offset = loc_block->bl_section_offset;
1377 locdesc->ld_locdesc_offset = loc_block->bl_locdesc_offset;
1378 locdesc->ld_rawlow = lowpc;
1379 locdesc->ld_rawhigh = highpc;
1380 /* Leaving the cooked values zero. Filled in later. */
1381 /* We have not yet looked for debug_addr, so we'll
1382 set it as not-missing. */
1383 locdesc->ld_index_failed = FALSE;
1384 return DW_DLV_OK;
1385 }
1386
1387
1388 /* Non-standard DWARF4 dwo loclist */
1389 static int
_dwarf_read_loc_section_dwo(Dwarf_Debug dbg,Dwarf_Block_c * return_block,Dwarf_Addr * lowpc,Dwarf_Addr * highpc,Dwarf_Bool * at_end,Dwarf_Half * lle_op,Dwarf_Off sec_offset,Dwarf_Half address_size,Dwarf_Half lkind,Dwarf_Error * error)1390 _dwarf_read_loc_section_dwo(Dwarf_Debug dbg,
1391 Dwarf_Block_c * return_block,
1392 Dwarf_Addr * lowpc,
1393 Dwarf_Addr * highpc,
1394 Dwarf_Bool *at_end,
1395 Dwarf_Half * lle_op,
1396 Dwarf_Off sec_offset,
1397 Dwarf_Half address_size,
1398 Dwarf_Half lkind,
1399 Dwarf_Error * error)
1400 {
1401 Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset;
1402 Dwarf_Small *locptr = 0;
1403 Dwarf_Small llecode = 0;
1404 Dwarf_Unsigned expr_offset = sec_offset;
1405 Dwarf_Byte_Ptr section_end = dbg->de_debug_loc.dss_data
1406 + dbg->de_debug_loc.dss_size;
1407
1408 if (sec_offset >= dbg->de_debug_loc.dss_size) {
1409 /* We're at the end. No more present. */
1410 return DW_DLV_NO_ENTRY;
1411 }
1412 memset(return_block,0,sizeof(*return_block));
1413
1414 /* not the same as non-split loclist, but still a list. */
1415 return_block->bl_kind = lkind;
1416
1417 /* This is non-standard GNU Dwarf4 loclist */
1418 return_block->bl_locdesc_offset = sec_offset;
1419 llecode = *beg;
1420 locptr = beg +1;
1421 expr_offset++;
1422 switch(llecode) {
1423 case DW_LLEX_end_of_list_entry:
1424 *at_end = TRUE;
1425 return_block->bl_section_offset = expr_offset;
1426 expr_offset++;
1427 break;
1428 case DW_LLEX_base_address_selection_entry: {
1429 Dwarf_Unsigned addr_index = 0;
1430
1431 DECODE_LEB128_UWORD_CK(locptr,addr_index,
1432 dbg,error,section_end);
1433 return_block->bl_section_offset = expr_offset;
1434 /* So this behaves much like non-dwo loclist */
1435 *lowpc=MAX_ADDR;
1436 *highpc=addr_index;
1437 }
1438 break;
1439 case DW_LLEX_start_end_entry: {
1440 Dwarf_Unsigned addr_indexs = 0;
1441 Dwarf_Unsigned addr_indexe= 0;
1442 Dwarf_Unsigned exprlen = 0;
1443 Dwarf_Unsigned leb128_length = 0;
1444
1445 DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexs,
1446 leb128_length,
1447 dbg,error,section_end);
1448 expr_offset += leb128_length;
1449
1450 DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexe,
1451 leb128_length,
1452 dbg,error,section_end);
1453 expr_offset +=leb128_length;
1454
1455 *lowpc=addr_indexs;
1456 *highpc=addr_indexe;
1457
1458 READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr,
1459 DWARF_HALF_SIZE,
1460 error,section_end);
1461 locptr += DWARF_HALF_SIZE;
1462 expr_offset += DWARF_HALF_SIZE;
1463
1464 return_block->bl_len = exprlen;
1465 return_block->bl_data = locptr;
1466 return_block->bl_section_offset = expr_offset;
1467
1468 expr_offset += exprlen;
1469 if (expr_offset > dbg->de_debug_loc.dss_size) {
1470
1471 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
1472 return DW_DLV_ERROR;
1473 }
1474 }
1475 break;
1476 case DW_LLEX_start_length_entry: {
1477 Dwarf_Unsigned addr_index = 0;
1478 Dwarf_Unsigned range_length = 0;
1479 Dwarf_Unsigned exprlen = 0;
1480 Dwarf_Unsigned leb128_length = 0;
1481
1482 DECODE_LEB128_UWORD_LEN_CK(locptr,addr_index,
1483 leb128_length,
1484 dbg,error,section_end);
1485 expr_offset +=leb128_length;
1486
1487 READ_UNALIGNED_CK(dbg, range_length, Dwarf_Unsigned, locptr,
1488 DWARF_32BIT_SIZE,
1489 error,section_end);
1490 locptr += DWARF_32BIT_SIZE;
1491 expr_offset += DWARF_32BIT_SIZE;
1492
1493 READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr,
1494 DWARF_HALF_SIZE,
1495 error,section_end);
1496 locptr += DWARF_HALF_SIZE;
1497 expr_offset += DWARF_HALF_SIZE;
1498
1499 *lowpc = addr_index;
1500 *highpc = range_length;
1501 return_block->bl_len = exprlen;
1502 return_block->bl_data = locptr;
1503 return_block->bl_section_offset = expr_offset;
1504 /* exprblock_size can be zero, means no expression */
1505
1506 expr_offset += exprlen;
1507 if (expr_offset > dbg->de_debug_loc.dss_size) {
1508 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
1509 return DW_DLV_ERROR;
1510 }
1511 }
1512 break;
1513 case DW_LLEX_offset_pair_entry: {
1514 Dwarf_Unsigned startoffset = 0;
1515 Dwarf_Unsigned endoffset = 0;
1516 Dwarf_Unsigned exprlen = 0;
1517
1518 READ_UNALIGNED_CK(dbg, startoffset,
1519 Dwarf_Unsigned, locptr,
1520 DWARF_32BIT_SIZE,
1521 error,section_end);
1522 locptr += DWARF_32BIT_SIZE;
1523 expr_offset += DWARF_32BIT_SIZE;
1524
1525 READ_UNALIGNED_CK(dbg, endoffset,
1526 Dwarf_Unsigned, locptr,
1527 DWARF_32BIT_SIZE,
1528 error,section_end);
1529 locptr += DWARF_32BIT_SIZE;
1530 expr_offset += DWARF_32BIT_SIZE;
1531 *lowpc= startoffset;
1532 *highpc = endoffset;
1533
1534 READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr,
1535 DWARF_HALF_SIZE,
1536 error,section_end);
1537 locptr += DWARF_HALF_SIZE;
1538 expr_offset += DWARF_HALF_SIZE;
1539
1540 return_block->bl_len = exprlen;
1541 return_block->bl_data = locptr;
1542 return_block->bl_section_offset = expr_offset;
1543
1544 expr_offset += exprlen;
1545 if (expr_offset > dbg->de_debug_loc.dss_size) {
1546 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
1547 return DW_DLV_ERROR;
1548 }
1549 }
1550 break;
1551 default:
1552 _dwarf_error(dbg,error,DW_DLE_LLE_CODE_UNKNOWN);
1553 return DW_DLV_ERROR;
1554 }
1555 *lle_op = llecode;
1556 return DW_DLV_OK;
1557 }
1558
1559
1560 int
dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c ll_header,unsigned int * kind,UNUSEDARG Dwarf_Error * error)1561 dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c ll_header,
1562 unsigned int * kind,
1563 UNUSEDARG Dwarf_Error * error)
1564 {
1565 *kind = ll_header->ll_kind;
1566 return DW_DLV_OK;
1567 }
1568
1569 static int
_dwarf_original_loclist_build(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Attribute attr,Dwarf_Error * error)1570 _dwarf_original_loclist_build(Dwarf_Debug dbg,
1571 Dwarf_Loc_Head_c llhead,
1572 Dwarf_Attribute attr,
1573 Dwarf_Error *error)
1574 {
1575 Dwarf_Unsigned loclist_offset = 0;
1576 int off_res = DW_DLV_ERROR;
1577 int count_res = DW_DLV_ERROR;
1578 int loclist_count = 0;
1579 Dwarf_Unsigned lli = 0;
1580 unsigned lkind = llhead->ll_kind;
1581 unsigned address_size = llhead->ll_address_size;
1582 Dwarf_Unsigned listlen = 0;
1583 Dwarf_Locdesc_c llbuf = 0;
1584 Dwarf_CU_Context cucontext;
1585
1586 off_res = _dwarf_get_loclist_header_start(dbg,
1587 attr, &loclist_offset, error);
1588 if (off_res != DW_DLV_OK) {
1589 return off_res;
1590 }
1591 #if 0
1592 res = dwarf_global_formref(attr,&loclist_offset,error);
1593 if (res != DW_DLV_OK) {
1594 return res;
1595 }
1596 #endif
1597
1598 if (lkind == DW_LKIND_GNU_exp_list) {
1599 count_res = _dwarf_get_loclist_lle_count_dwo(dbg,
1600 loclist_offset,
1601 address_size,
1602 llhead->ll_kind,
1603 &loclist_count,
1604 error);
1605 } else {
1606 count_res = _dwarf_get_loclist_lle_count(dbg,
1607 loclist_offset, address_size,
1608 llhead->ll_kind,
1609 &loclist_count,
1610 error);
1611 }
1612 if (count_res != DW_DLV_OK) {
1613 return count_res;
1614 }
1615 if (loclist_count == 0) {
1616 return DW_DLV_NO_ENTRY;
1617 }
1618
1619 listlen = loclist_count;
1620 llbuf = (Dwarf_Locdesc_c)
1621 _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen);
1622 if (!llbuf) {
1623 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1624 return (DW_DLV_ERROR);
1625 }
1626 llhead->ll_locdesc = llbuf;
1627 llhead->ll_locdesc_count = listlen;
1628 cucontext = llhead->ll_context;
1629 llhead->ll_llearea_offset = loclist_offset;
1630
1631 /* New get loc ops */
1632 for (lli = 0; lli < listlen; ++lli) {
1633 int lres = 0;
1634 Dwarf_Half lle_op = 0;
1635 Dwarf_Bool at_end = 0;
1636 Dwarf_Block_c loc_block;
1637 Dwarf_Unsigned lowpc = 0;
1638 Dwarf_Unsigned highpc = 0;
1639 int blkres = 0;
1640
1641 memset(&loc_block,0,sizeof(loc_block));
1642 if( lkind == DW_LKIND_GNU_exp_list) {
1643 blkres = _dwarf_read_loc_section_dwo(dbg,
1644 &loc_block,
1645 &lowpc, &highpc,
1646 &at_end, &lle_op,
1647 loclist_offset,
1648 address_size,
1649 lkind,
1650 error);
1651 } else {
1652 blkres = _dwarf_read_loc_section(dbg,
1653 &loc_block,
1654 &lowpc, &highpc,
1655 &lle_op,
1656 loclist_offset,
1657 address_size,
1658 lkind,
1659 error);
1660 }
1661 if (blkres != DW_DLV_OK) {
1662 return blkres;
1663 }
1664 /* Fills in the locdesc and its operators list at index lli */
1665 lres = _dwarf_fill_in_locdesc_op_c(dbg,
1666 lli,
1667 llhead,
1668 &loc_block,
1669 address_size,
1670 cucontext->cc_length_size,
1671 cucontext->cc_version_stamp,
1672 lowpc,
1673 highpc,
1674 lle_op,
1675 error);
1676 if (lres != DW_DLV_OK) {
1677 return lres;
1678 }
1679 /* Now get to next loclist entry offset. */
1680 loclist_offset = loc_block.bl_section_offset +
1681 loc_block.bl_len;
1682 }
1683 return DW_DLV_OK;
1684 }
1685
1686 static int
_dwarf_original_expression_build(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Attribute attr,Dwarf_Error * error)1687 _dwarf_original_expression_build(Dwarf_Debug dbg,
1688 Dwarf_Loc_Head_c llhead,
1689 Dwarf_Attribute attr,
1690 Dwarf_Error *error)
1691 {
1692
1693 Dwarf_Block_c loc_blockc;
1694 Dwarf_Unsigned lowpc = 0;
1695 Dwarf_Unsigned highpc = 0;
1696 unsigned form = llhead->ll_attrform;
1697 int blkres = 0;
1698 Dwarf_Locdesc_c llbuf = 0;
1699 unsigned listlen = 1;
1700 Dwarf_CU_Context cucontext = llhead->ll_context;
1701
1702 memset(&loc_blockc,0,sizeof(loc_blockc));
1703 if( form == DW_FORM_exprloc) {
1704 blkres = dwarf_formexprloc(attr,&loc_blockc.bl_len,
1705 &loc_blockc.bl_data,error);
1706 if(blkres != DW_DLV_OK) {
1707 dwarf_loc_head_c_dealloc(llhead);
1708 return blkres;
1709 }
1710 loc_blockc.bl_kind = llhead->ll_kind;
1711 loc_blockc.bl_section_offset =
1712 (char *)loc_blockc.bl_data -
1713 (char *)dbg->de_debug_info.dss_data;
1714 loc_blockc.bl_locdesc_offset = 0; /* not relevant */
1715 } else {
1716 Dwarf_Block loc_block;
1717
1718 memset(&loc_block,0,sizeof(loc_block));
1719 blkres = _dwarf_formblock_internal(dbg,attr,
1720 llhead->ll_context,
1721 &loc_block,
1722 error);
1723 if (blkres != DW_DLV_OK) {
1724 return blkres;
1725 }
1726 loc_blockc.bl_len = loc_block.bl_len;
1727 loc_blockc.bl_data = loc_block.bl_data;
1728 loc_blockc.bl_kind = llhead->ll_kind;
1729 loc_blockc.bl_section_offset = loc_block.bl_section_offset;
1730 loc_blockc.bl_locdesc_offset = 0; /* not relevant */
1731 }
1732 /* This hack ensures that the Locdesc_c
1733 is marked DW_LLE_start_end. But really unncessary
1734 as we are marked as the correct ll_kind */
1735 lowpc = 0; /* HACK */
1736 highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
1737
1738 llbuf = (Dwarf_Locdesc_c)
1739 _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen);
1740 if (!llbuf) {
1741 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1742 return (DW_DLV_ERROR);
1743 }
1744 llhead->ll_locdesc = llbuf;
1745 /* One by definition of a location entry. */
1746 llhead->ll_locdesc_count = listlen;
1747
1748 /* An empty location description (block length 0)
1749 means the code generator emitted no variable,
1750 the variable was not generated, it was unused
1751 or perhaps never tested after being set. Dwarf2,
1752 section 2.4.1 In other words, it is not an error,
1753 and we don't test for block length 0 specially here. */
1754
1755 /* Fills in the locdesc and its operators list at index 0 */
1756 blkres = _dwarf_fill_in_locdesc_op_c(dbg,
1757 0, /* fake locdesc is index 0 */
1758 llhead,
1759 &loc_blockc,
1760 llhead->ll_address_size,
1761 cucontext->cc_length_size,
1762 cucontext->cc_version_stamp,
1763 lowpc, highpc,
1764 0,
1765 error);
1766 if (blkres != DW_DLV_OK) {
1767 /* low level error already set: let it be passed back */
1768 return blkres;
1769 }
1770 return DW_DLV_OK;
1771 }
1772
1773 /* Following the original loclist definition the low
1774 value is all one bits, the high value is the base
1775 address. */
1776 static int
cook_original_loclist_contents(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Error * error)1777 cook_original_loclist_contents(Dwarf_Debug dbg,
1778 Dwarf_Loc_Head_c llhead,
1779 Dwarf_Error *error)
1780 {
1781 Dwarf_Unsigned baseaddress = llhead->ll_cu_base_address;
1782 Dwarf_Unsigned count = llhead->ll_locdesc_count;
1783 Dwarf_Unsigned i = 0;
1784
1785 for ( i = 0 ; i < count; ++i) {
1786 Dwarf_Locdesc_c llc = 0;
1787
1788 llc = llhead->ll_locdesc +i;
1789 switch(llc->ld_lle_value) {
1790 case DW_LLE_end_of_list: {
1791 /* nothing to do */
1792 break;
1793 }
1794 case DW_LLE_base_address: {
1795 llc->ld_lopc = llc->ld_rawhigh;
1796 llc->ld_highpc = llc->ld_rawhigh;
1797 baseaddress = llc->ld_rawhigh;
1798 break;
1799 }
1800 case DW_LLE_offset_pair: {
1801 llc->ld_lopc = llc->ld_rawlow + baseaddress;
1802 llc->ld_highpc = llc->ld_rawhigh + baseaddress;
1803 break;
1804 }
1805 default: {
1806 dwarfstring m;
1807
1808 dwarfstring_constructor(&m);
1809 dwarfstring_append_printf_u(&m,
1810 "DW_DLE_LOCLISTS_ERROR: improper synthesized LLE code "
1811 "of 0x%x is unknown. In standard DWARF3/4 loclist",
1812 llc->ld_lle_value);
1813 _dwarf_error_string(dbg,error,
1814 DW_DLE_LOCLISTS_ERROR,
1815 dwarfstring_string(&m));
1816 dwarfstring_destructor(&m);
1817 return DW_DLV_ERROR;
1818 }
1819 }
1820 }
1821 return DW_DLV_OK;
1822 }
1823
1824 static int
cook_gnu_loclist_contents(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Error * error)1825 cook_gnu_loclist_contents(Dwarf_Debug dbg,
1826 Dwarf_Loc_Head_c llhead,
1827 Dwarf_Error *error)
1828 {
1829 Dwarf_Unsigned baseaddress = llhead->ll_cu_base_address;
1830 Dwarf_Unsigned count = llhead->ll_locdesc_count;
1831 Dwarf_Unsigned i = 0;
1832 Dwarf_CU_Context cucontext = llhead->ll_context;
1833 int res = 0;
1834
1835 for (i = 0 ; i < count ; ++i) {
1836 Dwarf_Locdesc_c llc = 0;
1837
1838 llc = llhead->ll_locdesc +i;
1839 switch(llc->ld_lle_value) {
1840 case DW_LLEX_base_address_selection_entry:{
1841 Dwarf_Addr targaddr = 0;
1842 res = _dwarf_extract_address_from_debug_addr(dbg,
1843 cucontext,llc->ld_rawhigh,&targaddr,error);
1844 if (res != DW_DLV_OK) {
1845 llc->ld_index_failed = TRUE;
1846 llc->ld_lopc = 0;
1847 llc->ld_highpc = 0;
1848 if (res == DW_DLV_ERROR) {
1849 dwarf_dealloc_error(dbg, *error);
1850 *error = 0;
1851 }
1852 } else {
1853 llc->ld_lopc = targaddr;
1854 llc->ld_highpc = targaddr;
1855 }
1856 break;
1857 }
1858 case DW_LLEX_end_of_list_entry:{
1859 /* Nothing to do. */
1860 break;
1861 }
1862 case DW_LLEX_start_length_entry:{
1863 Dwarf_Addr targaddr = 0;
1864 res = _dwarf_extract_address_from_debug_addr(dbg,
1865 cucontext,llc->ld_rawlow,&targaddr,error);
1866 if (res != DW_DLV_OK) {
1867 llc->ld_index_failed = TRUE;
1868 llc->ld_lopc = 0;
1869 if (res == DW_DLV_ERROR) {
1870 dwarf_dealloc_error(dbg, *error);
1871 *error = 0;
1872 }
1873 } else {
1874 llc->ld_lopc = targaddr;
1875 llc->ld_highpc = llc->ld_lopc +llc->ld_rawhigh;
1876 }
1877 break;
1878 }
1879 case DW_LLEX_offset_pair_entry:{
1880 llc->ld_lopc = llc->ld_rawlow + baseaddress;
1881 llc->ld_highpc = llc->ld_rawhigh + baseaddress;
1882 break;
1883 }
1884 case DW_LLEX_start_end_entry:{
1885 Dwarf_Addr targaddr = 0;
1886 res = _dwarf_extract_address_from_debug_addr(dbg,
1887 cucontext,llc->ld_rawlow,&targaddr,error);
1888 if (res != DW_DLV_OK) {
1889 llc->ld_index_failed = TRUE;
1890 llc->ld_lopc = 0;
1891 if (res == DW_DLV_ERROR) {
1892 dwarf_dealloc_error(dbg, *error);
1893 *error = 0;
1894 }
1895 } else {
1896 llc->ld_lopc = targaddr;
1897 }
1898 res = _dwarf_extract_address_from_debug_addr(dbg,
1899 cucontext,llc->ld_rawhigh,&targaddr,error);
1900 if (res != DW_DLV_OK) {
1901 llc->ld_index_failed = TRUE;
1902 llc->ld_highpc = 0;
1903 if (res == DW_DLV_ERROR) {
1904 dwarf_dealloc_error(dbg, *error);
1905 *error = 0;
1906 }
1907 } else {
1908 llc->ld_highpc = targaddr;
1909 }
1910
1911
1912 break;
1913 }
1914 default:{
1915 dwarfstring m;
1916
1917 dwarfstring_constructor(&m);
1918 dwarfstring_append_printf_u(&m,
1919 "DW_DLE_LOCLISTS_ERROR: improper LLEX code "
1920 "of 0x%x is unknown. GNU LLEX dwo loclists error",
1921 llc->ld_lle_value);
1922 _dwarf_error_string(dbg,error,
1923 DW_DLE_LOCLISTS_ERROR,
1924 dwarfstring_string(&m));
1925 dwarfstring_destructor(&m);
1926 return DW_DLV_ERROR;
1927
1928 break;
1929 }
1930 }
1931 }
1932 return DW_DLV_OK;
1933 }
1934
1935
1936 /* DWARF5 */
1937 static int
cook_loclists_contents(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Error * error)1938 cook_loclists_contents(Dwarf_Debug dbg,
1939 Dwarf_Loc_Head_c llhead,
1940 Dwarf_Error *error)
1941 {
1942 Dwarf_Unsigned baseaddress = llhead->ll_cu_base_address;
1943 Dwarf_Unsigned count = llhead->ll_locdesc_count;
1944 Dwarf_Unsigned i = 0;
1945 Dwarf_CU_Context cucontext = llhead->ll_context;
1946 int res = 0;
1947
1948 for (i = 0 ; i < count ; ++i) {
1949 Dwarf_Locdesc_c llc = 0;
1950
1951 llc = llhead->ll_locdesc +i;
1952 switch(llc->ld_lle_value) {
1953 case DW_LLE_base_addressx: {
1954 Dwarf_Addr targaddr = 0;
1955 res = _dwarf_extract_address_from_debug_addr(dbg,
1956 cucontext,llc->ld_rawlow,&targaddr,error);
1957 if (res != DW_DLV_OK) {
1958 llc->ld_index_failed = TRUE;
1959 llc->ld_lopc = 0;
1960 if (res == DW_DLV_ERROR) {
1961 dwarf_dealloc_error(dbg, *error);
1962 *error = 0;
1963 }
1964 } else {
1965 llc->ld_lopc = targaddr;
1966 }
1967 break;
1968 }
1969 case DW_LLE_startx_endx:{
1970 /* two indexes into debug_addr */
1971 Dwarf_Addr targaddr = 0;
1972 res = _dwarf_extract_address_from_debug_addr(dbg,
1973 cucontext,llc->ld_rawlow,&targaddr,error);
1974 if (res != DW_DLV_OK) {
1975 llc->ld_index_failed = TRUE;
1976 llc->ld_lopc = 0;
1977 if (res == DW_DLV_ERROR) {
1978 dwarf_dealloc_error(dbg, *error);
1979 *error = 0;
1980 }
1981 } else {
1982 llc->ld_lopc = targaddr;
1983 }
1984 res = _dwarf_extract_address_from_debug_addr(dbg,
1985 cucontext,llc->ld_rawhigh,&targaddr,error);
1986 if (res != DW_DLV_OK) {
1987 llc->ld_index_failed = TRUE;
1988 llc->ld_highpc = 0;
1989 if (res == DW_DLV_ERROR) {
1990 dwarf_dealloc_error(dbg, *error);
1991 *error = 0;
1992 }
1993 } else {
1994 llc->ld_highpc = targaddr;
1995 }
1996 break;
1997 }
1998 case DW_LLE_startx_length:{
1999 /* one index to debug_addr other a length */
2000 Dwarf_Addr targaddr = 0;
2001 res = _dwarf_extract_address_from_debug_addr(dbg,
2002 cucontext,llc->ld_rawlow,&targaddr,error);
2003 if (res != DW_DLV_OK) {
2004 llc->ld_index_failed = TRUE;
2005 llc->ld_lopc = 0;
2006 if (res == DW_DLV_ERROR) {
2007 dwarf_dealloc_error(dbg, *error);
2008 *error = 0;
2009 }
2010 } else {
2011 llc->ld_lopc = targaddr;
2012 llc->ld_highpc = targaddr + llc->ld_rawhigh;
2013 }
2014 break;
2015 }
2016 case DW_LLE_offset_pair:{
2017 /*offsets of the current base address*/
2018 llc->ld_lopc = llc->ld_rawlow +baseaddress;
2019 llc->ld_highpc = llc->ld_rawhigh +baseaddress;
2020 break;
2021 }
2022 case DW_LLE_default_location:{
2023 /* nothing to do here, just has a counted
2024 location description */
2025 break;
2026 }
2027 case DW_LLE_base_address:{
2028 llc->ld_lopc = llc->ld_rawlow;
2029 llc->ld_highpc = llc->ld_rawlow;
2030 baseaddress = llc->ld_rawlow;
2031 break;
2032 }
2033 case DW_LLE_start_end:{
2034 llc->ld_lopc = llc->ld_rawlow;
2035 llc->ld_highpc = llc->ld_rawhigh;
2036 break;
2037 }
2038 case DW_LLE_start_length:{
2039 llc->ld_lopc = llc->ld_rawlow;
2040 llc->ld_highpc = llc->ld_rawlow + llc->ld_rawhigh;
2041 break;
2042 }
2043 case DW_LLE_end_of_list:{
2044 /* do nothing */
2045 break;
2046 }
2047 default: {
2048 dwarfstring m;
2049
2050 dwarfstring_constructor(&m);
2051 dwarfstring_append_printf_u(&m,
2052 "DW_DLE_LOCLISTS_ERROR: improper DW_LLE code "
2053 "of 0x%x is unknown. DWARF5 loclists error",
2054 llc->ld_lle_value);
2055 _dwarf_error_string(dbg,error,
2056 DW_DLE_LOCLISTS_ERROR,
2057 dwarfstring_string(&m));
2058 dwarfstring_destructor(&m);
2059 return DW_DLV_ERROR;
2060 }
2061 }
2062 }
2063 return DW_DLV_OK;
2064 }
2065
2066 /* New October 2015
2067 This interface requires the use of interface functions
2068 to get data from Dwarf_Locdesc_c. The structures
2069 are not visible to callers. */
2070 int
dwarf_get_loclist_c(Dwarf_Attribute attr,Dwarf_Loc_Head_c * ll_header_out,Dwarf_Unsigned * listlen_out,Dwarf_Error * error)2071 dwarf_get_loclist_c(Dwarf_Attribute attr,
2072 Dwarf_Loc_Head_c * ll_header_out,
2073 Dwarf_Unsigned * listlen_out,
2074 Dwarf_Error * error)
2075 {
2076 Dwarf_Debug dbg;
2077 Dwarf_Half form = 0;
2078 Dwarf_Loc_Head_c llhead = 0;
2079 Dwarf_CU_Context cucontext = 0;
2080 unsigned address_size = 0;
2081 int cuversionstamp = 0;
2082 Dwarf_Bool is_cu = FALSE;
2083 Dwarf_Unsigned attrnum = 0;
2084 Dwarf_Bool is_dwo = 0;
2085 int setup_res = DW_DLV_ERROR;
2086 int lkind = 0;
2087
2088 /* ***** BEGIN CODE ***** */
2089 setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
2090 if (setup_res != DW_DLV_OK) {
2091 return setup_res;
2092 }
2093 attrnum = attr->ar_attribute;
2094 cuversionstamp = cucontext->cc_version_stamp;
2095 address_size = cucontext->cc_address_size;
2096 is_dwo = cucontext->cc_is_dwo;
2097 lkind = determine_location_lkind(cuversionstamp,
2098 form, attrnum, is_dwo);
2099 if (lkind == DW_LKIND_unknown) {
2100 dwarfstring m;
2101 const char * formname = "<unknownform>";
2102 const char * attrname = "<unknown attribute>";
2103
2104 dwarfstring_constructor(&m);
2105 dwarf_get_FORM_name(form,&formname);
2106 dwarf_get_AT_name(attrnum,&attrname);
2107 dwarfstring_append_printf_u(&m,
2108 "DW_DLE_LOC_EXPR_BAD: For Compilation Unit "
2109 "version %u",cuversionstamp);
2110 dwarfstring_append_printf_u(&m,
2111 ", attribute 0x%x (",attrnum);
2112 dwarfstring_append(&m,(char *)attrname);
2113 dwarfstring_append_printf_u(&m,
2114 ") form 0x%x (",form);
2115 dwarfstring_append(&m,(char *)formname);
2116 if (is_dwo) {
2117 dwarfstring_append(&m,") (the CU is a .dwo) ");
2118 } else {
2119 dwarfstring_append(&m,") (the CU is not a .dwo) ");
2120 }
2121 dwarfstring_append(&m," we don't undrstand the location");
2122 _dwarf_error_string(dbg,error,DW_DLE_LOC_EXPR_BAD,
2123 dwarfstring_string(&m));
2124 dwarfstring_destructor(&m);
2125 return DW_DLV_ERROR;
2126 }
2127 /* Doing this early (first) to avoid repeating the alloc code
2128 for each type */
2129 llhead = (Dwarf_Loc_Head_c)
2130 _dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1);
2131 if (!llhead) {
2132 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
2133 return (DW_DLV_ERROR);
2134 }
2135 llhead->ll_cuversion = cuversionstamp;
2136 llhead->ll_kind = lkind;
2137 llhead->ll_attrnum = attrnum;
2138 llhead->ll_attrform = form;
2139 llhead->ll_dbg = dbg;
2140 llhead->ll_address_size = address_size;
2141 llhead->ll_offset_size = cucontext->cc_length_size;
2142 llhead->ll_context = cucontext;
2143
2144 llhead->ll_at_loclists_base_present =
2145 cucontext->cc_loclists_base_present;
2146 llhead->ll_at_loclists_base = cucontext->cc_loclists_base;
2147 llhead->ll_cu_base_address_present = cucontext->cc_low_pc_present;
2148 llhead->ll_cu_base_address = cucontext->cc_low_pc;
2149 llhead->ll_cu_addr_base = cucontext->cc_addr_base;
2150 llhead->ll_cu_addr_base_present = cucontext->cc_addr_base_present;
2151
2152 if (lkind == DW_LKIND_loclist ||
2153 lkind == DW_LKIND_GNU_exp_list) {
2154 int ores = 0;
2155 /* Here we have a loclist to deal with. */
2156 ores = context_is_cu_not_tu(cucontext,&is_cu);
2157 if(ores != DW_DLV_OK) {
2158 dwarf_loc_head_c_dealloc(llhead);
2159 return setup_res;
2160 }
2161 ores = _dwarf_original_loclist_build(dbg,
2162 llhead, attr, error);
2163 if (ores != DW_DLV_OK) {
2164 dwarf_loc_head_c_dealloc(llhead);
2165 return ores;
2166 }
2167 if (lkind == DW_LKIND_loclist) {
2168 ores = cook_original_loclist_contents(dbg,llhead,error);
2169 } else {
2170 ores = cook_gnu_loclist_contents(dbg,llhead,error);
2171 }
2172 if (ores != DW_DLV_OK) {
2173 dwarf_loc_head_c_dealloc(llhead);
2174 return ores;
2175 }
2176 } else if (lkind == DW_LKIND_expression) {
2177 /* DWARF2,3,4,5 */
2178 int eres = 0;
2179 eres = _dwarf_original_expression_build(dbg,
2180 llhead, attr, error);
2181 if (eres != DW_DLV_OK) {
2182 dwarf_loc_head_c_dealloc(llhead);
2183 return eres;
2184 }
2185 } else if (lkind == DW_LKIND_loclists) {
2186 /* DWARF5! */
2187 int leres = 0;
2188
2189 leres = _dwarf_loclists_fill_in_lle_head(dbg,
2190 attr,llhead,error);
2191 if (leres != DW_DLV_OK) {
2192 dwarf_loc_head_c_dealloc(llhead);
2193 return leres;
2194 }
2195 leres = cook_loclists_contents(dbg,llhead,error);
2196 if (leres != DW_DLV_OK) {
2197 dwarf_loc_head_c_dealloc(llhead);
2198 return leres;
2199 }
2200 } /* ASSERT else impossible */
2201 *ll_header_out = llhead;
2202 *listlen_out = llhead->ll_locdesc_count;
2203 return DW_DLV_OK;
2204 }
2205
2206 /* An interface giving us no cu context!
2207 This is not going to be quite right. */
2208 int
dwarf_loclist_from_expr_c(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Half address_size,Dwarf_Half offset_size,Dwarf_Small dwarf_version,Dwarf_Loc_Head_c * loc_head,Dwarf_Unsigned * listlen,Dwarf_Error * error)2209 dwarf_loclist_from_expr_c(Dwarf_Debug dbg,
2210 Dwarf_Ptr expression_in,
2211 Dwarf_Unsigned expression_length,
2212 Dwarf_Half address_size,
2213 Dwarf_Half offset_size,
2214 Dwarf_Small dwarf_version,
2215 Dwarf_Loc_Head_c *loc_head,
2216 Dwarf_Unsigned * listlen,
2217 Dwarf_Error * error)
2218 {
2219 /* Dwarf_Block that describes a single location expression. */
2220 Dwarf_Block_c loc_block;
2221 Dwarf_Loc_Head_c llhead = 0;
2222 Dwarf_Locdesc_c llbuf = 0;
2223 int local_listlen = 1;
2224 Dwarf_Addr lowpc = 0;
2225 Dwarf_Addr highpc = MAX_ADDR;
2226 Dwarf_Small version_stamp = dwarf_version;
2227 int res = 0;
2228
2229 llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg,
2230 DW_DLA_LOC_HEAD_C, 1);
2231 if (!llhead) {
2232 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
2233 return (DW_DLV_ERROR);
2234 }
2235 memset(&loc_block,0,sizeof(loc_block));
2236 loc_block.bl_len = expression_length;
2237 loc_block.bl_data = expression_in;
2238 loc_block.bl_kind = DW_LKIND_expression; /* Not from loclist. */
2239 loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
2240 loc_block.bl_locdesc_offset = 0; /* Fake. Not meaningful. */
2241 llbuf = (Dwarf_Locdesc_c)
2242 _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, local_listlen);
2243 if (!llbuf) {
2244 dwarf_loc_head_c_dealloc(llhead);
2245 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
2246 return (DW_DLV_ERROR);
2247 }
2248 llhead->ll_locdesc = llbuf;
2249 llhead->ll_locdesc_count = local_listlen;
2250 llhead->ll_context = 0; /* Not available! */
2251 llhead->ll_dbg = dbg;
2252 llhead->ll_kind = DW_LKIND_expression;
2253
2254 /* An empty location description (block length 0)
2255 means the code generator emitted no variable,
2256 the variable was not generated,
2257 it was unused or perhaps never tested
2258 after being set. Dwarf2,
2259 section 2.4.1 In other words, it is not
2260 an error, and we don't
2261 test for block length 0 specially here. */
2262
2263 /* Fills in the locdesc and its operators list at index 0 */
2264 res = _dwarf_fill_in_locdesc_op_c(dbg,
2265 0,
2266 llhead,
2267 &loc_block,
2268 address_size,
2269 offset_size,
2270 version_stamp,
2271 lowpc,
2272 highpc,
2273 DW_LKIND_expression,
2274 error);
2275 if (res != DW_DLV_OK) {
2276 /* low level error already set: let it be passed back */
2277 dwarf_loc_head_c_dealloc(llhead);
2278 return (DW_DLV_ERROR);
2279 }
2280 *loc_head = llhead;
2281 *listlen = local_listlen;
2282 return (DW_DLV_OK);
2283 }
2284
2285
2286 /* New June 2020. */
2287 int
dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head,Dwarf_Unsigned index,Dwarf_Small * lle_value_out,Dwarf_Unsigned * rawval1,Dwarf_Unsigned * rawval2,Dwarf_Bool * debug_addr_unavailable,Dwarf_Addr * lowpc_out,Dwarf_Addr * hipc_out,Dwarf_Unsigned * loclist_expr_op_count_out,Dwarf_Locdesc_c * locdesc_entry_out,Dwarf_Small * loclist_source_out,Dwarf_Unsigned * expression_offset_out,Dwarf_Unsigned * locdesc_offset_out,Dwarf_Error * error)2288 dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head,
2289 Dwarf_Unsigned index,
2290 Dwarf_Small * lle_value_out,
2291 Dwarf_Unsigned * rawval1,
2292 Dwarf_Unsigned * rawval2,
2293 Dwarf_Bool * debug_addr_unavailable,
2294 Dwarf_Addr * lowpc_out, /* 'cooked' value */
2295 Dwarf_Addr * hipc_out, /* 'cooked' value */
2296 Dwarf_Unsigned * loclist_expr_op_count_out,
2297 /* Returns pointer to the specific locdesc of the index; */
2298 Dwarf_Locdesc_c* locdesc_entry_out,
2299 Dwarf_Small * loclist_source_out, /* 0,1, or 2 */
2300 Dwarf_Unsigned * expression_offset_out,
2301 Dwarf_Unsigned * locdesc_offset_out,
2302 Dwarf_Error * error)
2303 {
2304 Dwarf_Locdesc_c descs_base = 0;
2305 Dwarf_Locdesc_c desc = 0;
2306 Dwarf_Unsigned desc_count = 0;
2307 Dwarf_Debug dbg;
2308
2309 desc_count = loclist_head->ll_locdesc_count;
2310 descs_base = loclist_head->ll_locdesc;
2311 dbg = loclist_head->ll_dbg;
2312 if (index >= desc_count) {
2313 _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR);
2314 return (DW_DLV_ERROR);
2315 }
2316 desc = descs_base + index;
2317 *lle_value_out = desc->ld_lle_value;
2318 *rawval1 = desc->ld_rawlow;
2319 *rawval2 = desc->ld_rawhigh;
2320 *lowpc_out = desc->ld_lopc;
2321 *hipc_out = desc->ld_highpc;
2322 *debug_addr_unavailable = desc->ld_index_failed;
2323 *loclist_expr_op_count_out = desc->ld_cents;
2324 *locdesc_entry_out = desc;
2325 *loclist_source_out = desc->ld_kind;
2326 *expression_offset_out = desc->ld_section_offset;
2327 *locdesc_offset_out = desc->ld_locdesc_offset;
2328 return DW_DLV_OK;
2329 }
2330 int
dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c loclist_head,Dwarf_Unsigned index,Dwarf_Small * lle_value_out,Dwarf_Addr * lowpc_out,Dwarf_Addr * hipc_out,Dwarf_Unsigned * loclist_count_out,Dwarf_Locdesc_c * locdesc_entry_out,Dwarf_Small * loclist_source_out,Dwarf_Unsigned * expression_offset_out,Dwarf_Unsigned * locdesc_offset_out,Dwarf_Error * error)2331 dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c loclist_head,
2332 Dwarf_Unsigned index,
2333 Dwarf_Small * lle_value_out,
2334 Dwarf_Addr * lowpc_out,
2335 Dwarf_Addr * hipc_out,
2336 Dwarf_Unsigned * loclist_count_out,
2337
2338 /* Returns pointer to the specific locdesc of the index; */
2339 Dwarf_Locdesc_c* locdesc_entry_out,
2340 Dwarf_Small * loclist_source_out, /* 0,1, or 2 */
2341 Dwarf_Unsigned * expression_offset_out,
2342 Dwarf_Unsigned * locdesc_offset_out,
2343 Dwarf_Error * error)
2344 {
2345 int res = 0;
2346 Dwarf_Unsigned cookedlow = 0;
2347 Dwarf_Unsigned cookedhigh = 0;
2348 Dwarf_Bool debug_addr_unavailable = FALSE;
2349
2350 res = dwarf_get_locdesc_entry_d(loclist_head,
2351 index,lle_value_out,
2352 lowpc_out,hipc_out,
2353 &debug_addr_unavailable,
2354 &cookedlow,&cookedhigh,
2355 loclist_count_out,
2356 locdesc_entry_out,
2357 loclist_source_out,
2358 expression_offset_out,
2359 locdesc_offset_out,
2360 error);
2361 return res;
2362 }
2363
2364
2365 int
dwarf_get_location_op_value_d(Dwarf_Locdesc_c locdesc,Dwarf_Unsigned index,Dwarf_Small * atom_out,Dwarf_Unsigned * operand1,Dwarf_Unsigned * operand2,Dwarf_Unsigned * operand3,Dwarf_Unsigned * rawop1,Dwarf_Unsigned * rawop2,Dwarf_Unsigned * rawop3,Dwarf_Unsigned * offset_for_branch,Dwarf_Error * error)2366 dwarf_get_location_op_value_d(Dwarf_Locdesc_c locdesc,
2367 Dwarf_Unsigned index,
2368 Dwarf_Small * atom_out,
2369 Dwarf_Unsigned * operand1,
2370 Dwarf_Unsigned * operand2,
2371 Dwarf_Unsigned * operand3,
2372 Dwarf_Unsigned * rawop1,
2373 Dwarf_Unsigned * rawop2,
2374 Dwarf_Unsigned * rawop3,
2375 Dwarf_Unsigned * offset_for_branch,
2376 Dwarf_Error* error)
2377 {
2378 Dwarf_Loc_Expr_Op op = 0;
2379 Dwarf_Unsigned max = locdesc->ld_cents;
2380
2381 if(index >= max) {
2382 Dwarf_Debug dbg = locdesc->ld_loclist_head->ll_dbg;
2383 _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR);
2384 return (DW_DLV_ERROR);
2385 }
2386 op = locdesc->ld_s + index;
2387 *atom_out = op->lr_atom;
2388 *operand1 = op->lr_number;
2389 *operand2 = op->lr_number2;
2390 *operand3 = op->lr_number3;
2391 *rawop1 = op->lr_raw1;
2392 *rawop2 = op->lr_raw2;
2393 *rawop3 = op->lr_raw3;
2394 *offset_for_branch = op->lr_offset;
2395 return DW_DLV_OK;
2396 }
2397
2398
2399 int
dwarf_get_location_op_value_c(Dwarf_Locdesc_c locdesc,Dwarf_Unsigned index,Dwarf_Small * atom_out,Dwarf_Unsigned * operand1,Dwarf_Unsigned * operand2,Dwarf_Unsigned * operand3,Dwarf_Unsigned * offset_for_branch,Dwarf_Error * error)2400 dwarf_get_location_op_value_c(Dwarf_Locdesc_c locdesc,
2401 Dwarf_Unsigned index,
2402 Dwarf_Small * atom_out,
2403 Dwarf_Unsigned * operand1,
2404 Dwarf_Unsigned * operand2,
2405 Dwarf_Unsigned * operand3,
2406 Dwarf_Unsigned * offset_for_branch,
2407 Dwarf_Error* error)
2408 {
2409 Dwarf_Unsigned raw1 = 0;
2410 Dwarf_Unsigned raw2 = 0;
2411 Dwarf_Unsigned raw3 = 0;
2412 int res = 0;
2413
2414 res = dwarf_get_location_op_value_d(locdesc,
2415 index,atom_out,
2416 operand1,operand2,operand3,
2417 &raw1,&raw2,&raw3,
2418 offset_for_branch,
2419 error);
2420 return res;
2421 }
2422
2423 void
dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head)2424 dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head)
2425 {
2426 Dwarf_Debug dbg = loclist_head->ll_dbg;
2427 _dwarf_free_loclists_head(loclist_head);
2428 dwarf_dealloc(dbg,loclist_head,DW_DLA_LOC_HEAD_C);
2429 }
2430 /* ============== End of the October 2015 interfaces. */
2431