xref: /netbsd-src/external/gpl3/binutils/dist/gas/dw2gencfi.h (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
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