dwarf_getlocation.c revision 6fb3451de3ba29b628be6e30a01ef104156d4733
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return location expression list. 20ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath Copyright (C) 2000-2010 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; 1327e0aecdad525d8b290e2b9b999f6960a42bee33dRoland McGrath const Dwarf_Op *op; 133f0371041995308d197447019eb2ac9285c96477bRoland McGrath Dwarf_Block *return_block; 134f0371041995308d197447019eb2ac9285c96477bRoland McGrath{ 135f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (attr == NULL) 136f0371041995308d197447019eb2ac9285c96477bRoland McGrath return -1; 137f0371041995308d197447019eb2ac9285c96477bRoland McGrath 1387e0aecdad525d8b290e2b9b999f6960a42bee33dRoland McGrath struct loc_block_s fake = { .addr = (void *) 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{ 157888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath if (attr->code != DW_AT_data_member_location) 158cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return 1; 159cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 160888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath switch (attr->form) 161888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath { 162888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath /* Punt for any non-constant form. */ 163888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath default: 164888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath return 1; 165888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath 166888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_data1: 167888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_data2: 168888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_sdata: 169888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_udata: 170888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath break; 171888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath 172888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_data4: 173888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_data8: 174888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath /* These are loclistptr, not constants. 175888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath XXX check cu->version > 3??? 176888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath */ 177888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath return 1; 178888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath } 179888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath 180cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath /* Check whether we already cached this location. */ 181cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s fake = { .addr = attr->valp }; 182cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare); 183cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 184cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (found == NULL) 185cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath { 186cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Word offset; 187cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (INTUSE(dwarf_formudata) (attr, &offset) != 0) 188cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return -1; 189cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 190cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Op *result = libdw_alloc (attr->cu->dbg, 191cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Op, sizeof (Dwarf_Op), 1); 192cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 193cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->atom = DW_OP_plus_uconst; 194cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->number = offset; 195cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->number2 = 0; 196cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->offset = 0; 197cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 198cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath /* Insert a record in the search tree so we can find it again later. */ 199cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s *newp = libdw_alloc (attr->cu->dbg, 200cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s, sizeof (struct loc_s), 201cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 1); 202cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath newp->addr = attr->valp; 203cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath newp->loc = result; 204cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath newp->nloc = 1; 205cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 206cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath found = tsearch (newp, &attr->cu->locs, loc_compare); 207cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath } 208cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 209cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath assert ((*found)->nloc == 1); 210cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 211cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (llbuf != NULL) 212cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath { 213cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath *llbuf = (*found)->loc; 214cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath *listlen = 1; 215cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath } 216cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 217cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return 0; 218cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath} 219cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 2203c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathint 2213c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathinternal_function 222688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath__libdw_intern_expression (Dwarf *dbg, bool other_byte_order, 223688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath unsigned int address_size, unsigned int ref_size, 2240ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath void **cache, const Dwarf_Block *block, 2250ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath bool cfap, bool valuep, 2263c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Op **llbuf, size_t *listlen, int sec_index) 227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether we already looked at this list. */ 229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loc_s fake = { .addr = block->data }; 2303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath struct loc_s **found = tfind (&fake, cache, loc_compare); 231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (found != NULL) 232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We already saw it. */ 234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *llbuf = (*found)->loc; 235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *listlen = (*found)->nloc; 236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 237af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath if (valuep) 238af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath { 239af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath assert (*listlen > 1); 240af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value); 241af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath } 242af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const unsigned char *data = block->data; 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const unsigned char *const end_data = data + block->length; 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2493c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath const struct { bool other_byte_order; } bo = { other_byte_order }; 2503c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loclist *loclist = NULL; 252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int n = 0; 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Decode the opcodes. It is possible in some situations to have a 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper block of size zero. */ 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (data < end_data) 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loclist *newloc; 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc = (struct loclist *) alloca (sizeof (struct loclist)); 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number = 0; 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number2 = 0; 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->offset = data - block->data; 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->next = loclist; 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loclist = newloc; 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++n; 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch ((newloc->atom = *data++)) 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_addr: 269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Address, depends on address size of CU. */ 27005c4e04640d173a4d1ce6e2f25a24060c21a67abRoland McGrath if (__libdw_read_address_inc (dbg, sec_index, &data, 2713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath address_size, &newloc->number)) 27299d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper return -1; 273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 275688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath case DW_OP_call_ref: 276688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath /* DW_FORM_ref_addr, depends on offset size of CU. */ 277688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size, 278688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath &newloc->number, IDX_debug_info, 0)) 279688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath return -1; 280688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath break; 281688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath 282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_deref: 283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_dup: 284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_drop: 285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_over: 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_swap: 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_rot: 288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_xderef: 289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_abs: 290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_and: 291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_div: 292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_minus: 293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_mod: 294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_mul: 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_neg: 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_not: 297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_or: 298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_plus: 299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_shl: 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_shr: 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_shra: 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_xor: 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_eq: 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_ge: 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_gt: 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_le: 307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_lt: 308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_ne: 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_lit0 ... DW_OP_lit31: 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_reg0 ... DW_OP_reg31: 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_nop: 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_push_object_address: 3138089343cc61743db7bf0fd75c21132cbab5c01fdRoland McGrath case DW_OP_call_frame_cfa: 3147dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath case DW_OP_form_tls_address: 315d1083043cf63551270f31aa83233d55286a89d65Roland McGrath case DW_OP_GNU_push_tls_address: 31696349ffaa68a1b4eec2fd1c9eb97a3d0b4e95a1eRoland McGrath case DW_OP_stack_value: 317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No operand. */ 318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const1u: 321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_pick: 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_deref_size: 323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_xderef_size: 324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data >= end_data)) 32599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper { 32699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper invalid: 32799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper __libdw_seterrno (DWARF_E_INVALID_DWARF); 32899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper return -1; 32999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper } 330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number = *data++; 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const1s: 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data >= end_data)) 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number = *((int8_t *) data); 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++data; 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const2u: 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 2 > end_data)) 344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3463c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_2ubyte_unaligned_inc (&bo, data); 347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const2s: 350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_skip: 351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_bra: 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_call2: 353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 2 > end_data)) 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3563c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_2sbyte_unaligned_inc (&bo, data); 357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const4u: 360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 4 > end_data)) 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_4ubyte_unaligned_inc (&bo, data); 364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const4s: 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_call4: 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 4 > end_data)) 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_4sbyte_unaligned_inc (&bo, data); 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const8u: 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 8 > end_data)) 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3783c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_8ubyte_unaligned_inc (&bo, data); 379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const8s: 382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 8 > end_data)) 383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3853c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_8sbyte_unaligned_inc (&bo, data); 386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_constu: 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_plus_uconst: 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_regx: 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_piece: 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX Check size. */ 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper get_uleb128 (newloc->number, data); 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_consts: 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_breg0 ... DW_OP_breg31: 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_fbreg: 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX Check size. */ 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper get_sleb128 (newloc->number, data); 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_bregx: 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX Check size. */ 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper get_uleb128 (newloc->number, data); 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper get_sleb128 (newloc->number2, data); 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4097dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath case DW_OP_bit_piece: 4107dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath /* XXX Check size. */ 4117dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath get_uleb128 (newloc->number, data); 4127dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath get_uleb128 (newloc->number2, data); 4137dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath break; 4147dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath 415f0371041995308d197447019eb2ac9285c96477bRoland McGrath case DW_OP_implicit_value: 416f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* This cannot be used in a CFI expression. */ 417f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (unlikely (dbg == NULL)) 418f0371041995308d197447019eb2ac9285c96477bRoland McGrath goto invalid; 419f0371041995308d197447019eb2ac9285c96477bRoland McGrath 420f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* XXX Check size. */ 421f0371041995308d197447019eb2ac9285c96477bRoland McGrath get_uleb128 (newloc->number, data); /* Block length. */ 422f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number)) 423f0371041995308d197447019eb2ac9285c96477bRoland McGrath goto invalid; 424f0371041995308d197447019eb2ac9285c96477bRoland McGrath newloc->number2 = data - block->data; /* Relative block offset. */ 425f0371041995308d197447019eb2ac9285c96477bRoland McGrath data += newloc->number; /* Skip the block. */ 426f0371041995308d197447019eb2ac9285c96477bRoland McGrath break; 427f0371041995308d197447019eb2ac9285c96477bRoland McGrath 428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (n == 0)) 434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is not allowed. 436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper XXX Is it? */ 438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 441af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath if (valuep) 442af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath { 443af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath struct loclist *newloc; 444af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc = (struct loclist *) alloca (sizeof (struct loclist)); 445af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->atom = DW_OP_stack_value; 446af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->number = 0; 447af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->number2 = 0; 448af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->offset = data - block->data; 449af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->next = loclist; 450af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath loclist = newloc; 451af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath ++n; 452af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath } 453af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath 4540ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath if (cfap) 4550ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath ++n; 4560ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath 457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allocate the array. */ 4583c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Op *result; 4593c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (dbg != NULL) 4603c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n); 4613c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath else 4623c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 4633c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath result = malloc (sizeof *result * n); 4643c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (result == NULL) 4653c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 4663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath nomem: 4673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath __libdw_seterrno (DWARF_E_NOMEM); 4683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return -1; 4693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 4703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Store the result. */ 473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *llbuf = result; 474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *listlen = n; 475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4760ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath if (cfap) 4770ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath { 4780ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath /* Synthesize the operation to push the CFA before the expression. */ 4790ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath --n; 4800ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath result[0].atom = DW_OP_call_frame_cfa; 4810ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath result[0].number = 0; 4820ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath result[0].number2 = 0; 4830ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath result[0].offset = -1; 4840ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath } 4850ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath 486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 488f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* We populate the array from the back since the list is backwards. */ 489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper --n; 490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].atom = loclist->atom; 491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].number = loclist->number; 492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].number2 = loclist->number2; 493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].offset = loclist->offset; 494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 495f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (result[n].atom == DW_OP_implicit_value) 496f0371041995308d197447019eb2ac9285c96477bRoland McGrath store_implicit_value (dbg, cache, &result[n], block->data); 497f0371041995308d197447019eb2ac9285c96477bRoland McGrath 498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loclist = loclist->next; 499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (n > 0); 501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 502f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* Insert a record in the search tree so that we can find it again later. */ 5033c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath struct loc_s *newp; 5043c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (dbg != NULL) 5053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1); 5063c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath else 5073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 5083c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newp = malloc (sizeof *newp); 5093c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (newp == NULL) 5103c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 5113c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath free (result); 5123c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath goto nomem; 5133c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 5143c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 5153c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->addr = block->data; 517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->loc = result; 518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->nloc = *listlen; 5193c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath (void) tsearch (newp, cache, loc_compare); 520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We did it. */ 522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 5253c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic int 5263c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathgetlocation (struct Dwarf_CU *cu, const Dwarf_Block *block, 5273c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Op **llbuf, size_t *listlen, int sec_index) 5283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{ 5293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order, 530688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath cu->address_size, (cu->version == 2 531688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath ? cu->address_size 532688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath : cu->offset_size), 533688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath &cu->locs, block, 5340ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath false, false, 535af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath llbuf, listlen, sec_index); 5363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath} 5373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 5396724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation (attr, llbuf, listlen) 540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Attribute *attr; 5416724c90d02659f7466b67b357563042e403d154eRoland McGrath Dwarf_Op **llbuf; 542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t *listlen; 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 5446fb3451de3ba29b628be6e30a01ef104156d4733Ulrich Drepper if (! attr_ok (attr)) 5456fb3451de3ba29b628be6e30a01ef104156d4733Ulrich Drepper return -1; 5466fb3451de3ba29b628be6e30a01ef104156d4733Ulrich Drepper 547cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath int result = check_constant_offset (attr, llbuf, listlen); 548cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (result != 1) 549cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return result; 550cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If it has a block form, it's a single location expression. */ 552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Block block; 553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (INTUSE(dwarf_formblock) (attr, &block) != 0) 554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 55699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper return getlocation (attr->cu, &block, llbuf, listlen, IDX_debug_info); 557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 5606724c90d02659f7466b67b357563042e403d154eRoland McGrathdwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs) 561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Attribute *attr; 562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr address; 5636724c90d02659f7466b67b357563042e403d154eRoland McGrath Dwarf_Op **llbufs; 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t *listlens; 565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t maxlocs; 566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! attr_ok (attr)) 568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (llbufs == NULL) 571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper maxlocs = SIZE_MAX; 572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If it has a block form, it's a single location expression. */ 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Block block; 575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (INTUSE(dwarf_formblock) (attr, &block) == 0) 576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (maxlocs == 0) 578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (llbufs != NULL && 58099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper getlocation (attr->cu, &block, &llbufs[0], &listlens[0], 58199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper IDX_debug_info) != 0) 582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return listlens[0] == 0 ? 0 : 1; 584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int error = INTUSE(dwarf_errno) (); 587f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath if (unlikely (error != DWARF_E_NO_BLOCK)) 588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdw_seterrno (error); 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 593cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath int result = check_constant_offset (attr, &llbufs[0], &listlens[0]); 594cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (result != 1) 595cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return result ?: 1; 596cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 59799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper unsigned char *endp; 59899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper unsigned char *readp = __libdw_formptr (attr, IDX_debug_loc, 59999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper DWARF_E_NO_LOCLIST, &endp, NULL); 60099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (readp == NULL) 601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 603f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath Dwarf_Addr base = (Dwarf_Addr) -1; 604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t got = 0; 605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (got < maxlocs) 606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 60799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (endp - readp < attr->cu->address_size * 2) 608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper invalid: 610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdw_seterrno (DWARF_E_INVALID_DWARF); 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr begin; 615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr end; 616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 61799d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper int status 61899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper = __libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc, 61999d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper &readp, attr->cu->address_size, 62099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper &begin, &end, &base); 62199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (status == 2) /* End of list entry. */ 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 62399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper else if (status == 1) /* Base address selected. */ 62499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper continue; 62599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper else if (status < 0) 62699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper return status; 627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 62899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (endp - readp < 2) 629f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath goto invalid; 630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have a location expression. */ 632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp); 633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper block.data = readp; 63499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper if (endp - readp < (ptrdiff_t) block.length) 635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper readp += block.length; 637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 638f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath if (base == (Dwarf_Addr) -1) 639f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath { 640f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath /* Fetch the CU's base address. */ 641f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath Dwarf_Die cudie = CUDIE (attr->cu); 642f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath 643f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath /* Find the base address of the compilation unit. It will 644f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath normally be specified by DW_AT_low_pc. In DWARF-3 draft 4, 645f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath the base address could be overridden by DW_AT_entry_pc. It's 646f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc 647f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath for compilation units with discontinuous ranges. */ 648f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath Dwarf_Attribute attr_mem; 649f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath if (unlikely (INTUSE(dwarf_lowpc) (&cudie, &base) != 0) 650f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, 651f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath DW_AT_entry_pc, 652f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath &attr_mem), 653f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath &base) != 0) 654f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath { 65556bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper if (INTUSE(dwarf_errno) () != 0) 6568190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath return -1; 65756bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper 65856bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper /* The compiler provided no base address when it should 65956bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper have. Buggy GCC does this when it used absolute 66056bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper addresses in the location list and no DW_AT_ranges. */ 66156bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper base = 0; 662f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath } 663f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath } 664f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath 665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (address >= base + begin && address < base + end) 666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This one matches the address. */ 6686724c90d02659f7466b67b357563042e403d154eRoland McGrath if (llbufs != NULL 669f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath && unlikely (getlocation (attr->cu, &block, 67099d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper &llbufs[got], &listlens[got], 67199d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper IDX_debug_loc) != 0)) 672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++got; 674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return got; 678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 679