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