1 /* Internal definitions for libdw CFI interpreter.
2 Copyright (C) 2009-2010 Red Hat, Inc.
3 This file is part of Red Hat elfutils.
5 Red Hat elfutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by the
7 Free Software Foundation; version 2 of the License.
9 Red Hat elfutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with Red Hat elfutils; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
18 In addition, as a special exception, Red Hat, Inc. gives You the
19 additional right to link the code of Red Hat elfutils with code licensed
20 under any Open Source Initiative certified open source license
21 (http://www.opensource.org/licenses/index.php) which requires the
22 distribution of source code with any binary distribution and to
23 distribute linked combinations of the two. Non-GPL Code permitted under
24 this exception must only link to the code of Red Hat elfutils through
25 those well defined interfaces identified in the file named EXCEPTION
26 found in the source code files (the "Approved Interfaces"). The files
27 of Non-GPL Code may instantiate templates or use macros or inline
28 functions from the Approved Interfaces without causing the resulting
29 work to be covered by the GNU General Public License. Only Red Hat,
30 Inc. may make changes or additions to the list of Approved Interfaces.
31 Red Hat's grant of this exception is conditioned upon your not adding
32 any new exceptions. If you wish to add a new Approved Interface or
33 exception, please contact Red Hat. You must obey the GNU General Public
34 License in all respects for all of the Red Hat elfutils code and other
35 code used in conjunction with Red Hat elfutils except the Non-GPL Code
36 covered by this exception. If you modify this file, you may extend this
37 exception to your version of the file, but you are not obligated to do
38 so. If you do not wish to provide this exception without modification,
39 you must delete this exception statement from your version and license
40 this file solely under the GPL without exception.
42 Red Hat elfutils is an included package of the Open Invention Network.
43 An included package of the Open Invention Network is a package for which
44 Open Invention Network licensees cross-license their patents. No patent
45 license is granted, either expressly or impliedly, by designation as an
46 included package. Should you wish to participate in the Open Invention
47 Network licensing program, please visit www.openinventionnetwork.com
48 <http://www.openinventionnetwork.com>. */
57 /* Cached CIE representation. */
60 Dwarf_Off offset; /* Our position, as seen in FDEs' CIE_pointer. */
62 Dwarf_Word code_alignment_factor;
63 Dwarf_Sword data_alignment_factor;
64 Dwarf_Word return_address_register;
66 size_t fde_augmentation_data_size;
68 // play out to initial state
69 const uint8_t *initial_instructions;
70 const uint8_t *initial_instructions_end;
72 const Dwarf_Frame *initial_state;
74 uint8_t fde_encoding; /* DW_EH_PE_* for addresses in FDEs. */
75 uint8_t lsda_encoding; /* DW_EH_PE_* for LSDA in FDE augmentation. */
77 bool sized_augmentation_data; /* Saw 'z': FDEs have self-sized data. */
78 bool signal_frame; /* Saw 'S': FDE is for a signal frame. */
81 /* Cached FDE representation. */
84 struct dwarf_cie *cie;
86 /* This FDE describes PC values in [start, end). */
90 const uint8_t *instructions;
91 const uint8_t *instructions_end;
94 /* This holds everything we cache about the CFI from each ELF file's
95 .debug_frame or .eh_frame section. */
98 /* Dwarf handle we came from. If null, this is .eh_frame data. */
100 #define CFI_IS_EH(cfi) ((cfi)->dbg == NULL)
102 /* Data of the .debug_frame or .eh_frame section. */
104 const unsigned char *e_ident; /* For EI_DATA and EI_CLASS. */
106 Dwarf_Addr frame_vaddr; /* DW_EH_PE_pcrel, address of frame section. */
107 Dwarf_Addr textrel; /* DW_EH_PE_textrel base address. */
108 Dwarf_Addr datarel; /* DW_EH_PE_datarel base address. */
110 /* Location of next unread entry in the section. */
111 Dwarf_Off next_offset;
113 /* Search tree for the CIEs, indexed by CIE_pointer (section offset). */
116 /* Search tree for the FDEs, indexed by PC address. */
119 /* Search tree for parsed DWARF expressions, indexed by raw pointer. */
125 /* Binary search table in .eh_frame_hdr section. */
126 const uint8_t *search_table;
127 Dwarf_Addr search_table_vaddr;
128 size_t search_table_entries;
129 uint8_t search_table_encoding;
131 /* True if the file has a byte order different from the host. */
132 bool other_byte_order;
134 /* Default rule for registers not previously mentioned
135 is same_value, not undefined. */
136 bool default_same_value;
140 enum dwarf_frame_rule
142 reg_unspecified, /* Uninitialized state. */
143 reg_undefined, /* DW_CFA_undefined */
144 reg_same_value, /* DW_CFA_same_value */
145 reg_offset, /* DW_CFA_offset_extended et al */
146 reg_val_offset, /* DW_CFA_val_offset et al */
147 reg_register, /* DW_CFA_register */
148 reg_expression, /* DW_CFA_expression */
149 reg_val_expression, /* DW_CFA_val_expression */
152 /* This describes what we know about an individual register. */
153 struct dwarf_frame_register
155 enum dwarf_frame_rule rule:3;
157 /* The meaning of the value bits depends on the rule:
163 offset(N) N (register saved at CFA + value)
164 val_offset(N) N (register = CFA + value)
165 register(R) R (register = register #value)
166 expression(E) section offset of DW_FORM_block containing E
167 (register saved at address E computes)
168 val_expression(E) section offset of DW_FORM_block containing E
169 (register = value E computes)
171 Dwarf_Sword value:(sizeof (Dwarf_Sword) * 8 - 3);
174 /* This holds everything we know about the state of the frame
175 at a particular PC location described by an FDE. */
178 /* This frame description covers PC values in [start, end). */
184 /* Previous state saved by DW_CFA_remember_state, or .cie->initial_state,
185 or NULL in an initial_state pseudo-frame. */
188 /* The FDE that generated this frame state. This points to its CIE,
189 which has the return_address_register and signal_frame flag. */
190 struct dwarf_fde *fde;
192 /* The CFA is unknown, is R+N, or is computed by a DWARF expression.
193 A bogon in the CFI can indicate an invalid/incalculable rule.
194 We store that as cfa_invalid rather than barfing when processing it,
195 so callers can ignore the bogon unless they really need that CFA. */
196 enum { cfa_undefined, cfa_offset, cfa_expr, cfa_invalid } cfa_rule;
202 /* We store an offset rule as a DW_OP_bregx operation. */
203 #define cfa_val_reg cfa_data.offset.number
204 #define cfa_val_offset cfa_data.offset.number2
207 struct dwarf_frame_register regs[];
211 /* Clean up the data structure and all it points to. */
212 extern void __libdw_destroy_frame_cache (Dwarf_CFI *cache)
213 __nonnull_attribute__ (1) internal_function;
215 /* Enter a CIE encountered while reading through for FDEs. */
216 extern void __libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset,
217 const Dwarf_CIE *info)
218 __nonnull_attribute__ (1, 3) internal_function;
220 /* Look up a CIE_pointer for random access. */
221 extern struct dwarf_cie *__libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset)
222 __nonnull_attribute__ (1) internal_function;
225 /* Look for an FDE covering the given PC address. */
226 extern struct dwarf_fde *__libdw_find_fde (Dwarf_CFI *cache,
228 __nonnull_attribute__ (1) internal_function;
230 /* Look for an FDE by its offset in the section. */
231 extern struct dwarf_fde *__libdw_fde_by_offset (Dwarf_CFI *cache,
233 __nonnull_attribute__ (1) internal_function;
235 /* Process the FDE that contains the given PC address,
236 to yield the frame state when stopped there.
237 The return value is a DWARF_E_* error code. */
238 extern int __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde,
239 Dwarf_Addr address, Dwarf_Frame **frame)
240 __nonnull_attribute__ (1, 2, 4) internal_function;
243 /* Dummy struct for memory-access.h macros. */
244 #define BYTE_ORDER_DUMMY(var, e_ident) \
245 const struct { bool other_byte_order; } var = \
246 { ((BYTE_ORDER == LITTLE_ENDIAN && e_ident[EI_DATA] == ELFDATA2MSB) \
247 || (BYTE_ORDER == BIG_ENDIAN && e_ident[EI_DATA] == ELFDATA2LSB)) }
250 INTDECL (dwarf_next_cfi)
251 INTDECL (dwarf_getcfi)
252 INTDECL (dwarf_getcfi_elf)
253 INTDECL (dwarf_cfi_end)
254 INTDECL (dwarf_cfi_addrframe)
256 #endif /* unwindP.h */