1 /* Internal definitions for libdw CFI interpreter. 2 Copyright (C) 2009-2010, 2013, 2015 Red Hat, Inc. 3 This file is part of elfutils. 4 5 This file is free software; you can redistribute it and/or modify 6 it under the terms of either 7 8 * the GNU Lesser General Public License as published by the Free 9 Software Foundation; either version 3 of the License, or (at 10 your option) any later version 11 12 or 13 14 * the GNU General Public License as published by the Free 15 Software Foundation; either version 2 of the License, or (at 16 your option) any later version 17 18 or both in parallel, as here. 19 20 elfutils is distributed in the hope that it will be useful, but 21 WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 General Public License for more details. 24 25 You should have received copies of the GNU General Public License and 26 the GNU Lesser General Public License along with this program. If 27 not, see <http://www.gnu.org/licenses/>. */ 28 29 #ifndef _UNWINDP_H 30 #define _UNWINDP_H 1 31 32 #include "libdwP.h" 33 #include "libelfP.h" 34 struct ebl; 35 36 /* Cached CIE representation. */ 37 struct dwarf_cie 38 { 39 Dwarf_Off offset; /* Our position, as seen in FDEs' CIE_pointer. */ 40 41 Dwarf_Word code_alignment_factor; 42 Dwarf_Sword data_alignment_factor; 43 Dwarf_Word return_address_register; 44 45 size_t fde_augmentation_data_size; 46 47 // play out to initial state 48 const uint8_t *initial_instructions; 49 const uint8_t *initial_instructions_end; 50 51 const Dwarf_Frame *initial_state; 52 53 uint8_t fde_encoding; /* DW_EH_PE_* for addresses in FDEs. */ 54 uint8_t lsda_encoding; /* DW_EH_PE_* for LSDA in FDE augmentation. */ 55 56 bool sized_augmentation_data; /* Saw 'z': FDEs have self-sized data. */ 57 bool signal_frame; /* Saw 'S': FDE is for a signal frame. */ 58 }; 59 60 /* Cached FDE representation. */ 61 struct dwarf_fde 62 { 63 struct dwarf_cie *cie; 64 65 /* This FDE describes PC values in [start, end). */ 66 Dwarf_Addr start; 67 Dwarf_Addr end; 68 69 const uint8_t *instructions; 70 const uint8_t *instructions_end; 71 }; 72 73 /* This holds everything we cache about the CFI from each ELF file's 74 .debug_frame or .eh_frame section. */ 75 struct Dwarf_CFI_s 76 { 77 /* Dwarf handle we came from. If null, this is .eh_frame data. */ 78 Dwarf *dbg; 79 #define CFI_IS_EH(cfi) ((cfi)->dbg == NULL) 80 81 /* Data of the .debug_frame or .eh_frame section. */ 82 Elf_Data_Scn *data; 83 const unsigned char *e_ident; /* For EI_DATA and EI_CLASS. */ 84 85 Dwarf_Addr frame_vaddr; /* DW_EH_PE_pcrel, address of frame section. */ 86 Dwarf_Addr textrel; /* DW_EH_PE_textrel base address. */ 87 Dwarf_Addr datarel; /* DW_EH_PE_datarel base address. */ 88 89 /* Location of next unread entry in the section. */ 90 Dwarf_Off next_offset; 91 92 /* Search tree for the CIEs, indexed by CIE_pointer (section offset). */ 93 void *cie_tree; 94 95 /* Search tree for the FDEs, indexed by PC address. */ 96 void *fde_tree; 97 98 /* Search tree for parsed DWARF expressions, indexed by raw pointer. */ 99 void *expr_tree; 100 101 /* Backend hook. */ 102 struct ebl *ebl; 103 104 /* Binary search table in .eh_frame_hdr section. */ 105 const uint8_t *search_table; 106 size_t search_table_len; 107 Dwarf_Addr search_table_vaddr; 108 size_t search_table_entries; 109 uint8_t search_table_encoding; 110 111 uint16_t e_machine; 112 113 /* True if the file has a byte order different from the host. */ 114 bool other_byte_order; 115 116 /* Default rule for registers not previously mentioned 117 is same_value, not undefined. */ 118 bool default_same_value; 119 }; 120 121 122 enum dwarf_frame_rule 123 { 124 reg_unspecified, /* Uninitialized state. */ 125 reg_undefined, /* DW_CFA_undefined */ 126 reg_same_value, /* DW_CFA_same_value */ 127 reg_offset, /* DW_CFA_offset_extended et al */ 128 reg_val_offset, /* DW_CFA_val_offset et al */ 129 reg_register, /* DW_CFA_register */ 130 reg_expression, /* DW_CFA_expression */ 131 reg_val_expression, /* DW_CFA_val_expression */ 132 }; 133 134 /* This describes what we know about an individual register. */ 135 struct dwarf_frame_register 136 { 137 enum dwarf_frame_rule rule:3; 138 139 /* The meaning of the value bits depends on the rule: 140 141 Rule Value 142 ---- ----- 143 undefined unused 144 same_value unused 145 offset(N) N (register saved at CFA + value) 146 val_offset(N) N (register = CFA + value) 147 register(R) R (register = register #value) 148 expression(E) section offset of DW_FORM_block containing E 149 (register saved at address E computes) 150 val_expression(E) section offset of DW_FORM_block containing E 151 (register = value E computes) 152 */ 153 Dwarf_Sword value:(sizeof (Dwarf_Sword) * 8 - 3); 154 }; 155 156 /* This holds instructions for unwinding frame at a particular PC location 157 described by an FDE. */ 158 struct Dwarf_Frame_s 159 { 160 /* This frame description covers PC values in [start, end). */ 161 Dwarf_Addr start; 162 Dwarf_Addr end; 163 164 Dwarf_CFI *cache; 165 166 /* Previous state saved by DW_CFA_remember_state, or .cie->initial_state, 167 or NULL in an initial_state pseudo-frame. */ 168 Dwarf_Frame *prev; 169 170 /* The FDE that generated this frame state. This points to its CIE, 171 which has the return_address_register and signal_frame flag. */ 172 struct dwarf_fde *fde; 173 174 /* The CFA is unknown, is R+N, or is computed by a DWARF expression. 175 A bogon in the CFI can indicate an invalid/incalculable rule. 176 We store that as cfa_invalid rather than barfing when processing it, 177 so callers can ignore the bogon unless they really need that CFA. */ 178 enum { cfa_undefined, cfa_offset, cfa_expr, cfa_invalid } cfa_rule; 179 union 180 { 181 Dwarf_Op offset; 182 Dwarf_Block expr; 183 } cfa_data; 184 /* We store an offset rule as a DW_OP_bregx operation. */ 185 #define cfa_val_reg cfa_data.offset.number 186 #define cfa_val_offset cfa_data.offset.number2 187 188 size_t nregs; 189 struct dwarf_frame_register regs[]; 190 }; 191 192 193 /* Clean up the data structure and all it points to. */ 194 extern void __libdw_destroy_frame_cache (Dwarf_CFI *cache) 195 __nonnull_attribute__ (1) internal_function; 196 197 /* Enter a CIE encountered while reading through for FDEs. */ 198 extern void __libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset, 199 const Dwarf_CIE *info) 200 __nonnull_attribute__ (1, 3) internal_function; 201 202 /* Look up a CIE_pointer for random access. */ 203 extern struct dwarf_cie *__libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset) 204 __nonnull_attribute__ (1) internal_function; 205 206 207 /* Look for an FDE covering the given PC address. */ 208 extern struct dwarf_fde *__libdw_find_fde (Dwarf_CFI *cache, 209 Dwarf_Addr address) 210 __nonnull_attribute__ (1) internal_function; 211 212 /* Look for an FDE by its offset in the section. */ 213 extern struct dwarf_fde *__libdw_fde_by_offset (Dwarf_CFI *cache, 214 Dwarf_Off offset) 215 __nonnull_attribute__ (1) internal_function; 216 217 /* Process the FDE that contains the given PC address, 218 to yield the frame state when stopped there. 219 The return value is a DWARF_E_* error code. */ 220 extern int __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde, 221 Dwarf_Addr address, Dwarf_Frame **frame) 222 __nonnull_attribute__ (1, 2, 4) internal_function; 223 224 225 /* Dummy struct for memory-access.h macros. */ 226 #define BYTE_ORDER_DUMMY(var, e_ident) \ 227 const struct { bool other_byte_order; } var = \ 228 { ((BYTE_ORDER == LITTLE_ENDIAN && e_ident[EI_DATA] == ELFDATA2MSB) \ 229 || (BYTE_ORDER == BIG_ENDIAN && e_ident[EI_DATA] == ELFDATA2LSB)) } 230 231 232 INTDECL (dwarf_next_cfi) 233 INTDECL (dwarf_getcfi) 234 INTDECL (dwarf_getcfi_elf) 235 INTDECL (dwarf_cfi_end) 236 INTDECL (dwarf_cfi_addrframe) 237 238 #endif /* unwindP.h */ 239