| 1 | /* This file is tc-arm.h | 
|---|
| 2 | Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 | 
|---|
| 3 | Free Software Foundation, Inc. | 
|---|
| 4 | Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) | 
|---|
| 5 | Modified by David Taylor (dtaylor@armltd.co.uk) | 
|---|
| 6 |  | 
|---|
| 7 | This file is part of GAS, the GNU Assembler. | 
|---|
| 8 |  | 
|---|
| 9 | GAS is free software; you can redistribute it and/or modify | 
|---|
| 10 | it under the terms of the GNU General Public License as published by | 
|---|
| 11 | the Free Software Foundation; either version 2, or (at your option) | 
|---|
| 12 | any later version. | 
|---|
| 13 |  | 
|---|
| 14 | GAS is distributed in the hope that it will be useful, | 
|---|
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 17 | GNU General Public License for more details. | 
|---|
| 18 |  | 
|---|
| 19 | You should have received a copy of the GNU General Public License | 
|---|
| 20 | along with GAS; see the file COPYING.  If not, write to the Free | 
|---|
| 21 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | 
|---|
| 22 | 02111-1307, USA.  */ | 
|---|
| 23 |  | 
|---|
| 24 | #define TC_ARM 1 | 
|---|
| 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 COFF_MAGIC      ARMMAGIC | 
|---|
| 33 | #define TARGET_ARCH     bfd_arch_arm | 
|---|
| 34 |  | 
|---|
| 35 | #define AOUT_MACHTYPE   0 | 
|---|
| 36 |  | 
|---|
| 37 | #define DIFF_EXPR_OK | 
|---|
| 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 | #if defined OBJ_AOUT | 
|---|
| 51 | #if defined TE_RISCIX | 
|---|
| 52 | # define TARGET_FORMAT "a.out-riscix" | 
|---|
| 53 | #elif defined TE_LINUX | 
|---|
| 54 | # define ARM_BI_ENDIAN | 
|---|
| 55 | # define TARGET_FORMAT "a.out-arm-linux" | 
|---|
| 56 | #elif defined TE_NetBSD | 
|---|
| 57 | # define TARGET_FORMAT "a.out-arm-netbsd" | 
|---|
| 58 | #else | 
|---|
| 59 | # define ARM_BI_ENDIAN | 
|---|
| 60 | # define TARGET_FORMAT \ | 
|---|
| 61 | (target_big_endian ? "a.out-arm-big" : "a.out-arm-little") | 
|---|
| 62 | #endif | 
|---|
| 63 | #endif /* OBJ_AOUT */ | 
|---|
| 64 |  | 
|---|
| 65 | #ifdef OBJ_AIF | 
|---|
| 66 | #define TARGET_FORMAT "aif" | 
|---|
| 67 | #endif | 
|---|
| 68 |  | 
|---|
| 69 | struct fix; | 
|---|
| 70 |  | 
|---|
| 71 | #if defined OBJ_COFF || defined OBJ_ELF | 
|---|
| 72 | # define ARM_BI_ENDIAN | 
|---|
| 73 |  | 
|---|
| 74 | # define TC_VALIDATE_FIX(FIX, SEGTYPE, LABEL) arm_validate_fix (FIX) | 
|---|
| 75 | extern void arm_validate_fix PARAMS ((struct fix *)); | 
|---|
| 76 | #endif | 
|---|
| 77 |  | 
|---|
| 78 | #ifdef OBJ_COFF | 
|---|
| 79 | # if defined TE_PE | 
|---|
| 80 | #   ifdef TE_EPOC | 
|---|
| 81 | #    define TARGET_FORMAT (target_big_endian ? "epoc-pe-arm-big" : "epoc-pe-arm-little") | 
|---|
| 82 | #   else | 
|---|
| 83 | #    define TARGET_FORMAT (target_big_endian ? "pe-arm-big" : "pe-arm-little") | 
|---|
| 84 | #   endif | 
|---|
| 85 | # else | 
|---|
| 86 | #  define TARGET_FORMAT (target_big_endian ? "coff-arm-big" : "coff-arm-little") | 
|---|
| 87 | # endif | 
|---|
| 88 | #endif | 
|---|
| 89 |  | 
|---|
| 90 | #ifdef OBJ_ELF | 
|---|
| 91 | # define TARGET_FORMAT elf32_arm_target_format() | 
|---|
| 92 | extern const char * elf32_arm_target_format PARAMS ((void)); | 
|---|
| 93 | #endif | 
|---|
| 94 |  | 
|---|
| 95 | #define TC_FORCE_RELOCATION(FIX) arm_force_relocation (FIX) | 
|---|
| 96 | extern int arm_force_relocation PARAMS ((struct fix *)); | 
|---|
| 97 |  | 
|---|
| 98 | #define md_convert_frag(b, s, f) {as_fatal (_("arm convert_frag\n"));} | 
|---|
| 99 |  | 
|---|
| 100 | #define md_cleanup() arm_cleanup () | 
|---|
| 101 | extern void arm_cleanup PARAMS ((void)); | 
|---|
| 102 |  | 
|---|
| 103 | #define md_start_line_hook() arm_start_line_hook () | 
|---|
| 104 | extern void arm_start_line_hook PARAMS ((void)); | 
|---|
| 105 |  | 
|---|
| 106 | #define tc_frob_label(S) arm_frob_label (S) | 
|---|
| 107 | extern void arm_frob_label PARAMS ((symbolS *)); | 
|---|
| 108 |  | 
|---|
| 109 | /* We also need to mark assembler created symbols:  */ | 
|---|
| 110 | #define tc_frob_fake_label(S) arm_frob_label (S) | 
|---|
| 111 |  | 
|---|
| 112 | /* NOTE: The fake label creation in stabs.c:s_stab_generic() has | 
|---|
| 113 | deliberately not been updated to mark assembler created stabs | 
|---|
| 114 | symbols as Thumb.  */ | 
|---|
| 115 |  | 
|---|
| 116 | #define TC_FIX_TYPE PTR | 
|---|
| 117 | #define TC_INIT_FIX_DATA(FIX) ((FIX)->tc_fix_data = NULL) | 
|---|
| 118 |  | 
|---|
| 119 | #if defined OBJ_ELF || defined OBJ_COFF | 
|---|
| 120 | #define EXTERN_FORCE_RELOC 1 | 
|---|
| 121 |  | 
|---|
| 122 | #define tc_fix_adjustable(FIX) arm_fix_adjustable (FIX) | 
|---|
| 123 | bfd_boolean arm_fix_adjustable PARAMS ((struct fix *)); | 
|---|
| 124 |  | 
|---|
| 125 | /* Values passed to md_apply_fix3 don't include the symbol value.  */ | 
|---|
| 126 | #define MD_APPLY_SYM_VALUE(FIX) 0 | 
|---|
| 127 | #endif | 
|---|
| 128 |  | 
|---|
| 129 | /* We need to keep some local information on symbols.  */ | 
|---|
| 130 |  | 
|---|
| 131 | #define TC_SYMFIELD_TYPE unsigned int | 
|---|
| 132 | #define ARM_GET_FLAG(s)         (*symbol_get_tc (s)) | 
|---|
| 133 | #define ARM_SET_FLAG(s,v)       (*symbol_get_tc (s) |= (v)) | 
|---|
| 134 | #define ARM_RESET_FLAG(s,v)     (*symbol_get_tc (s) &= ~(v)) | 
|---|
| 135 |  | 
|---|
| 136 | #define ARM_FLAG_THUMB          (1 << 0)        /* The symbol is a Thumb symbol rather than an Arm symbol.  */ | 
|---|
| 137 | #define ARM_FLAG_INTERWORK      (1 << 1)        /* The symbol is attached to code that suppports interworking.  */ | 
|---|
| 138 | #define THUMB_FLAG_FUNC         (1 << 2)        /* The symbol is attached to the start of a Thumb function.  */ | 
|---|
| 139 |  | 
|---|
| 140 | #define ARM_IS_THUMB(s)         (ARM_GET_FLAG (s) & ARM_FLAG_THUMB) | 
|---|
| 141 | #define ARM_IS_INTERWORK(s)     (ARM_GET_FLAG (s) & ARM_FLAG_INTERWORK) | 
|---|
| 142 | #define THUMB_IS_FUNC(s)        (ARM_GET_FLAG (s) & THUMB_FLAG_FUNC) | 
|---|
| 143 |  | 
|---|
| 144 | #define ARM_SET_THUMB(s,t)      ((t) ? ARM_SET_FLAG (s, ARM_FLAG_THUMB)     : ARM_RESET_FLAG (s, ARM_FLAG_THUMB)) | 
|---|
| 145 | #define ARM_SET_INTERWORK(s,t)  ((t) ? ARM_SET_FLAG (s, ARM_FLAG_INTERWORK) : ARM_RESET_FLAG (s, ARM_FLAG_INTERWORK)) | 
|---|
| 146 | #define THUMB_SET_FUNC(s,t)     ((t) ? ARM_SET_FLAG (s, THUMB_FLAG_FUNC)    : ARM_RESET_FLAG (s, THUMB_FLAG_FUNC)) | 
|---|
| 147 |  | 
|---|
| 148 | #define TC_START_LABEL(C,STR) \ | 
|---|
| 149 | (c == ':' || (c == '/' && arm_data_in_code ())) | 
|---|
| 150 | int arm_data_in_code PARAMS ((void)); | 
|---|
| 151 |  | 
|---|
| 152 | #define tc_canonicalize_symbol_name(str) \ | 
|---|
| 153 | arm_canonicalize_symbol_name (str); | 
|---|
| 154 | char * arm_canonicalize_symbol_name PARAMS ((char *)); | 
|---|
| 155 |  | 
|---|
| 156 | #define obj_adjust_symtab() arm_adjust_symtab () | 
|---|
| 157 | extern void arm_adjust_symtab PARAMS ((void)); | 
|---|
| 158 |  | 
|---|
| 159 | #ifdef OBJ_ELF | 
|---|
| 160 | #define obj_frob_symbol(sym, punt)  armelf_frob_symbol ((sym), & (punt)) | 
|---|
| 161 | void armelf_frob_symbol PARAMS ((symbolS *, int *)); | 
|---|
| 162 | #endif | 
|---|
| 163 |  | 
|---|
| 164 | #define tc_aout_pre_write_hook(x)       {;}     /* not used */ | 
|---|
| 165 |  | 
|---|
| 166 | #define LISTING_HEADER "ARM GAS " | 
|---|
| 167 |  | 
|---|
| 168 | #define OPTIONAL_REGISTER_PREFIX '%' | 
|---|
| 169 |  | 
|---|
| 170 | #define LOCAL_LABEL(name) (name[0] == '.' && (name[1] == 'L')) | 
|---|
| 171 | #define LOCAL_LABELS_FB   1 | 
|---|
| 172 | #ifdef OBJ_ELF | 
|---|
| 173 | #define LOCAL_LABEL_PREFIX '.' | 
|---|
| 174 | #endif | 
|---|
| 175 |  | 
|---|
| 176 | /* This expression evaluates to true if the relocation is for a local | 
|---|
| 177 | object for which we still want to do the relocation at runtime. | 
|---|
| 178 | False if we are willing to perform this relocation while building | 
|---|
| 179 | the .o file.  GOTOFF does not need to be checked here because it is | 
|---|
| 180 | not pcrel.  I am not sure if some of the others are ever used with | 
|---|
| 181 | pcrel, but it is easier to be safe than sorry.  */ | 
|---|
| 182 |  | 
|---|
| 183 | #define TC_FORCE_RELOCATION_LOCAL(FIX)                  \ | 
|---|
| 184 | (!(FIX)->fx_pcrel                                     \ | 
|---|
| 185 | || (FIX)->fx_plt                                     \ | 
|---|
| 186 | || (FIX)->fx_r_type == BFD_RELOC_ARM_GOT12           \ | 
|---|
| 187 | || (FIX)->fx_r_type == BFD_RELOC_ARM_GOT32           \ | 
|---|
| 188 | || (FIX)->fx_r_type == BFD_RELOC_32                  \ | 
|---|
| 189 | || TC_FORCE_RELOCATION (FIX)) | 
|---|
| 190 |  | 
|---|
| 191 | #define TC_CONS_FIX_NEW cons_fix_new_arm | 
|---|
| 192 | extern void cons_fix_new_arm PARAMS ((fragS *, int, int, expressionS *)); | 
|---|
| 193 |  | 
|---|
| 194 | #ifdef OBJ_ELF | 
|---|
| 195 | #define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_" | 
|---|
| 196 | #else | 
|---|
| 197 | #define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_" | 
|---|
| 198 | #endif | 
|---|
| 199 |  | 
|---|
| 200 | #ifdef OBJ_ELF | 
|---|
| 201 | #define DWARF2_LINE_MIN_INSN_LENGTH 2 | 
|---|
| 202 | #endif | 
|---|
| 203 |  | 
|---|
| 204 | #define MAX_MEM_FOR_RS_ALIGN_CODE 31 | 
|---|
| 205 |  | 
|---|
| 206 | /* For frags in code sections we need to record whether they contain | 
|---|
| 207 | ARM code or THUMB code.  This is that if they have to be aligned, | 
|---|
| 208 | they can contain the correct type of no-op instruction.  */ | 
|---|
| 209 | #define TC_FRAG_TYPE    int | 
|---|
| 210 | #define TC_FRAG_INIT(fragp)     arm_init_frag (fragp) | 
|---|
| 211 | extern void arm_init_frag PARAMS ((struct frag *)); | 
|---|
| 212 |  | 
|---|
| 213 | #define HANDLE_ALIGN(fragp) arm_handle_align (fragp) | 
|---|
| 214 | extern void arm_handle_align PARAMS ((struct frag *)); | 
|---|
| 215 |  | 
|---|
| 216 | #define md_do_align(N, FILL, LEN, MAX, LABEL)                                   \ | 
|---|
| 217 | if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg))     \ | 
|---|
| 218 | {                                                                           \ | 
|---|
| 219 | arm_frag_align_code (N, MAX);                                             \ | 
|---|
| 220 | goto LABEL;                                                               \ | 
|---|
| 221 | } | 
|---|
| 222 | extern void arm_frag_align_code PARAMS ((int, int)); | 
|---|