libdwfl: Sanity check partial core file dyn data read.
[platform/upstream/elfutils.git] / libdw / dwarf_getlocation.c
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 }