dwarf_getlocation.c revision d1083043cf63551270f31aa83233d55286a89d65
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
115cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath/* DW_AT_data_member_location can be a constant as well as a loclistptr.
116cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath   Only data[48] indicate a loclistptr.  */
117cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrathstatic int
118cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrathcheck_constant_offset (Dwarf_Attribute *attr,
119cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath		       Dwarf_Op **llbuf, size_t *listlen)
120cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath{
121cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (attr->code != DW_AT_data_member_location
122cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      || attr->form == DW_FORM_data4
123cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      || attr->form == DW_FORM_data8)
124cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    return 1;
125cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
126cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  /* Check whether we already cached this location.  */
127cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  struct loc_s fake = { .addr = attr->valp };
128cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
129cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
130cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (found == NULL)
131cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    {
132cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      Dwarf_Word offset;
133cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
134cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath	return -1;
135cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
136cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      Dwarf_Op *result = libdw_alloc (attr->cu->dbg,
137cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath				      Dwarf_Op, sizeof (Dwarf_Op), 1);
138cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
139cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->atom = DW_OP_plus_uconst;
140cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->number = offset;
141cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->number2 = 0;
142cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      result->offset = 0;
143cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
144cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      /* Insert a record in the search tree so we can find it again later.  */
145cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      struct loc_s *newp = libdw_alloc (attr->cu->dbg,
146cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath					struct loc_s, sizeof (struct loc_s),
147cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath					1);
148cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      newp->addr = attr->valp;
149cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      newp->loc = result;
150cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      newp->nloc = 1;
151cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
152cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      found = tsearch (newp, &attr->cu->locs, loc_compare);
153cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    }
154cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
155cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  assert ((*found)->nloc == 1);
156cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
157cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (llbuf != NULL)
158cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    {
159cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      *llbuf = (*found)->loc;
160cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath      *listlen = 1;
161cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    }
162cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
163cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  return 0;
164cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath}
165cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
1663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathint
1673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathinternal_function
1683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath__libdw_intern_expression (Dwarf *dbg,
1693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath			   bool other_byte_order, unsigned int address_size,
1703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath			   void **cache, const Dwarf_Block *block,
1713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath			   Dwarf_Op **llbuf, size_t *listlen, int sec_index)
172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check whether we already looked at this list.  */
174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loc_s fake = { .addr = block->data };
1753c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  struct loc_s **found = tfind (&fake, cache, loc_compare);
176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (found != NULL)
177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We already saw it.  */
179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *llbuf = (*found)->loc;
180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *listlen = (*found)->nloc;
181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return 0;
183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const unsigned char *data = block->data;
186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const unsigned char *const end_data = data + block->length;
187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1883c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  const struct { bool other_byte_order; } bo = { other_byte_order };
1893c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loclist *loclist = NULL;
191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  unsigned int n = 0;
192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Decode the opcodes.  It is possible in some situations to have a
193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     block of size zero.  */
194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (data < end_data)
195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct loclist *newloc;
197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc = (struct loclist *) alloca (sizeof (struct loclist));
198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->number = 0;
199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->number2 = 0;
200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->offset = data - block->data;
201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->next = loclist;
202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      loclist = newloc;
203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ++n;
204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      switch ((newloc->atom = *data++))
206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_addr:
208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Address, depends on address size of CU.  */
20905c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath	  if (__libdw_read_address_inc (dbg, sec_index, &data,
2103c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath					address_size, &newloc->number))
21199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    return -1;
212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_deref:
215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_dup:
216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_drop:
217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_over:
218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_swap:
219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_rot:
220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xderef:
221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_abs:
222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_and:
223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_div:
224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_minus:
225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_mod:
226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_mul:
227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_neg:
228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_not:
229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_or:
230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_plus:
231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shl:
232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shr:
233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shra:
234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xor:
235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_eq:
236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_ge:
237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_gt:
238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_le:
239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_lt:
240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_ne:
241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_lit0 ... DW_OP_lit31:
242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_reg0 ... DW_OP_reg31:
243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_nop:
244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_push_object_address:
245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call_ref:
2468089343cc61743db7bf0fd75c21132cbab5c01fdRoland McGrath	case DW_OP_call_frame_cfa:
2477dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	case DW_OP_form_tls_address:
248d1083043cf63551270f31aa83233d55286a89d65Roland McGrath	case DW_OP_GNU_push_tls_address:
24996349ffaa68a1b4eec2fd1c9eb97a3d0b4e95a1eRoland McGrath	case DW_OP_stack_value:
250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* No operand.  */
251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const1u:
254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_pick:
255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_deref_size:
256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xderef_size:
257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data >= end_data))
25899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    {
25999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    invalid:
26099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
26199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	      return -1;
26299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	    }
263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = *data++;
265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const1s:
268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data >= end_data))
269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = *((int8_t *) data);
272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ++data;
273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const2u:
276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 2 > end_data))
277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2793c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_2ubyte_unaligned_inc (&bo, data);
280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const2s:
283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_skip:
284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_bra:
285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call2:
286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 2 > end_data))
287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2893c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_2sbyte_unaligned_inc (&bo, data);
290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const4u:
293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 4 > end_data))
294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
2963c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_4ubyte_unaligned_inc (&bo, data);
297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const4s:
300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call4:
301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 4 > end_data))
302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_4sbyte_unaligned_inc (&bo, data);
305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const8u:
308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 8 > end_data))
309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_8ubyte_unaligned_inc (&bo, data);
312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const8s:
315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 8 > end_data))
316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3183c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  newloc->number = read_8sbyte_unaligned_inc (&bo, data);
319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_constu:
322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_plus_uconst:
323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_regx:
324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_piece:
325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_uleb128 (newloc->number, data);
327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_consts:
330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_breg0 ... DW_OP_breg31:
331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_fbreg:
332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_sleb128 (newloc->number, data);
334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_bregx:
337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_uleb128 (newloc->number, data);
339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_sleb128 (newloc->number2, data);
340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3427dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	case DW_OP_bit_piece:
3437dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  /* XXX Check size.  */
3447dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  get_uleb128 (newloc->number, data);
3457dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  get_uleb128 (newloc->number2, data);
3467dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath	  break;
3477dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath
348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	default:
349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto invalid;
350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (unlikely (n == 0))
354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* This is not allowed.
356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 XXX Is it?  */
358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      goto invalid;
359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Allocate the array.  */
3623c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  Dwarf_Op *result;
3633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (dbg != NULL)
3643c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n);
3653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  else
3663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
3673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      result = malloc (sizeof *result * n);
3683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (result == NULL)
3693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
3703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	nomem:
3713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  __libdw_seterrno (DWARF_E_NOMEM);
3723c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  return -1;
3733c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
3743c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Store the result.  */
377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  *llbuf = result;
378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  *listlen = n;
379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  do
381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We populate the array from the back since the list is
383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper         backwards.  */
384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      --n;
385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].atom = loclist->atom;
386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].number = loclist->number;
387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].number2 = loclist->number2;
388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].offset = loclist->offset;
389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      loclist = loclist->next;
391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (n > 0);
393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Insert a record in the search tree so that we can find it again
395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     later.  */
3963c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  struct loc_s *newp;
3973c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  if (dbg != NULL)
3983c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1);
3993c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  else
4003c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    {
4013c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      newp = malloc (sizeof *newp);
4023c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath      if (newp == NULL)
4033c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	{
4043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  free (result);
4053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	  goto nomem;
4063c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	}
4073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath    }
4083c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->addr = block->data;
410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->loc = result;
411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->nloc = *listlen;
4123c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  (void) tsearch (newp, cache, loc_compare);
413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We did it.  */
415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return 0;
416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
4183c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic int
4193c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathgetlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
4203c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath	     Dwarf_Op **llbuf, size_t *listlen, int sec_index)
4213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{
4223c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath  return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
4233c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath				    cu->address_size, &cu->locs,
4243c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath				    block, llbuf, listlen, sec_index);
4253c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath}
4263c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath
427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
4286724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation (attr, llbuf, listlen)
429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Attribute *attr;
4306724c90d02659f7466b67b357563042e403d154eRoland McGrath     Dwarf_Op **llbuf;
431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t *listlen;
432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
433cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  int result = check_constant_offset (attr, llbuf, listlen);
434cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (result != 1)
435cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    return result;
436cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (! attr_ok (attr))
438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* If it has a block form, it's a single location expression.  */
441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Block block;
442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (INTUSE(dwarf_formblock) (attr, &block) != 0)
443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
44599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  return getlocation (attr->cu, &block, llbuf, listlen, IDX_debug_info);
446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
4496724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Attribute *attr;
451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Addr address;
4526724c90d02659f7466b67b357563042e403d154eRoland McGrath     Dwarf_Op **llbufs;
453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t *listlens;
454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t maxlocs;
455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (! attr_ok (attr))
457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (llbufs == NULL)
460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    maxlocs = SIZE_MAX;
461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* If it has a block form, it's a single location expression.  */
463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Block block;
464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (INTUSE(dwarf_formblock) (attr, &block) == 0)
465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (maxlocs == 0)
467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return 0;
468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (llbufs != NULL &&
46999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	  getlocation (attr->cu, &block, &llbufs[0], &listlens[0],
47099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper		       IDX_debug_info) != 0)
471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return -1;
472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return listlens[0] == 0 ? 0 : 1;
473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  int error = INTUSE(dwarf_errno) ();
476f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  if (unlikely (error != DWARF_E_NO_BLOCK))
477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (error);
479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return -1;
480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
482cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  int result = check_constant_offset (attr, &llbufs[0], &listlens[0]);
483cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath  if (result != 1)
484cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath    return result ?: 1;
485cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath
48699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  unsigned char *endp;
48799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  unsigned char *readp = __libdw_formptr (attr, IDX_debug_loc,
48899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					  DWARF_E_NO_LOCLIST, &endp, NULL);
48999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper  if (readp == NULL)
490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
492f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  Dwarf_Addr base = (Dwarf_Addr) -1;
493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t got = 0;
494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (got < maxlocs)
495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
49699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (endp - readp < attr->cu->address_size * 2)
497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	invalid:
499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  return -1;
501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Dwarf_Addr begin;
504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Dwarf_Addr end;
505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
50699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      int status
50799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	= __libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc,
50899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					   &readp, attr->cu->address_size,
50999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					   &begin, &end, &base);
51099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (status == 2) /* End of list entry.  */
511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	break;
51299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      else if (status == 1) /* Base address selected.  */
51399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	continue;
51499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      else if (status < 0)
51599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper	return status;
516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
51799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (endp - readp < 2)
518f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	goto invalid;
519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We have a location expression.  */
521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      block.data = readp;
52399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper      if (endp - readp < (ptrdiff_t) block.length)
524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	goto invalid;
525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      readp += block.length;
526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
527f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath      if (base == (Dwarf_Addr) -1)
528f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	{
529f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  /* Fetch the CU's base address.  */
530f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  Dwarf_Die cudie = CUDIE (attr->cu);
531f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath
532f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  /* Find the base address of the compilation unit.  It will
533f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     normally be specified by DW_AT_low_pc.  In DWARF-3 draft 4,
534f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     the base address could be overridden by DW_AT_entry_pc.  It's
535f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
536f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     for compilation units with discontinuous ranges.  */
537f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  Dwarf_Attribute attr_mem;
538f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  if (unlikely (INTUSE(dwarf_lowpc) (&cudie, &base) != 0)
539f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	      && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
540f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath							     DW_AT_entry_pc,
541f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath							     &attr_mem),
542f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath					 &base) != 0)
543f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	    {
54456bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      if (INTUSE(dwarf_errno) () != 0)
5458190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath		return -1;
54656bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper
54756bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      /* The compiler provided no base address when it should
54856bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper		 have.  Buggy GCC does this when it used absolute
54956bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper		 addresses in the location list and no DW_AT_ranges.  */
55056bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      base = 0;
551f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	    }
552f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	}
553f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath
554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (address >= base + begin && address < base + end)
555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* This one matches the address.  */
5576724c90d02659f7466b67b357563042e403d154eRoland McGrath	  if (llbufs != NULL
558f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	      && unlikely (getlocation (attr->cu, &block,
55999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					&llbufs[got], &listlens[got],
56099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper					IDX_debug_loc) != 0))
561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    return -1;
562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ++got;
563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return got;
567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
568