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