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