1  /* tc-aarch64.h -- Header file for tc-aarch64.c.
       2     Copyright (C) 2009-2023 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 */