8dffb83f496f33caa7ea2d1aa1b52aa3d17a9987
[platform/upstream/elfutils.git] / libdw / dwarf_getlocation.c
1 /* Return location expression list.
2    Copyright (C) 2000-2010, 2013 Red Hat, Inc.
3    This file is part of elfutils.
4    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
5
6    This file is free software; you can redistribute it and/or modify
7    it under the terms of either
8
9      * the GNU Lesser General Public License as published by the Free
10        Software Foundation; either version 3 of the License, or (at
11        your option) any later version
12
13    or
14
15      * the GNU General Public License as published by the Free
16        Software Foundation; either version 2 of the License, or (at
17        your option) any later version
18
19    or both in parallel, as here.
20
21    elfutils is distributed in the hope that it will be useful, but
22    WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24    General Public License for more details.
25
26    You should have received copies of the GNU General Public License and
27    the GNU Lesser General Public License along with this program.  If
28    not, see <http://www.gnu.org/licenses/>.  */
29
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
33
34 #include <dwarf.h>
35 #include <search.h>
36 #include <stdlib.h>
37 #include <assert.h>
38
39 #include <libdwP.h>
40
41
42 static bool
43 attr_ok (Dwarf_Attribute *attr)
44 {
45   if (attr == NULL)
46     return false;
47
48   /* Must be one of the attributes listed below.  */
49   switch (attr->code)
50     {
51     case DW_AT_location:
52     case DW_AT_data_member_location:
53     case DW_AT_vtable_elem_location:
54     case DW_AT_string_length:
55     case DW_AT_use_location:
56     case DW_AT_frame_base:
57     case DW_AT_return_addr:
58     case DW_AT_static_link:
59     case DW_AT_segment:
60       break;
61
62     default:
63       __libdw_seterrno (DWARF_E_NO_LOCLIST);
64       return false;
65     }
66
67   return true;
68 }
69
70
71 struct loclist
72 {
73   uint8_t atom;
74   Dwarf_Word number;
75   Dwarf_Word number2;
76   Dwarf_Word offset;
77   struct loclist *next;
78 };
79
80
81 static int
82 loc_compare (const void *p1, const void *p2)
83 {
84   const struct loc_s *l1 = (const struct loc_s *) p1;
85   const struct loc_s *l2 = (const struct loc_s *) p2;
86
87   if ((uintptr_t) l1->addr < (uintptr_t) l2->addr)
88     return -1;
89   if ((uintptr_t) l1->addr > (uintptr_t) l2->addr)
90     return 1;
91
92   return 0;
93 }
94
95 /* For each DW_OP_implicit_value, we store a special entry in the cache.
96    This points us directly to the block data for later fetching.  */
97 static void
98 store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op)
99 {
100   struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s,
101                                            sizeof (struct loc_block_s), 1);
102   const unsigned char *data = (const unsigned char *) (uintptr_t) op->number2;
103   (void) __libdw_get_uleb128 (&data); // Ignored, equal to op->number.
104   block->addr = op;
105   block->data = (unsigned char *) data;
106   block->length = op->number;
107   (void) tsearch (block, cache, loc_compare);
108 }
109
110 int
111 dwarf_getlocation_implicit_value (attr, op, return_block)
112      Dwarf_Attribute *attr;
113      const Dwarf_Op *op;
114      Dwarf_Block *return_block;
115 {
116   if (attr == NULL)
117     return -1;
118
119   struct loc_block_s fake = { .addr = (void *) op };
120   struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
121   if (unlikely (found == NULL))
122     {
123       __libdw_seterrno (DWARF_E_NO_BLOCK);
124       return -1;
125     }
126
127   return_block->length = (*found)->length;
128   return_block->data = (*found)->data;
129   return 0;
130 }
131
132 /* DW_AT_data_member_location can be a constant as well as a loclistptr.
133    Only data[48] indicate a loclistptr.  */
134 static int
135 check_constant_offset (Dwarf_Attribute *attr,
136                        Dwarf_Op **llbuf, size_t *listlen)
137 {
138   if (attr->code != DW_AT_data_member_location)
139     return 1;
140
141   switch (attr->form)
142     {
143       /* Punt for any non-constant form.  */
144     default:
145       return 1;
146
147     case DW_FORM_data1:
148     case DW_FORM_data2:
149     case DW_FORM_data4:
150     case DW_FORM_data8:
151     case DW_FORM_sdata:
152     case DW_FORM_udata:
153       break;
154     }
155
156   /* Check whether we already cached this location.  */
157   struct loc_s fake = { .addr = attr->valp };
158   struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
159
160   if (found == NULL)
161     {
162       Dwarf_Word offset;
163       if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
164         return -1;
165
166       Dwarf_Op *result = libdw_alloc (attr->cu->dbg,
167                                       Dwarf_Op, sizeof (Dwarf_Op), 1);
168
169       result->atom = DW_OP_plus_uconst;
170       result->number = offset;
171       result->number2 = 0;
172       result->offset = 0;
173
174       /* Insert a record in the search tree so we can find it again later.  */
175       struct loc_s *newp = libdw_alloc (attr->cu->dbg,
176                                         struct loc_s, sizeof (struct loc_s),
177                                         1);
178       newp->addr = attr->valp;
179       newp->loc = result;
180       newp->nloc = 1;
181
182       found = tsearch (newp, &attr->cu->locs, loc_compare);
183     }
184
185   assert ((*found)->nloc == 1);
186
187   if (llbuf != NULL)
188     {
189       *llbuf = (*found)->loc;
190       *listlen = 1;
191     }
192
193   return 0;
194 }
195
196 int
197 internal_function
198 __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
199                            unsigned int address_size, unsigned int ref_size,
200                            void **cache, const Dwarf_Block *block,
201                            bool cfap, bool valuep,
202                            Dwarf_Op **llbuf, size_t *listlen, int sec_index)
203 {
204   /* Empty location expressions don't have any ops to intern.  */
205   if (block->length == 0)
206     {
207       *listlen = 0;
208       return 0;
209     }
210
211   /* Check whether we already looked at this list.  */
212   struct loc_s fake = { .addr = block->data };
213   struct loc_s **found = tfind (&fake, cache, loc_compare);
214   if (found != NULL)
215     {
216       /* We already saw it.  */
217       *llbuf = (*found)->loc;
218       *listlen = (*found)->nloc;
219
220       if (valuep)
221         {
222           assert (*listlen > 1);
223           assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value);
224         }
225
226       return 0;
227     }
228
229   const unsigned char *data = block->data;
230   const unsigned char *const end_data = data + block->length;
231
232   const struct { bool other_byte_order; } bo = { other_byte_order };
233
234   struct loclist *loclist = NULL;
235   unsigned int n = 0;
236
237   if (cfap)
238     {
239       /* Synthesize the operation to push the CFA before the expression.  */
240       struct loclist *newloc;
241       newloc = (struct loclist *) alloca (sizeof (struct loclist));
242       newloc->atom = DW_OP_call_frame_cfa;
243       newloc->number = 0;
244       newloc->number2 = 0;
245       newloc->offset = -1;
246       newloc->next = loclist;
247       loclist = newloc;
248       ++n;
249     }
250
251   /* Decode the opcodes.  It is possible in some situations to have a
252      block of size zero.  */
253   while (data < end_data)
254     {
255       struct loclist *newloc;
256       newloc = (struct loclist *) alloca (sizeof (struct loclist));
257       newloc->number = 0;
258       newloc->number2 = 0;
259       newloc->offset = data - block->data;
260       newloc->next = loclist;
261       loclist = newloc;
262       ++n;
263
264       switch ((newloc->atom = *data++))
265         {
266         case DW_OP_addr:
267           /* Address, depends on address size of CU.  */
268           if (__libdw_read_address_inc (dbg, sec_index, &data,
269                                         address_size, &newloc->number))
270             return -1;
271           break;
272
273         case DW_OP_call_ref:
274           /* DW_FORM_ref_addr, depends on offset size of CU.  */
275           if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
276                                        &newloc->number, IDX_debug_info, 0))
277             return -1;
278           break;
279
280         case DW_OP_deref:
281         case DW_OP_dup:
282         case DW_OP_drop:
283         case DW_OP_over:
284         case DW_OP_swap:
285         case DW_OP_rot:
286         case DW_OP_xderef:
287         case DW_OP_abs:
288         case DW_OP_and:
289         case DW_OP_div:
290         case DW_OP_minus:
291         case DW_OP_mod:
292         case DW_OP_mul:
293         case DW_OP_neg:
294         case DW_OP_not:
295         case DW_OP_or:
296         case DW_OP_plus:
297         case DW_OP_shl:
298         case DW_OP_shr:
299         case DW_OP_shra:
300         case DW_OP_xor:
301         case DW_OP_eq:
302         case DW_OP_ge:
303         case DW_OP_gt:
304         case DW_OP_le:
305         case DW_OP_lt:
306         case DW_OP_ne:
307         case DW_OP_lit0 ... DW_OP_lit31:
308         case DW_OP_reg0 ... DW_OP_reg31:
309         case DW_OP_nop:
310         case DW_OP_push_object_address:
311         case DW_OP_call_frame_cfa:
312         case DW_OP_form_tls_address:
313         case DW_OP_GNU_push_tls_address:
314         case DW_OP_stack_value:
315           /* No operand.  */
316           break;
317
318         case DW_OP_const1u:
319         case DW_OP_pick:
320         case DW_OP_deref_size:
321         case DW_OP_xderef_size:
322           if (unlikely (data >= end_data))
323             {
324             invalid:
325               __libdw_seterrno (DWARF_E_INVALID_DWARF);
326               return -1;
327             }
328
329           newloc->number = *data++;
330           break;
331
332         case DW_OP_const1s:
333           if (unlikely (data >= end_data))
334             goto invalid;
335
336           newloc->number = *((int8_t *) data);
337           ++data;
338           break;
339
340         case DW_OP_const2u:
341           if (unlikely (data + 2 > end_data))
342             goto invalid;
343
344           newloc->number = read_2ubyte_unaligned_inc (&bo, data);
345           break;
346
347         case DW_OP_const2s:
348         case DW_OP_skip:
349         case DW_OP_bra:
350         case DW_OP_call2:
351           if (unlikely (data + 2 > end_data))
352             goto invalid;
353
354           newloc->number = read_2sbyte_unaligned_inc (&bo, data);
355           break;
356
357         case DW_OP_const4u:
358           if (unlikely (data + 4 > end_data))
359             goto invalid;
360
361           newloc->number = read_4ubyte_unaligned_inc (&bo, data);
362           break;
363
364         case DW_OP_const4s:
365         case DW_OP_call4:
366         case DW_OP_GNU_parameter_ref:
367           if (unlikely (data + 4 > end_data))
368             goto invalid;
369
370           newloc->number = read_4sbyte_unaligned_inc (&bo, data);
371           break;
372
373         case DW_OP_const8u:
374           if (unlikely (data + 8 > end_data))
375             goto invalid;
376
377           newloc->number = read_8ubyte_unaligned_inc (&bo, data);
378           break;
379
380         case DW_OP_const8s:
381           if (unlikely (data + 8 > end_data))
382             goto invalid;
383
384           newloc->number = read_8sbyte_unaligned_inc (&bo, data);
385           break;
386
387         case DW_OP_constu:
388         case DW_OP_plus_uconst:
389         case DW_OP_regx:
390         case DW_OP_piece:
391         case DW_OP_GNU_convert:
392         case DW_OP_GNU_reinterpret:
393           /* XXX Check size.  */
394           get_uleb128 (newloc->number, data);
395           break;
396
397         case DW_OP_consts:
398         case DW_OP_breg0 ... DW_OP_breg31:
399         case DW_OP_fbreg:
400           /* XXX Check size.  */
401           get_sleb128 (newloc->number, data);
402           break;
403
404         case DW_OP_bregx:
405           /* XXX Check size.  */
406           get_uleb128 (newloc->number, data);
407           get_sleb128 (newloc->number2, data);
408           break;
409
410         case DW_OP_bit_piece:
411         case DW_OP_GNU_regval_type:
412           /* XXX Check size.  */
413           get_uleb128 (newloc->number, data);
414           get_uleb128 (newloc->number2, data);
415           break;
416
417         case DW_OP_implicit_value:
418         case DW_OP_GNU_entry_value:
419           /* This cannot be used in a CFI expression.  */
420           if (unlikely (dbg == NULL))
421             goto invalid;
422
423           /* start of block inc. len.  */
424           newloc->number2 = (Dwarf_Word) (uintptr_t) data;
425           /* XXX Check size.  */
426           get_uleb128 (newloc->number, data); /* Block length.  */
427           if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number))
428             goto invalid;
429           data += newloc->number;               /* Skip the block.  */
430           break;
431
432         case DW_OP_GNU_implicit_pointer:
433           /* DW_FORM_ref_addr, depends on offset size of CU.  */
434           if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
435                                        &newloc->number, IDX_debug_info, 0))
436             return -1;
437           /* XXX Check size.  */
438           get_uleb128 (newloc->number2, data); /* Byte offset.  */
439           break;
440
441         case DW_OP_GNU_deref_type:
442           if (unlikely (data >= end_data))
443             goto invalid;
444           newloc->number = *data++;
445           get_uleb128 (newloc->number2, data);
446           break;
447
448         case DW_OP_GNU_const_type:
449           {
450             size_t size;
451
452             /* XXX Check size.  */
453             get_uleb128 (newloc->number, data);
454             if (unlikely (data >= end_data))
455               goto invalid;
456
457             /* start of block inc. len.  */
458             newloc->number2 = (Dwarf_Word) (uintptr_t) data;
459             size = *data++;
460             if (unlikely ((Dwarf_Word) (end_data - data) < size))
461               goto invalid;
462             data += size;               /* Skip the block.  */
463           }
464           break;
465
466         default:
467           goto invalid;
468         }
469     }
470
471   if (unlikely (n == 0))
472     {
473       /* This is not allowed.
474          It would mean an empty location expression, which we handled
475          already as a special case above.  */
476       goto invalid;
477     }
478
479   if (valuep)
480     {
481       struct loclist *newloc;
482       newloc = (struct loclist *) alloca (sizeof (struct loclist));
483       newloc->atom = DW_OP_stack_value;
484       newloc->number = 0;
485       newloc->number2 = 0;
486       newloc->offset = data - block->data;
487       newloc->next = loclist;
488       loclist = newloc;
489       ++n;
490     }
491
492   /* Allocate the array.  */
493   Dwarf_Op *result;
494   if (dbg != NULL)
495     result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n);
496   else
497     {
498       result = malloc (sizeof *result * n);
499       if (result == NULL)
500         {
501         nomem:
502           __libdw_seterrno (DWARF_E_NOMEM);
503           return -1;
504         }
505     }
506
507   /* Store the result.  */
508   *llbuf = result;
509   *listlen = n;
510
511   do
512     {
513       /* We populate the array from the back since the list is backwards.  */
514       --n;
515       result[n].atom = loclist->atom;
516       result[n].number = loclist->number;
517       result[n].number2 = loclist->number2;
518       result[n].offset = loclist->offset;
519
520       if (result[n].atom == DW_OP_implicit_value)
521         store_implicit_value (dbg, cache, &result[n]);
522
523       loclist = loclist->next;
524     }
525   while (n > 0);
526
527   /* Insert a record in the search tree so that we can find it again later.  */
528   struct loc_s *newp;
529   if (dbg != NULL)
530     newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1);
531   else
532     {
533       newp = malloc (sizeof *newp);
534       if (newp == NULL)
535         {
536           free (result);
537           goto nomem;
538         }
539     }
540
541   newp->addr = block->data;
542   newp->loc = result;
543   newp->nloc = *listlen;
544   (void) tsearch (newp, cache, loc_compare);
545
546   /* We did it.  */
547   return 0;
548 }
549
550 static int
551 getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
552              Dwarf_Op **llbuf, size_t *listlen, int sec_index)
553 {
554   return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
555                                     cu->address_size, (cu->version == 2
556                                                        ? cu->address_size
557                                                        : cu->offset_size),
558                                     &cu->locs, block,
559                                     false, false,
560                                     llbuf, listlen, sec_index);
561 }
562
563 int
564 dwarf_getlocation (attr, llbuf, listlen)
565      Dwarf_Attribute *attr;
566      Dwarf_Op **llbuf;
567      size_t *listlen;
568 {
569   if (! attr_ok (attr))
570     return -1;
571
572   int result = check_constant_offset (attr, llbuf, listlen);
573   if (result != 1)
574     return result;
575
576   /* If it has a block form, it's a single location expression.  */
577   Dwarf_Block block;
578   if (INTUSE(dwarf_formblock) (attr, &block) != 0)
579     return -1;
580
581   return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu));
582 }
583
584 static int
585 attr_base_address (attr, basep)
586      Dwarf_Attribute *attr;
587      Dwarf_Addr *basep;
588 {
589   /* Fetch the CU's base address.  */
590   Dwarf_Die cudie = CUDIE (attr->cu);
591
592   /* Find the base address of the compilation unit.  It will
593      normally be specified by DW_AT_low_pc.  In DWARF-3 draft 4,
594      the base address could be overridden by DW_AT_entry_pc.  It's
595      been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
596      for compilation units with discontinuous ranges.  */
597   Dwarf_Attribute attr_mem;
598   if (unlikely (INTUSE(dwarf_lowpc) (&cudie, basep) != 0)
599       && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
600                                                      DW_AT_entry_pc,
601                                                      &attr_mem),
602                                  basep) != 0)
603     {
604       if (INTUSE(dwarf_errno) () != 0)
605         return -1;
606
607       /* The compiler provided no base address when it should
608          have.  Buggy GCC does this when it used absolute
609          addresses in the location list and no DW_AT_ranges.  */
610       *basep = 0;
611     }
612   return 0;
613 }
614
615 static int
616 initial_offset_base (attr, offset, basep)
617      Dwarf_Attribute *attr;
618      ptrdiff_t *offset;
619      Dwarf_Addr *basep;
620 {
621   if (attr_base_address (attr, basep) != 0)
622     return -1;
623
624   Dwarf_Word start_offset;
625   if (__libdw_formptr (attr, IDX_debug_loc,
626                        DWARF_E_NO_LOCLIST,
627                        NULL, &start_offset) == NULL)
628     return -1;
629
630   *offset = start_offset;
631   return 0;
632 }
633
634 static ptrdiff_t
635 getlocations_addr (attr, offset, basep, startp, endp, address,
636                    locs, expr, exprlen)
637      Dwarf_Attribute *attr;
638      ptrdiff_t offset;
639      Dwarf_Addr *basep;
640      Dwarf_Addr *startp;
641      Dwarf_Addr *endp;
642      Dwarf_Addr address;
643      Elf_Data *locs;
644      Dwarf_Op **expr;
645      size_t *exprlen;
646 {
647   unsigned char *readp = locs->d_buf + offset;
648   unsigned char *readendp = locs->d_buf + locs->d_size;
649
650  next:
651   if (readendp - readp < attr->cu->address_size * 2)
652     {
653     invalid:
654       __libdw_seterrno (DWARF_E_INVALID_DWARF);
655       return -1;
656     }
657
658   Dwarf_Addr begin;
659   Dwarf_Addr end;
660
661   switch (__libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc,
662                                            &readp, attr->cu->address_size,
663                                            &begin, &end, basep))
664     {
665     case 0: /* got location range. */
666       break;
667     case 1: /* base address setup. */
668       goto next;
669     case 2: /* end of loclist */
670       return 0;
671     default: /* error */
672       return -1;
673     }
674
675   if (readendp - readp < 2)
676     goto invalid;
677
678   /* We have a location expression.  */
679   Dwarf_Block block;
680   block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
681   block.data = readp;
682   if (readendp - readp < (ptrdiff_t) block.length)
683     goto invalid;
684   readp += block.length;
685
686   *startp = *basep + begin;
687   *endp = *basep + end;
688
689   /* If address is minus one we want them all, otherwise only matching.  */
690   if (address != (Dwarf_Word) -1 && (address < *startp || address >= *endp))
691     goto next;
692
693   if (getlocation (attr->cu, &block, expr, exprlen, IDX_debug_loc) != 0)
694     return -1;
695
696   return readp - (unsigned char *) locs->d_buf;
697 }
698
699 int
700 dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
701      Dwarf_Attribute *attr;
702      Dwarf_Addr address;
703      Dwarf_Op **llbufs;
704      size_t *listlens;
705      size_t maxlocs;
706 {
707   if (! attr_ok (attr))
708     return -1;
709
710   if (llbufs == NULL)
711     maxlocs = SIZE_MAX;
712
713   /* If it has a block form, it's a single location expression.  */
714   Dwarf_Block block;
715   if (INTUSE(dwarf_formblock) (attr, &block) == 0)
716     {
717       if (maxlocs == 0)
718         return 0;
719       if (llbufs != NULL &&
720           getlocation (attr->cu, &block, &llbufs[0], &listlens[0],
721                        cu_sec_idx (attr->cu)) != 0)
722         return -1;
723       return listlens[0] == 0 ? 0 : 1;
724     }
725
726   int error = INTUSE(dwarf_errno) ();
727   if (unlikely (error != DWARF_E_NO_BLOCK))
728     {
729       __libdw_seterrno (error);
730       return -1;
731     }
732
733   int result = check_constant_offset (attr, &llbufs[0], &listlens[0]);
734   if (result != 1)
735     return result ?: 1;
736
737   Dwarf_Addr base, start, end;
738   Dwarf_Op *expr;
739   size_t expr_len;
740   ptrdiff_t off = 0;
741   size_t got = 0;
742
743   /* This is a true loclistptr, fetch the initial base address and offset.  */
744   if (initial_offset_base (attr, &off, &base) != 0)
745     return -1;
746
747   const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
748   if (d == NULL)
749     {
750       __libdw_seterrno (DWARF_E_NO_LOCLIST);
751       return -1;
752     }
753
754   while (got < maxlocs
755          && (off = getlocations_addr (attr, off, &base, &start, &end,
756                                    address, d, &expr, &expr_len)) > 0)
757     {
758       /* This one matches the address.  */
759       if (llbufs != NULL)
760         {
761           llbufs[got] = expr;
762           listlens[got] = expr_len;
763         }
764       ++got;
765     }
766
767   /* We might stop early, so off can be zero or positive on success.  */
768   if (off < 0)
769     return -1;
770
771   return got;
772 }
773
774 ptrdiff_t
775 dwarf_getlocations (attr, offset, basep, startp, endp, expr, exprlen)
776      Dwarf_Attribute *attr;
777      ptrdiff_t offset;
778      Dwarf_Addr *basep;
779      Dwarf_Addr *startp;
780      Dwarf_Addr *endp;
781      Dwarf_Op **expr;
782      size_t *exprlen;
783 {
784   if (! attr_ok (attr))
785     return -1;
786
787   /* 1 is an invalid offset, meaning no more locations. */
788   if (offset == 1)
789     return 0;
790
791   if (offset == 0)
792     {
793       /* If it has a block form, it's a single location expression.  */
794       Dwarf_Block block;
795       if (INTUSE(dwarf_formblock) (attr, &block) == 0)
796         {
797           if (getlocation (attr->cu, &block, expr, exprlen,
798                            cu_sec_idx (attr->cu)) != 0)
799             return -1;
800
801           /* This is the one and only location covering everything. */
802           *startp = 0;
803           *endp = -1;
804           return 1;
805         }
806
807       int error = INTUSE(dwarf_errno) ();
808       if (unlikely (error != DWARF_E_NO_BLOCK))
809         {
810           __libdw_seterrno (error);
811           return -1;
812         }
813
814       int result = check_constant_offset (attr, expr, exprlen);
815       if (result != 1)
816         {
817           if (result == 0)
818             {
819               /* This is the one and only location covering everything. */
820               *startp = 0;
821               *endp = -1;
822               return 1;
823             }
824           return result;
825         }
826
827       /* We must be looking at a true loclistptr, fetch the initial
828          base address and offset.  */
829       if (initial_offset_base (attr, &offset, basep) != 0)
830         return -1;
831     }
832
833   const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
834   if (d == NULL)
835     {
836       __libdw_seterrno (DWARF_E_NO_LOCLIST);
837       return -1;
838     }
839
840   return getlocations_addr (attr, offset, basep, startp, endp,
841                             (Dwarf_Word) -1, d, expr, exprlen);
842 }