1/* dw2gencfi.h - Support for generating Dwarf2 CFI information. 2 Copyright (C) 2003-2022 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 27struct symbol; 28 29extern const pseudo_typeS cfi_pseudo_table[]; 30 31/* cfi_finish() is called at the end of file. It will complain if 32 the last CFI wasn't properly closed by .cfi_endproc. */ 33extern void cfi_finish (void); 34 35/* Entry points for backends to add unwind information. */ 36extern void cfi_new_fde (struct symbol *); 37extern void cfi_end_fde (struct symbol *); 38extern void cfi_set_return_column (unsigned); 39extern void cfi_set_sections (void); 40extern void cfi_add_advance_loc (struct symbol *); 41extern void cfi_add_label (const char *); 42 43extern void cfi_add_CFA_offset (unsigned, offsetT); 44extern void cfi_add_CFA_val_offset (unsigned, offsetT); 45extern void cfi_add_CFA_def_cfa (unsigned, offsetT); 46extern void cfi_add_CFA_register (unsigned, unsigned); 47extern void cfi_add_CFA_def_cfa_register (unsigned); 48extern void cfi_add_CFA_def_cfa_offset (offsetT); 49extern void cfi_add_CFA_restore (unsigned); 50extern void cfi_add_CFA_undefined (unsigned); 51extern void cfi_add_CFA_same_value (unsigned); 52extern void cfi_add_CFA_remember_state (void); 53extern void cfi_add_CFA_restore_state (void); 54 55/* Structures for md_cfi_end. */ 56 57#if defined (TE_PE) || defined (TE_PEP) 58#define SUPPORT_FRAME_LINKONCE 1 59#else 60#define SUPPORT_FRAME_LINKONCE 0 61#endif 62 63#ifdef tc_cfi_reloc_for_encoding 64#define SUPPORT_COMPACT_EH 1 65#else 66#define SUPPORT_COMPACT_EH 0 67#endif 68 69#define MULTIPLE_FRAME_SECTIONS (SUPPORT_FRAME_LINKONCE || SUPPORT_COMPACT_EH) 70 71struct cfi_insn_data 72{ 73 struct cfi_insn_data *next; 74#if MULTIPLE_FRAME_SECTIONS 75 segT cur_seg; 76#endif 77 int insn; 78 union 79 { 80 struct 81 { 82 unsigned reg; 83 offsetT offset; 84 } ri; 85 86 struct 87 { 88 unsigned reg1; 89 unsigned reg2; 90 } rr; 91 92 unsigned r; 93 offsetT i; 94 95 struct 96 { 97 symbolS *lab1; 98 symbolS *lab2; 99 } ll; 100 101 struct cfi_escape_data *esc; 102 103 struct 104 { 105 unsigned reg, encoding; 106 expressionS exp; 107 } ea; 108 109 const char *sym_name; 110 } u; 111}; 112 113/* An enumeration describing the Compact EH header format. The least 114 significant bit is used to distinguish the entries. 115 116 Inline Compact: Function offset [0] 117 Four chars of unwind data. 118 Out-of-line Compact: Function offset [1] 119 Compact unwind data offset [0] 120 Legacy: Function offset [1] 121 Unwind data offset [1] 122 123 The header type is initialized to EH_COMPACT_UNKNOWN until the 124 format is discovered by encountering a .fde_data entry. 125 Failure to find a .fde_data entry will cause an EH_COMPACT_LEGACY 126 header to be generated. */ 127 128enum { 129 EH_COMPACT_UNKNOWN, 130 EH_COMPACT_LEGACY, 131 EH_COMPACT_INLINE, 132 EH_COMPACT_OUTLINE, 133 EH_COMPACT_OUTLINE_DONE, 134 /* Outline if .cfi_inline_lsda used, otherwise legacy FDE. */ 135 EH_COMPACT_HAS_LSDA 136}; 137 138/* Stack of old CFI data, for save/restore. */ 139struct cfa_save_data 140{ 141 struct cfa_save_data *next; 142 offsetT cfa_offset; 143}; 144 145/* Current open FDE entry. */ 146struct frch_cfi_data 147{ 148 struct fde_entry *cur_fde_data; 149 symbolS *last_address; 150 offsetT cur_cfa_offset; 151 struct cfa_save_data *cfa_save_stack; 152}; 153 154struct fde_entry 155{ 156 struct fde_entry *next; 157#if MULTIPLE_FRAME_SECTIONS 158 segT cur_seg; 159#endif 160 symbolS *start_address; 161 symbolS *end_address; 162 struct cfi_insn_data *data; 163 struct cfi_insn_data **last; 164 unsigned char per_encoding; 165 unsigned char lsda_encoding; 166 int personality_id; 167 expressionS personality; 168 expressionS lsda; 169 unsigned int return_column; 170 unsigned int signal_frame; 171#if MULTIPLE_FRAME_SECTIONS 172 int handled; 173#endif 174 int eh_header_type; 175 /* Compact unwinding opcodes, not including the PR byte or LSDA. */ 176 int eh_data_size; 177 bfd_byte *eh_data; 178 /* For out of line tables and FDEs. */ 179 symbolS *eh_loc; 180 int sections; 181#ifdef tc_fde_entry_extras 182 tc_fde_entry_extras 183#endif 184}; 185 186/* The list of all FDEs that have been collected. */ 187extern struct fde_entry *all_fde_data; 188 189/* Fake CFI type; outside the byte range of any real CFI insn. */ 190#define CFI_adjust_cfa_offset 0x100 191#define CFI_return_column 0x101 192#define CFI_rel_offset 0x102 193#define CFI_escape 0x103 194#define CFI_signal_frame 0x104 195#define CFI_val_encoded_addr 0x105 196#define CFI_label 0x106 197 198/* By default emit .eh_frame only, not .debug_frame. */ 199#define CFI_EMIT_eh_frame (1 << 0) 200#define CFI_EMIT_debug_frame (1 << 1) 201#define CFI_EMIT_target (1 << 2) 202#define CFI_EMIT_eh_frame_compact (1 << 3) 203 204#endif /* DW2GENCFI_H */ 205