1 /* Internal definitions for libdw CFI interpreter.
2 Copyright (C) 2009-2010, 2013 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
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
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
18 or both in parallel, as here.
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.
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/>. */
36 /* Cached CIE representation. */
39 Dwarf_Off offset; /* Our position, as seen in FDEs' CIE_pointer. */
41 Dwarf_Word code_alignment_factor;
42 Dwarf_Sword data_alignment_factor;
43 Dwarf_Word return_address_register;
45 size_t fde_augmentation_data_size;
47 // play out to initial state
48 const uint8_t *initial_instructions;
49 const uint8_t *initial_instructions_end;
51 const Dwarf_Frame *initial_state;
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. */
56 bool sized_augmentation_data; /* Saw 'z': FDEs have self-sized data. */
57 bool signal_frame; /* Saw 'S': FDE is for a signal frame. */
60 /* Cached FDE representation. */
63 struct dwarf_cie *cie;
65 /* This FDE describes PC values in [start, end). */
69 const uint8_t *instructions;
70 const uint8_t *instructions_end;
73 /* This holds everything we cache about the CFI from each ELF file's
74 .debug_frame or .eh_frame section. */
77 /* Dwarf handle we came from. If null, this is .eh_frame data. */
79 #define CFI_IS_EH(cfi) ((cfi)->dbg == NULL)
81 /* Data of the .debug_frame or .eh_frame section. */
83 const unsigned char *e_ident; /* For EI_DATA and EI_CLASS. */
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. */
89 /* Location of next unread entry in the section. */
90 Dwarf_Off next_offset;
92 /* Search tree for the CIEs, indexed by CIE_pointer (section offset). */
95 /* Search tree for the FDEs, indexed by PC address. */
98 /* Search tree for parsed DWARF expressions, indexed by raw pointer. */
104 /* Binary search table in .eh_frame_hdr section. */
105 const uint8_t *search_table;
106 Dwarf_Addr search_table_vaddr;
107 size_t search_table_entries;
108 uint8_t search_table_encoding;
110 /* True if the file has a byte order different from the host. */
111 bool other_byte_order;
113 /* Default rule for registers not previously mentioned
114 is same_value, not undefined. */
115 bool default_same_value;
119 enum dwarf_frame_rule
121 reg_unspecified, /* Uninitialized state. */
122 reg_undefined, /* DW_CFA_undefined */
123 reg_same_value, /* DW_CFA_same_value */
124 reg_offset, /* DW_CFA_offset_extended et al */
125 reg_val_offset, /* DW_CFA_val_offset et al */
126 reg_register, /* DW_CFA_register */
127 reg_expression, /* DW_CFA_expression */
128 reg_val_expression, /* DW_CFA_val_expression */
131 /* This describes what we know about an individual register. */
132 struct dwarf_frame_register
134 enum dwarf_frame_rule rule:3;
136 /* The meaning of the value bits depends on the rule:
142 offset(N) N (register saved at CFA + value)
143 val_offset(N) N (register = CFA + value)
144 register(R) R (register = register #value)
145 expression(E) section offset of DW_FORM_block containing E
146 (register saved at address E computes)
147 val_expression(E) section offset of DW_FORM_block containing E
148 (register = value E computes)
150 Dwarf_Sword value:(sizeof (Dwarf_Sword) * 8 - 3);
153 /* This holds instructions for unwinding frame at a particular PC location
154 described by an FDE. */
157 /* This frame description covers PC values in [start, end). */
163 /* Previous state saved by DW_CFA_remember_state, or .cie->initial_state,
164 or NULL in an initial_state pseudo-frame. */
167 /* The FDE that generated this frame state. This points to its CIE,
168 which has the return_address_register and signal_frame flag. */
169 struct dwarf_fde *fde;
171 /* The CFA is unknown, is R+N, or is computed by a DWARF expression.
172 A bogon in the CFI can indicate an invalid/incalculable rule.
173 We store that as cfa_invalid rather than barfing when processing it,
174 so callers can ignore the bogon unless they really need that CFA. */
175 enum { cfa_undefined, cfa_offset, cfa_expr, cfa_invalid } cfa_rule;
181 /* We store an offset rule as a DW_OP_bregx operation. */
182 #define cfa_val_reg cfa_data.offset.number
183 #define cfa_val_offset cfa_data.offset.number2
186 struct dwarf_frame_register regs[];
190 /* Clean up the data structure and all it points to. */
191 extern void __libdw_destroy_frame_cache (Dwarf_CFI *cache)
192 __nonnull_attribute__ (1) internal_function;
194 /* Enter a CIE encountered while reading through for FDEs. */
195 extern void __libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset,
196 const Dwarf_CIE *info)
197 __nonnull_attribute__ (1, 3) internal_function;
199 /* Look up a CIE_pointer for random access. */
200 extern struct dwarf_cie *__libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset)
201 __nonnull_attribute__ (1) internal_function;
204 /* Look for an FDE covering the given PC address. */
205 extern struct dwarf_fde *__libdw_find_fde (Dwarf_CFI *cache,
207 __nonnull_attribute__ (1) internal_function;
209 /* Look for an FDE by its offset in the section. */
210 extern struct dwarf_fde *__libdw_fde_by_offset (Dwarf_CFI *cache,
212 __nonnull_attribute__ (1) internal_function;
214 /* Process the FDE that contains the given PC address,
215 to yield the frame state when stopped there.
216 The return value is a DWARF_E_* error code. */
217 extern int __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde,
218 Dwarf_Addr address, Dwarf_Frame **frame)
219 __nonnull_attribute__ (1, 2, 4) internal_function;
222 /* Dummy struct for memory-access.h macros. */
223 #define BYTE_ORDER_DUMMY(var, e_ident) \
224 const struct { bool other_byte_order; } var = \
225 { ((BYTE_ORDER == LITTLE_ENDIAN && e_ident[EI_DATA] == ELFDATA2MSB) \
226 || (BYTE_ORDER == BIG_ENDIAN && e_ident[EI_DATA] == ELFDATA2LSB)) }
229 INTDECL (dwarf_next_cfi)
230 INTDECL (dwarf_getcfi)
231 INTDECL (dwarf_getcfi_elf)
232 INTDECL (dwarf_cfi_end)
233 INTDECL (dwarf_cfi_addrframe)
235 #endif /* unwindP.h */