dwarf_getlocation.c revision f0371041995308d197447019eb2ac9285c96477b
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return location expression list.
205c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath   Copyright (C) 2000-2009 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;
132f0371041995308d197447019eb2ac9285c96477bRoland McGrath     Dwarf_Op *op;
133f0371041995308d197447019eb2ac9285c96477bRoland McGrath     Dwarf_Block *return_block;
134f0371041995308d197447019eb2ac9285c96477bRoland McGrath{
135f0371041995308d197447019eb2ac9285c96477bRoland McGrath  if (attr == NULL)
136f0371041995308d197447019eb2ac9285c96477bRoland McGrath    return -1;
137f0371041995308d197447019eb2ac9285c96477bRoland McGrath
138f0371041995308d197447019eb2ac9285c96477bRoland McGrath  struct loc_block_s fake = { .addr = 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{
157cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (attr->code != DW_AT_data_member_location
158cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      || attr->form == DW_FORM_data4
159cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      || attr->form == DW_FORM_data8)
160cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    return 1;
161cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
162cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  /* Check whether we already cached this location.  */
163cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  struct loc_s fake = { .addr = attr->valp };
164cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
165cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
166cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (found == NULL)
167cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    {
168cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      Dwarf_Word offset;
169cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
170cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath	return -1;
171cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
172cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      Dwarf_Op *result = libdw_alloc (attr->cu->dbg,
173cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath				      Dwarf_Op, sizeof (Dwarf_Op), 1);
174cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
175cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->atom = DW_OP_plus_uconst;
176cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->number = offset;
177cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->number2 = 0;
178cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->offset = 0;
179cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
180cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      /* Insert a record in the search tree so we can find it again later.  */
181cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      struct loc_s *newp = libdw_alloc (attr->cu->dbg,
182cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath					struct loc_s, sizeof (struct loc_s),
183cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath					1);
184cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      newp->addr = attr->valp;
185cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      newp->loc = result;
186cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      newp->nloc = 1;
187cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
188cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      found = tsearch (newp, &attr->cu->locs, loc_compare);
189cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    }
190cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
191cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  assert ((*found)->nloc == 1);
192cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
193cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (llbuf != NULL)
194cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    {
195cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      *llbuf = (*found)->loc;
196cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      *listlen = 1;
197cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    }
198cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
199cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  return 0;
200cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath}
201cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
2023c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathint
2033c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathinternal_function
2043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath__libdw_intern_expression (Dwarf *dbg,
2053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath			   bool other_byte_order, unsigned int address_size,
206af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath			   void **cache, const Dwarf_Block *block, bool valuep,
2073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath			   Dwarf_Op **llbuf, size_t *listlen, int sec_index)
208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check whether we already looked at this list.  */
210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loc_s fake = { .addr = block->data };
2113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  struct loc_s **found = tfind (&fake, cache, loc_compare);
212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (found != NULL)
213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We already saw it.  */
215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *llbuf = (*found)->loc;
216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *listlen = (*found)->nloc;
217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
218af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      if (valuep)
219af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath	{
220af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath	  assert (*listlen > 1);
221af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath	  assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value);
222af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath	}
223af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath
224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return 0;
225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const unsigned char *data = block->data;
228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const unsigned char *const end_data = data + block->length;
229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  const struct { bool other_byte_order; } bo = { other_byte_order };
2313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loclist *loclist = NULL;
233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  unsigned int n = 0;
234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Decode the opcodes.  It is possible in some situations to have a
235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     block of size zero.  */
236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (data < end_data)
237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct loclist *newloc;
239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc = (struct loclist *) alloca (sizeof (struct loclist));
240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->number = 0;
241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->number2 = 0;
242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->offset = data - block->data;
243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->next = loclist;
244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      loclist = newloc;
245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ++n;
246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      switch ((newloc->atom = *data++))
248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_addr:
250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Address, depends on address size of CU.  */
25105c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath	  if (__libdw_read_address_inc (dbg, sec_index, &data,
2523c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath					address_size, &newloc->number))
25399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    return -1;
254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_deref:
257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_dup:
258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_drop:
259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_over:
260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_swap:
261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_rot:
262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xderef:
263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_abs:
264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_and:
265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_div:
266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_minus:
267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_mod:
268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_mul:
269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_neg:
270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_not:
271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_or:
272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_plus:
273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shl:
274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shr:
275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shra:
276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xor:
277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_eq:
278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_ge:
279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_gt:
280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_le:
281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_lt:
282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_ne:
283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_lit0 ... DW_OP_lit31:
284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_reg0 ... DW_OP_reg31:
285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_nop:
286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_push_object_address:
287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call_ref:
2888089343cc61743db7bf0fd75c21132cbab5c01fdRoland McGrath	case DW_OP_call_frame_cfa:
2897dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	case DW_OP_form_tls_address:
290d1083043cf63551270f31aa83233d55286a89d65Roland McGrath	case DW_OP_GNU_push_tls_address:
29196349ffaa68a1b4eec2fd1c9eb97a3d0b4e95a1eRoland McGrath	case DW_OP_stack_value:
292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* No operand.  */
293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const1u:
296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_pick:
297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_deref_size:
298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xderef_size:
299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data >= end_data))
30099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    {
30199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    invalid:
30299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
30399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	      return -1;
30499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    }
305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = *data++;
307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const1s:
310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data >= end_data))
311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = *((int8_t *) data);
314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ++data;
315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const2u:
318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 2 > end_data))
319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_2ubyte_unaligned_inc (&bo, data);
322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const2s:
325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_skip:
326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_bra:
327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call2:
328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 2 > end_data))
329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_2sbyte_unaligned_inc (&bo, data);
332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const4u:
335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 4 > end_data))
336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3383c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_4ubyte_unaligned_inc (&bo, data);
339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const4s:
342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call4:
343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 4 > end_data))
344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3463c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_4sbyte_unaligned_inc (&bo, data);
347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const8u:
350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 8 > end_data))
351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3533c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_8ubyte_unaligned_inc (&bo, data);
354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const8s:
357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 8 > end_data))
358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3603c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_8sbyte_unaligned_inc (&bo, data);
361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_constu:
364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_plus_uconst:
365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_regx:
366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_piece:
367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_uleb128 (newloc->number, data);
369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_consts:
372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_breg0 ... DW_OP_breg31:
373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_fbreg:
374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_sleb128 (newloc->number, data);
376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_bregx:
379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_uleb128 (newloc->number, data);
381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_sleb128 (newloc->number2, data);
382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3847dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	case DW_OP_bit_piece:
3857dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  /* XXX Check size.  */
3867dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  get_uleb128 (newloc->number, data);
3877dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  get_uleb128 (newloc->number2, data);
3887dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  break;
3897dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath
390f0371041995308d197447019eb2ac9285c96477bRoland McGrath	case DW_OP_implicit_value:
391f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  /* This cannot be used in a CFI expression.  */
392f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  if (unlikely (dbg == NULL))
393f0371041995308d197447019eb2ac9285c96477bRoland McGrath	    goto invalid;
394f0371041995308d197447019eb2ac9285c96477bRoland McGrath
395f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  /* XXX Check size.  */
396f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  get_uleb128 (newloc->number, data); /* Block length.  */
397f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number))
398f0371041995308d197447019eb2ac9285c96477bRoland McGrath	    goto invalid;
399f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  newloc->number2 = data - block->data; /* Relative block offset.  */
400f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  data += newloc->number;		/* Skip the block.  */
401f0371041995308d197447019eb2ac9285c96477bRoland McGrath	  break;
402f0371041995308d197447019eb2ac9285c96477bRoland McGrath
403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	default:
404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto invalid;
405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (unlikely (n == 0))
409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* This is not allowed.
411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 XXX Is it?  */
413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      goto invalid;
414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
416af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath  if (valuep)
417af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath    {
418af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      struct loclist *newloc;
419af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc = (struct loclist *) alloca (sizeof (struct loclist));
420af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->atom = DW_OP_stack_value;
421af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->number = 0;
422af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->number2 = 0;
423af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->offset = data - block->data;
424af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      newloc->next = loclist;
425af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      loclist = newloc;
426af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath      ++n;
427af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath    }
428af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath
429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Allocate the array.  */
4303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  Dwarf_Op *result;
4313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (dbg != NULL)
4323c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n);
4333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  else
4343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
4353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      result = malloc (sizeof *result * n);
4363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (result == NULL)
4373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
4383c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	nomem:
4393c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  __libdw_seterrno (DWARF_E_NOMEM);
4403c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  return -1;
4413c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
4423c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Store the result.  */
445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  *llbuf = result;
446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  *listlen = n;
447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  do
449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
450f0371041995308d197447019eb2ac9285c96477bRoland McGrath      /* We populate the array from the back since the list is backwards.  */
451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      --n;
452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].atom = loclist->atom;
453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].number = loclist->number;
454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].number2 = loclist->number2;
455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].offset = loclist->offset;
456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
457f0371041995308d197447019eb2ac9285c96477bRoland McGrath      if (result[n].atom == DW_OP_implicit_value)
458f0371041995308d197447019eb2ac9285c96477bRoland McGrath	store_implicit_value (dbg, cache, &result[n], block->data);
459f0371041995308d197447019eb2ac9285c96477bRoland McGrath
460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      loclist = loclist->next;
461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (n > 0);
463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
464f0371041995308d197447019eb2ac9285c96477bRoland McGrath  /* Insert a record in the search tree so that we can find it again later.  */
4653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  struct loc_s *newp;
4663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (dbg != NULL)
4673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1);
4683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  else
4693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
4703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      newp = malloc (sizeof *newp);
4713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (newp == NULL)
4723c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
4733c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  free (result);
4743c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  goto nomem;
4753c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
4763c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
4773c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->addr = block->data;
479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->loc = result;
480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->nloc = *listlen;
4813c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  (void) tsearch (newp, cache, loc_compare);
482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We did it.  */
484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return 0;
485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
4873c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic int
4883c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathgetlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
4893c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	     Dwarf_Op **llbuf, size_t *listlen, int sec_index)
4903c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{
4913c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
492af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath				    cu->address_size, &cu->locs, block, false,
493af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath				    llbuf, listlen, sec_index);
4943c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath}
4953c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
4976724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation (attr, llbuf, listlen)
498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Attribute *attr;
4996724c90d02659f7466b67b357563042e403d154eRoland McGrath     Dwarf_Op **llbuf;
500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t *listlen;
501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
502cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  int result = check_constant_offset (attr, llbuf, listlen);
503cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (result != 1)
504cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    return result;
505cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (! attr_ok (attr))
507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* If it has a block form, it's a single location expression.  */
510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Block block;
511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (INTUSE(dwarf_formblock) (attr, &block) != 0)
512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
51499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  return getlocation (attr->cu, &block, llbuf, listlen, IDX_debug_info);
515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
5186724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Attribute *attr;
520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Addr address;
5216724c90d02659f7466b67b357563042e403d154eRoland McGrath     Dwarf_Op **llbufs;
522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t *listlens;
523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t maxlocs;
524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (! attr_ok (attr))
526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (llbufs == NULL)
529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    maxlocs = SIZE_MAX;
530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* If it has a block form, it's a single location expression.  */
532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Block block;
533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (INTUSE(dwarf_formblock) (attr, &block) == 0)
534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (maxlocs == 0)
536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return 0;
537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (llbufs != NULL &&
53899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	  getlocation (attr->cu, &block, &llbufs[0], &listlens[0],
53999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper		       IDX_debug_info) != 0)
540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return -1;
541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return listlens[0] == 0 ? 0 : 1;
542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  int error = INTUSE(dwarf_errno) ();
545f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  if (unlikely (error != DWARF_E_NO_BLOCK))
546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (error);
548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return -1;
549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
551cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  int result = check_constant_offset (attr, &llbufs[0], &listlens[0]);
552cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (result != 1)
553cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    return result ?: 1;
554cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
55599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  unsigned char *endp;
55699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  unsigned char *readp = __libdw_formptr (attr, IDX_debug_loc,
55799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					  DWARF_E_NO_LOCLIST, &endp, NULL);
55899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  if (readp == NULL)
559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
561f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  Dwarf_Addr base = (Dwarf_Addr) -1;
562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t got = 0;
563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (got < maxlocs)
564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
56599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (endp - readp < attr->cu->address_size * 2)
566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	invalid:
568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  return -1;
570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Dwarf_Addr begin;
573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Dwarf_Addr end;
574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
57599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      int status
57699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	= __libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc,
57799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					   &readp, attr->cu->address_size,
57899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					   &begin, &end, &base);
57999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (status == 2) /* End of list entry.  */
580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	break;
58199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      else if (status == 1) /* Base address selected.  */
58299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	continue;
58399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      else if (status < 0)
58499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	return status;
585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
58699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (endp - readp < 2)
587f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	goto invalid;
588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We have a location expression.  */
590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      block.data = readp;
59299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (endp - readp < (ptrdiff_t) block.length)
593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	goto invalid;
594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      readp += block.length;
595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
596f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath      if (base == (Dwarf_Addr) -1)
597f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	{
598f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  /* Fetch the CU's base address.  */
599f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  Dwarf_Die cudie = CUDIE (attr->cu);
600f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath
601f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  /* Find the base address of the compilation unit.  It will
602f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     normally be specified by DW_AT_low_pc.  In DWARF-3 draft 4,
603f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     the base address could be overridden by DW_AT_entry_pc.  It's
604f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
605f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     for compilation units with discontinuous ranges.  */
606f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  Dwarf_Attribute attr_mem;
607f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  if (unlikely (INTUSE(dwarf_lowpc) (&cudie, &base) != 0)
608f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	      && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
609f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath							     DW_AT_entry_pc,
610f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath							     &attr_mem),
611f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath					 &base) != 0)
612f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	    {
61356bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      if (INTUSE(dwarf_errno) () != 0)
6148190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath		return -1;
61556bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper
61656bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      /* The compiler provided no base address when it should
61756bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper		 have.  Buggy GCC does this when it used absolute
61856bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper		 addresses in the location list and no DW_AT_ranges.  */
61956bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      base = 0;
620f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	    }
621f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	}
622f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath
623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (address >= base + begin && address < base + end)
624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* This one matches the address.  */
6266724c90d02659f7466b67b357563042e403d154eRoland McGrath	  if (llbufs != NULL
627f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	      && unlikely (getlocation (attr->cu, &block,
62899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					&llbufs[got], &listlens[got],
62999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					IDX_debug_loc) != 0))
630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    return -1;
631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ++got;
632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return got;
636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
637