1 /* dw2gencfi.h - Support for generating Dwarf2 CFI information. 2 Copyright (C) 2003-2024 Free Software Foundation, Inc. 3 Contributed by Michal Ludvig <mludvig@suse.cz> 4 5 This file is part of GAS, the GNU Assembler. 6 7 GAS is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 GAS is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GAS; see the file COPYING. If not, write to the Free 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22 #ifndef DW2GENCFI_H 23 #define DW2GENCFI_H 24 25 #include "dwarf2.h" 26 27 struct symbol; 28 struct fde_entry; 29 30 extern int all_cfi_sections; 31 32 extern const pseudo_typeS cfi_pseudo_table[]; 33 34 #ifndef tc_cfi_frame_initial_instructions 35 #define tc_cfi_frame_initial_instructions() ((void)0) 36 #endif 37 38 #ifndef tc_cfi_startproc 39 # define tc_cfi_startproc() ((void)0) 40 #endif 41 42 #ifndef tc_cfi_endproc 43 # define tc_cfi_endproc(fde) ((void) (fde)) 44 #endif 45 46 /* Parse CFI assembler directive .cfi_sections. This is an external function 47 because SCFI functionality also uses the same implementation. */ 48 extern void dot_cfi_sections (int); 49 50 /* cfi_finish() is called at the end of file. It will complain if 51 the last CFI wasn't properly closed by .cfi_endproc. */ 52 extern void cfi_finish (void); 53 54 /* Entry points for backends to add unwind information. */ 55 extern void cfi_new_fde (struct symbol *); 56 extern void cfi_end_fde (struct symbol *); 57 extern void cfi_set_last_fde (struct fde_entry *fde); 58 extern void cfi_set_return_column (unsigned); 59 extern void cfi_set_sections (void); 60 extern void cfi_add_advance_loc (struct symbol *); 61 extern void cfi_add_label (const char *); 62 63 extern void cfi_add_CFA_offset (unsigned, offsetT); 64 extern void cfi_add_CFA_val_offset (unsigned, offsetT); 65 extern void cfi_add_CFA_def_cfa (unsigned, offsetT); 66 extern void cfi_add_CFA_register (unsigned, unsigned); 67 extern void cfi_add_CFA_def_cfa_register (unsigned); 68 extern void cfi_add_CFA_def_cfa_offset (offsetT); 69 extern void cfi_add_CFA_restore (unsigned); 70 extern void cfi_add_CFA_undefined (unsigned); 71 extern void cfi_add_CFA_same_value (unsigned); 72 extern void cfi_add_CFA_remember_state (void); 73 extern void cfi_add_CFA_restore_state (void); 74 75 /* Structures for md_cfi_end. */ 76 77 #if defined (TE_PE) || defined (TE_PEP) 78 #define SUPPORT_FRAME_LINKONCE 1 79 #else 80 #define SUPPORT_FRAME_LINKONCE 0 81 #endif 82 83 #ifdef tc_cfi_reloc_for_encoding 84 #define SUPPORT_COMPACT_EH 1 85 #else 86 #define SUPPORT_COMPACT_EH 0 87 #endif 88 89 #ifndef TARGET_MULTIPLE_EH_FRAME_SECTIONS 90 #define TARGET_MULTIPLE_EH_FRAME_SECTIONS 0 91 #endif 92 93 #define MULTIPLE_FRAME_SECTIONS (SUPPORT_FRAME_LINKONCE || SUPPORT_COMPACT_EH \ 94 || TARGET_MULTIPLE_EH_FRAME_SECTIONS) 95 96 struct cfi_insn_data 97 { 98 struct cfi_insn_data *next; 99 #if MULTIPLE_FRAME_SECTIONS 100 segT cur_seg; 101 #endif 102 int insn; 103 union 104 { 105 struct 106 { 107 unsigned reg; 108 offsetT offset; 109 } ri; 110 111 struct 112 { 113 unsigned reg1; 114 unsigned reg2; 115 } rr; 116 117 unsigned r; 118 offsetT i; 119 120 struct 121 { 122 symbolS *lab1; 123 symbolS *lab2; 124 } ll; 125 126 struct cfi_escape_data *esc; 127 128 struct 129 { 130 unsigned reg, encoding; 131 expressionS exp; 132 } ea; 133 134 const char *sym_name; 135 } u; 136 }; 137 138 /* An enumeration describing the Compact EH header format. The least 139 significant bit is used to distinguish the entries. 140 141 Inline Compact: Function offset [0] 142 Four chars of unwind data. 143 Out-of-line Compact: Function offset [1] 144 Compact unwind data offset [0] 145 Legacy: Function offset [1] 146 Unwind data offset [1] 147 148 The header type is initialized to EH_COMPACT_UNKNOWN until the 149 format is discovered by encountering a .fde_data entry. 150 Failure to find a .fde_data entry will cause an EH_COMPACT_LEGACY 151 header to be generated. */ 152 153 enum { 154 EH_COMPACT_UNKNOWN, 155 EH_COMPACT_LEGACY, 156 EH_COMPACT_INLINE, 157 EH_COMPACT_OUTLINE, 158 EH_COMPACT_OUTLINE_DONE, 159 /* Outline if .cfi_inline_lsda used, otherwise legacy FDE. */ 160 EH_COMPACT_HAS_LSDA 161 }; 162 163 /* Stack of old CFI data, for save/restore. */ 164 struct cfa_save_data 165 { 166 struct cfa_save_data *next; 167 offsetT cfa_offset; 168 }; 169 170 /* Current open FDE entry. */ 171 struct frch_cfi_data 172 { 173 struct fde_entry *cur_fde_data; 174 symbolS *last_address; 175 offsetT cur_cfa_offset; 176 struct cfa_save_data *cfa_save_stack; 177 }; 178 179 struct fde_entry 180 { 181 struct fde_entry *next; 182 #if MULTIPLE_FRAME_SECTIONS 183 segT cur_seg; 184 #endif 185 symbolS *start_address; 186 symbolS *end_address; 187 struct cfi_insn_data *data; 188 struct cfi_insn_data **last; 189 unsigned char per_encoding; 190 unsigned char lsda_encoding; 191 int personality_id; 192 expressionS personality; 193 expressionS lsda; 194 unsigned int return_column; 195 unsigned int signal_frame; 196 #if MULTIPLE_FRAME_SECTIONS 197 int handled; 198 #endif 199 int eh_header_type; 200 /* Compact unwinding opcodes, not including the PR byte or LSDA. */ 201 int eh_data_size; 202 bfd_byte *eh_data; 203 /* For out of line tables and FDEs. */ 204 symbolS *eh_loc; 205 int sections; 206 #ifdef tc_fde_entry_extras 207 tc_fde_entry_extras 208 #endif 209 }; 210 211 /* The list of all FDEs that have been collected. */ 212 extern struct fde_entry *all_fde_data; 213 214 /* Fake CFI type; outside the byte range of any real CFI insn. */ 215 #define CFI_adjust_cfa_offset 0x100 216 #define CFI_return_column 0x101 217 #define CFI_rel_offset 0x102 218 #define CFI_escape 0x103 219 #define CFI_signal_frame 0x104 220 #define CFI_val_encoded_addr 0x105 221 #define CFI_label 0x106 222 223 /* By default emit .eh_frame only, not .debug_frame. */ 224 #define CFI_EMIT_eh_frame (1 << 0) 225 #define CFI_EMIT_debug_frame (1 << 1) 226 #define CFI_EMIT_target (1 << 2) 227 #define CFI_EMIT_eh_frame_compact (1 << 3) 228 #define CFI_EMIT_sframe (1 << 4) 229 230 #endif /* DW2GENCFI_H */ 231