1 /* Return location expression list.
2 Copyright (C) 2000-2010, 2013 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
9 * the GNU Lesser General Public License as published by the Free
10 Software Foundation; either version 3 of the License, or (at
11 your option) any later version
15 * the GNU General Public License as published by the Free
16 Software Foundation; either version 2 of the License, or (at
17 your option) any later version
19 or both in parallel, as here.
21 elfutils is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received copies of the GNU General Public License and
27 the GNU Lesser General Public License along with this program. If
28 not, see <http://www.gnu.org/licenses/>. */
43 attr_ok (Dwarf_Attribute *attr)
48 /* Must be one of the attributes listed below. */
52 case DW_AT_data_member_location:
53 case DW_AT_vtable_elem_location:
54 case DW_AT_string_length:
55 case DW_AT_use_location:
56 case DW_AT_frame_base:
57 case DW_AT_return_addr:
58 case DW_AT_static_link:
63 __libdw_seterrno (DWARF_E_NO_LOCLIST);
82 loc_compare (const void *p1, const void *p2)
84 const struct loc_s *l1 = (const struct loc_s *) p1;
85 const struct loc_s *l2 = (const struct loc_s *) p2;
87 if ((uintptr_t) l1->addr < (uintptr_t) l2->addr)
89 if ((uintptr_t) l1->addr > (uintptr_t) l2->addr)
95 /* For each DW_OP_implicit_value, we store a special entry in the cache.
96 This points us directly to the block data for later fetching. */
98 store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op)
100 struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s,
101 sizeof (struct loc_block_s), 1);
102 const unsigned char *data = (const unsigned char *) (uintptr_t) op->number2;
103 (void) __libdw_get_uleb128 (&data); // Ignored, equal to op->number.
105 block->data = (unsigned char *) data;
106 block->length = op->number;
107 (void) tsearch (block, cache, loc_compare);
111 dwarf_getlocation_implicit_value (attr, op, return_block)
112 Dwarf_Attribute *attr;
114 Dwarf_Block *return_block;
119 struct loc_block_s fake = { .addr = (void *) op };
120 struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
121 if (unlikely (found == NULL))
123 __libdw_seterrno (DWARF_E_NO_BLOCK);
127 return_block->length = (*found)->length;
128 return_block->data = (*found)->data;
132 /* DW_AT_data_member_location can be a constant as well as a loclistptr.
133 Only data[48] indicate a loclistptr. */
135 check_constant_offset (Dwarf_Attribute *attr,
136 Dwarf_Op **llbuf, size_t *listlen)
138 if (attr->code != DW_AT_data_member_location)
143 /* Punt for any non-constant form. */
156 /* Check whether we already cached this location. */
157 struct loc_s fake = { .addr = attr->valp };
158 struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
163 if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
166 Dwarf_Op *result = libdw_alloc (attr->cu->dbg,
167 Dwarf_Op, sizeof (Dwarf_Op), 1);
169 result->atom = DW_OP_plus_uconst;
170 result->number = offset;
174 /* Insert a record in the search tree so we can find it again later. */
175 struct loc_s *newp = libdw_alloc (attr->cu->dbg,
176 struct loc_s, sizeof (struct loc_s),
178 newp->addr = attr->valp;
182 found = tsearch (newp, &attr->cu->locs, loc_compare);
185 assert ((*found)->nloc == 1);
189 *llbuf = (*found)->loc;
198 __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
199 unsigned int address_size, unsigned int ref_size,
200 void **cache, const Dwarf_Block *block,
201 bool cfap, bool valuep,
202 Dwarf_Op **llbuf, size_t *listlen, int sec_index)
204 /* Empty location expressions don't have any ops to intern. */
205 if (block->length == 0)
211 /* Check whether we already looked at this list. */
212 struct loc_s fake = { .addr = block->data };
213 struct loc_s **found = tfind (&fake, cache, loc_compare);
216 /* We already saw it. */
217 *llbuf = (*found)->loc;
218 *listlen = (*found)->nloc;
222 assert (*listlen > 1);
223 assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value);
229 const unsigned char *data = block->data;
230 const unsigned char *const end_data = data + block->length;
232 const struct { bool other_byte_order; } bo = { other_byte_order };
234 struct loclist *loclist = NULL;
239 /* Synthesize the operation to push the CFA before the expression. */
240 struct loclist *newloc;
241 newloc = (struct loclist *) alloca (sizeof (struct loclist));
242 newloc->atom = DW_OP_call_frame_cfa;
246 newloc->next = loclist;
251 /* Decode the opcodes. It is possible in some situations to have a
252 block of size zero. */
253 while (data < end_data)
255 struct loclist *newloc;
256 newloc = (struct loclist *) alloca (sizeof (struct loclist));
259 newloc->offset = data - block->data;
260 newloc->next = loclist;
264 switch ((newloc->atom = *data++))
267 /* Address, depends on address size of CU. */
268 if (__libdw_read_address_inc (dbg, sec_index, &data,
269 address_size, &newloc->number))
274 /* DW_FORM_ref_addr, depends on offset size of CU. */
275 if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
276 &newloc->number, IDX_debug_info, 0))
307 case DW_OP_lit0 ... DW_OP_lit31:
308 case DW_OP_reg0 ... DW_OP_reg31:
310 case DW_OP_push_object_address:
311 case DW_OP_call_frame_cfa:
312 case DW_OP_form_tls_address:
313 case DW_OP_GNU_push_tls_address:
314 case DW_OP_stack_value:
320 case DW_OP_deref_size:
321 case DW_OP_xderef_size:
322 if (unlikely (data >= end_data))
325 __libdw_seterrno (DWARF_E_INVALID_DWARF);
329 newloc->number = *data++;
333 if (unlikely (data >= end_data))
336 newloc->number = *((int8_t *) data);
341 if (unlikely (data + 2 > end_data))
344 newloc->number = read_2ubyte_unaligned_inc (&bo, data);
351 if (unlikely (data + 2 > end_data))
354 newloc->number = read_2sbyte_unaligned_inc (&bo, data);
358 if (unlikely (data + 4 > end_data))
361 newloc->number = read_4ubyte_unaligned_inc (&bo, data);
366 case DW_OP_GNU_parameter_ref:
367 if (unlikely (data + 4 > end_data))
370 newloc->number = read_4sbyte_unaligned_inc (&bo, data);
374 if (unlikely (data + 8 > end_data))
377 newloc->number = read_8ubyte_unaligned_inc (&bo, data);
381 if (unlikely (data + 8 > end_data))
384 newloc->number = read_8sbyte_unaligned_inc (&bo, data);
388 case DW_OP_plus_uconst:
391 case DW_OP_GNU_convert:
392 case DW_OP_GNU_reinterpret:
393 /* XXX Check size. */
394 get_uleb128 (newloc->number, data);
398 case DW_OP_breg0 ... DW_OP_breg31:
400 /* XXX Check size. */
401 get_sleb128 (newloc->number, data);
405 /* XXX Check size. */
406 get_uleb128 (newloc->number, data);
407 get_sleb128 (newloc->number2, data);
410 case DW_OP_bit_piece:
411 case DW_OP_GNU_regval_type:
412 /* XXX Check size. */
413 get_uleb128 (newloc->number, data);
414 get_uleb128 (newloc->number2, data);
417 case DW_OP_implicit_value:
418 case DW_OP_GNU_entry_value:
419 /* This cannot be used in a CFI expression. */
420 if (unlikely (dbg == NULL))
423 /* start of block inc. len. */
424 newloc->number2 = (Dwarf_Word) (uintptr_t) data;
425 /* XXX Check size. */
426 get_uleb128 (newloc->number, data); /* Block length. */
427 if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number))
429 data += newloc->number; /* Skip the block. */
432 case DW_OP_GNU_implicit_pointer:
433 /* DW_FORM_ref_addr, depends on offset size of CU. */
434 if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
435 &newloc->number, IDX_debug_info, 0))
437 /* XXX Check size. */
438 get_uleb128 (newloc->number2, data); /* Byte offset. */
441 case DW_OP_GNU_deref_type:
442 if (unlikely (data >= end_data))
444 newloc->number = *data++;
445 get_uleb128 (newloc->number2, data);
448 case DW_OP_GNU_const_type:
452 /* XXX Check size. */
453 get_uleb128 (newloc->number, data);
454 if (unlikely (data >= end_data))
457 /* start of block inc. len. */
458 newloc->number2 = (Dwarf_Word) (uintptr_t) data;
460 if (unlikely ((Dwarf_Word) (end_data - data) < size))
462 data += size; /* Skip the block. */
471 if (unlikely (n == 0))
473 /* This is not allowed.
474 It would mean an empty location expression, which we handled
475 already as a special case above. */
481 struct loclist *newloc;
482 newloc = (struct loclist *) alloca (sizeof (struct loclist));
483 newloc->atom = DW_OP_stack_value;
486 newloc->offset = data - block->data;
487 newloc->next = loclist;
492 /* Allocate the array. */
495 result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n);
498 result = malloc (sizeof *result * n);
502 __libdw_seterrno (DWARF_E_NOMEM);
507 /* Store the result. */
513 /* We populate the array from the back since the list is backwards. */
515 result[n].atom = loclist->atom;
516 result[n].number = loclist->number;
517 result[n].number2 = loclist->number2;
518 result[n].offset = loclist->offset;
520 if (result[n].atom == DW_OP_implicit_value)
521 store_implicit_value (dbg, cache, &result[n]);
523 loclist = loclist->next;
527 /* Insert a record in the search tree so that we can find it again later. */
530 newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1);
533 newp = malloc (sizeof *newp);
541 newp->addr = block->data;
543 newp->nloc = *listlen;
544 (void) tsearch (newp, cache, loc_compare);
551 getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
552 Dwarf_Op **llbuf, size_t *listlen, int sec_index)
554 return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
555 cu->address_size, (cu->version == 2
560 llbuf, listlen, sec_index);
564 dwarf_getlocation (attr, llbuf, listlen)
565 Dwarf_Attribute *attr;
569 if (! attr_ok (attr))
572 int result = check_constant_offset (attr, llbuf, listlen);
576 /* If it has a block form, it's a single location expression. */
578 if (INTUSE(dwarf_formblock) (attr, &block) != 0)
581 return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu));
585 attr_base_address (attr, basep)
586 Dwarf_Attribute *attr;
589 /* Fetch the CU's base address. */
590 Dwarf_Die cudie = CUDIE (attr->cu);
592 /* Find the base address of the compilation unit. It will
593 normally be specified by DW_AT_low_pc. In DWARF-3 draft 4,
594 the base address could be overridden by DW_AT_entry_pc. It's
595 been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
596 for compilation units with discontinuous ranges. */
597 Dwarf_Attribute attr_mem;
598 if (unlikely (INTUSE(dwarf_lowpc) (&cudie, basep) != 0)
599 && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
604 if (INTUSE(dwarf_errno) () != 0)
607 /* The compiler provided no base address when it should
608 have. Buggy GCC does this when it used absolute
609 addresses in the location list and no DW_AT_ranges. */
616 initial_offset_base (attr, offset, basep)
617 Dwarf_Attribute *attr;
621 if (attr_base_address (attr, basep) != 0)
624 Dwarf_Word start_offset;
625 if (__libdw_formptr (attr, IDX_debug_loc,
627 NULL, &start_offset) == NULL)
630 *offset = start_offset;
635 getlocations_addr (attr, offset, basep, startp, endp, address,
637 Dwarf_Attribute *attr;
647 unsigned char *readp = locs->d_buf + offset;
648 unsigned char *readendp = locs->d_buf + locs->d_size;
651 if (readendp - readp < attr->cu->address_size * 2)
654 __libdw_seterrno (DWARF_E_INVALID_DWARF);
661 switch (__libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc,
662 &readp, attr->cu->address_size,
663 &begin, &end, basep))
665 case 0: /* got location range. */
667 case 1: /* base address setup. */
669 case 2: /* end of loclist */
675 if (readendp - readp < 2)
678 /* We have a location expression. */
680 block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
682 if (readendp - readp < (ptrdiff_t) block.length)
684 readp += block.length;
686 *startp = *basep + begin;
687 *endp = *basep + end;
689 /* If address is minus one we want them all, otherwise only matching. */
690 if (address != (Dwarf_Word) -1 && (address < *startp || address >= *endp))
693 if (getlocation (attr->cu, &block, expr, exprlen, IDX_debug_loc) != 0)
696 return readp - (unsigned char *) locs->d_buf;
700 dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
701 Dwarf_Attribute *attr;
707 if (! attr_ok (attr))
713 /* If it has a block form, it's a single location expression. */
715 if (INTUSE(dwarf_formblock) (attr, &block) == 0)
719 if (llbufs != NULL &&
720 getlocation (attr->cu, &block, &llbufs[0], &listlens[0],
721 cu_sec_idx (attr->cu)) != 0)
723 return listlens[0] == 0 ? 0 : 1;
726 int error = INTUSE(dwarf_errno) ();
727 if (unlikely (error != DWARF_E_NO_BLOCK))
729 __libdw_seterrno (error);
733 int result = check_constant_offset (attr, &llbufs[0], &listlens[0]);
737 Dwarf_Addr base, start, end;
743 /* This is a true loclistptr, fetch the initial base address and offset. */
744 if (initial_offset_base (attr, &off, &base) != 0)
747 const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
750 __libdw_seterrno (DWARF_E_NO_LOCLIST);
755 && (off = getlocations_addr (attr, off, &base, &start, &end,
756 address, d, &expr, &expr_len)) > 0)
758 /* This one matches the address. */
762 listlens[got] = expr_len;
767 /* We might stop early, so off can be zero or positive on success. */
775 dwarf_getlocations (attr, offset, basep, startp, endp, expr, exprlen)
776 Dwarf_Attribute *attr;
784 if (! attr_ok (attr))
787 /* 1 is an invalid offset, meaning no more locations. */
793 /* If it has a block form, it's a single location expression. */
795 if (INTUSE(dwarf_formblock) (attr, &block) == 0)
797 if (getlocation (attr->cu, &block, expr, exprlen,
798 cu_sec_idx (attr->cu)) != 0)
801 /* This is the one and only location covering everything. */
807 int error = INTUSE(dwarf_errno) ();
808 if (unlikely (error != DWARF_E_NO_BLOCK))
810 __libdw_seterrno (error);
814 int result = check_constant_offset (attr, expr, exprlen);
819 /* This is the one and only location covering everything. */
827 /* We must be looking at a true loclistptr, fetch the initial
828 base address and offset. */
829 if (initial_offset_base (attr, &offset, basep) != 0)
833 const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
836 __libdw_seterrno (DWARF_E_NO_LOCLIST);
840 return getlocations_addr (attr, offset, basep, startp, endp,
841 (Dwarf_Word) -1, d, expr, exprlen);