1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return location expression list. 25316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard Copyright (C) 2000-2010, 2013-2015 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2000. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of either 8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 21de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 28de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard not, see <http://www.gnu.org/licenses/>. */ 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <dwarf.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <search.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 37cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath#include <assert.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libdwP.h> 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperattr_ok (Dwarf_Attribute *attr) 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (attr == NULL) 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Must be one of the attributes listed below. */ 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (attr->code) 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_location: 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_data_member_location: 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_vtable_elem_location: 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_string_length: 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_use_location: 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_frame_base: 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_return_addr: 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_AT_static_link: 5966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard case DW_AT_segment: 60476feb1c7db2c6dfa217f8a18d2eb1af2789cbb0Petr Machata case DW_AT_GNU_call_site_value: 61476feb1c7db2c6dfa217f8a18d2eb1af2789cbb0Petr Machata case DW_AT_GNU_call_site_data_value: 62476feb1c7db2c6dfa217f8a18d2eb1af2789cbb0Petr Machata case DW_AT_GNU_call_site_target: 63476feb1c7db2c6dfa217f8a18d2eb1af2789cbb0Petr Machata case DW_AT_GNU_call_site_target_clobbered: 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdw_seterrno (DWARF_E_NO_LOCLIST); 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstruct loclist 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint8_t atom; 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word number; 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word number2; 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word offset; 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loclist *next; 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperloc_compare (const void *p1, const void *p2) 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const struct loc_s *l1 = (const struct loc_s *) p1; 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const struct loc_s *l2 = (const struct loc_s *) p2; 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((uintptr_t) l1->addr < (uintptr_t) l2->addr) 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((uintptr_t) l1->addr > (uintptr_t) l2->addr) 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 99f0371041995308d197447019eb2ac9285c96477bRoland McGrath/* For each DW_OP_implicit_value, we store a special entry in the cache. 100f0371041995308d197447019eb2ac9285c96477bRoland McGrath This points us directly to the block data for later fetching. */ 101f0371041995308d197447019eb2ac9285c96477bRoland McGrathstatic void 102b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaardstore_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op) 103f0371041995308d197447019eb2ac9285c96477bRoland McGrath{ 104f0371041995308d197447019eb2ac9285c96477bRoland McGrath struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s, 105f0371041995308d197447019eb2ac9285c96477bRoland McGrath sizeof (struct loc_block_s), 1); 10674f9b7337562c06a93722ad757d258db8f082663Mark Wielaard const unsigned char *data = (const unsigned char *) (uintptr_t) op->number2; 1077a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard // Ignored, equal to op->number. And data length already checked. 1087a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard (void) __libdw_get_uleb128 (&data, data + len_leb128 (Dwarf_Word)); 109f0371041995308d197447019eb2ac9285c96477bRoland McGrath block->addr = op; 110b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard block->data = (unsigned char *) data; 111f0371041995308d197447019eb2ac9285c96477bRoland McGrath block->length = op->number; 112f0371041995308d197447019eb2ac9285c96477bRoland McGrath (void) tsearch (block, cache, loc_compare); 113f0371041995308d197447019eb2ac9285c96477bRoland McGrath} 114f0371041995308d197447019eb2ac9285c96477bRoland McGrath 115f0371041995308d197447019eb2ac9285c96477bRoland McGrathint 1161ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaarddwarf_getlocation_implicit_value (Dwarf_Attribute *attr, const Dwarf_Op *op, 1171ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard Dwarf_Block *return_block) 118f0371041995308d197447019eb2ac9285c96477bRoland McGrath{ 119f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (attr == NULL) 120f0371041995308d197447019eb2ac9285c96477bRoland McGrath return -1; 121f0371041995308d197447019eb2ac9285c96477bRoland McGrath 1227e0aecdad525d8b290e2b9b999f6960a42bee33dRoland McGrath struct loc_block_s fake = { .addr = (void *) op }; 123f0371041995308d197447019eb2ac9285c96477bRoland McGrath struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare); 124f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (unlikely (found == NULL)) 125f0371041995308d197447019eb2ac9285c96477bRoland McGrath { 126f0371041995308d197447019eb2ac9285c96477bRoland McGrath __libdw_seterrno (DWARF_E_NO_BLOCK); 127f0371041995308d197447019eb2ac9285c96477bRoland McGrath return -1; 128f0371041995308d197447019eb2ac9285c96477bRoland McGrath } 129f0371041995308d197447019eb2ac9285c96477bRoland McGrath 130f0371041995308d197447019eb2ac9285c96477bRoland McGrath return_block->length = (*found)->length; 131f0371041995308d197447019eb2ac9285c96477bRoland McGrath return_block->data = (*found)->data; 132f0371041995308d197447019eb2ac9285c96477bRoland McGrath return 0; 133f0371041995308d197447019eb2ac9285c96477bRoland McGrath} 134f0371041995308d197447019eb2ac9285c96477bRoland McGrath 135cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath/* DW_AT_data_member_location can be a constant as well as a loclistptr. 136cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Only data[48] indicate a loclistptr. */ 137cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrathstatic int 138cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrathcheck_constant_offset (Dwarf_Attribute *attr, 139cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Op **llbuf, size_t *listlen) 140cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath{ 141888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath if (attr->code != DW_AT_data_member_location) 142cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return 1; 143cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 144888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath switch (attr->form) 145888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath { 146888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath /* Punt for any non-constant form. */ 147888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath default: 148888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath return 1; 149888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath 150888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_data1: 151888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_data2: 152c16966a0043dc173fcaab5d3f8b754b4e9c9ceb7Roland McGrath case DW_FORM_data4: 153c16966a0043dc173fcaab5d3f8b754b4e9c9ceb7Roland McGrath case DW_FORM_data8: 154888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_sdata: 155888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath case DW_FORM_udata: 156888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath break; 157888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath } 158888381b9ace5251b9feaad14f9bfa8c9d85cb1fdRoland McGrath 159cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath /* Check whether we already cached this location. */ 160cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s fake = { .addr = attr->valp }; 161cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare); 162cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 163cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (found == NULL) 164cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath { 165cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Word offset; 166cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (INTUSE(dwarf_formudata) (attr, &offset) != 0) 167cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return -1; 168cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 169cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Op *result = libdw_alloc (attr->cu->dbg, 170cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath Dwarf_Op, sizeof (Dwarf_Op), 1); 171cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 172cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->atom = DW_OP_plus_uconst; 173cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->number = offset; 174cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->number2 = 0; 175cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath result->offset = 0; 176cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 177cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath /* Insert a record in the search tree so we can find it again later. */ 178cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s *newp = libdw_alloc (attr->cu->dbg, 179cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath struct loc_s, sizeof (struct loc_s), 180cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 1); 181cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath newp->addr = attr->valp; 182cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath newp->loc = result; 183cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath newp->nloc = 1; 184cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 185cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath found = tsearch (newp, &attr->cu->locs, loc_compare); 186cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath } 187cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 188cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath assert ((*found)->nloc == 1); 189cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 190cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (llbuf != NULL) 191cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath { 192cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath *llbuf = (*found)->loc; 193cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath *listlen = 1; 194cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath } 195cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 196cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return 0; 197cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath} 198cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 1993c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathint 2003c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathinternal_function 201688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath__libdw_intern_expression (Dwarf *dbg, bool other_byte_order, 202688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath unsigned int address_size, unsigned int ref_size, 2030ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath void **cache, const Dwarf_Block *block, 2040ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath bool cfap, bool valuep, 2053c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Op **llbuf, size_t *listlen, int sec_index) 206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2073951f2ec0aaca021c77a2c7a464dcf43433261c3Mark Wielaard /* Empty location expressions don't have any ops to intern. */ 2083951f2ec0aaca021c77a2c7a464dcf43433261c3Mark Wielaard if (block->length == 0) 2093951f2ec0aaca021c77a2c7a464dcf43433261c3Mark Wielaard { 2103951f2ec0aaca021c77a2c7a464dcf43433261c3Mark Wielaard *listlen = 0; 2113951f2ec0aaca021c77a2c7a464dcf43433261c3Mark Wielaard return 0; 2123951f2ec0aaca021c77a2c7a464dcf43433261c3Mark Wielaard } 2133951f2ec0aaca021c77a2c7a464dcf43433261c3Mark Wielaard 214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether we already looked at this list. */ 215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loc_s fake = { .addr = block->data }; 2163c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath struct loc_s **found = tfind (&fake, cache, loc_compare); 217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (found != NULL) 218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We already saw it. */ 220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *llbuf = (*found)->loc; 221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *listlen = (*found)->nloc; 222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 223af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath if (valuep) 224af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath { 225af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath assert (*listlen > 1); 226af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value); 227af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath } 228af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath 229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const unsigned char *data = block->data; 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const unsigned char *const end_data = data + block->length; 234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath const struct { bool other_byte_order; } bo = { other_byte_order }; 2363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loclist *loclist = NULL; 238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int n = 0; 23996a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil 240720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard /* Stack allocate at most this many locs. */ 241720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard#define MAX_STACK_LOCS 256 242720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard struct loclist stack_locs[MAX_STACK_LOCS]; 243720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard#define NEW_LOC() ({ struct loclist *ll; \ 244720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard ll = (likely (n < MAX_STACK_LOCS) \ 245720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard ? &stack_locs[n] \ 246720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard : malloc (sizeof (struct loclist))); \ 247720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard if (unlikely (ll == NULL)) \ 248720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard goto nomem; \ 249720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard n++; \ 250720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard ll->next = loclist; \ 251720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard loclist = ll; \ 252720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard ll; }) 253720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard 25496a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil if (cfap) 25596a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil { 25696a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil /* Synthesize the operation to push the CFA before the expression. */ 257720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard struct loclist *newloc = NEW_LOC (); 25896a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil newloc->atom = DW_OP_call_frame_cfa; 25996a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil newloc->number = 0; 26096a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil newloc->number2 = 0; 26196a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil newloc->offset = -1; 26296a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil } 26396a9fc6ae246e2e03f9d82f136960691fa4a88feJan Kratochvil 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Decode the opcodes. It is possible in some situations to have a 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper block of size zero. */ 266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (data < end_data) 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loclist *newloc; 269720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard newloc = NEW_LOC (); 270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number = 0; 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number2 = 0; 272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->offset = data - block->data; 273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch ((newloc->atom = *data++)) 275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_addr: 277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Address, depends on address size of CU. */ 2785316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard if (dbg == NULL) 2795316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard { 2805316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard // XXX relocation? 2815316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard if (address_size == 4) 2825316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard { 2835316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard if (unlikely (data + 4 > end_data)) 2845316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard goto invalid; 2855316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard else 2865316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard newloc->number = read_4ubyte_unaligned_inc (&bo, data); 2875316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard } 2885316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard else 2895316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard { 2905316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard if (unlikely (data + 8 > end_data)) 2915316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard goto invalid; 2925316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard else 2935316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard newloc->number = read_8ubyte_unaligned_inc (&bo, data); 2945316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard } 2955316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard } 2965316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard else if (__libdw_read_address_inc (dbg, sec_index, &data, 2975316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard address_size, &newloc->number)) 2985316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard goto invalid; 299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 301688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath case DW_OP_call_ref: 302688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath /* DW_FORM_ref_addr, depends on offset size of CU. */ 3035316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data, 3045316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard ref_size, 3055316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard &newloc->number, 3065316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard IDX_debug_info, 0)) 3075316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard goto invalid; 308688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath break; 309688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_deref: 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_dup: 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_drop: 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_over: 314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_swap: 315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_rot: 316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_xderef: 317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_abs: 318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_and: 319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_div: 320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_minus: 321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_mod: 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_mul: 323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_neg: 324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_not: 325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_or: 326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_plus: 327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_shl: 328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_shr: 329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_shra: 330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_xor: 331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_eq: 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_ge: 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_gt: 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_le: 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_lt: 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_ne: 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_lit0 ... DW_OP_lit31: 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_reg0 ... DW_OP_reg31: 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_nop: 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_push_object_address: 3418089343cc61743db7bf0fd75c21132cbab5c01fdRoland McGrath case DW_OP_call_frame_cfa: 3427dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath case DW_OP_form_tls_address: 343d1083043cf63551270f31aa83233d55286a89d65Roland McGrath case DW_OP_GNU_push_tls_address: 34496349ffaa68a1b4eec2fd1c9eb97a3d0b4e95a1eRoland McGrath case DW_OP_stack_value: 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No operand. */ 346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const1u: 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_pick: 350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_deref_size: 351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_xderef_size: 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data >= end_data)) 35399d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper { 35499d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper invalid: 35599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper __libdw_seterrno (DWARF_E_INVALID_DWARF); 356720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard returnmem: 357720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard /* Free any dynamicly allocated loclists, if any. */ 358720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard while (n > MAX_STACK_LOCS) 359720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard { 360720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard struct loclist *loc = loclist; 361720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard loclist = loc->next; 362720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard free (loc); 363720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard n--; 364720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard } 36599d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper return -1; 36699d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper } 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number = *data++; 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const1s: 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data >= end_data)) 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newloc->number = *((int8_t *) data); 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++data; 377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const2u: 380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 2 > end_data)) 381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3833c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_2ubyte_unaligned_inc (&bo, data); 384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const2s: 387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_skip: 388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_bra: 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_call2: 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 2 > end_data)) 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3933c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_2sbyte_unaligned_inc (&bo, data); 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const4u: 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 4 > end_data)) 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4003c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_4ubyte_unaligned_inc (&bo, data); 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const4s: 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_call4: 405b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata case DW_OP_GNU_parameter_ref: 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 4 > end_data)) 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4093c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_4sbyte_unaligned_inc (&bo, data); 410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const8u: 413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 8 > end_data)) 414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4163c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_8ubyte_unaligned_inc (&bo, data); 417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_const8s: 420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (data + 8 > end_data)) 421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4233c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newloc->number = read_8sbyte_unaligned_inc (&bo, data); 424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_constu: 427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_plus_uconst: 428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_regx: 429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_piece: 430b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata case DW_OP_GNU_convert: 431b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata case DW_OP_GNU_reinterpret: 4327a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_uleb128 (newloc->number, data, end_data); 433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_consts: 436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_breg0 ... DW_OP_breg31: 437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_fbreg: 4387a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_sleb128 (newloc->number, data, end_data); 439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DW_OP_bregx: 4427a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_uleb128 (newloc->number, data, end_data); 4437a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard if (unlikely (data >= end_data)) 4447a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard goto invalid; 4457a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_sleb128 (newloc->number2, data, end_data); 446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4487dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath case DW_OP_bit_piece: 449b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata case DW_OP_GNU_regval_type: 4507a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_uleb128 (newloc->number, data, end_data); 4517a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard if (unlikely (data >= end_data)) 4527a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard goto invalid; 4537a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_uleb128 (newloc->number2, data, end_data); 4547dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath break; 4557dd9464d06c7826952be3c4fa7fc963dd563c025Roland McGrath 456f0371041995308d197447019eb2ac9285c96477bRoland McGrath case DW_OP_implicit_value: 457b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata case DW_OP_GNU_entry_value: 458f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* This cannot be used in a CFI expression. */ 459f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (unlikely (dbg == NULL)) 460f0371041995308d197447019eb2ac9285c96477bRoland McGrath goto invalid; 461f0371041995308d197447019eb2ac9285c96477bRoland McGrath 46274f9b7337562c06a93722ad757d258db8f082663Mark Wielaard /* start of block inc. len. */ 46374f9b7337562c06a93722ad757d258db8f082663Mark Wielaard newloc->number2 = (Dwarf_Word) (uintptr_t) data; 4647a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_uleb128 (newloc->number, data, end_data); /* Block length. */ 465f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number)) 466f0371041995308d197447019eb2ac9285c96477bRoland McGrath goto invalid; 467f0371041995308d197447019eb2ac9285c96477bRoland McGrath data += newloc->number; /* Skip the block. */ 468f0371041995308d197447019eb2ac9285c96477bRoland McGrath break; 469f0371041995308d197447019eb2ac9285c96477bRoland McGrath 470932585d2385c9d4e5686e4ddc9ba30c68172d7f3Roland McGrath case DW_OP_GNU_implicit_pointer: 471932585d2385c9d4e5686e4ddc9ba30c68172d7f3Roland McGrath /* DW_FORM_ref_addr, depends on offset size of CU. */ 4725316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data, 4735316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard ref_size, 4745316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard &newloc->number, 4755316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard IDX_debug_info, 0)) 4765316e412a4931d99ac5611e5f89ef187d4e9e335Mark Wielaard goto invalid; 4777a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard if (unlikely (data >= end_data)) 4787a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard goto invalid; 4797a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_uleb128 (newloc->number2, data, end_data); /* Byte offset. */ 480932585d2385c9d4e5686e4ddc9ba30c68172d7f3Roland McGrath break; 481932585d2385c9d4e5686e4ddc9ba30c68172d7f3Roland McGrath 482b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata case DW_OP_GNU_deref_type: 4837a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard if (unlikely (data + 1 >= end_data)) 484b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata goto invalid; 485b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata newloc->number = *data++; 4867a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_uleb128 (newloc->number2, data, end_data); 487b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata break; 488b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata 489b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata case DW_OP_GNU_const_type: 490b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard { 491b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard size_t size; 4927a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_uleb128 (newloc->number, data, end_data); 493b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard if (unlikely (data >= end_data)) 494b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard goto invalid; 495b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard 49674f9b7337562c06a93722ad757d258db8f082663Mark Wielaard /* start of block inc. len. */ 49774f9b7337562c06a93722ad757d258db8f082663Mark Wielaard newloc->number2 = (Dwarf_Word) (uintptr_t) data; 498b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard size = *data++; 499b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard if (unlikely ((Dwarf_Word) (end_data - data) < size)) 500b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard goto invalid; 501b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard data += size; /* Skip the block. */ 502b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard } 503b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata break; 504b5c0b037203eea0dc41f93900330522fe821eca9Petr Machata 505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (n == 0)) 511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is not allowed. 5133951f2ec0aaca021c77a2c7a464dcf43433261c3Mark Wielaard It would mean an empty location expression, which we handled 5143951f2ec0aaca021c77a2c7a464dcf43433261c3Mark Wielaard already as a special case above. */ 515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto invalid; 516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 518af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath if (valuep) 519af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath { 520720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard struct loclist *newloc = NEW_LOC (); 521af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->atom = DW_OP_stack_value; 522af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->number = 0; 523af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->number2 = 0; 524af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath newloc->offset = data - block->data; 525af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath } 526af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath 527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allocate the array. */ 5283c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Op *result; 5293c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (dbg != NULL) 5303c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n); 5313c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath else 5323c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 5333c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath result = malloc (sizeof *result * n); 5343c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (result == NULL) 5353c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 5363c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath nomem: 5373c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath __libdw_seterrno (DWARF_E_NOMEM); 538720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard goto returnmem; 5393c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 5403c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Store the result. */ 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *llbuf = result; 544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *listlen = n; 545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 548f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* We populate the array from the back since the list is backwards. */ 549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper --n; 550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].atom = loclist->atom; 551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].number = loclist->number; 552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].number2 = loclist->number2; 553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result[n].offset = loclist->offset; 554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 555f0371041995308d197447019eb2ac9285c96477bRoland McGrath if (result[n].atom == DW_OP_implicit_value) 556b2535b6a6be7717cdd41834d76e5cb48cb446b83Mark Wielaard store_implicit_value (dbg, cache, &result[n]); 557f0371041995308d197447019eb2ac9285c96477bRoland McGrath 558720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard struct loclist *loc = loclist; 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loclist = loclist->next; 560720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard if (unlikely (n + 1 > MAX_STACK_LOCS)) 561720f83a563fd3d550cdc7a14be9fb13269022b91Mark Wielaard free (loc); 562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (n > 0); 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 565f0371041995308d197447019eb2ac9285c96477bRoland McGrath /* Insert a record in the search tree so that we can find it again later. */ 5663c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath struct loc_s *newp; 5673c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (dbg != NULL) 5683c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1); 5693c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath else 5703c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 5713c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath newp = malloc (sizeof *newp); 5723c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath if (newp == NULL) 5733c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath { 5743c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath free (result); 5753c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath goto nomem; 5763c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 5773c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath } 5783c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->addr = block->data; 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->loc = result; 581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->nloc = *listlen; 5823c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath (void) tsearch (newp, cache, loc_compare); 583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We did it. */ 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 5883c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathstatic int 5893c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrathgetlocation (struct Dwarf_CU *cu, const Dwarf_Block *block, 5903c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath Dwarf_Op **llbuf, size_t *listlen, int sec_index) 5913c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath{ 5929202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard /* Empty location expressions don't have any ops to intern. 5939202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard Note that synthetic empty_cu doesn't have an associated DWARF dbg. */ 5949202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard if (block->length == 0) 5959202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard { 5969202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard *listlen = 0; 5979202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard return 0; 5989202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard } 5999202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard 6003c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order, 601688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath cu->address_size, (cu->version == 2 602688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath ? cu->address_size 603688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath : cu->offset_size), 604688f7fcdb395cefef6a098b5ac9ddd167bb5fc3dRoland McGrath &cu->locs, block, 6050ab97839da3c382ab8799ebdbf5eb0a79bf20bdcRoland McGrath false, false, 606af80014e49796185298dfb261ddf1e51d98f25c0Roland McGrath llbuf, listlen, sec_index); 6073c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath} 6083c84db3b4b610bf636c4363abb6d3dac5ae020f9Roland McGrath 609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 6101ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaarddwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **llbuf, size_t *listlen) 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 6126fb3451de3ba29b628be6e30a01ef104156d4733Ulrich Drepper if (! attr_ok (attr)) 6136fb3451de3ba29b628be6e30a01ef104156d4733Ulrich Drepper return -1; 6146fb3451de3ba29b628be6e30a01ef104156d4733Ulrich Drepper 615cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath int result = check_constant_offset (attr, llbuf, listlen); 616cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (result != 1) 617cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return result; 618cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If it has a block form, it's a single location expression. */ 620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Block block; 621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (INTUSE(dwarf_formblock) (attr, &block) != 0) 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6243e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu)); 625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 62766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaardstatic int 6281ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaardattr_base_address (Dwarf_Attribute *attr, Dwarf_Addr *basep) 62966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard{ 63066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* Fetch the CU's base address. */ 63166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard Dwarf_Die cudie = CUDIE (attr->cu); 63266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 63366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* Find the base address of the compilation unit. It will 63466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard normally be specified by DW_AT_low_pc. In DWARF-3 draft 4, 63566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard the base address could be overridden by DW_AT_entry_pc. It's 63666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc 63766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard for compilation units with discontinuous ranges. */ 63866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard Dwarf_Attribute attr_mem; 63966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (unlikely (INTUSE(dwarf_lowpc) (&cudie, basep) != 0) 64066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, 64166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard DW_AT_entry_pc, 64266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard &attr_mem), 64366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard basep) != 0) 64466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard { 64566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (INTUSE(dwarf_errno) () != 0) 64666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 64766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 64866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* The compiler provided no base address when it should 64966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard have. Buggy GCC does this when it used absolute 65066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard addresses in the location list and no DW_AT_ranges. */ 65166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard *basep = 0; 65266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard } 65366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return 0; 65466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard} 65566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 65666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaardstatic int 6571ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaardinitial_offset_base (Dwarf_Attribute *attr, ptrdiff_t *offset, 6581ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard Dwarf_Addr *basep) 65966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard{ 66066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (attr_base_address (attr, basep) != 0) 66166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 66266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 66366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard Dwarf_Word start_offset; 66466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (__libdw_formptr (attr, IDX_debug_loc, 66566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard DWARF_E_NO_LOCLIST, 66666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard NULL, &start_offset) == NULL) 66766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 66866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 66966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard *offset = start_offset; 67066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return 0; 67166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard} 67266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 67366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaardstatic ptrdiff_t 674f6b93914662566bbbb974cc85ef686a9f6b41a42Chih-Hung Hsiehgetlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset, 675f6b93914662566bbbb974cc85ef686a9f6b41a42Chih-Hung Hsieh Dwarf_Addr *basep, Dwarf_Addr *startp, Dwarf_Addr *endp, 676f6b93914662566bbbb974cc85ef686a9f6b41a42Chih-Hung Hsieh Dwarf_Addr address, const Elf_Data *locs, Dwarf_Op **expr, 677f6b93914662566bbbb974cc85ef686a9f6b41a42Chih-Hung Hsieh size_t *exprlen) 67866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard{ 67966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard unsigned char *readp = locs->d_buf + offset; 68066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard unsigned char *readendp = locs->d_buf + locs->d_size; 68166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 68266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard next: 68366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (readendp - readp < attr->cu->address_size * 2) 68466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard { 68566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard invalid: 68666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard __libdw_seterrno (DWARF_E_INVALID_DWARF); 68766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 68866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard } 68966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 69066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard Dwarf_Addr begin; 69166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard Dwarf_Addr end; 69266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 69366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard switch (__libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc, 69466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard &readp, attr->cu->address_size, 69566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard &begin, &end, basep)) 69666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard { 69766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard case 0: /* got location range. */ 69866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard break; 69966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard case 1: /* base address setup. */ 70066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard goto next; 70166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard case 2: /* end of loclist */ 70266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return 0; 70366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard default: /* error */ 70466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 70566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard } 70666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 70766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (readendp - readp < 2) 70866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard goto invalid; 70966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 71066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* We have a location expression. */ 71166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard Dwarf_Block block; 71266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp); 71366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard block.data = readp; 71466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (readendp - readp < (ptrdiff_t) block.length) 71566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard goto invalid; 71666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard readp += block.length; 71766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 71866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard *startp = *basep + begin; 71966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard *endp = *basep + end; 72066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 72166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* If address is minus one we want them all, otherwise only matching. */ 72266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (address != (Dwarf_Word) -1 && (address < *startp || address >= *endp)) 72366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard goto next; 72466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 72566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (getlocation (attr->cu, &block, expr, exprlen, IDX_debug_loc) != 0) 72666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 72766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 72866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return readp - (unsigned char *) locs->d_buf; 72966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard} 73066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 7321ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaarddwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address, 7331ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard Dwarf_Op **llbufs, size_t *listlens, size_t maxlocs) 734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 735b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! attr_ok (attr)) 736b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (llbufs == NULL) 739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper maxlocs = SIZE_MAX; 740b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 741b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If it has a block form, it's a single location expression. */ 742b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Block block; 743b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (INTUSE(dwarf_formblock) (attr, &block) == 0) 744b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (maxlocs == 0) 746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (llbufs != NULL && 74899d2372b25d1231d786b70278478c7a112f2b27cUlrich Drepper getlocation (attr->cu, &block, &llbufs[0], &listlens[0], 7493e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath cu_sec_idx (attr->cu)) != 0) 750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return listlens[0] == 0 ? 0 : 1; 752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int error = INTUSE(dwarf_errno) (); 755f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath if (unlikely (error != DWARF_E_NO_BLOCK)) 756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __libdw_seterrno (error); 758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 761cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath int result = check_constant_offset (attr, &llbufs[0], &listlens[0]); 762cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath if (result != 1) 763cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath return result ?: 1; 764cfdd86ed929c137eaca5dd49cd266bb739c6cdbdRoland McGrath 76566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard Dwarf_Addr base, start, end; 76666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard Dwarf_Op *expr; 76766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard size_t expr_len; 76866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard ptrdiff_t off = 0; 76966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard size_t got = 0; 77066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 77166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* This is a true loclistptr, fetch the initial base address and offset. */ 77266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (initial_offset_base (attr, &off, &base) != 0) 773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 77566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc]; 77666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (d == NULL) 777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 77866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard __libdw_seterrno (DWARF_E_NO_LOCLIST); 77966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 78066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard } 78166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 78266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard while (got < maxlocs 78366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard && (off = getlocations_addr (attr, off, &base, &start, &end, 78466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard address, d, &expr, &expr_len)) > 0) 78566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard { 78666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* This one matches the address. */ 78766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (llbufs != NULL) 788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 78966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard llbufs[got] = expr; 79066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard listlens[got] = expr_len; 791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 79266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard ++got; 79366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard } 794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 79566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* We might stop early, so off can be zero or positive on success. */ 79666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (off < 0) 79766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 79966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return got; 80066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard} 80166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 80266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaardptrdiff_t 8031ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaarddwarf_getlocations (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr *basep, 8041ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard Dwarf_Addr *startp, Dwarf_Addr *endp, Dwarf_Op **expr, 8051ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard size_t *exprlen) 80666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard{ 80766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (! attr_ok (attr)) 80866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 80966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 81066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* 1 is an invalid offset, meaning no more locations. */ 81166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (offset == 1) 81266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return 0; 81366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 81466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (offset == 0) 81566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard { 81666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* If it has a block form, it's a single location expression. */ 81766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard Dwarf_Block block; 81866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (INTUSE(dwarf_formblock) (attr, &block) == 0) 819f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath { 82066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (getlocation (attr->cu, &block, expr, exprlen, 82166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard cu_sec_idx (attr->cu)) != 0) 82266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 82356bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper 82466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* This is the one and only location covering everything. */ 82566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard *startp = 0; 82666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard *endp = -1; 82766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return 1; 828f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath } 829f64a44262134500154f96c368a7d3d6e59f593c6Roland McGrath 83066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard int error = INTUSE(dwarf_errno) (); 83166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (unlikely (error != DWARF_E_NO_BLOCK)) 832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 83366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard __libdw_seterrno (error); 83466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 83666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 83766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard int result = check_constant_offset (attr, expr, exprlen); 83866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (result != 1) 83966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard { 84066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (result == 0) 84166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard { 84266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* This is the one and only location covering everything. */ 84366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard *startp = 0; 84466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard *endp = -1; 84566eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return 1; 84666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard } 84766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return result; 84866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard } 84966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 85066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard /* We must be looking at a true loclistptr, fetch the initial 85166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard base address and offset. */ 85266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (initial_offset_base (attr, &offset, basep) != 0) 85366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 855b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 85666eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc]; 85766eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard if (d == NULL) 85866eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard { 85966eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard __libdw_seterrno (DWARF_E_NO_LOCLIST); 86066eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return -1; 86166eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard } 86266eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard 86366eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard return getlocations_addr (attr, offset, basep, startp, endp, 86466eaae9bcc1608efad65e3aa0204afbb3cb1a83dMark Wielaard (Dwarf_Word) -1, d, expr, exprlen); 865b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 866