xref: /netbsd-src/external/gpl3/binutils/dist/gas/config/tc-aarch64.h (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* tc-aarch64.h -- Header file for tc-aarch64.c.
2    Copyright (C) 2009-2024 Free Software Foundation, Inc.
3    Contributed by ARM Ltd.
4 
5    This file is part of GAS.
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 of the license, or
10    (at your option) 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 this program; see the file COPYING3. If not,
19    see <http://www.gnu.org/licenses/>.  */
20 
21 #ifndef TC_AARCH64
22 #define TC_AARCH64 1
23 
24 #include "opcode/aarch64.h"
25 
26 #ifndef TARGET_BYTES_BIG_ENDIAN
27 #define TARGET_BYTES_BIG_ENDIAN 0
28 #endif
29 
30 #define WORKING_DOT_WORD
31 
32 #define TARGET_ARCH 	bfd_arch_aarch64
33 
34 #define DIFF_EXPR_OK
35 
36 /* Permit // comments.  */
37 #define DOUBLESLASH_LINE_COMMENTS
38 
39 #ifdef  LITTLE_ENDIAN
40 #undef  LITTLE_ENDIAN
41 #endif
42 
43 #ifdef  BIG_ENDIAN
44 #undef  BIG_ENDIAN
45 #endif
46 
47 #define LITTLE_ENDIAN 	1234
48 #define BIG_ENDIAN 	4321
49 
50 #define SWAP_32(n) \
51   ((((n) & 0xff) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) \
52    | (((n) >> 24) & 0xff))
53 
54 struct fix;
55 
56 struct aarch64_fix
57 {
58   struct aarch64_inst *inst;
59   enum aarch64_opnd opnd;
60 };
61 
62 #ifdef OBJ_ELF
63 # define AARCH64_BI_ENDIAN
64 # define TARGET_FORMAT	elf64_aarch64_target_format ()
65 #elif defined (OBJ_COFF)
66 # define TARGET_FORMAT coff_aarch64_target_format ()
67 #endif
68 
69 #define TC_FORCE_RELOCATION(FIX) aarch64_force_relocation (FIX)
70 
71 /* Currently there is no machine specific frags generated.  */
72 #define md_convert_frag(b,s,f) as_fatal ("aarch64 convert_frag called\n")
73 
74 #define md_cleanup() aarch64_cleanup ()
75 
76 #define md_start_line_hook() aarch64_start_line_hook ()
77 
78 #define tc_frob_label(S) aarch64_frob_label (S)
79 
80 /* We also need to mark assembler created symbols:  */
81 #define tc_frob_fake_label(S) aarch64_frob_label (S)
82 
83 #define tc_frob_section(S) aarch64_frob_section (S)
84 
85 /* The key used to sign a function's return address.  */
86 enum pointer_auth_key {
87   AARCH64_PAUTH_KEY_A,
88   AARCH64_PAUTH_KEY_B
89 };
90 
91 /* The extra fields required by AArch64 in fde_entry and cie_entry.  Currently
92    only used to store the key used to sign the frame's return address.  */
93 #define tc_fde_entry_extras enum pointer_auth_key pauth_key;
94 #define tc_cie_entry_extras enum pointer_auth_key pauth_key;
95 
96 /* The extra initialisation steps needed by AArch64 in alloc_fde_entry.
97    Currently only used to initialise the key used to sign the return
98    address.  */
99 #define tc_fde_entry_init_extra(fde) fde->pauth_key = AARCH64_PAUTH_KEY_A;
100 
101 /* Extra checks required by AArch64 when outputting the current cie_entry.
102    Currently only used to output a 'B' if the return address is signed with the
103    B key.  */
104 #define tc_output_cie_extra(cie) \
105     do \
106       { \
107 	if (cie->pauth_key == AARCH64_PAUTH_KEY_B) \
108 	  out_one ('B'); \
109       } \
110     while (0)
111 
112 /* Extra equivalence checks required by AArch64 when selecting the correct cie
113    for some fde.  Currently only used to check for quivalence between keys used
114    to sign ther return address.  */
115 #define tc_cie_fde_equivalent_extra(cie, fde) (cie->pauth_key == fde->pauth_key)
116 
117 /* The extra initialisation steps needed by AArch64 in select_cie_for_fde.
118    Currently only used to initialise the key used to sign the return
119    address.  */
120 #define tc_cie_entry_init_extra(cie, fde) cie->pauth_key = fde->pauth_key;
121 
122 #define TC_FIX_TYPE struct aarch64_fix
123 #define TC_INIT_FIX_DATA(FIX) { (FIX)->tc_fix_data.inst = NULL;	\
124     (FIX)->tc_fix_data.opnd = AARCH64_OPND_NIL; }
125 
126 #define TC_SYMFIELD_TYPE 	unsigned int
127 #define AARCH64_GET_FLAG(s)   	(*symbol_get_tc (s))
128 
129 void aarch64_copy_symbol_attributes (symbolS *, symbolS *);
130 #ifndef TC_COPY_SYMBOL_ATTRIBUTES
131 #define TC_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \
132   (aarch64_copy_symbol_attributes (DEST, SRC))
133 #endif
134 
135 #ifdef OBJ_ELF
136 void aarch64_elf_copy_symbol_attributes (symbolS *, symbolS *);
137 #define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \
138   aarch64_elf_copy_symbol_attributes (DEST, SRC)
139 #endif
140 
141 #define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR)			\
142   (NEXT_CHAR == ':' || (NEXT_CHAR == '/' && aarch64_data_in_code ()))
143 #define tc_canonicalize_symbol_name(str) aarch64_canonicalize_symbol_name (str);
144 #define obj_adjust_symtab() 		 aarch64_adjust_symtab ()
145 
146 #define LISTING_HEADER "AARCH64 GAS "
147 
148 #define LOCAL_LABEL(name)  (name[0] == '.' && name[1] == 'L')
149 #define LOCAL_LABELS_FB    1
150 
151 /* This expression evaluates to true if the relocation is for a local
152    object for which we still want to do the relocation at runtime.
153    False if we are willing to perform this relocation while building
154    the .o file.  GOTOFF does not need to be checked here because it is
155    not pcrel.  I am not sure if some of the others are ever used with
156    pcrel, but it is easier to be safe than sorry.  */
157 
158 #define TC_FORCE_RELOCATION_LOCAL(FIX)			\
159   (GENERIC_FORCE_RELOCATION_LOCAL (FIX)			\
160    || (FIX)->fx_r_type == BFD_RELOC_64			\
161    || (FIX)->fx_r_type == BFD_RELOC_32)
162 
163 #define TC_CONS_FIX_NEW(f,w,s,e,r) cons_fix_new_aarch64 ((f), (w), (s), (e))
164 
165 /* Max space for a rs_align_code fragment is 3 unaligned bytes
166    (fr_fix) plus 4 bytes to contain the repeating NOP (fr_var).  */
167 #define MAX_MEM_FOR_RS_ALIGN_CODE 7
168 
169 /* For frags in code sections we need to record whether they contain
170    code or data.  */
171 struct aarch64_frag_type
172 {
173   int recorded;
174 #if defined OBJ_ELF || defined OBJ_COFF
175   /* If there is a mapping symbol at offset 0 in this frag,
176      it will be saved in FIRST_MAP.  If there are any mapping
177      symbols in this frag, the last one will be saved in
178      LAST_MAP.  */
179   symbolS *first_map, *last_map;
180 #endif
181 };
182 
183 #define TC_FRAG_TYPE		struct aarch64_frag_type
184 #define TC_FRAG_INIT(fragp, max_bytes) aarch64_init_frag (fragp, max_bytes)
185 #define HANDLE_ALIGN(fragp)	aarch64_handle_align (fragp)
186 
187 #define md_do_align(N, FILL, LEN, MAX, LABEL)					\
188   if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg))	\
189     {										\
190       frag_align_code (N, MAX);							\
191       goto LABEL;								\
192     }
193 
194 /* COFF sub section alignment calculated using the write.c implementation.  */
195 #ifndef OBJ_COFF
196 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
197 #endif
198 
199 #define DWARF2_LINE_MIN_INSN_LENGTH 	4
200 
201 /* The lr register is r30.  */
202 #define DWARF2_DEFAULT_RETURN_COLUMN  30
203 
204 /* Registers are generally saved at negative offsets to the CFA.  */
205 #define DWARF2_CIE_DATA_ALIGNMENT     (-8)
206 
207 extern int aarch64_dwarf2_addr_size (void);
208 #define DWARF2_ADDR_SIZE(bfd) aarch64_dwarf2_addr_size ()
209 
210 #if defined OBJ_ELF || defined OBJ_COFF
211 #ifdef OBJ_ELF
212 # define obj_frob_symbol(sym, punt)	aarch64elf_frob_symbol ((sym), & (punt))
213 #endif
214 
215 # define GLOBAL_OFFSET_TABLE_NAME	"_GLOBAL_OFFSET_TABLE_"
216 # define TC_SEGMENT_INFO_TYPE 		struct aarch64_segment_info_type
217 
218 /* This is not really an alignment operation, but it's something we
219    need to do at the same time: whenever we are figuring out the
220    alignment for data, we should check whether a $d symbol is
221    necessary.  */
222 # define md_cons_align(nbytes)		mapping_state (MAP_DATA)
223 
224 enum mstate
225 {
226   MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections.  */
227   MAP_DATA,
228   MAP_INSN,
229 };
230 
231 void mapping_state (enum mstate);
232 
233 struct aarch64_segment_info_type
234 {
235   const char *last_file;
236   unsigned last_line;
237   enum mstate mapstate;
238   unsigned int marked_pr_dependency;
239   aarch64_instr_sequence insn_sequence;
240 };
241 
242 /* We want .cfi_* pseudo-ops for generating unwind info.  */
243 #define TARGET_USE_CFIPOP              1
244 
245 /* CFI hooks.  */
246 #define tc_regname_to_dw2regnum            tc_aarch64_regname_to_dw2regnum
247 #define tc_cfi_frame_initial_instructions  tc_aarch64_frame_initial_instructions
248 
249 extern void aarch64_after_parse_args (void);
250 #define md_after_parse_args() aarch64_after_parse_args ()
251 
252 # define EXTERN_FORCE_RELOC 			1
253 # define tc_fix_adjustable(FIX) 		1
254 
255 /* Values passed to md_apply_fix don't include the symbol value.  */
256 # define MD_APPLY_SYM_VALUE(FIX) 		0
257 
258 #else /* Neither OBJ_ELF nor OBJ_COFF.  */
259 
260 #define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
261 
262 #endif /*  OBJ_ELF || OBJ_COFF.  */
263 
264 #ifdef OBJ_ELF
265 
266 /* Whether SFrame stack trace info is supported.  */
267 extern bool aarch64_support_sframe_p (void);
268 #define support_sframe_p aarch64_support_sframe_p
269 
270 /* The stack-pointer register number for SFrame stack trace info.  */
271 extern unsigned int aarch64_sframe_cfa_sp_reg;
272 #define SFRAME_CFA_SP_REG aarch64_sframe_cfa_sp_reg
273 
274 /* The base-pointer register number for CFA stack trace info.  */
275 extern unsigned int aarch64_sframe_cfa_fp_reg;
276 #define SFRAME_CFA_FP_REG aarch64_sframe_cfa_fp_reg
277 
278 /* The return address register number for CFA stack trace info.  */
279 extern unsigned int aarch64_sframe_cfa_ra_reg;
280 #define SFRAME_CFA_RA_REG aarch64_sframe_cfa_ra_reg
281 
282 /* Specify if RA tracking is needed.  */
283 extern bool aarch64_sframe_ra_tracking_p (void);
284 #define sframe_ra_tracking_p aarch64_sframe_ra_tracking_p
285 
286 /* Specify the fixed offset to recover RA from CFA.
287    (useful only when RA tracking is not needed).  */
288 extern offsetT aarch64_sframe_cfa_ra_offset (void);
289 #define sframe_cfa_ra_offset aarch64_sframe_cfa_ra_offset
290 
291 /* The abi/arch indentifier for SFrame.  */
292 unsigned char aarch64_sframe_get_abi_arch (void);
293 #define sframe_get_abi_arch aarch64_sframe_get_abi_arch
294 
295 #endif /* OBJ_ELF  */
296 
297 #define MD_PCREL_FROM_SECTION(F,S) md_pcrel_from_section(F,S)
298 
299 extern void aarch64_frag_align_code (int, int);
300 extern const char * elf64_aarch64_target_format (void);
301 extern const char * coff_aarch64_target_format (void);
302 extern int aarch64_force_relocation (struct fix *);
303 extern void aarch64_cleanup (void);
304 extern void aarch64_start_line_hook (void);
305 extern void aarch64_frob_label (symbolS *);
306 extern void aarch64_frob_section (asection *sec);
307 extern int aarch64_data_in_code (void);
308 extern char * aarch64_canonicalize_symbol_name (char *);
309 extern void aarch64_adjust_symtab (void);
310 extern void aarch64elf_frob_symbol (symbolS *, int *);
311 extern void cons_fix_new_aarch64 (fragS *, int, int, expressionS *);
312 extern void aarch64_init_frag (struct frag *, int);
313 extern void aarch64_handle_align (struct frag *);
314 extern int tc_aarch64_regname_to_dw2regnum (char *regname);
315 extern void tc_aarch64_frame_initial_instructions (void);
316 
317 #ifdef TE_PE
318 
319 #define O_secrel O_md1
320 
321 #define TC_DWARF2_EMIT_OFFSET  tc_pe_dwarf2_emit_offset
322 void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
323 
324 #endif /* TE_PE */
325 
326 #endif /* TC_AARCH64 */
327