1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Get macro information. 2fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Copyright (C) 2002-2009, 2014 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2002. 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 34fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata#include <assert.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <dwarf.h> 36fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata#include <search.h> 37fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata#include <stdlib.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libdwP.h> 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 42fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic int 43fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machataget_offset_from (Dwarf_Die *die, int name, Dwarf_Word *retp) 44fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 45fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* Get the appropriate attribute. */ 46fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Attribute attr; 47fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (INTUSE(dwarf_attr) (die, name, &attr) == NULL) 48fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return -1; 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 50fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* Offset into the corresponding section. */ 51fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return INTUSE(dwarf_formudata) (&attr, retp); 52fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 53fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 54fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic int 55fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatamacro_op_compare (const void *p1, const void *p2) 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 57fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const Dwarf_Macro_Op_Table *t1 = (const Dwarf_Macro_Op_Table *) p1; 58fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const Dwarf_Macro_Op_Table *t2 = (const Dwarf_Macro_Op_Table *) p2; 59fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 60fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (t1->offset < t2->offset) 61e7c163324ebddf922f2827789b498ec1d7d9a2aaRoland McGrath return -1; 62fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (t1->offset > t2->offset) 63fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return 1; 64fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 65fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (t1->sec_index < t2->sec_index) 66fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return -1; 67fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (t1->sec_index > t2->sec_index) 68fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return 1; 69fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 70fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return 0; 71fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 72fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 73fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic void 74fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatabuild_table (Dwarf_Macro_Op_Table *table, 75fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Proto op_protos[static 255]) 76fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 77fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata unsigned ct = 0; 78fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata for (unsigned i = 1; i < 256; ++i) 79fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (op_protos[i - 1].forms != NULL) 80fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata table->table[table->opcodes[i - 1] = ct++] = op_protos[i - 1]; 81fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata else 82fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata table->opcodes[i - 1] = 0xff; 83fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 84fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 85fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata#define MACRO_PROTO(NAME, ...) \ 86fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Proto NAME = ({ \ 87fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata static const uint8_t proto[] = {__VA_ARGS__}; \ 88fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata (Dwarf_Macro_Op_Proto) {sizeof proto, proto}; \ 89fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata }) 90fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 91fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machataenum { macinfo_data_size = offsetof (Dwarf_Macro_Op_Table, table[5]) }; 92fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic unsigned char macinfo_data[macinfo_data_size] 93fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __attribute__ ((aligned (__alignof (Dwarf_Macro_Op_Table)))); 94fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 95fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic __attribute__ ((constructor)) void 96fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatainit_macinfo_table (void) 97fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 98fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string); 99fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata); 100fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata MACRO_PROTO (p_none); 101fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 102fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Proto op_protos[255] = 103fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 104fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACINFO_define - 1] = p_udata_str, 105fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACINFO_undef - 1] = p_udata_str, 106fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACINFO_vendor_ext - 1] = p_udata_str, 107fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACINFO_start_file - 1] = p_udata_udata, 108fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACINFO_end_file - 1] = p_none, 109fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* If you are adding more elements to this array, increase 110fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata MACINFO_DATA_SIZE above. */ 111fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata }; 112fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 113fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Table *macinfo_table = (void *) macinfo_data; 114fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata memset (macinfo_table, 0, sizeof macinfo_data); 115fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata build_table (macinfo_table, op_protos); 116fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata macinfo_table->sec_index = IDX_debug_macinfo; 117fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 118fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 119fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic Dwarf_Macro_Op_Table * 120fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machataget_macinfo_table (Dwarf *dbg, Dwarf_Word macoff, Dwarf_Die *cudie) 121fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 122fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata assert (cudie != NULL); 123fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 124fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Attribute attr_mem, *attr 125fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem); 126fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Off line_offset = (Dwarf_Off) -1; 127fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (attr != NULL) 1281dcbe0c59a72eb1c6908ebce5209683769526349Mark Wielaard if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0)) 1291dcbe0c59a72eb1c6908ebce5209683769526349Mark Wielaard return NULL; 130fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 131fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table, 132fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata macinfo_data_size, 1); 133fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata memcpy (table, macinfo_data, macinfo_data_size); 134fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 135fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata table->offset = macoff; 136fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata table->sec_index = IDX_debug_macinfo; 137fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata table->line_offset = line_offset; 138fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata table->is_64bit = cudie->cu->address_size == 8; 139fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata table->comp_dir = __libdw_getcompdir (cudie); 140fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 141fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return table; 142fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 143fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 144fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic Dwarf_Macro_Op_Table * 145fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machataget_table_for_offset (Dwarf *dbg, Dwarf_Word macoff, 146fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const unsigned char *readp, 147fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const unsigned char *const endp, 148fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Die *cudie) 149fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 150fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const unsigned char *startp = readp; 151fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 152fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* Request at least 3 bytes for header. */ 153fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (readp + 3 > endp) 154fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 155fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata invalid_dwarf: 156fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_INVALID_DWARF); 157fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return NULL; 158fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 159fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 160fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata uint16_t version = read_2ubyte_unaligned_inc (dbg, readp); 161fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (version != 4) 162fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 163fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_INVALID_VERSION); 164fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return NULL; 165fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 166fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 167fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata uint8_t flags = *readp++; 168fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata bool is_64bit = (flags & 0x1) != 0; 169fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 170fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Off line_offset = (Dwarf_Off) -1; 171fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if ((flags & 0x2) != 0) 172fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 173fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata line_offset = read_addr_unaligned_inc (is_64bit ? 8 : 4, dbg, readp); 174fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (readp > endp) 175fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata goto invalid_dwarf; 176fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 177fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata else if (cudie != NULL) 178fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 179fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Attribute attr_mem, *attr 180fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem); 181fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (attr != NULL) 1821dcbe0c59a72eb1c6908ebce5209683769526349Mark Wielaard if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0)) 1831dcbe0c59a72eb1c6908ebce5209683769526349Mark Wielaard return NULL; 184fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 185fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 186fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* """The macinfo entry types defined in this standard may, but 187fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata might not, be described in the table""". 188fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 189fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata I.e. these may be present. It's tempting to simply skip them, 190fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata but it's probably more correct to tolerate that a producer tweaks 191fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata the way certain opcodes are encoded, for whatever reasons. */ 192fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 193fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string); 194fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata MACRO_PROTO (p_udata_strp, DW_FORM_udata, DW_FORM_strp); 195fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata); 196fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata MACRO_PROTO (p_secoffset, DW_FORM_sec_offset); 197fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata MACRO_PROTO (p_none); 198fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 199fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Proto op_protos[255] = 200fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 201fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACRO_GNU_define - 1] = p_udata_str, 202fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACRO_GNU_undef - 1] = p_udata_str, 203fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACRO_GNU_define_indirect - 1] = p_udata_strp, 204fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACRO_GNU_undef_indirect - 1] = p_udata_strp, 205fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACRO_GNU_start_file - 1] = p_udata_udata, 206fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACRO_GNU_end_file - 1] = p_none, 207fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata [DW_MACRO_GNU_transparent_include - 1] = p_secoffset, 208fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* N.B. DW_MACRO_undef_indirectx, DW_MACRO_define_indirectx 209fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata should be added when 130313.1 is supported. */ 210fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata }; 211fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 212fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if ((flags & 0x4) != 0) 213fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 214fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata unsigned count = *readp++; 215fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata for (unsigned i = 0; i < count; ++i) 216fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 217fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata unsigned opcode = *readp++; 218fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 219fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Proto e; 2207a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard if (readp >= endp) 2217a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard goto invalid; 2227a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard get_uleb128 (e.nforms, readp, endp); 223fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata e.forms = readp; 224fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata op_protos[opcode - 1] = e; 225fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 226fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata readp += e.nforms; 227fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (readp > endp) 228fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 2297a053473c7bedd22e3db39c444a4cd8f97eace25Mark Wielaard invalid: 230fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_INVALID_DWARF); 231fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return NULL; 232fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 233fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 234fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 235fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 236fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata size_t ct = 0; 237fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata for (unsigned i = 1; i < 256; ++i) 238fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (op_protos[i - 1].forms != NULL) 239fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata ++ct; 240fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 241fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* We support at most 0xfe opcodes defined in the table, as 0xff is 242fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata a value that means that given opcode is not stored at all. But 243fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata that should be fine, as opcode 0 is not allocated. */ 244fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata assert (ct < 0xff); 245fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 246fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata size_t macop_table_size = offsetof (Dwarf_Macro_Op_Table, table[ct]); 247fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 248fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table, 249fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata macop_table_size, 1); 250e7c163324ebddf922f2827789b498ec1d7d9a2aaRoland McGrath 251fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata *table = (Dwarf_Macro_Op_Table) { 252fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .offset = macoff, 253fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .sec_index = IDX_debug_macro, 254fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .line_offset = line_offset, 255fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .header_len = readp - startp, 256fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .version = version, 257fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .is_64bit = is_64bit, 258fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 259fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* NULL if CUDIE is NULL or DW_AT_comp_dir is absent. */ 260fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .comp_dir = __libdw_getcompdir (cudie), 261fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata }; 262fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata build_table (table, op_protos); 263fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 264fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return table; 265fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 266fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 267fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic Dwarf_Macro_Op_Table * 268fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatacache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff, 269fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const unsigned char *startp, 270fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const unsigned char *const endp, 271fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Die *cudie) 272fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 273fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Table fake = { .offset = macoff, .sec_index = sec_index }; 274fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Table **found = tfind (&fake, &dbg->macro_ops, 275fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata macro_op_compare); 276fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (found != NULL) 277fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return *found; 278fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 279fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Table *table = sec_index == IDX_debug_macro 280fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata ? get_table_for_offset (dbg, macoff, startp, endp, cudie) 281fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata : get_macinfo_table (dbg, macoff, cudie); 282fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 283fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (table == NULL) 284fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return NULL; 285fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 286fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Table **ret = tsearch (table, &dbg->macro_ops, 287fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata macro_op_compare); 288fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (unlikely (ret == NULL)) 289fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 290fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_NOMEM); 291fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return NULL; 292fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 293fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 294fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return *ret; 295fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 296fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 297fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic ptrdiff_t 298fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machataread_macros (Dwarf *dbg, int sec_index, 299fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *), 300fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata void *arg, ptrdiff_t offset, bool accept_0xff, 301fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Die *cudie) 302fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 303fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Elf_Data *d = dbg->sectiondata[sec_index]; 304fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (unlikely (d == NULL || d->d_buf == NULL)) 305f3df61f7514b4c217b4bf16a62c93493bb1fef56Petr Machata { 306f3df61f7514b4c217b4bf16a62c93493bb1fef56Petr Machata __libdw_seterrno (DWARF_E_NO_ENTRY); 307f3df61f7514b4c217b4bf16a62c93493bb1fef56Petr Machata return -1; 308f3df61f7514b4c217b4bf16a62c93493bb1fef56Petr Machata } 309f3df61f7514b4c217b4bf16a62c93493bb1fef56Petr Machata 310fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (unlikely (macoff >= d->d_size)) 311e2eabd88c9a95e640fee4afc64d7445d323b0716Roland McGrath { 312fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_INVALID_DWARF); 313fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return -1; 314fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 315e2eabd88c9a95e640fee4afc64d7445d323b0716Roland McGrath 316fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const unsigned char *const startp = d->d_buf + macoff; 317fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const unsigned char *const endp = d->d_buf + d->d_size; 318e2eabd88c9a95e640fee4afc64d7445d323b0716Roland McGrath 319fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Table *table = cache_op_table (dbg, sec_index, macoff, 320fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata startp, endp, cudie); 321fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (table == NULL) 322fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return -1; 323e2eabd88c9a95e640fee4afc64d7445d323b0716Roland McGrath 324fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (offset == 0) 325fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata offset = table->header_len; 326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 327fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata assert (offset >= 0); 328fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata assert (offset < endp - startp); 329fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata const unsigned char *readp = startp + offset; 330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 331fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata while (readp < endp) 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int opcode = *readp++; 334fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (opcode == 0) 335fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* Nothing more to do. */ 336fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return 0; 337fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 338fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (unlikely (opcode == 0xff && ! accept_0xff)) 339fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 340fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* See comment below at dwarf_getmacros for explanation of 341fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata why we are doing this. */ 342fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_INVALID_OPCODE); 343fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return -1; 344fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 345fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 346fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata unsigned int idx = table->opcodes[opcode - 1]; 347fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (idx == 0xff) 348fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 349fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_INVALID_OPCODE); 350fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return -1; 351fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 352fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 353fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro_Op_Proto *proto = &table->table[idx]; 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 355fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* A fake CU with bare minimum data to fool dwarf_formX into 356fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata doing the right thing with the attributes that we put out. 357fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata We arbitrarily pretend it's version 4. */ 358fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_CU fake_cu = { 359fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .dbg = dbg, 360fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .version = 4, 361fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .offset_size = table->is_64bit ? 8 : 4, 3629202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard .startp = (void *) startp + offset, 3639202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard .endp = (void *) endp, 364fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata }; 365fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 366f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard Dwarf_Attribute *attributes; 367f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard Dwarf_Attribute *attributesp = NULL; 368f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard Dwarf_Attribute nattributes[8]; 369f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard if (unlikely (proto->nforms > 8)) 370f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard { 371f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard attributesp = malloc (sizeof (Dwarf_Attribute) * proto->nforms); 372f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard if (attributesp == NULL) 373f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard { 374f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard __libdw_seterrno (DWARF_E_NOMEM); 375f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard return -1; 376f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard } 377f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard attributes = attributesp; 378f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard } 379f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard else 380f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard attributes = &nattributes[0]; 381f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard 382fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata for (Dwarf_Word i = 0; i < proto->nforms; ++i) 383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 384fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* We pretend this is a DW_AT_GNU_macros attribute so that 385fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata DW_FORM_sec_offset forms get correctly interpreted as 386fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata offset into .debug_macro. */ 387fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata attributes[i].code = DW_AT_GNU_macros; 388fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata attributes[i].form = proto->forms[i]; 389fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata attributes[i].valp = (void *) readp; 390fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata attributes[i].cu = &fake_cu; 391fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 3929202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp); 393f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard if (unlikely (len == (size_t) -1)) 394f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard { 395f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard free (attributesp); 396f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard return -1; 397f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard } 398cb73b5a015606a02f952f7eddaba15327f6191faMark Wielaard 399cb73b5a015606a02f952f7eddaba15327f6191faMark Wielaard readp += len; 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 402fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Macro macro = { 403fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .table = table, 404fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .opcode = opcode, 405fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .attributes = attributes, 406fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata }; 407fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 408f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard int res = callback (¯o, arg); 409f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard if (unlikely (attributesp != NULL)) 410f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard free (attributesp); 411f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard 412f98b99db09f80666d5cf491a2ce126a59af0fdb1Mark Wielaard if (res != DWARF_CB_OK) 413fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return readp - startp; 414fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 415fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 416fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return 0; 417fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 418fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 419edb079a596b25379828836e501d003f20afdb879Petr Machata/* Token layout: 420edb079a596b25379828836e501d003f20afdb879Petr Machata 421edb079a596b25379828836e501d003f20afdb879Petr Machata - The highest bit is used for distinguishing between callers that 422edb079a596b25379828836e501d003f20afdb879Petr Machata know that opcode 0xff may have one of two incompatible meanings. 423edb079a596b25379828836e501d003f20afdb879Petr Machata The mask that we use for selecting this bit is 424edb079a596b25379828836e501d003f20afdb879Petr Machata DWARF_GETMACROS_START. 425edb079a596b25379828836e501d003f20afdb879Petr Machata 426edb079a596b25379828836e501d003f20afdb879Petr Machata - The rest of the token (31 or 63 bits) encodes address inside the 427edb079a596b25379828836e501d003f20afdb879Petr Machata macro unit. 428edb079a596b25379828836e501d003f20afdb879Petr Machata 429edb079a596b25379828836e501d003f20afdb879Petr Machata Besides, token value of 0 signals end of iteration and -1 is 430edb079a596b25379828836e501d003f20afdb879Petr Machata reserved for signaling errors. That means it's impossible to 431edb079a596b25379828836e501d003f20afdb879Petr Machata represent maximum offset of a .debug_macro unit to new-style 432edb079a596b25379828836e501d003f20afdb879Petr Machata callers (which in practice decreases the permissible macro unit 433edb079a596b25379828836e501d003f20afdb879Petr Machata size by another 1 byte). */ 434edb079a596b25379828836e501d003f20afdb879Petr Machata 435edb079a596b25379828836e501d003f20afdb879Petr Machatastatic ptrdiff_t 436edb079a596b25379828836e501d003f20afdb879Petr Machatatoken_from_offset (ptrdiff_t offset, bool accept_0xff) 437edb079a596b25379828836e501d003f20afdb879Petr Machata{ 438edb079a596b25379828836e501d003f20afdb879Petr Machata if (offset == -1 || offset == 0) 439edb079a596b25379828836e501d003f20afdb879Petr Machata return offset; 440edb079a596b25379828836e501d003f20afdb879Petr Machata 441edb079a596b25379828836e501d003f20afdb879Petr Machata /* Make sure the offset didn't overflow into the flag bit. */ 442edb079a596b25379828836e501d003f20afdb879Petr Machata if ((offset & DWARF_GETMACROS_START) != 0) 443edb079a596b25379828836e501d003f20afdb879Petr Machata { 444edb079a596b25379828836e501d003f20afdb879Petr Machata __libdw_seterrno (DWARF_E_TOO_BIG); 445edb079a596b25379828836e501d003f20afdb879Petr Machata return -1; 446edb079a596b25379828836e501d003f20afdb879Petr Machata } 447edb079a596b25379828836e501d003f20afdb879Petr Machata 448edb079a596b25379828836e501d003f20afdb879Petr Machata if (accept_0xff) 449edb079a596b25379828836e501d003f20afdb879Petr Machata offset |= DWARF_GETMACROS_START; 450edb079a596b25379828836e501d003f20afdb879Petr Machata 451edb079a596b25379828836e501d003f20afdb879Petr Machata return offset; 452edb079a596b25379828836e501d003f20afdb879Petr Machata} 453edb079a596b25379828836e501d003f20afdb879Petr Machata 454edb079a596b25379828836e501d003f20afdb879Petr Machatastatic ptrdiff_t 455edb079a596b25379828836e501d003f20afdb879Petr Machataoffset_from_token (ptrdiff_t token, bool *accept_0xffp) 456edb079a596b25379828836e501d003f20afdb879Petr Machata{ 457edb079a596b25379828836e501d003f20afdb879Petr Machata *accept_0xffp = (token & DWARF_GETMACROS_START) != 0; 458edb079a596b25379828836e501d003f20afdb879Petr Machata token &= ~DWARF_GETMACROS_START; 459edb079a596b25379828836e501d003f20afdb879Petr Machata 460edb079a596b25379828836e501d003f20afdb879Petr Machata return token; 461edb079a596b25379828836e501d003f20afdb879Petr Machata} 462edb079a596b25379828836e501d003f20afdb879Petr Machata 463fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic ptrdiff_t 464fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatagnu_macros_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, 465fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata int (*callback) (Dwarf_Macro *, void *), 466edb079a596b25379828836e501d003f20afdb879Petr Machata void *arg, ptrdiff_t offset, bool accept_0xff, 467fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata Dwarf_Die *cudie) 468fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 469edb079a596b25379828836e501d003f20afdb879Petr Machata assert (offset >= 0); 470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 471fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (macoff >= dbg->sectiondata[IDX_debug_macro]->d_size) 472fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 473fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_INVALID_OFFSET); 474fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return -1; 475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 477edb079a596b25379828836e501d003f20afdb879Petr Machata return read_macros (dbg, IDX_debug_macro, macoff, 478edb079a596b25379828836e501d003f20afdb879Petr Machata callback, arg, offset, accept_0xff, cudie); 479fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 480fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 481fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatastatic ptrdiff_t 482fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatamacro_info_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, 483fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata int (*callback) (Dwarf_Macro *, void *), 484edb079a596b25379828836e501d003f20afdb879Petr Machata void *arg, ptrdiff_t offset, Dwarf_Die *cudie) 485fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 486edb079a596b25379828836e501d003f20afdb879Petr Machata assert (offset >= 0); 487fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 488fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return read_macros (dbg, IDX_debug_macinfo, macoff, 489edb079a596b25379828836e501d003f20afdb879Petr Machata callback, arg, offset, true, cudie); 490fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 491fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 492fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machataptrdiff_t 493fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machatadwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, 494fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata int (*callback) (Dwarf_Macro *, void *), 495fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata void *arg, ptrdiff_t token) 496fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 497fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (dbg == NULL) 498fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 499fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_NO_DWARF); 500fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return -1; 501fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 502fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 503edb079a596b25379828836e501d003f20afdb879Petr Machata bool accept_0xff; 504edb079a596b25379828836e501d003f20afdb879Petr Machata ptrdiff_t offset = offset_from_token (token, &accept_0xff); 505edb079a596b25379828836e501d003f20afdb879Petr Machata assert (accept_0xff); 506fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 507edb079a596b25379828836e501d003f20afdb879Petr Machata offset = gnu_macros_getmacros_off (dbg, macoff, callback, arg, offset, 508edb079a596b25379828836e501d003f20afdb879Petr Machata accept_0xff, NULL); 509edb079a596b25379828836e501d003f20afdb879Petr Machata 510edb079a596b25379828836e501d003f20afdb879Petr Machata return token_from_offset (offset, accept_0xff); 511fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata} 512fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 513edb079a596b25379828836e501d003f20afdb879Petr Machataptrdiff_t 5141ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaarddwarf_getmacros (Dwarf_Die *cudie, int (*callback) (Dwarf_Macro *, void *), 5151ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard void *arg, ptrdiff_t token) 516fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata{ 517fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata if (cudie == NULL) 518fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata { 519fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata __libdw_seterrno (DWARF_E_NO_DWARF); 520fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata return -1; 521fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata } 522fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 523fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata /* This function might be called from a code that expects to see 524fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata DW_MACINFO_* opcodes, not DW_MACRO_{GNU_,}* ones. It is fine to 525fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata serve most DW_MACRO_{GNU_,}* opcodes to such code, because those 526fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata whose values are the same as DW_MACINFO_* ones also have the same 527fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata behavior. It is not very likely that a .debug_macro section 528fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata would only use the part of opcode space that it shares with 529fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata .debug_macinfo, but it is possible. Serving the opcodes that are 530fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata only valid in DW_MACRO_{GNU_,}* domain is OK as well, because 531fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata clients in general need to be ready that newer standards define 532fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata more opcodes, and have coping mechanisms for unfamiliar opcodes. 533fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 534fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata The one exception to the above rule is opcode 0xff, which has 535fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata concrete semantics in .debug_macinfo, but falls into vendor block 536fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata in .debug_macro, and can be assigned to do whatever. There is 537fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata some small probability that the two opcodes would look 538fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata superficially similar enough that a client would be confused and 539fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata misbehave as a result. For this reason, we refuse to serve 540edb079a596b25379828836e501d003f20afdb879Petr Machata through this interface 0xff's originating from .debug_macro 541edb079a596b25379828836e501d003f20afdb879Petr Machata unless the TOKEN that we obtained indicates the call originates 542edb079a596b25379828836e501d003f20afdb879Petr Machata from a new-style caller. See above for details on what 543edb079a596b25379828836e501d003f20afdb879Petr Machata information is encoded into tokens. */ 544edb079a596b25379828836e501d003f20afdb879Petr Machata 545edb079a596b25379828836e501d003f20afdb879Petr Machata bool accept_0xff; 546edb079a596b25379828836e501d003f20afdb879Petr Machata ptrdiff_t offset = offset_from_token (token, &accept_0xff); 547edb079a596b25379828836e501d003f20afdb879Petr Machata 548edb079a596b25379828836e501d003f20afdb879Petr Machata /* DW_AT_macro_info */ 549edb079a596b25379828836e501d003f20afdb879Petr Machata if (dwarf_hasattr (cudie, DW_AT_macro_info)) 550edb079a596b25379828836e501d003f20afdb879Petr Machata { 551edb079a596b25379828836e501d003f20afdb879Petr Machata Dwarf_Word macoff; 552edb079a596b25379828836e501d003f20afdb879Petr Machata if (get_offset_from (cudie, DW_AT_macro_info, &macoff) != 0) 553edb079a596b25379828836e501d003f20afdb879Petr Machata return -1; 554edb079a596b25379828836e501d003f20afdb879Petr Machata offset = macro_info_getmacros_off (cudie->cu->dbg, macoff, 555edb079a596b25379828836e501d003f20afdb879Petr Machata callback, arg, offset, cudie); 556edb079a596b25379828836e501d003f20afdb879Petr Machata } 557edb079a596b25379828836e501d003f20afdb879Petr Machata else 558edb079a596b25379828836e501d003f20afdb879Petr Machata { 559edb079a596b25379828836e501d003f20afdb879Petr Machata /* DW_AT_GNU_macros, DW_AT_macros */ 560edb079a596b25379828836e501d003f20afdb879Petr Machata Dwarf_Word macoff; 561edb079a596b25379828836e501d003f20afdb879Petr Machata if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0) 562edb079a596b25379828836e501d003f20afdb879Petr Machata return -1; 563edb079a596b25379828836e501d003f20afdb879Petr Machata offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff, 564edb079a596b25379828836e501d003f20afdb879Petr Machata callback, arg, offset, accept_0xff, 565edb079a596b25379828836e501d003f20afdb879Petr Machata cudie); 566edb079a596b25379828836e501d003f20afdb879Petr Machata } 567fb90bf3f84b5683bbc1f234ee05008ff26250e5cPetr Machata 568edb079a596b25379828836e501d003f20afdb879Petr Machata return token_from_offset (offset, accept_0xff); 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 570