1 /* Return location expression list.
2 Copyright (C) 2000-2010 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:
62 __libdw_seterrno (DWARF_E_NO_LOCLIST);
81 loc_compare (const void *p1, const void *p2)
83 const struct loc_s *l1 = (const struct loc_s *) p1;
84 const struct loc_s *l2 = (const struct loc_s *) p2;
86 if ((uintptr_t) l1->addr < (uintptr_t) l2->addr)
88 if ((uintptr_t) l1->addr > (uintptr_t) l2->addr)
94 /* For each DW_OP_implicit_value, we store a special entry in the cache.
95 This points us directly to the block data for later fetching. */
97 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);
103 block->data = data + op->number2;
104 block->length = op->number;
105 (void) tsearch (block, cache, loc_compare);
109 dwarf_getlocation_implicit_value (attr, op, return_block)
110 Dwarf_Attribute *attr;
112 Dwarf_Block *return_block;
117 struct loc_block_s fake = { .addr = (void *) op };
118 struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
119 if (unlikely (found == NULL))
121 __libdw_seterrno (DWARF_E_NO_BLOCK);
125 return_block->length = (*found)->length;
126 return_block->data = (*found)->data;
130 /* DW_AT_data_member_location can be a constant as well as a loclistptr.
131 Only data[48] indicate a loclistptr. */
133 check_constant_offset (Dwarf_Attribute *attr,
134 Dwarf_Op **llbuf, size_t *listlen)
136 if (attr->code != DW_AT_data_member_location)
141 /* Punt for any non-constant form. */
154 /* Check whether we already cached this location. */
155 struct loc_s fake = { .addr = attr->valp };
156 struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
161 if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
164 Dwarf_Op *result = libdw_alloc (attr->cu->dbg,
165 Dwarf_Op, sizeof (Dwarf_Op), 1);
167 result->atom = DW_OP_plus_uconst;
168 result->number = offset;
172 /* Insert a record in the search tree so we can find it again later. */
173 struct loc_s *newp = libdw_alloc (attr->cu->dbg,
174 struct loc_s, sizeof (struct loc_s),
176 newp->addr = attr->valp;
180 found = tsearch (newp, &attr->cu->locs, loc_compare);
183 assert ((*found)->nloc == 1);
187 *llbuf = (*found)->loc;
196 __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
197 unsigned int address_size, unsigned int ref_size,
198 void **cache, const Dwarf_Block *block,
199 bool cfap, bool valuep,
200 Dwarf_Op **llbuf, size_t *listlen, int sec_index)
202 /* Check whether we already looked at this list. */
203 struct loc_s fake = { .addr = block->data };
204 struct loc_s **found = tfind (&fake, cache, loc_compare);
207 /* We already saw it. */
208 *llbuf = (*found)->loc;
209 *listlen = (*found)->nloc;
213 assert (*listlen > 1);
214 assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value);
220 const unsigned char *data = block->data;
221 const unsigned char *const end_data = data + block->length;
223 const struct { bool other_byte_order; } bo = { other_byte_order };
225 struct loclist *loclist = NULL;
227 /* Decode the opcodes. It is possible in some situations to have a
228 block of size zero. */
229 while (data < end_data)
231 struct loclist *newloc;
232 newloc = (struct loclist *) alloca (sizeof (struct loclist));
235 newloc->offset = data - block->data;
236 newloc->next = loclist;
240 switch ((newloc->atom = *data++))
243 /* Address, depends on address size of CU. */
244 if (__libdw_read_address_inc (dbg, sec_index, &data,
245 address_size, &newloc->number))
250 /* DW_FORM_ref_addr, depends on offset size of CU. */
251 if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
252 &newloc->number, IDX_debug_info, 0))
283 case DW_OP_lit0 ... DW_OP_lit31:
284 case DW_OP_reg0 ... DW_OP_reg31:
286 case DW_OP_push_object_address:
287 case DW_OP_call_frame_cfa:
288 case DW_OP_form_tls_address:
289 case DW_OP_GNU_push_tls_address:
290 case DW_OP_stack_value:
296 case DW_OP_deref_size:
297 case DW_OP_xderef_size:
298 if (unlikely (data >= end_data))
301 __libdw_seterrno (DWARF_E_INVALID_DWARF);
305 newloc->number = *data++;
309 if (unlikely (data >= end_data))
312 newloc->number = *((int8_t *) data);
317 if (unlikely (data + 2 > end_data))
320 newloc->number = read_2ubyte_unaligned_inc (&bo, data);
327 if (unlikely (data + 2 > end_data))
330 newloc->number = read_2sbyte_unaligned_inc (&bo, data);
334 if (unlikely (data + 4 > end_data))
337 newloc->number = read_4ubyte_unaligned_inc (&bo, data);
342 if (unlikely (data + 4 > end_data))
345 newloc->number = read_4sbyte_unaligned_inc (&bo, data);
349 if (unlikely (data + 8 > end_data))
352 newloc->number = read_8ubyte_unaligned_inc (&bo, data);
356 if (unlikely (data + 8 > end_data))
359 newloc->number = read_8sbyte_unaligned_inc (&bo, data);
363 case DW_OP_plus_uconst:
366 /* XXX Check size. */
367 get_uleb128 (newloc->number, data);
371 case DW_OP_breg0 ... DW_OP_breg31:
373 /* XXX Check size. */
374 get_sleb128 (newloc->number, data);
378 /* XXX Check size. */
379 get_uleb128 (newloc->number, data);
380 get_sleb128 (newloc->number2, data);
383 case DW_OP_bit_piece:
384 /* XXX Check size. */
385 get_uleb128 (newloc->number, data);
386 get_uleb128 (newloc->number2, data);
389 case DW_OP_implicit_value:
390 /* This cannot be used in a CFI expression. */
391 if (unlikely (dbg == NULL))
394 /* XXX Check size. */
395 get_uleb128 (newloc->number, data); /* Block length. */
396 if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number))
398 newloc->number2 = data - block->data; /* Relative block offset. */
399 data += newloc->number; /* Skip the block. */
402 case DW_OP_GNU_implicit_pointer:
403 /* DW_FORM_ref_addr, depends on offset size of CU. */
404 if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
405 &newloc->number, IDX_debug_info, 0))
407 /* XXX Check size. */
408 get_uleb128 (newloc->number2, data); /* Byte offset. */
416 if (unlikely (n == 0))
418 /* This is not allowed.
426 struct loclist *newloc;
427 newloc = (struct loclist *) alloca (sizeof (struct loclist));
428 newloc->atom = DW_OP_stack_value;
431 newloc->offset = data - block->data;
432 newloc->next = loclist;
440 /* Allocate the array. */
443 result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n);
446 result = malloc (sizeof *result * n);
450 __libdw_seterrno (DWARF_E_NOMEM);
455 /* Store the result. */
461 /* Synthesize the operation to push the CFA before the expression. */
463 result[0].atom = DW_OP_call_frame_cfa;
464 result[0].number = 0;
465 result[0].number2 = 0;
466 result[0].offset = -1;
471 /* We populate the array from the back since the list is backwards. */
473 result[n].atom = loclist->atom;
474 result[n].number = loclist->number;
475 result[n].number2 = loclist->number2;
476 result[n].offset = loclist->offset;
478 if (result[n].atom == DW_OP_implicit_value)
479 store_implicit_value (dbg, cache, &result[n], block->data);
481 loclist = loclist->next;
485 /* Insert a record in the search tree so that we can find it again later. */
488 newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1);
491 newp = malloc (sizeof *newp);
499 newp->addr = block->data;
501 newp->nloc = *listlen;
502 (void) tsearch (newp, cache, loc_compare);
509 getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
510 Dwarf_Op **llbuf, size_t *listlen, int sec_index)
512 return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
513 cu->address_size, (cu->version == 2
518 llbuf, listlen, sec_index);
522 dwarf_getlocation (attr, llbuf, listlen)
523 Dwarf_Attribute *attr;
527 if (! attr_ok (attr))
530 int result = check_constant_offset (attr, llbuf, listlen);
534 /* If it has a block form, it's a single location expression. */
536 if (INTUSE(dwarf_formblock) (attr, &block) != 0)
539 return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu));
543 dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
544 Dwarf_Attribute *attr;
550 if (! attr_ok (attr))
556 /* If it has a block form, it's a single location expression. */
558 if (INTUSE(dwarf_formblock) (attr, &block) == 0)
562 if (llbufs != NULL &&
563 getlocation (attr->cu, &block, &llbufs[0], &listlens[0],
564 cu_sec_idx (attr->cu)) != 0)
566 return listlens[0] == 0 ? 0 : 1;
569 int error = INTUSE(dwarf_errno) ();
570 if (unlikely (error != DWARF_E_NO_BLOCK))
572 __libdw_seterrno (error);
576 int result = check_constant_offset (attr, &llbufs[0], &listlens[0]);
581 unsigned char *readp = __libdw_formptr (attr, IDX_debug_loc,
582 DWARF_E_NO_LOCLIST, &endp, NULL);
586 Dwarf_Addr base = (Dwarf_Addr) -1;
588 while (got < maxlocs)
590 if (endp - readp < attr->cu->address_size * 2)
593 __libdw_seterrno (DWARF_E_INVALID_DWARF);
601 = __libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc,
602 &readp, attr->cu->address_size,
603 &begin, &end, &base);
604 if (status == 2) /* End of list entry. */
606 else if (status == 1) /* Base address selected. */
611 if (endp - readp < 2)
614 /* We have a location expression. */
615 block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
617 if (endp - readp < (ptrdiff_t) block.length)
619 readp += block.length;
621 if (base == (Dwarf_Addr) -1)
623 /* Fetch the CU's base address. */
624 Dwarf_Die cudie = CUDIE (attr->cu);
626 /* Find the base address of the compilation unit. It will
627 normally be specified by DW_AT_low_pc. In DWARF-3 draft 4,
628 the base address could be overridden by DW_AT_entry_pc. It's
629 been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
630 for compilation units with discontinuous ranges. */
631 Dwarf_Attribute attr_mem;
632 if (unlikely (INTUSE(dwarf_lowpc) (&cudie, &base) != 0)
633 && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
638 if (INTUSE(dwarf_errno) () != 0)
641 /* The compiler provided no base address when it should
642 have. Buggy GCC does this when it used absolute
643 addresses in the location list and no DW_AT_ranges. */
648 if (address >= base + begin && address < base + end)
650 /* This one matches the address. */
652 && unlikely (getlocation (attr->cu, &block,
653 &llbufs[got], &listlens[got],
654 IDX_debug_loc) != 0))