dwarf_getlocation.c revision f0371041995308d197447019eb2ac9285c96477b
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return location expression list. 205c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath Copyright (C) 2000-2009 Red Hat, Inc. 3361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper This file is part of Red Hat elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2000. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat elfutils is free software; you can redistribute it and/or modify 7361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper it under the terms of the GNU General Public License as published by the 8361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Free Software Foundation; version 2 of the License. 9b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 10361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat elfutils is distributed in the hope that it will be useful, but 11361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 14361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 15361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper You should have received a copy of the GNU General Public License along 16361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper with Red Hat elfutils; if not, write to the Free Software Foundation, 171e9ef50681e20ef14c2ba38aef37a71ff148be08Ulrich Drepper Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 18361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 19361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper In addition, as a special exception, Red Hat, Inc. gives You the 20361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper additional right to link the code of Red Hat elfutils with code licensed 21361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper under any Open Source Initiative certified open source license 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper (http://www.opensource.org/licenses/index.php) which requires the 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper distribution of source code with any binary distribution and to 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper distribute linked combinations of the two. Non-GPL Code permitted under 25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper this exception must only link to the code of Red Hat elfutils through 26361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper those well defined interfaces identified in the file named EXCEPTION 27361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper found in the source code files (the "Approved Interfaces"). The files 28361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper of Non-GPL Code may instantiate templates or use macros or inline 29361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper functions from the Approved Interfaces without causing the resulting 30361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper work to be covered by the GNU General Public License. Only Red Hat, 31361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Inc. may make changes or additions to the list of Approved Interfaces. 32361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat's grant of this exception is conditioned upon your not adding 33361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper any new exceptions. If you wish to add a new Approved Interface or 34361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper exception, please contact Red Hat. You must obey the GNU General Public 35361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper License in all respects for all of the Red Hat elfutils code and other 36361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper code used in conjunction with Red Hat elfutils except the Non-GPL Code 37361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper covered by this exception. If you modify this file, you may extend this 38361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper exception to your version of the file, but you are not obligated to do 39361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper so. If you do not wish to provide this exception without modification, 40361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper you must delete this exception statement from your version and license 41361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper this file solely under the GPL without exception. 42361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 43361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat elfutils is an included package of the Open Invention Network. 44361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper An included package of the Open Invention Network is a package for which 45361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Open Invention Network licensees cross-license their patents. No patent 46361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper license is granted, either expressly or impliedly, by designation as an 47361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper included package. Should you wish to participate in the Open Invention 48361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Network licensing program, please visit www.openinventionnetwork.com 49361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper <http://www.openinventionnetwork.com>. */ 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <dwarf.h> 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <search.h> 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 58cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath#include <assert.h> 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libdwP.h> 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperattr_ok (Dwarf_Attribute *attr) 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (attr == NULL) 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Must be one of the attributes listed below. */ 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (attr->code) 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_location: 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_data_member_location: 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_vtable_elem_location: 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_string_length: 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_use_location: 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_frame_base: 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_return_addr: 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_static_link: 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdw_seterrno (DWARF_E_NO_LOCLIST); 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstruct loclist 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint8_t atom; 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word number; 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word number2; 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word offset; 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loclist *next; 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperloc_compare (const void *p1, const void *p2) 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const struct loc_s *l1 = (const struct loc_s *) p1; 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const struct loc_s *l2 = (const struct loc_s *) p2; 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((uintptr_t) l1->addr < (uintptr_t) l2->addr) 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((uintptr_t) l1->addr > (uintptr_t) l2->addr) 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 115f0371041995308d197447019eb2ac9285c96477bRoland McGrath/* For each DW_OP_implicit_value, we store a special entry in the cache. 116f0371041995308d197447019eb2ac9285c96477bRoland McGrath This points us directly to the block data for later fetching. */ 117f0371041995308d197447019eb2ac9285c96477bRoland McGrathstatic void 118f0371041995308d197447019eb2ac9285c96477bRoland McGrathstore_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op, 119f0371041995308d197447019eb2ac9285c96477bRoland McGrath unsigned char *data) 120f0371041995308d197447019eb2ac9285c96477bRoland McGrath{ 121f0371041995308d197447019eb2ac9285c96477bRoland McGrath struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s, 122f0371041995308d197447019eb2ac9285c96477bRoland McGrath sizeof (struct loc_block_s), 1); 123f0371041995308d197447019eb2ac9285c96477bRoland McGrath block->addr = op; 124f0371041995308d197447019eb2ac9285c96477bRoland McGrath block->data = data + op->number2; 125f0371041995308d197447019eb2ac9285c96477bRoland McGrath block->length = op->number; 126f0371041995308d197447019eb2ac9285c96477bRoland McGrath (void) tsearch (block, cache, loc_compare); 127f0371041995308d197447019eb2ac9285c96477bRoland McGrath} 128f0371041995308d197447019eb2ac9285c96477bRoland McGrath 129f0371041995308d197447019eb2ac9285c96477bRoland McGrathint 130f0371041995308d197447019eb2ac9285c96477bRoland McGrathdwarf_getlocation_implicit_value (attr, op, return_block) 131f0371041995308d197447019eb2ac9285c96477bRoland McGrath Dwarf_Attribute *attr; 132f0371041995308d197447019eb2ac9285c96477bRoland McGrath Dwarf_Op *op; 133f0371041995308d197447019eb2ac9285c96477bRoland McGrath Dwarf_Block *return_block; 134f0371041995308d197447019eb2ac9285c96477bRoland McGrath{ 135f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (attr == NULL) 136f0371041995308d197447019eb2ac9285c96477bRoland McGrath return -1; 137f0371041995308d197447019eb2ac9285c96477bRoland McGrath 138f0371041995308d197447019eb2ac9285c96477bRoland McGrath struct loc_block_s fake = { .addr = op }; 139f0371041995308d197447019eb2ac9285c96477bRoland McGrath struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare); 140f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (unlikely (found == NULL)) 141f0371041995308d197447019eb2ac9285c96477bRoland McGrath { 142f0371041995308d197447019eb2ac9285c96477bRoland McGrath __libdw_seterrno (DWARF_E_NO_BLOCK); 143f0371041995308d197447019eb2ac9285c96477bRoland McGrath return -1; 144f0371041995308d197447019eb2ac9285c96477bRoland McGrath } 145f0371041995308d197447019eb2ac9285c96477bRoland McGrath 146f0371041995308d197447019eb2ac9285c96477bRoland McGrath return_block->length = (*found)->length; 147f0371041995308d197447019eb2ac9285c96477bRoland McGrath return_block->data = (*found)->data; 148f0371041995308d197447019eb2ac9285c96477bRoland McGrath return 0; 149f0371041995308d197447019eb2ac9285c96477bRoland McGrath} 150f0371041995308d197447019eb2ac9285c96477bRoland McGrath 151cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath/* DW_AT_data_member_location can be a constant as well as a loclistptr. 152cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Only data[48] indicate a loclistptr. */ 153cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrathstatic int 154cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrathcheck_constant_offset (Dwarf_Attribute *attr, 155cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Op **llbuf, size_t *listlen) 156cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath{ 157cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (attr->code != DW_AT_data_member_location 158cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath || attr->form == DW_FORM_data4 159cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath || attr->form == DW_FORM_data8) 160cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return 1; 161cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 162cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath /* Check whether we already cached this location. */ 163cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s fake = { .addr = attr->valp }; 164cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare); 165cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 166cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (found == NULL) 167cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath { 168cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Word offset; 169cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (INTUSE(dwarf_formudata) (attr, &offset) != 0) 170cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return -1; 171cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 172cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Op *result = libdw_alloc (attr->cu->dbg, 173cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Op, sizeof (Dwarf_Op), 1); 174cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 175cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->atom = DW_OP_plus_uconst; 176cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->number = offset; 177cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->number2 = 0; 178cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->offset = 0; 179cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 180cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath /* Insert a record in the search tree so we can find it again later. */ 181cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s *newp = libdw_alloc (attr->cu->dbg, 182cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s, sizeof (struct loc_s), 183cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 1); 184cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath newp->addr = attr->valp; 185cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath newp->loc = result; 186cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath newp->nloc = 1; 187cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 188cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath found = tsearch (newp, &attr->cu->locs, loc_compare); 189cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath } 190cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 191cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath assert ((*found)->nloc == 1); 192cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 193cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (llbuf != NULL) 194cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath { 195cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath *llbuf = (*found)->loc; 196cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath *listlen = 1; 197cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath } 198cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 199cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return 0; 200cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath} 201cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 2023c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathint 2033c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathinternal_function 2043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath__libdw_intern_expression (Dwarf *dbg, 2053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath bool other_byte_order, unsigned int address_size, 206af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath void **cache, const Dwarf_Block *block, bool valuep, 2073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Op **llbuf, size_t *listlen, int sec_index) 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether we already looked at this list. */ 210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loc_s fake = { .addr = block->data }; 2113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath struct loc_s **found = tfind (&fake, cache, loc_compare); 212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (found != NULL) 213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We already saw it. */ 215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *llbuf = (*found)->loc; 216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *listlen = (*found)->nloc; 217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 218af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath if (valuep) 219af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath { 220af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath assert (*listlen > 1); 221af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value); 222af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath } 223af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const unsigned char *data = block->data; 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const unsigned char *const end_data = data + block->length; 229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath const struct { bool other_byte_order; } bo = { other_byte_order }; 2313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loclist *loclist = NULL; 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int n = 0; 234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Decode the opcodes. It is possible in some situations to have a 235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper block of size zero. */ 236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (data < end_data) 237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loclist *newloc; 239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc = (struct loclist *) alloca (sizeof (struct loclist)); 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number = 0; 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number2 = 0; 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->offset = data - block->data; 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->next = loclist; 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loclist = newloc; 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++n; 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch ((newloc->atom = *data++)) 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_addr: 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Address, depends on address size of CU. */ 25105c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath if (__libdw_read_address_inc (dbg, sec_index, &data, 2523c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath address_size, &newloc->number)) 25399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper return -1; 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_deref: 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_dup: 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_drop: 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_over: 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_swap: 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_rot: 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_xderef: 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_abs: 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_and: 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_div: 266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_minus: 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_mod: 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_mul: 269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_neg: 270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_not: 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_or: 272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_plus: 273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_shl: 274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_shr: 275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_shra: 276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_xor: 277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_eq: 278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_ge: 279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_gt: 280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_le: 281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_lt: 282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_ne: 283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_lit0 ... DW_OP_lit31: 284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_reg0 ... DW_OP_reg31: 285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_nop: 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_push_object_address: 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_call_ref: 2888089343cc61743db7bf0fd75c21132cbab5c01fdRoland McGrath case DW_OP_call_frame_cfa: 2897dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath case DW_OP_form_tls_address: 290d1083043cf63551270f31aa83233d55286a89d65Roland McGrath case DW_OP_GNU_push_tls_address: 29196349ffaa68a1b4eec2fd1c9eb97a3d0b4e95a1eRoland McGrath case DW_OP_stack_value: 292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No operand. */ 293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const1u: 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_pick: 297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_deref_size: 298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_xderef_size: 299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data >= end_data)) 30099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper { 30199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper invalid: 30299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper __libdw_seterrno (DWARF_E_INVALID_DWARF); 30399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper return -1; 30499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper } 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number = *data++; 307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const1s: 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data >= end_data)) 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number = *((int8_t *) data); 314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++data; 315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const2u: 318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 2 > end_data)) 319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_2ubyte_unaligned_inc (&bo, data); 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const2s: 325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_skip: 326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_bra: 327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_call2: 328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 2 > end_data)) 329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_2sbyte_unaligned_inc (&bo, data); 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const4u: 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 4 > end_data)) 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3383c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_4ubyte_unaligned_inc (&bo, data); 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const4s: 342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_call4: 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 4 > end_data)) 344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3463c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_4sbyte_unaligned_inc (&bo, data); 347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const8u: 350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 8 > end_data)) 351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3533c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_8ubyte_unaligned_inc (&bo, data); 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const8s: 357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 8 > end_data)) 358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3603c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_8sbyte_unaligned_inc (&bo, data); 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_constu: 364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_plus_uconst: 365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_regx: 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_piece: 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX Check size. */ 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper get_uleb128 (newloc->number, data); 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_consts: 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_breg0 ... DW_OP_breg31: 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_fbreg: 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX Check size. */ 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper get_sleb128 (newloc->number, data); 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_bregx: 379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX Check size. */ 380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper get_uleb128 (newloc->number, data); 381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper get_sleb128 (newloc->number2, data); 382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3847dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath case DW_OP_bit_piece: 3857dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath /* XXX Check size. */ 3867dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath get_uleb128 (newloc->number, data); 3877dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath get_uleb128 (newloc->number2, data); 3887dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath break; 3897dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath 390f0371041995308d197447019eb2ac9285c96477bRoland McGrath case DW_OP_implicit_value: 391f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* This cannot be used in a CFI expression. */ 392f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (unlikely (dbg == NULL)) 393f0371041995308d197447019eb2ac9285c96477bRoland McGrath goto invalid; 394f0371041995308d197447019eb2ac9285c96477bRoland McGrath 395f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* XXX Check size. */ 396f0371041995308d197447019eb2ac9285c96477bRoland McGrath get_uleb128 (newloc->number, data); /* Block length. */ 397f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number)) 398f0371041995308d197447019eb2ac9285c96477bRoland McGrath goto invalid; 399f0371041995308d197447019eb2ac9285c96477bRoland McGrath newloc->number2 = data - block->data; /* Relative block offset. */ 400f0371041995308d197447019eb2ac9285c96477bRoland McGrath data += newloc->number; /* Skip the block. */ 401f0371041995308d197447019eb2ac9285c96477bRoland McGrath break; 402f0371041995308d197447019eb2ac9285c96477bRoland McGrath 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (n == 0)) 409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is not allowed. 411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper XXX Is it? */ 413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 416af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath if (valuep) 417af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath { 418af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath struct loclist *newloc; 419af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc = (struct loclist *) alloca (sizeof (struct loclist)); 420af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->atom = DW_OP_stack_value; 421af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->number = 0; 422af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->number2 = 0; 423af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->offset = data - block->data; 424af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->next = loclist; 425af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath loclist = newloc; 426af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath ++n; 427af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath } 428af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath 429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allocate the array. */ 4303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Op *result; 4313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (dbg != NULL) 4323c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n); 4333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath else 4343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 4353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath result = malloc (sizeof *result * n); 4363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (result == NULL) 4373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 4383c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath nomem: 4393c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath __libdw_seterrno (DWARF_E_NOMEM); 4403c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return -1; 4413c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 4423c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Store the result. */ 445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *llbuf = result; 446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *listlen = n; 447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 450f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* We populate the array from the back since the list is backwards. */ 451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper --n; 452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].atom = loclist->atom; 453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].number = loclist->number; 454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].number2 = loclist->number2; 455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].offset = loclist->offset; 456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 457f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (result[n].atom == DW_OP_implicit_value) 458f0371041995308d197447019eb2ac9285c96477bRoland McGrath store_implicit_value (dbg, cache, &result[n], block->data); 459f0371041995308d197447019eb2ac9285c96477bRoland McGrath 460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loclist = loclist->next; 461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (n > 0); 463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 464f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* Insert a record in the search tree so that we can find it again later. */ 4653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath struct loc_s *newp; 4663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (dbg != NULL) 4673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1); 4683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath else 4693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 4703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newp = malloc (sizeof *newp); 4713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (newp == NULL) 4723c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 4733c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath free (result); 4743c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath goto nomem; 4753c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 4763c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 4773c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->addr = block->data; 479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->loc = result; 480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->nloc = *listlen; 4813c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath (void) tsearch (newp, cache, loc_compare); 482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We did it. */ 484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4873c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic int 4883c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathgetlocation (struct Dwarf_CU *cu, const Dwarf_Block *block, 4893c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Op **llbuf, size_t *listlen, int sec_index) 4903c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{ 4913c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order, 492af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath cu->address_size, &cu->locs, block, false, 493af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath llbuf, listlen, sec_index); 4943c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath} 4953c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 4976724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation (attr, llbuf, listlen) 498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Attribute *attr; 4996724c90d02659f7466b67b357563042e403d154eRoland McGrath Dwarf_Op **llbuf; 500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t *listlen; 501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 502cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath int result = check_constant_offset (attr, llbuf, listlen); 503cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (result != 1) 504cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return result; 505cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! attr_ok (attr)) 507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If it has a block form, it's a single location expression. */ 510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Block block; 511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (INTUSE(dwarf_formblock) (attr, &block) != 0) 512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 51499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper return getlocation (attr->cu, &block, llbuf, listlen, IDX_debug_info); 515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 5186724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs) 519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Attribute *attr; 520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr address; 5216724c90d02659f7466b67b357563042e403d154eRoland McGrath Dwarf_Op **llbufs; 522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t *listlens; 523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t maxlocs; 524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! attr_ok (attr)) 526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (llbufs == NULL) 529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper maxlocs = SIZE_MAX; 530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If it has a block form, it's a single location expression. */ 532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Block block; 533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (INTUSE(dwarf_formblock) (attr, &block) == 0) 534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (maxlocs == 0) 536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (llbufs != NULL && 53899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper getlocation (attr->cu, &block, &llbufs[0], &listlens[0], 53999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper IDX_debug_info) != 0) 540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return listlens[0] == 0 ? 0 : 1; 542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int error = INTUSE(dwarf_errno) (); 545f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath if (unlikely (error != DWARF_E_NO_BLOCK)) 546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdw_seterrno (error); 548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 551cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath int result = check_constant_offset (attr, &llbufs[0], &listlens[0]); 552cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (result != 1) 553cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return result ?: 1; 554cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 55599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper unsigned char *endp; 55699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper unsigned char *readp = __libdw_formptr (attr, IDX_debug_loc, 55799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper DWARF_E_NO_LOCLIST, &endp, NULL); 55899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (readp == NULL) 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 561f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath Dwarf_Addr base = (Dwarf_Addr) -1; 562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t got = 0; 563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (got < maxlocs) 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 56599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (endp - readp < attr->cu->address_size * 2) 566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper invalid: 568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdw_seterrno (DWARF_E_INVALID_DWARF); 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr begin; 573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr end; 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 57599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper int status 57699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper = __libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc, 57799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper &readp, attr->cu->address_size, 57899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper &begin, &end, &base); 57999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (status == 2) /* End of list entry. */ 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 58199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper else if (status == 1) /* Base address selected. */ 58299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper continue; 58399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper else if (status < 0) 58499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper return status; 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 58699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (endp - readp < 2) 587f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath goto invalid; 588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have a location expression. */ 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp); 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper block.data = readp; 59299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (endp - readp < (ptrdiff_t) block.length) 593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper readp += block.length; 595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 596f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath if (base == (Dwarf_Addr) -1) 597f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath { 598f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath /* Fetch the CU's base address. */ 599f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath Dwarf_Die cudie = CUDIE (attr->cu); 600f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath 601f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath /* Find the base address of the compilation unit. It will 602f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath normally be specified by DW_AT_low_pc. In DWARF-3 draft 4, 603f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath the base address could be overridden by DW_AT_entry_pc. It's 604f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc 605f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath for compilation units with discontinuous ranges. */ 606f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath Dwarf_Attribute attr_mem; 607f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath if (unlikely (INTUSE(dwarf_lowpc) (&cudie, &base) != 0) 608f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, 609f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath DW_AT_entry_pc, 610f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath &attr_mem), 611f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath &base) != 0) 612f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath { 61356bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper if (INTUSE(dwarf_errno) () != 0) 6148190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath return -1; 61556bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper 61656bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper /* The compiler provided no base address when it should 61756bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper have. Buggy GCC does this when it used absolute 61856bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper addresses in the location list and no DW_AT_ranges. */ 61956bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper base = 0; 620f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath } 621f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath } 622f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (address >= base + begin && address < base + end) 624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This one matches the address. */ 6266724c90d02659f7466b67b357563042e403d154eRoland McGrath if (llbufs != NULL 627f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath && unlikely (getlocation (attr->cu, &block, 62899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper &llbufs[got], &listlens[got], 62999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper IDX_debug_loc) != 0)) 630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++got; 632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return got; 636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 637