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