1 /* Return location expression list.
2 Copyright (C) 2000-2010, 2013-2015, 2017, 2018 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
7
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
11
12 or
13
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
28
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32
33 #include <dwarf.h>
34 #include <search.h>
35 #include <stdlib.h>
36 #include <assert.h>
37
38 #include <libdwP.h>
39
40
41 static bool
attr_ok(Dwarf_Attribute * attr)42 attr_ok (Dwarf_Attribute *attr)
43 {
44 if (attr == NULL)
45 return false;
46
47 /* If it is an exprloc, it is obviously OK. */
48 if (dwarf_whatform (attr) == DW_FORM_exprloc)
49 return true;
50
51 /* Otherwise must be one of the attributes listed below. Older
52 DWARF versions might have encoded the exprloc as block, and we
53 cannot easily distinguish attributes in the loclist class because
54 the same forms are used for different classes. */
55 switch (attr->code)
56 {
57 case DW_AT_location:
58 case DW_AT_byte_size:
59 case DW_AT_bit_offset:
60 case DW_AT_bit_size:
61 case DW_AT_lower_bound:
62 case DW_AT_bit_stride:
63 case DW_AT_upper_bound:
64 case DW_AT_count:
65 case DW_AT_allocated:
66 case DW_AT_associated:
67 case DW_AT_data_location:
68 case DW_AT_byte_stride:
69 case DW_AT_rank:
70 case DW_AT_call_value:
71 case DW_AT_call_target:
72 case DW_AT_call_target_clobbered:
73 case DW_AT_call_data_location:
74 case DW_AT_call_data_value:
75 case DW_AT_data_member_location:
76 case DW_AT_vtable_elem_location:
77 case DW_AT_string_length:
78 case DW_AT_use_location:
79 case DW_AT_frame_base:
80 case DW_AT_return_addr:
81 case DW_AT_static_link:
82 case DW_AT_segment:
83 case DW_AT_GNU_call_site_value:
84 case DW_AT_GNU_call_site_data_value:
85 case DW_AT_GNU_call_site_target:
86 case DW_AT_GNU_call_site_target_clobbered:
87 break;
88
89 default:
90 __libdw_seterrno (DWARF_E_NO_LOC_VALUE);
91 return false;
92 }
93
94 return true;
95 }
96
97
98 struct loclist
99 {
100 uint8_t atom;
101 Dwarf_Word number;
102 Dwarf_Word number2;
103 Dwarf_Word offset;
104 struct loclist *next;
105 };
106
107
108 static int
loc_compare(const void * p1,const void * p2)109 loc_compare (const void *p1, const void *p2)
110 {
111 const struct loc_s *l1 = (const struct loc_s *) p1;
112 const struct loc_s *l2 = (const struct loc_s *) p2;
113
114 if ((uintptr_t) l1->addr < (uintptr_t) l2->addr)
115 return -1;
116 if ((uintptr_t) l1->addr > (uintptr_t) l2->addr)
117 return 1;
118
119 return 0;
120 }
121
122 /* For each DW_OP_implicit_value, we store a special entry in the cache.
123 This points us directly to the block data for later fetching.
124 Returns zero on success, -1 on bad DWARF or 1 if tsearch failed. */
125 static int
store_implicit_value(Dwarf * dbg,void ** cache,Dwarf_Op * op)126 store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op)
127 {
128 if (dbg == NULL)
129 return -1;
130 struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s,
131 sizeof (struct loc_block_s), 1);
132 const unsigned char *data = (const unsigned char *) (uintptr_t) op->number2;
133 /* Skip the block length. */
134 __libdw_get_uleb128_unchecked (&data);
135 block->addr = op;
136 block->data = (unsigned char *) data;
137 block->length = op->number;
138 if (unlikely (tsearch (block, cache, loc_compare) == NULL))
139 return 1;
140 return 0;
141 }
142
143 int
dwarf_getlocation_implicit_value(Dwarf_Attribute * attr,const Dwarf_Op * op,Dwarf_Block * return_block)144 dwarf_getlocation_implicit_value (Dwarf_Attribute *attr, const Dwarf_Op *op,
145 Dwarf_Block *return_block)
146 {
147 if (attr == NULL)
148 return -1;
149
150 struct loc_block_s fake = { .addr = (void *) op };
151 struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
152 if (unlikely (found == NULL))
153 {
154 __libdw_seterrno (DWARF_E_NO_BLOCK);
155 return -1;
156 }
157
158 return_block->length = (*found)->length;
159 return_block->data = (*found)->data;
160 return 0;
161 }
162
163 /* If the given attribute is DW_AT_data_member_location and it has constant
164 form then create a fake location using DW_OP_plus_uconst and the offset
165 value. On success returns zero and fills in llbuf (when not NULL) and
166 sets listlen to 1. Returns 1 when this isn't a DW_AT_data_member_location
167 offset. Returns -1 and sets dwarf_errno on failure (bad DWARF data). */
168 static int
is_constant_offset(Dwarf_Attribute * attr,Dwarf_Op ** llbuf,size_t * listlen)169 is_constant_offset (Dwarf_Attribute *attr,
170 Dwarf_Op **llbuf, size_t *listlen)
171 {
172 if (attr->code != DW_AT_data_member_location)
173 return 1;
174
175 switch (attr->form)
176 {
177 /* Punt for any non-constant form. */
178 default:
179 return 1;
180
181 /* Note, we don't regard DW_FORM_data16 as a constant form,
182 even though technically it is according to the standard. */
183 case DW_FORM_data1:
184 case DW_FORM_data2:
185 case DW_FORM_data4:
186 case DW_FORM_data8:
187 case DW_FORM_sdata:
188 case DW_FORM_udata:
189 break;
190 }
191
192 /* Check whether we already cached this location. */
193 struct loc_s fake = { .addr = attr->valp };
194 struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
195
196 if (found == NULL)
197 {
198 Dwarf_Word offset;
199 if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
200 return -1;
201
202 Dwarf_Op *result = libdw_alloc (attr->cu->dbg,
203 Dwarf_Op, sizeof (Dwarf_Op), 1);
204
205 result->atom = DW_OP_plus_uconst;
206 result->number = offset;
207 result->number2 = 0;
208 result->offset = 0;
209
210 /* Insert a record in the search tree so we can find it again later. */
211 struct loc_s *newp = libdw_alloc (attr->cu->dbg,
212 struct loc_s, sizeof (struct loc_s),
213 1);
214 newp->addr = attr->valp;
215 newp->loc = result;
216 newp->nloc = 1;
217
218 found = tsearch (newp, &attr->cu->locs, loc_compare);
219 }
220
221 assert ((*found)->nloc == 1);
222
223 if (llbuf != NULL)
224 {
225 *llbuf = (*found)->loc;
226 *listlen = 1;
227 }
228
229 return 0;
230 }
231
232 int
233 internal_function
__libdw_intern_expression(Dwarf * dbg,bool other_byte_order,unsigned int address_size,unsigned int ref_size,void ** cache,const Dwarf_Block * block,bool cfap,bool valuep,Dwarf_Op ** llbuf,size_t * listlen,int sec_index)234 __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
235 unsigned int address_size, unsigned int ref_size,
236 void **cache, const Dwarf_Block *block,
237 bool cfap, bool valuep,
238 Dwarf_Op **llbuf, size_t *listlen, int sec_index)
239 {
240 /* Empty location expressions don't have any ops to intern. */
241 if (block->length == 0)
242 {
243 *listlen = 0;
244 return 0;
245 }
246
247 /* Check whether we already looked at this list. */
248 struct loc_s fake = { .addr = block->data };
249 struct loc_s **found = tfind (&fake, cache, loc_compare);
250 if (found != NULL)
251 {
252 /* We already saw it. */
253 *llbuf = (*found)->loc;
254 *listlen = (*found)->nloc;
255
256 if (valuep)
257 {
258 assert (*listlen > 1);
259 assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value);
260 }
261
262 return 0;
263 }
264
265 const unsigned char *data = block->data;
266 const unsigned char *const end_data = data + block->length;
267
268 const struct { bool other_byte_order; } bo = { other_byte_order };
269
270 struct loclist *loclist = NULL;
271 unsigned int n = 0;
272
273 /* Stack allocate at most this many locs. */
274 #define MAX_STACK_LOCS 256
275 struct loclist stack_locs[MAX_STACK_LOCS];
276 #define NEW_LOC() ({ struct loclist *ll; \
277 ll = (likely (n < MAX_STACK_LOCS) \
278 ? &stack_locs[n] \
279 : malloc (sizeof (struct loclist))); \
280 if (unlikely (ll == NULL)) \
281 goto nomem; \
282 n++; \
283 ll->next = loclist; \
284 loclist = ll; \
285 ll; })
286
287 if (cfap)
288 {
289 /* Synthesize the operation to push the CFA before the expression. */
290 struct loclist *newloc = NEW_LOC ();
291 newloc->atom = DW_OP_call_frame_cfa;
292 newloc->number = 0;
293 newloc->number2 = 0;
294 newloc->offset = -1;
295 }
296
297 /* Decode the opcodes. It is possible in some situations to have a
298 block of size zero. */
299 while (data < end_data)
300 {
301 struct loclist *newloc;
302 newloc = NEW_LOC ();
303 newloc->number = 0;
304 newloc->number2 = 0;
305 newloc->offset = data - block->data;
306
307 switch ((newloc->atom = *data++))
308 {
309 case DW_OP_addr:
310 /* Address, depends on address size of CU. */
311 if (dbg == NULL)
312 {
313 // XXX relocation?
314 if (address_size == 4)
315 {
316 if (unlikely (data + 4 > end_data))
317 goto invalid;
318 else
319 newloc->number = read_4ubyte_unaligned_inc (&bo, data);
320 }
321 else
322 {
323 if (unlikely (data + 8 > end_data))
324 goto invalid;
325 else
326 newloc->number = read_8ubyte_unaligned_inc (&bo, data);
327 }
328 }
329 else if (__libdw_read_address_inc (dbg, sec_index, &data,
330 address_size, &newloc->number))
331 goto invalid;
332 break;
333
334 case DW_OP_call_ref:
335 case DW_OP_GNU_variable_value:
336 /* DW_FORM_ref_addr, depends on offset size of CU. */
337 if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data,
338 ref_size,
339 &newloc->number,
340 IDX_debug_info, 0))
341 goto invalid;
342 break;
343
344 case DW_OP_deref:
345 case DW_OP_dup:
346 case DW_OP_drop:
347 case DW_OP_over:
348 case DW_OP_swap:
349 case DW_OP_rot:
350 case DW_OP_xderef:
351 case DW_OP_abs:
352 case DW_OP_and:
353 case DW_OP_div:
354 case DW_OP_minus:
355 case DW_OP_mod:
356 case DW_OP_mul:
357 case DW_OP_neg:
358 case DW_OP_not:
359 case DW_OP_or:
360 case DW_OP_plus:
361 case DW_OP_shl:
362 case DW_OP_shr:
363 case DW_OP_shra:
364 case DW_OP_xor:
365 case DW_OP_eq:
366 case DW_OP_ge:
367 case DW_OP_gt:
368 case DW_OP_le:
369 case DW_OP_lt:
370 case DW_OP_ne:
371 case DW_OP_lit0 ... DW_OP_lit31:
372 case DW_OP_reg0 ... DW_OP_reg31:
373 case DW_OP_nop:
374 case DW_OP_push_object_address:
375 case DW_OP_call_frame_cfa:
376 case DW_OP_form_tls_address:
377 case DW_OP_GNU_push_tls_address:
378 case DW_OP_stack_value:
379 /* No operand. */
380 break;
381
382 case DW_OP_const1u:
383 case DW_OP_pick:
384 case DW_OP_deref_size:
385 case DW_OP_xderef_size:
386 if (unlikely (data >= end_data))
387 {
388 invalid:
389 __libdw_seterrno (DWARF_E_INVALID_DWARF);
390 returnmem:
391 /* Free any dynamically allocated loclists, if any. */
392 while (n > MAX_STACK_LOCS)
393 {
394 struct loclist *loc = loclist;
395 loclist = loc->next;
396 free (loc);
397 n--;
398 }
399 return -1;
400 }
401
402 newloc->number = *data++;
403 break;
404
405 case DW_OP_const1s:
406 if (unlikely (data >= end_data))
407 goto invalid;
408
409 newloc->number = *((int8_t *) data);
410 ++data;
411 break;
412
413 case DW_OP_const2u:
414 if (unlikely (data + 2 > end_data))
415 goto invalid;
416
417 newloc->number = read_2ubyte_unaligned_inc (&bo, data);
418 break;
419
420 case DW_OP_const2s:
421 case DW_OP_skip:
422 case DW_OP_bra:
423 case DW_OP_call2:
424 if (unlikely (data + 2 > end_data))
425 goto invalid;
426
427 newloc->number = read_2sbyte_unaligned_inc (&bo, data);
428 break;
429
430 case DW_OP_const4u:
431 if (unlikely (data + 4 > end_data))
432 goto invalid;
433
434 newloc->number = read_4ubyte_unaligned_inc (&bo, data);
435 break;
436
437 case DW_OP_const4s:
438 case DW_OP_call4:
439 case DW_OP_GNU_parameter_ref:
440 if (unlikely (data + 4 > end_data))
441 goto invalid;
442
443 newloc->number = read_4sbyte_unaligned_inc (&bo, data);
444 break;
445
446 case DW_OP_const8u:
447 if (unlikely (data + 8 > end_data))
448 goto invalid;
449
450 newloc->number = read_8ubyte_unaligned_inc (&bo, data);
451 break;
452
453 case DW_OP_const8s:
454 if (unlikely (data + 8 > end_data))
455 goto invalid;
456
457 newloc->number = read_8sbyte_unaligned_inc (&bo, data);
458 break;
459
460 case DW_OP_constu:
461 case DW_OP_plus_uconst:
462 case DW_OP_regx:
463 case DW_OP_piece:
464 case DW_OP_convert:
465 case DW_OP_GNU_convert:
466 case DW_OP_reinterpret:
467 case DW_OP_GNU_reinterpret:
468 case DW_OP_addrx:
469 case DW_OP_GNU_addr_index:
470 case DW_OP_constx:
471 case DW_OP_GNU_const_index:
472 get_uleb128 (newloc->number, data, end_data);
473 break;
474
475 case DW_OP_consts:
476 case DW_OP_breg0 ... DW_OP_breg31:
477 case DW_OP_fbreg:
478 get_sleb128 (newloc->number, data, end_data);
479 break;
480
481 case DW_OP_bregx:
482 get_uleb128 (newloc->number, data, end_data);
483 if (unlikely (data >= end_data))
484 goto invalid;
485 get_sleb128 (newloc->number2, data, end_data);
486 break;
487
488 case DW_OP_bit_piece:
489 case DW_OP_regval_type:
490 case DW_OP_GNU_regval_type:
491 get_uleb128 (newloc->number, data, end_data);
492 if (unlikely (data >= end_data))
493 goto invalid;
494 get_uleb128 (newloc->number2, data, end_data);
495 break;
496
497 case DW_OP_implicit_value:
498 case DW_OP_entry_value:
499 case DW_OP_GNU_entry_value:
500 /* This cannot be used in a CFI expression. */
501 if (unlikely (dbg == NULL))
502 goto invalid;
503
504 /* start of block inc. len. */
505 newloc->number2 = (Dwarf_Word) (uintptr_t) data;
506 get_uleb128 (newloc->number, data, end_data); /* Block length. */
507 if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number))
508 goto invalid;
509 data += newloc->number; /* Skip the block. */
510 break;
511
512 case DW_OP_implicit_pointer:
513 case DW_OP_GNU_implicit_pointer:
514 /* DW_FORM_ref_addr, depends on offset size of CU. */
515 if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data,
516 ref_size,
517 &newloc->number,
518 IDX_debug_info, 0))
519 goto invalid;
520 if (unlikely (data >= end_data))
521 goto invalid;
522 get_uleb128 (newloc->number2, data, end_data); /* Byte offset. */
523 break;
524
525 case DW_OP_deref_type:
526 case DW_OP_GNU_deref_type:
527 case DW_OP_xderef_type:
528 if (unlikely (data + 1 >= end_data))
529 goto invalid;
530 newloc->number = *data++;
531 get_uleb128 (newloc->number2, data, end_data);
532 break;
533
534 case DW_OP_const_type:
535 case DW_OP_GNU_const_type:
536 {
537 size_t size;
538 get_uleb128 (newloc->number, data, end_data);
539 if (unlikely (data >= end_data))
540 goto invalid;
541
542 /* start of block inc. len. */
543 newloc->number2 = (Dwarf_Word) (uintptr_t) data;
544 size = *data++;
545 if (unlikely ((Dwarf_Word) (end_data - data) < size))
546 goto invalid;
547 data += size; /* Skip the block. */
548 }
549 break;
550
551 default:
552 goto invalid;
553 }
554 }
555
556 if (unlikely (n == 0))
557 {
558 /* This is not allowed.
559 It would mean an empty location expression, which we handled
560 already as a special case above. */
561 goto invalid;
562 }
563
564 if (valuep)
565 {
566 struct loclist *newloc = NEW_LOC ();
567 newloc->atom = DW_OP_stack_value;
568 newloc->number = 0;
569 newloc->number2 = 0;
570 newloc->offset = data - block->data;
571 }
572
573 /* Allocate the array. */
574 Dwarf_Op *result;
575 if (dbg != NULL)
576 result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n);
577 else
578 {
579 result = malloc (sizeof *result * n);
580 if (result == NULL)
581 {
582 nomem:
583 __libdw_seterrno (DWARF_E_NOMEM);
584 goto returnmem;
585 }
586 }
587
588 /* Store the result. */
589 *llbuf = result;
590 *listlen = n;
591
592 do
593 {
594 /* We populate the array from the back since the list is backwards. */
595 --n;
596 result[n].atom = loclist->atom;
597 result[n].number = loclist->number;
598 result[n].number2 = loclist->number2;
599 result[n].offset = loclist->offset;
600
601 if (result[n].atom == DW_OP_implicit_value)
602 {
603 int store = store_implicit_value (dbg, cache, &result[n]);
604 if (unlikely (store != 0))
605 {
606 if (store < 0)
607 goto invalid;
608 else
609 goto nomem;
610 }
611 }
612
613 struct loclist *loc = loclist;
614 loclist = loclist->next;
615 if (unlikely (n + 1 > MAX_STACK_LOCS))
616 free (loc);
617 }
618 while (n > 0);
619
620 /* Insert a record in the search tree so that we can find it again later. */
621 struct loc_s *newp;
622 if (dbg != NULL)
623 newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1);
624 else
625 {
626 newp = malloc (sizeof *newp);
627 if (newp == NULL)
628 {
629 free (result);
630 goto nomem;
631 }
632 }
633
634 newp->addr = block->data;
635 newp->loc = result;
636 newp->nloc = *listlen;
637 (void) tsearch (newp, cache, loc_compare);
638
639 /* We did it. */
640 return 0;
641 }
642
643 static int
getlocation(struct Dwarf_CU * cu,const Dwarf_Block * block,Dwarf_Op ** llbuf,size_t * listlen,int sec_index)644 getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
645 Dwarf_Op **llbuf, size_t *listlen, int sec_index)
646 {
647 /* Empty location expressions don't have any ops to intern.
648 Note that synthetic empty_cu doesn't have an associated DWARF dbg. */
649 if (block->length == 0)
650 {
651 *listlen = 0;
652 return 0;
653 }
654
655 return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
656 cu->address_size, (cu->version == 2
657 ? cu->address_size
658 : cu->offset_size),
659 &cu->locs, block,
660 false, false,
661 llbuf, listlen, sec_index);
662 }
663
664 int
dwarf_getlocation(Dwarf_Attribute * attr,Dwarf_Op ** llbuf,size_t * listlen)665 dwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **llbuf, size_t *listlen)
666 {
667 if (! attr_ok (attr))
668 return -1;
669
670 int result = is_constant_offset (attr, llbuf, listlen);
671 if (result != 1)
672 return result; /* Either success 0, or -1 to indicate error. */
673
674 /* If it has a block form, it's a single location expression.
675 Except for DW_FORM_data16, which is a 128bit constant. */
676 if (attr->form == DW_FORM_data16)
677 {
678 __libdw_seterrno (DWARF_E_NO_BLOCK);
679 return -1;
680 }
681 Dwarf_Block block;
682 if (INTUSE(dwarf_formblock) (attr, &block) != 0)
683 return -1;
684
685 return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu));
686 }
687
688 Dwarf_Addr
__libdw_cu_base_address(Dwarf_CU * cu)689 __libdw_cu_base_address (Dwarf_CU *cu)
690 {
691 if (cu->base_address == (Dwarf_Addr) -1)
692 {
693 Dwarf_Addr base;
694
695 /* Fetch the CU's base address. */
696 Dwarf_Die cudie = CUDIE (cu);
697
698 /* Find the base address of the compilation unit. It will
699 normally be specified by DW_AT_low_pc. In DWARF-3 draft 4,
700 the base address could be overridden by DW_AT_entry_pc. It's
701 been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
702 for compilation units with discontinuous ranges. */
703 Dwarf_Attribute attr_mem;
704 if (INTUSE(dwarf_lowpc) (&cudie, &base) != 0
705 && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
706 DW_AT_entry_pc,
707 &attr_mem),
708 &base) != 0)
709 {
710 /* The compiler provided no base address when it should
711 have. Buggy GCC does this when it used absolute
712 addresses in the location list and no DW_AT_ranges. */
713 base = 0;
714 }
715 cu->base_address = base;
716 }
717
718 return cu->base_address;
719 }
720
721 static int
initial_offset(Dwarf_Attribute * attr,ptrdiff_t * offset)722 initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset)
723 {
724 size_t secidx = (attr->cu->version < 5
725 ? IDX_debug_loc : IDX_debug_loclists);
726
727 Dwarf_Word start_offset;
728 if (attr->form == DW_FORM_loclistx)
729 {
730 Dwarf_Word idx;
731 Dwarf_CU *cu = attr->cu;
732 const unsigned char *datap = attr->valp;
733 const unsigned char *endp = cu->endp;
734 if (datap >= endp)
735 {
736 __libdw_seterrno (DWARF_E_INVALID_DWARF);
737 return -1;
738 }
739 get_uleb128 (idx, datap, endp);
740
741 Elf_Data *data = cu->dbg->sectiondata[secidx];
742 if (data == NULL && cu->unit_type == DW_UT_split_compile)
743 {
744 cu = __libdw_find_split_unit (cu);
745 if (cu != NULL)
746 data = cu->dbg->sectiondata[secidx];
747 }
748
749 if (data == NULL)
750 {
751 __libdw_seterrno (secidx == IDX_debug_loc
752 ? DWARF_E_NO_DEBUG_LOC
753 : DWARF_E_NO_DEBUG_LOCLISTS);
754 return -1;
755 }
756
757 Dwarf_Off loc_base_off = __libdw_cu_locs_base (cu);
758
759 /* The section should at least contain room for one offset. */
760 size_t sec_size = cu->dbg->sectiondata[secidx]->d_size;
761 size_t offset_size = cu->offset_size;
762 if (offset_size > sec_size)
763 {
764 invalid_offset:
765 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
766 return -1;
767 }
768
769 /* And the base offset should be at least inside the section. */
770 if (loc_base_off > (sec_size - offset_size))
771 goto invalid_offset;
772
773 size_t max_idx = (sec_size - offset_size - loc_base_off) / offset_size;
774 if (idx > max_idx)
775 goto invalid_offset;
776
777 datap = (cu->dbg->sectiondata[secidx]->d_buf
778 + loc_base_off + (idx * offset_size));
779 if (offset_size == 4)
780 start_offset = read_4ubyte_unaligned (cu->dbg, datap);
781 else
782 start_offset = read_8ubyte_unaligned (cu->dbg, datap);
783
784 start_offset += loc_base_off;
785 }
786 else
787 {
788 if (__libdw_formptr (attr, secidx,
789 (secidx == IDX_debug_loc
790 ? DWARF_E_NO_DEBUG_LOC
791 : DWARF_E_NO_DEBUG_LOCLISTS),
792 NULL, &start_offset) == NULL)
793 return -1;
794 }
795
796 *offset = start_offset;
797 return 0;
798 }
799
800 static ptrdiff_t
getlocations_addr(Dwarf_Attribute * attr,ptrdiff_t offset,Dwarf_Addr * basep,Dwarf_Addr * startp,Dwarf_Addr * endp,Dwarf_Addr address,const Elf_Data * locs,Dwarf_Op ** expr,size_t * exprlen)801 getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset,
802 Dwarf_Addr *basep, Dwarf_Addr *startp, Dwarf_Addr *endp,
803 Dwarf_Addr address, const Elf_Data *locs, Dwarf_Op **expr,
804 size_t *exprlen)
805 {
806 Dwarf_CU *cu = attr->cu;
807 Dwarf *dbg = cu->dbg;
808 size_t secidx = cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists;
809 const unsigned char *readp = locs->d_buf + offset;
810 const unsigned char *readendp = locs->d_buf + locs->d_size;
811
812 Dwarf_Addr begin;
813 Dwarf_Addr end;
814
815 next:
816 switch (__libdw_read_begin_end_pair_inc (cu, secidx,
817 &readp, readendp,
818 cu->address_size,
819 &begin, &end, basep))
820 {
821 case 0: /* got location range. */
822 break;
823 case 1: /* base address setup. */
824 goto next;
825 case 2: /* end of loclist */
826 return 0;
827 default: /* error */
828 return -1;
829 }
830
831 /* We have a location expression. */
832 Dwarf_Block block;
833 if (secidx == IDX_debug_loc)
834 {
835 if (readendp - readp < 2)
836 {
837 invalid:
838 __libdw_seterrno (DWARF_E_INVALID_DWARF);
839 return -1;
840 }
841 block.length = read_2ubyte_unaligned_inc (dbg, readp);
842 }
843 else
844 {
845 if (readendp - readp < 1)
846 goto invalid;
847 get_uleb128 (block.length, readp, readendp);
848 }
849 block.data = (unsigned char *) readp;
850 if (readendp - readp < (ptrdiff_t) block.length)
851 goto invalid;
852 readp += block.length;
853
854 /* Note these addresses include any base (if necessary) already. */
855 *startp = begin;
856 *endp = end;
857
858 /* If address is minus one we want them all, otherwise only matching. */
859 if (address != (Dwarf_Word) -1 && (address < *startp || address >= *endp))
860 goto next;
861
862 if (getlocation (cu, &block, expr, exprlen, secidx) != 0)
863 return -1;
864
865 return readp - (unsigned char *) locs->d_buf;
866 }
867
868 int
dwarf_getlocation_addr(Dwarf_Attribute * attr,Dwarf_Addr address,Dwarf_Op ** llbufs,size_t * listlens,size_t maxlocs)869 dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address,
870 Dwarf_Op **llbufs, size_t *listlens, size_t maxlocs)
871 {
872 if (! attr_ok (attr))
873 return -1;
874
875 if (llbufs == NULL)
876 maxlocs = SIZE_MAX;
877
878 /* If it has a block form, it's a single location expression.
879 Except for DW_FORM_data16, which is a 128bit constant. */
880 Dwarf_Block block;
881 if (attr->form != DW_FORM_data16
882 && INTUSE(dwarf_formblock) (attr, &block) == 0)
883 {
884 if (maxlocs == 0)
885 return 0;
886 if (llbufs != NULL &&
887 getlocation (attr->cu, &block, &llbufs[0], &listlens[0],
888 cu_sec_idx (attr->cu)) != 0)
889 return -1;
890 return listlens[0] == 0 ? 0 : 1;
891 }
892
893 if (attr->form != DW_FORM_data16)
894 {
895 int error = INTUSE(dwarf_errno) ();
896 if (unlikely (error != DWARF_E_NO_BLOCK))
897 {
898 __libdw_seterrno (error);
899 return -1;
900 }
901 }
902
903 /* If is_constant_offset is successful, we are done with 1 result. */
904 int result = is_constant_offset (attr, llbufs, listlens);
905 if (result != 1)
906 return result ?: 1;
907
908 Dwarf_Addr base, start, end;
909 Dwarf_Op *expr;
910 size_t expr_len;
911 ptrdiff_t off = 0;
912 size_t got = 0;
913
914 /* This is a true loclistptr, fetch the initial base address and offset. */
915 base = __libdw_cu_base_address (attr->cu);
916 if (base == (Dwarf_Addr) -1)
917 return -1;
918
919 if (initial_offset (attr, &off) != 0)
920 return -1;
921
922 size_t secidx = attr->cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists;
923 const Elf_Data *d = attr->cu->dbg->sectiondata[secidx];
924
925 while (got < maxlocs
926 && (off = getlocations_addr (attr, off, &base, &start, &end,
927 address, d, &expr, &expr_len)) > 0)
928 {
929 /* This one matches the address. */
930 if (llbufs != NULL)
931 {
932 llbufs[got] = expr;
933 listlens[got] = expr_len;
934 }
935 ++got;
936 }
937
938 /* We might stop early, so off can be zero or positive on success. */
939 if (off < 0)
940 return -1;
941
942 return got;
943 }
944
945 ptrdiff_t
dwarf_getlocations(Dwarf_Attribute * attr,ptrdiff_t offset,Dwarf_Addr * basep,Dwarf_Addr * startp,Dwarf_Addr * endp,Dwarf_Op ** expr,size_t * exprlen)946 dwarf_getlocations (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr *basep,
947 Dwarf_Addr *startp, Dwarf_Addr *endp, Dwarf_Op **expr,
948 size_t *exprlen)
949 {
950 if (! attr_ok (attr))
951 return -1;
952
953 /* 1 is an invalid offset, meaning no more locations. */
954 if (offset == 1)
955 return 0;
956
957 if (offset == 0)
958 {
959 /* If it has a block form, it's a single location expression.
960 Except for DW_FORM_data16, which is a 128bit constant. */
961 Dwarf_Block block;
962 if (attr->form != DW_FORM_data16
963 && INTUSE(dwarf_formblock) (attr, &block) == 0)
964 {
965 if (getlocation (attr->cu, &block, expr, exprlen,
966 cu_sec_idx (attr->cu)) != 0)
967 return -1;
968
969 /* This is the one and only location covering everything. */
970 *startp = 0;
971 *endp = -1;
972 return 1;
973 }
974
975 if (attr->form != DW_FORM_data16)
976 {
977 int error = INTUSE(dwarf_errno) ();
978 if (unlikely (error != DWARF_E_NO_BLOCK))
979 {
980 __libdw_seterrno (error);
981 return -1;
982 }
983 }
984
985 int result = is_constant_offset (attr, expr, exprlen);
986 if (result != 1)
987 {
988 if (result == 0)
989 {
990 /* This is the one and only location covering everything. */
991 *startp = 0;
992 *endp = -1;
993 return 1;
994 }
995 return result; /* Something bad, dwarf_errno has been set. */
996 }
997
998 /* We must be looking at a true loclistptr, fetch the initial
999 base address and offset. */
1000 *basep = __libdw_cu_base_address (attr->cu);
1001 if (*basep == (Dwarf_Addr) -1)
1002 return -1;
1003
1004 if (initial_offset (attr, &offset) != 0)
1005 return -1;
1006 }
1007
1008 size_t secidx = attr->cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists;
1009 const Elf_Data *d = attr->cu->dbg->sectiondata[secidx];
1010
1011 return getlocations_addr (attr, offset, basep, startp, endp,
1012 (Dwarf_Word) -1, d, expr, exprlen);
1013 }
1014