dwarf_getlocation.c revision 56bc0b83ea81b7e959aaa4e1d01f8b36f2804a52
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return location expression list.
28190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath   Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006 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>
58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libdwP.h>
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool
63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperattr_ok (Dwarf_Attribute *attr)
64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (attr == NULL)
66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return false;
67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Must be one of the attributes listed below.  */
69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  switch (attr->code)
70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_location:
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_data_member_location:
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_vtable_elem_location:
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_string_length:
75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_use_location:
76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_frame_base:
77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_return_addr:
78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case DW_AT_static_link:
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    default:
82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_NO_LOCLIST);
83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return false;
84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return true;
87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstruct loclist
91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  uint8_t atom;
93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Word number;
94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Word number2;
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Word offset;
96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loclist *next;
97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int
101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperloc_compare (const void *p1, const void *p2)
102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const struct loc_s *l1 = (const struct loc_s *) p1;
104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const struct loc_s *l2 = (const struct loc_s *) p2;
105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if ((uintptr_t) l1->addr < (uintptr_t) l2->addr)
107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if ((uintptr_t) l1->addr > (uintptr_t) l2->addr)
109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return 1;
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return 0;
112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int
1156724c90d02659f7466b67b357563042e403d154eRoland McGrathgetlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
1166724c90d02659f7466b67b357563042e403d154eRoland McGrath	     Dwarf_Op **llbuf, size_t *listlen)
117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf *dbg = cu->dbg;
119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Check whether we already looked at this list.  */
121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loc_s fake = { .addr = block->data };
122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loc_s **found = tfind (&fake, &cu->locs, loc_compare);
123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (found != NULL)
124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We already saw it.  */
126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *llbuf = (*found)->loc;
127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *listlen = (*found)->nloc;
128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return 0;
130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const unsigned char *data = block->data;
133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const unsigned char *const end_data = data + block->length;
134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loclist *loclist = NULL;
136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  unsigned int n = 0;
137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Decode the opcodes.  It is possible in some situations to have a
138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     block of size zero.  */
139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (data < end_data)
140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct loclist *newloc;
142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc = (struct loclist *) alloca (sizeof (struct loclist));
143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->number = 0;
144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->number2 = 0;
145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->offset = data - block->data;
146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newloc->next = loclist;
147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      loclist = newloc;
148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ++n;
149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      switch ((newloc->atom = *data++))
151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_addr:
153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Address, depends on address size of CU.  */
154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (cu->address_size == 4)
155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (unlikely (data + 4 > end_data))
157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		{
158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		invalid:
159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  __libdw_seterrno (DWARF_E_INVALID_DWARF);
160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  return -1;
161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		}
162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      newloc->number = read_4ubyte_unaligned_inc (dbg, data);
164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  else
166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (unlikely (data + 8 > end_data))
168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		goto invalid;
169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      newloc->number = read_8ubyte_unaligned_inc (dbg, data);
171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_deref:
175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_dup:
176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_drop:
177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_over:
178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_swap:
179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_rot:
180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xderef:
181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_abs:
182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_and:
183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_div:
184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_minus:
185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_mod:
186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_mul:
187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_neg:
188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_not:
189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_or:
190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_plus:
191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shl:
192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shr:
193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_shra:
194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xor:
195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_eq:
196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_ge:
197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_gt:
198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_le:
199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_lt:
200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_ne:
201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_lit0 ... DW_OP_lit31:
202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_reg0 ... DW_OP_reg31:
203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_nop:
204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_push_object_address:
205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call_ref:
206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* No operand.  */
207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const1u:
210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_pick:
211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_deref_size:
212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_xderef_size:
213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data >= end_data))
214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = *data++;
217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const1s:
220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data >= end_data))
221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = *((int8_t *) data);
224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ++data;
225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const2u:
228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 2 > end_data))
229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = read_2ubyte_unaligned_inc (dbg, data);
232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const2s:
235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_skip:
236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_bra:
237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call2:
238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 2 > end_data))
239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = read_2sbyte_unaligned_inc (dbg, data);
242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const4u:
245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 4 > end_data))
246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = read_4ubyte_unaligned_inc (dbg, data);
249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const4s:
252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_call4:
253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 4 > end_data))
254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = read_4sbyte_unaligned_inc (dbg, data);
257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const8u:
260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 8 > end_data))
261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = read_8ubyte_unaligned_inc (dbg, data);
264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_const8s:
267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (unlikely (data + 8 > end_data))
268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    goto invalid;
269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  newloc->number = read_8sbyte_unaligned_inc (dbg, data);
271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_constu:
274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_plus_uconst:
275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_regx:
276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_piece:
277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_uleb128 (newloc->number, data);
279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_consts:
282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_breg0 ... DW_OP_breg31:
283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_fbreg:
284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_sleb128 (newloc->number, data);
286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	case DW_OP_bregx:
289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* XXX Check size.  */
290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_uleb128 (newloc->number, data);
291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  get_sleb128 (newloc->number2, data);
292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	default:
295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto invalid;
296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (unlikely (n == 0))
300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* This is not allowed.
302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 XXX Is it?  */
304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      goto invalid;
305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Allocate the array.  */
3086724c90d02659f7466b67b357563042e403d154eRoland McGrath  Dwarf_Op *result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n);
309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Store the result.  */
311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  *llbuf = result;
312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  *listlen = n;
313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  do
315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We populate the array from the back since the list is
317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper         backwards.  */
318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      --n;
319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].atom = loclist->atom;
320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].number = loclist->number;
321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].number2 = loclist->number2;
322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result[n].offset = loclist->offset;
323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      loclist = loclist->next;
325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (n > 0);
327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Insert a record in the search tree so that we can find it again
329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     later.  */
330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct loc_s *newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s),
331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				    1);
332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->addr = block->data;
333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->loc = result;
334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->nloc = *listlen;
335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  (void) tsearch (newp, &cu->locs, loc_compare);
336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We did it.  */
338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return 0;
339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
3426724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation (attr, llbuf, listlen)
343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Attribute *attr;
3446724c90d02659f7466b67b357563042e403d154eRoland McGrath     Dwarf_Op **llbuf;
345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t *listlen;
346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (! attr_ok (attr))
348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* If it has a block form, it's a single location expression.  */
351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Block block;
352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (INTUSE(dwarf_formblock) (attr, &block) != 0)
353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3556724c90d02659f7466b67b357563042e403d154eRoland McGrath  return getlocation (attr->cu, &block, llbuf, listlen);
356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
3596724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Attribute *attr;
361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Addr address;
3626724c90d02659f7466b67b357563042e403d154eRoland McGrath     Dwarf_Op **llbufs;
363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t *listlens;
364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t maxlocs;
365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (! attr_ok (attr))
367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (llbufs == NULL)
370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    maxlocs = SIZE_MAX;
371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* If it has a block form, it's a single location expression.  */
373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Block block;
374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (INTUSE(dwarf_formblock) (attr, &block) == 0)
375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (maxlocs == 0)
377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return 0;
378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (llbufs != NULL &&
3796724c90d02659f7466b67b357563042e403d154eRoland McGrath	  getlocation (attr->cu, &block, &llbufs[0], &listlens[0]) != 0)
380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return -1;
381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return listlens[0] == 0 ? 0 : 1;
382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  int error = INTUSE(dwarf_errno) ();
385f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  if (unlikely (error != DWARF_E_NO_BLOCK))
386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (error);
388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return -1;
389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Must have the form data4 or data8 which act as an offset.  */
392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf_Word offset;
393f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  if (unlikely (INTUSE(dwarf_formudata) (attr, &offset) != 0))
394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return -1;
395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
397f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  if (unlikely (d == NULL))
398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_NO_LOCLIST);
400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return -1;
401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
403f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath  Dwarf_Addr base = (Dwarf_Addr) -1;
404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  unsigned char *readp = d->d_buf + offset;
405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t got = 0;
406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (got < maxlocs)
407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if ((unsigned char *) d->d_buf + d->d_size - readp
409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  < attr->cu->address_size * 2)
410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	invalid:
412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  return -1;
414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Dwarf_Addr begin;
417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Dwarf_Addr end;
418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (attr->cu->address_size == 8)
419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  begin = read_8ubyte_unaligned_inc (attr->cu->dbg, readp);
421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  end = read_8ubyte_unaligned_inc (attr->cu->dbg, readp);
422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (begin == (Elf64_Addr) -1l) /* Base address entry.  */
424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      base = end;
426f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	      if (unlikely (base == (Dwarf_Addr) -1))
427f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath		goto invalid;
428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      continue;
429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  begin = read_4ubyte_unaligned_inc (attr->cu->dbg, readp);
434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  end = read_4ubyte_unaligned_inc (attr->cu->dbg, readp);
435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (begin == (Elf32_Addr) -1) /* Base address entry.  */
437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      base = end;
439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      continue;
440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (begin == 0 && end == 0) /* End of list entry.  */
444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	break;
445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if ((unsigned char *) d->d_buf + d->d_size - readp < 2)
447f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	goto invalid;
448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We have a location expression.  */
450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      block.data = readp;
452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if ((unsigned char *) d->d_buf + d->d_size - readp
453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  < (ptrdiff_t) block.length)
454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	goto invalid;
455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      readp += block.length;
456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
457f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath      if (base == (Dwarf_Addr) -1)
458f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	{
459f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  /* Fetch the CU's base address.  */
460f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  Dwarf_Die cudie = CUDIE (attr->cu);
461f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath
462f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  /* Find the base address of the compilation unit.  It will
463f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     normally be specified by DW_AT_low_pc.  In DWARF-3 draft 4,
464f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     the base address could be overridden by DW_AT_entry_pc.  It's
465f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
466f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	     for compilation units with discontinuous ranges.  */
467f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  Dwarf_Attribute attr_mem;
468f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	  if (unlikely (INTUSE(dwarf_lowpc) (&cudie, &base) != 0)
469f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	      && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
470f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath							     DW_AT_entry_pc,
471f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath							     &attr_mem),
472f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath					 &base) != 0)
473f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	    {
47456bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      if (INTUSE(dwarf_errno) () != 0)
4758190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath		return -1;
47656bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper
47756bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      /* The compiler provided no base address when it should
47856bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper		 have.  Buggy GCC does this when it used absolute
47956bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper		 addresses in the location list and no DW_AT_ranges.  */
48056bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper	      base = 0;
481f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	    }
482f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	}
483f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath
484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (address >= base + begin && address < base + end)
485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* This one matches the address.  */
4876724c90d02659f7466b67b357563042e403d154eRoland McGrath	  if (llbufs != NULL
488f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath	      && unlikely (getlocation (attr->cu, &block,
489f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath					&llbufs[got], &listlens[got]) != 0))
490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    return -1;
491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ++got;
492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return got;
496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
497