dwarf_getlocation.c revision 6fb3451de3ba29b628be6e30a01ef104156d4733
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return location expression list.
20ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath   Copyright (C) 2000-2010 Red Hat, Inc.
3361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   This file is part of Red Hat elfutils.
4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
6361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat elfutils is free software; you can redistribute it and/or modify
7361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   it under the terms of the GNU General Public License as published by the
8361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Free Software Foundation; version 2 of the License.
9b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
10361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat elfutils is distributed in the hope that it will be useful, but
11361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   WITHOUT ANY WARRANTY; without even the implied warranty of
12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   General Public License for more details.
14361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
15361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   You should have received a copy of the GNU General Public License along
16361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   with Red Hat elfutils; if not, write to the Free Software Foundation,
171e9ef50681e20ef14c2ba38aef37a71ff148be08Ulrich Drepper   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
18361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
19361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   In addition, as a special exception, Red Hat, Inc. gives You the
20361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   additional right to link the code of Red Hat elfutils with code licensed
21361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   under any Open Source Initiative certified open source license
22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   (http://www.opensource.org/licenses/index.php) which requires the
23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   distribution of source code with any binary distribution and to
24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   distribute linked combinations of the two.  Non-GPL Code permitted under
25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   this exception must only link to the code of Red Hat elfutils through
26361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   those well defined interfaces identified in the file named EXCEPTION
27361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   found in the source code files (the "Approved Interfaces").  The files
28361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   of Non-GPL Code may instantiate templates or use macros or inline
29361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   functions from the Approved Interfaces without causing the resulting
30361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   work to be covered by the GNU General Public License.  Only Red Hat,
31361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Inc. may make changes or additions to the list of Approved Interfaces.
32361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat's grant of this exception is conditioned upon your not adding
33361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   any new exceptions.  If you wish to add a new Approved Interface or
34361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   exception, please contact Red Hat.  You must obey the GNU General Public
35361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   License in all respects for all of the Red Hat elfutils code and other
36361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   code used in conjunction with Red Hat elfutils except the Non-GPL Code
37361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   covered by this exception.  If you modify this file, you may extend this
38361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   exception to your version of the file, but you are not obligated to do
39361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   so.  If you do not wish to provide this exception without modification,
40361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   you must delete this exception statement from your version and license
41361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   this file solely under the GPL without exception.
42361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
43361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat elfutils is an included package of the Open Invention Network.
44361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   An included package of the Open Invention Network is a package for which
45361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Open Invention Network licensees cross-license their patents.  No patent
46361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   license is granted, either expressly or impliedly, by designation as an
47361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   included package.  Should you wish to participate in the Open Invention
48361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Network licensing program, please visit www.openinventionnetwork.com
49361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   <http://www.openinventionnetwork.com>.  */
50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H
52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h>
53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <dwarf.h>
56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <search.h>
57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h>
58cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath#include <assert.h>
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libdwP.h>
61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool
64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperattr_ok (Dwarf_Attribute *attr)
65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (attr == NULL)
67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return false;
68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Must be one of the attributes listed below.  */
70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  switch (attr->code)
71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_location:
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_data_member_location:
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_vtable_elem_location:
75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_string_length:
76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_use_location:
77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_frame_base:
78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_return_addr:
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_static_link:
80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    default:
83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_NO_LOCLIST);
84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return false;
85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return true;
88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstruct loclist
92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  uint8_t atom;
94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Word number;
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Word number2;
96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Word offset;
97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loclist *next;
98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int
102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperloc_compare (const void *p1, const void *p2)
103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const struct loc_s *l1 = (const struct loc_s *) p1;
105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const struct loc_s *l2 = (const struct loc_s *) p2;
106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if ((uintptr_t) l1->addr < (uintptr_t) l2->addr)
108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if ((uintptr_t) l1->addr > (uintptr_t) l2->addr)
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return 1;
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return 0;
113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
115f0371041995308d197447019eb2ac9285c96477bRoland McGrath/* For each DW_OP_implicit_value, we store a special entry in the cache.
116f0371041995308d197447019eb2ac9285c96477bRoland McGrath   This points us directly to the block data for later fetching.  */
117f0371041995308d197447019eb2ac9285c96477bRoland McGrathstatic void
118f0371041995308d197447019eb2ac9285c96477bRoland McGrathstore_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op,
119f0371041995308d197447019eb2ac9285c96477bRoland McGrath		      unsigned char *data)
120f0371041995308d197447019eb2ac9285c96477bRoland McGrath{
121f0371041995308d197447019eb2ac9285c96477bRoland McGrath  struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s,
122f0371041995308d197447019eb2ac9285c96477bRoland McGrath					   sizeof (struct loc_block_s), 1);
123f0371041995308d197447019eb2ac9285c96477bRoland McGrath  block->addr = op;
124f0371041995308d197447019eb2ac9285c96477bRoland McGrath  block->data = data + op->number2;
125f0371041995308d197447019eb2ac9285c96477bRoland McGrath  block->length = op->number;
126f0371041995308d197447019eb2ac9285c96477bRoland McGrath  (void) tsearch (block, cache, loc_compare);
127f0371041995308d197447019eb2ac9285c96477bRoland McGrath}
128f0371041995308d197447019eb2ac9285c96477bRoland McGrath
129f0371041995308d197447019eb2ac9285c96477bRoland McGrathint
130f0371041995308d197447019eb2ac9285c96477bRoland McGrathdwarf_getlocation_implicit_value (attr, op, return_block)
131f0371041995308d197447019eb2ac9285c96477bRoland McGrath     Dwarf_Attribute *attr;
1327e0aecdad525d8b290e2b9b999f6960a42bee33dRoland McGrath     const Dwarf_Op *op;
133f0371041995308d197447019eb2ac9285c96477bRoland McGrath     Dwarf_Block *return_block;
134f0371041995308d197447019eb2ac9285c96477bRoland McGrath{
135f0371041995308d197447019eb2ac9285c96477bRoland McGrath  if (attr == NULL)
136f0371041995308d197447019eb2ac9285c96477bRoland McGrath    return -1;
137f0371041995308d197447019eb2ac9285c96477bRoland McGrath
1387e0aecdad525d8b290e2b9b999f6960a42bee33dRoland McGrath  struct loc_block_s fake = { .addr = (void *) op };
139f0371041995308d197447019eb2ac9285c96477bRoland McGrath  struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
140f0371041995308d197447019eb2ac9285c96477bRoland McGrath  if (unlikely (found == NULL))
141f0371041995308d197447019eb2ac9285c96477bRoland McGrath    {
142f0371041995308d197447019eb2ac9285c96477bRoland McGrath      __libdw_seterrno (DWARF_E_NO_BLOCK);
143f0371041995308d197447019eb2ac9285c96477bRoland McGrath      return -1;
144f0371041995308d197447019eb2ac9285c96477bRoland McGrath    }
145f0371041995308d197447019eb2ac9285c96477bRoland McGrath
146f0371041995308d197447019eb2ac9285c96477bRoland McGrath  return_block->length = (*found)->length;
147f0371041995308d197447019eb2ac9285c96477bRoland McGrath  return_block->data = (*found)->data;
148f0371041995308d197447019eb2ac9285c96477bRoland McGrath  return 0;
149f0371041995308d197447019eb2ac9285c96477bRoland McGrath}
150f0371041995308d197447019eb2ac9285c96477bRoland McGrath
151cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath/* DW_AT_data_member_location can be a constant as well as a loclistptr.
152cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath   Only data[48] indicate a loclistptr.  */
153cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrathstatic int
154cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrathcheck_constant_offset (Dwarf_Attribute *attr,
155cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath		       Dwarf_Op **llbuf, size_t *listlen)
156cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath{
157888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath  if (attr->code != DW_AT_data_member_location)
158cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    return 1;
159cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
160888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath  switch (attr->form)
161888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath    {
162888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath      /* Punt for any non-constant form.  */
163888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath    default:
164888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath      return 1;
165888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath
166888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath    case DW_FORM_data1:
167888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath    case DW_FORM_data2:
168888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath    case DW_FORM_sdata:
169888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath    case DW_FORM_udata:
170888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath      break;
171888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath
172888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath    case DW_FORM_data4:
173888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath    case DW_FORM_data8:
174888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath      /* These are loclistptr, not constants.
175888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath	 XXX check cu->version > 3???
176888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath      */
177888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath      return 1;
178888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath    }
179888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath
180cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  /* Check whether we already cached this location.  */
181cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  struct loc_s fake = { .addr = attr->valp };
182cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
183cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
184cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (found == NULL)
185cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    {
186cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      Dwarf_Word offset;
187cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
188cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath	return -1;
189cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
190cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      Dwarf_Op *result = libdw_alloc (attr->cu->dbg,
191cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath				      Dwarf_Op, sizeof (Dwarf_Op), 1);
192cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
193cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->atom = DW_OP_plus_uconst;
194cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->number = offset;
195cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->number2 = 0;
196cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->offset = 0;
197cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
198cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      /* Insert a record in the search tree so we can find it again later.  */
199cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      struct loc_s *newp = libdw_alloc (attr->cu->dbg,
200cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath					struct loc_s, sizeof (struct loc_s),
201cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath					1);
202cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      newp->addr = attr->valp;
203cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      newp->loc = result;
204cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      newp->nloc = 1;
205cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
206cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      found = tsearch (newp, &attr->cu->locs, loc_compare);
207cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    }
208cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
209cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  assert ((*found)->nloc == 1);
210cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
211cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (llbuf != NULL)
212cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    {
213cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      *llbuf = (*found)->loc;
214cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      *listlen = 1;
215cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    }
216cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
217cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  return 0;
218cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath}
219cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
2203c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathint
2213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathinternal_function
222688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath__libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
223688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath			   unsigned int address_size, unsigned int ref_size,
2240ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath			   void **cache, const Dwarf_Block *block,
2250ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath			   bool cfap, bool valuep,
2263c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath			   Dwarf_Op **llbuf, size_t *listlen, int sec_index)
227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check whether we already looked at this list.  */
229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loc_s fake = { .addr = block->data };
2303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  struct loc_s **found = tfind (&fake, cache, loc_compare);
231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (found != NULL)
232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We already saw it.  */
234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *llbuf = (*found)->loc;
235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *listlen = (*found)->nloc;
236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
237af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      if (valuep)
238af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath	{
239af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath	  assert (*listlen > 1);
240af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath	  assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value);
241af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath	}
242af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath
243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return 0;
244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const unsigned char *data = block->data;
247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const unsigned char *const end_data = data + block->length;
248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2493c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  const struct { bool other_byte_order; } bo = { other_byte_order };
2503c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loclist *loclist = NULL;
252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  unsigned int n = 0;
253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Decode the opcodes.  It is possible in some situations to have a
254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     block of size zero.  */
255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (data < end_data)
256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct loclist *newloc;
258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc = (struct loclist *) alloca (sizeof (struct loclist));
259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->number = 0;
260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->number2 = 0;
261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->offset = data - block->data;
262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->next = loclist;
263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      loclist = newloc;
264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ++n;
265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      switch ((newloc->atom = *data++))
267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_addr:
269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Address, depends on address size of CU.  */
27005c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath	  if (__libdw_read_address_inc (dbg, sec_index, &data,
2713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath					address_size, &newloc->number))
27299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    return -1;
273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
275688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath	case DW_OP_call_ref:
276688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath	  /* DW_FORM_ref_addr, depends on offset size of CU.  */
277688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath	  if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
278688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath				       &newloc->number, IDX_debug_info, 0))
279688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath	    return -1;
280688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath	  break;
281688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath
282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_deref:
283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_dup:
284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_drop:
285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_over:
286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_swap:
287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_rot:
288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xderef:
289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_abs:
290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_and:
291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_div:
292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_minus:
293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_mod:
294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_mul:
295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_neg:
296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_not:
297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_or:
298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_plus:
299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shl:
300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shr:
301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shra:
302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xor:
303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_eq:
304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_ge:
305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_gt:
306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_le:
307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_lt:
308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_ne:
309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_lit0 ... DW_OP_lit31:
310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_reg0 ... DW_OP_reg31:
311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_nop:
312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_push_object_address:
3138089343cc61743db7bf0fd75c21132cbab5c01fdRoland McGrath	case DW_OP_call_frame_cfa:
3147dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	case DW_OP_form_tls_address:
315d1083043cf63551270f31aa83233d55286a89d65Roland McGrath	case DW_OP_GNU_push_tls_address:
31696349ffaa68a1b4eec2fd1c9eb97a3d0b4e95a1eRoland McGrath	case DW_OP_stack_value:
317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* No operand.  */
318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const1u:
321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_pick:
322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_deref_size:
323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xderef_size:
324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data >= end_data))
32599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    {
32699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    invalid:
32799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
32899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	      return -1;
32999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    }
330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = *data++;
332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const1s:
335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data >= end_data))
336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = *((int8_t *) data);
339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ++data;
340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const2u:
343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 2 > end_data))
344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3463c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_2ubyte_unaligned_inc (&bo, data);
347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const2s:
350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_skip:
351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_bra:
352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call2:
353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 2 > end_data))
354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3563c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_2sbyte_unaligned_inc (&bo, data);
357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const4u:
360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 4 > end_data))
361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_4ubyte_unaligned_inc (&bo, data);
364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const4s:
367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call4:
368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 4 > end_data))
369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_4sbyte_unaligned_inc (&bo, data);
372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const8u:
375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 8 > end_data))
376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3783c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_8ubyte_unaligned_inc (&bo, data);
379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const8s:
382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 8 > end_data))
383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3853c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_8sbyte_unaligned_inc (&bo, data);
386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_constu:
389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_plus_uconst:
390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_regx:
391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_piece:
392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_uleb128 (newloc->number, data);
394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_consts:
397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_breg0 ... DW_OP_breg31:
398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_fbreg:
399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_sleb128 (newloc->number, data);
401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_bregx:
404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_uleb128 (newloc->number, data);
406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_sleb128 (newloc->number2, data);
407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
4097dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	case DW_OP_bit_piece:
4107dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  /* XXX Check size.  */
4117dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  get_uleb128 (newloc->number, data);
4127dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  get_uleb128 (newloc->number2, data);
4137dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  break;
4147dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath
415f0371041995308d197447019eb2ac9285c96477bRoland McGrath	case DW_OP_implicit_value:
416f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  /* This cannot be used in a CFI expression.  */
417f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  if (unlikely (dbg == NULL))
418f0371041995308d197447019eb2ac9285c96477bRoland McGrath	    goto invalid;
419f0371041995308d197447019eb2ac9285c96477bRoland McGrath
420f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  /* XXX Check size.  */
421f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  get_uleb128 (newloc->number, data); /* Block length.  */
422f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number))
423f0371041995308d197447019eb2ac9285c96477bRoland McGrath	    goto invalid;
424f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  newloc->number2 = data - block->data; /* Relative block offset.  */
425f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  data += newloc->number;		/* Skip the block.  */
426f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  break;
427f0371041995308d197447019eb2ac9285c96477bRoland McGrath
428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	default:
429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto invalid;
430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (unlikely (n == 0))
434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* This is not allowed.
436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 XXX Is it?  */
438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      goto invalid;
439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
441af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath  if (valuep)
442af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath    {
443af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      struct loclist *newloc;
444af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc = (struct loclist *) alloca (sizeof (struct loclist));
445af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->atom = DW_OP_stack_value;
446af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->number = 0;
447af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->number2 = 0;
448af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->offset = data - block->data;
449af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->next = loclist;
450af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      loclist = newloc;
451af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      ++n;
452af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath    }
453af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath
4540ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath  if (cfap)
4550ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath    ++n;
4560ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath
457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Allocate the array.  */
4583c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  Dwarf_Op *result;
4593c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (dbg != NULL)
4603c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n);
4613c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  else
4623c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
4633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      result = malloc (sizeof *result * n);
4643c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (result == NULL)
4653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
4663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	nomem:
4673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  __libdw_seterrno (DWARF_E_NOMEM);
4683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  return -1;
4693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
4703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Store the result.  */
473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  *llbuf = result;
474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  *listlen = n;
475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
4760ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath  if (cfap)
4770ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath    {
4780ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath      /* Synthesize the operation to push the CFA before the expression.  */
4790ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath      --n;
4800ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath      result[0].atom = DW_OP_call_frame_cfa;
4810ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath      result[0].number = 0;
4820ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath      result[0].number2 = 0;
4830ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath      result[0].offset = -1;
4840ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath    }
4850ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath
486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  do
487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
488f0371041995308d197447019eb2ac9285c96477bRoland McGrath      /* We populate the array from the back since the list is backwards.  */
489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      --n;
490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].atom = loclist->atom;
491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].number = loclist->number;
492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].number2 = loclist->number2;
493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].offset = loclist->offset;
494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
495f0371041995308d197447019eb2ac9285c96477bRoland McGrath      if (result[n].atom == DW_OP_implicit_value)
496f0371041995308d197447019eb2ac9285c96477bRoland McGrath	store_implicit_value (dbg, cache, &result[n], block->data);
497f0371041995308d197447019eb2ac9285c96477bRoland McGrath
498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      loclist = loclist->next;
499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (n > 0);
501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
502f0371041995308d197447019eb2ac9285c96477bRoland McGrath  /* Insert a record in the search tree so that we can find it again later.  */
5033c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  struct loc_s *newp;
5043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (dbg != NULL)
5053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1);
5063c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  else
5073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
5083c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      newp = malloc (sizeof *newp);
5093c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (newp == NULL)
5103c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
5113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  free (result);
5123c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  goto nomem;
5133c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
5143c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
5153c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->addr = block->data;
517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->loc = result;
518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->nloc = *listlen;
5193c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  (void) tsearch (newp, cache, loc_compare);
520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We did it.  */
522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return 0;
523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
5253c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic int
5263c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathgetlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
5273c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	     Dwarf_Op **llbuf, size_t *listlen, int sec_index)
5283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{
5293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
530688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath				    cu->address_size, (cu->version == 2
531688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath						       ? cu->address_size
532688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath						       : cu->offset_size),
533688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath				    &cu->locs, block,
5340ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath				    false, false,
535af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath				    llbuf, listlen, sec_index);
5363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath}
5373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
5396724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation (attr, llbuf, listlen)
540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Attribute *attr;
5416724c90d02659f7466b67b357563042e403d154eRoland McGrath     Dwarf_Op **llbuf;
542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t *listlen;
543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
5446fb3451de3ba29b628be6e30a01ef104156d4733Ulrich Drepper  if (! attr_ok (attr))
5456fb3451de3ba29b628be6e30a01ef104156d4733Ulrich Drepper    return -1;
5466fb3451de3ba29b628be6e30a01ef104156d4733Ulrich Drepper
547cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  int result = check_constant_offset (attr, llbuf, listlen);
548cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (result != 1)
549cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    return result;
550cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* If it has a block form, it's a single location expression.  */
552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Block block;
553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (INTUSE(dwarf_formblock) (attr, &block) != 0)
554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
55699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  return getlocation (attr->cu, &block, llbuf, listlen, IDX_debug_info);
557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
5606724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Attribute *attr;
562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Addr address;
5636724c90d02659f7466b67b357563042e403d154eRoland McGrath     Dwarf_Op **llbufs;
564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t *listlens;
565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t maxlocs;
566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (! attr_ok (attr))
568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (llbufs == NULL)
571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    maxlocs = SIZE_MAX;
572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* If it has a block form, it's a single location expression.  */
574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Block block;
575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (INTUSE(dwarf_formblock) (attr, &block) == 0)
576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (maxlocs == 0)
578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return 0;
579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (llbufs != NULL &&
58099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	  getlocation (attr->cu, &block, &llbufs[0], &listlens[0],
58199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper		       IDX_debug_info) != 0)
582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return -1;
583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return listlens[0] == 0 ? 0 : 1;
584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  int error = INTUSE(dwarf_errno) ();
587f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  if (unlikely (error != DWARF_E_NO_BLOCK))
588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (error);
590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return -1;
591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
593cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  int result = check_constant_offset (attr, &llbufs[0], &listlens[0]);
594cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (result != 1)
595cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    return result ?: 1;
596cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
59799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  unsigned char *endp;
59899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  unsigned char *readp = __libdw_formptr (attr, IDX_debug_loc,
59999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					  DWARF_E_NO_LOCLIST, &endp, NULL);
60099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  if (readp == NULL)
601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
603f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  Dwarf_Addr base = (Dwarf_Addr) -1;
604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t got = 0;
605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (got < maxlocs)
606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
60799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (endp - readp < attr->cu->address_size * 2)
608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	invalid:
610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  return -1;
612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Dwarf_Addr begin;
615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Dwarf_Addr end;
616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
61799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      int status
61899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	= __libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc,
61999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					   &readp, attr->cu->address_size,
62099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					   &begin, &end, &base);
62199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (status == 2) /* End of list entry.  */
622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	break;
62399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      else if (status == 1) /* Base address selected.  */
62499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	continue;
62599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      else if (status < 0)
62699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	return status;
627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
62899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (endp - readp < 2)
629f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	goto invalid;
630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We have a location expression.  */
632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      block.data = readp;
63499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (endp - readp < (ptrdiff_t) block.length)
635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	goto invalid;
636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      readp += block.length;
637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
638f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath      if (base == (Dwarf_Addr) -1)
639f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	{
640f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  /* Fetch the CU's base address.  */
641f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  Dwarf_Die cudie = CUDIE (attr->cu);
642f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath
643f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  /* Find the base address of the compilation unit.  It will
644f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     normally be specified by DW_AT_low_pc.  In DWARF-3 draft 4,
645f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     the base address could be overridden by DW_AT_entry_pc.  It's
646f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
647f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     for compilation units with discontinuous ranges.  */
648f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  Dwarf_Attribute attr_mem;
649f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  if (unlikely (INTUSE(dwarf_lowpc) (&cudie, &base) != 0)
650f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	      && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
651f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath							     DW_AT_entry_pc,
652f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath							     &attr_mem),
653f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath					 &base) != 0)
654f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	    {
65556bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      if (INTUSE(dwarf_errno) () != 0)
6568190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath		return -1;
65756bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper
65856bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      /* The compiler provided no base address when it should
65956bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper		 have.  Buggy GCC does this when it used absolute
66056bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper		 addresses in the location list and no DW_AT_ranges.  */
66156bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      base = 0;
662f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	    }
663f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	}
664f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath
665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (address >= base + begin && address < base + end)
666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* This one matches the address.  */
6686724c90d02659f7466b67b357563042e403d154eRoland McGrath	  if (llbufs != NULL
669f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	      && unlikely (getlocation (attr->cu, &block,
67099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					&llbufs[got], &listlens[got],
67199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					IDX_debug_loc) != 0))
672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    return -1;
673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ++got;
674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return got;
678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
679