1 //===-- AArch64ELFObjectWriter.cpp - AArch64 ELF Writer -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file handles ELF-specific object emission, converting LLVM's internal 11 // fixups into the appropriate relocations. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "MCTargetDesc/AArch64FixupKinds.h" 16 #include "MCTargetDesc/AArch64MCTargetDesc.h" 17 #include "llvm/MC/MCELFObjectWriter.h" 18 #include "llvm/MC/MCValue.h" 19 #include "llvm/Support/ErrorHandling.h" 20 21 using namespace llvm; 22 23 namespace { 24 class AArch64ELFObjectWriter : public MCELFObjectTargetWriter { 25 public: 26 AArch64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian); 27 28 virtual ~AArch64ELFObjectWriter(); 29 30 protected: 31 unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 32 bool IsPCRel) const override; 33 34 private: 35 }; 36 } 37 38 AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian) 39 : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64, 40 /*HasRelocationAddend*/ true) 41 {} 42 43 AArch64ELFObjectWriter::~AArch64ELFObjectWriter() 44 {} 45 46 unsigned AArch64ELFObjectWriter::GetRelocType(const MCValue &Target, 47 const MCFixup &Fixup, 48 bool IsPCRel) const { 49 unsigned Type; 50 if (IsPCRel) { 51 switch ((unsigned)Fixup.getKind()) { 52 default: 53 llvm_unreachable("Unimplemented fixup -> relocation"); 54 case FK_Data_8: 55 return ELF::R_AARCH64_PREL64; 56 case FK_Data_4: 57 return ELF::R_AARCH64_PREL32; 58 case FK_Data_2: 59 return ELF::R_AARCH64_PREL16; 60 case AArch64::fixup_a64_ld_prel: 61 Type = ELF::R_AARCH64_LD_PREL_LO19; 62 break; 63 case AArch64::fixup_a64_adr_prel: 64 Type = ELF::R_AARCH64_ADR_PREL_LO21; 65 break; 66 case AArch64::fixup_a64_adr_prel_page: 67 Type = ELF::R_AARCH64_ADR_PREL_PG_HI21; 68 break; 69 case AArch64::fixup_a64_adr_prel_got_page: 70 Type = ELF::R_AARCH64_ADR_GOT_PAGE; 71 break; 72 case AArch64::fixup_a64_tstbr: 73 Type = ELF::R_AARCH64_TSTBR14; 74 break; 75 case AArch64::fixup_a64_condbr: 76 Type = ELF::R_AARCH64_CONDBR19; 77 break; 78 case AArch64::fixup_a64_uncondbr: 79 Type = ELF::R_AARCH64_JUMP26; 80 break; 81 case AArch64::fixup_a64_call: 82 Type = ELF::R_AARCH64_CALL26; 83 break; 84 case AArch64::fixup_a64_adr_gottprel_page: 85 Type = ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21; 86 break; 87 case AArch64::fixup_a64_ld_gottprel_prel19: 88 Type = ELF::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19; 89 break; 90 case AArch64::fixup_a64_tlsdesc_adr_page: 91 Type = ELF::R_AARCH64_TLSDESC_ADR_PAGE; 92 break; 93 } 94 } else { 95 switch ((unsigned)Fixup.getKind()) { 96 default: 97 llvm_unreachable("Unimplemented fixup -> relocation"); 98 case FK_Data_8: 99 return ELF::R_AARCH64_ABS64; 100 case FK_Data_4: 101 return ELF::R_AARCH64_ABS32; 102 case FK_Data_2: 103 return ELF::R_AARCH64_ABS16; 104 case AArch64::fixup_a64_add_lo12: 105 Type = ELF::R_AARCH64_ADD_ABS_LO12_NC; 106 break; 107 case AArch64::fixup_a64_ld64_got_lo12_nc: 108 Type = ELF::R_AARCH64_LD64_GOT_LO12_NC; 109 break; 110 case AArch64::fixup_a64_ldst8_lo12: 111 Type = ELF::R_AARCH64_LDST8_ABS_LO12_NC; 112 break; 113 case AArch64::fixup_a64_ldst16_lo12: 114 Type = ELF::R_AARCH64_LDST16_ABS_LO12_NC; 115 break; 116 case AArch64::fixup_a64_ldst32_lo12: 117 Type = ELF::R_AARCH64_LDST32_ABS_LO12_NC; 118 break; 119 case AArch64::fixup_a64_ldst64_lo12: 120 Type = ELF::R_AARCH64_LDST64_ABS_LO12_NC; 121 break; 122 case AArch64::fixup_a64_ldst128_lo12: 123 Type = ELF::R_AARCH64_LDST128_ABS_LO12_NC; 124 break; 125 case AArch64::fixup_a64_movw_uabs_g0: 126 Type = ELF::R_AARCH64_MOVW_UABS_G0; 127 break; 128 case AArch64::fixup_a64_movw_uabs_g0_nc: 129 Type = ELF::R_AARCH64_MOVW_UABS_G0_NC; 130 break; 131 case AArch64::fixup_a64_movw_uabs_g1: 132 Type = ELF::R_AARCH64_MOVW_UABS_G1; 133 break; 134 case AArch64::fixup_a64_movw_uabs_g1_nc: 135 Type = ELF::R_AARCH64_MOVW_UABS_G1_NC; 136 break; 137 case AArch64::fixup_a64_movw_uabs_g2: 138 Type = ELF::R_AARCH64_MOVW_UABS_G2; 139 break; 140 case AArch64::fixup_a64_movw_uabs_g2_nc: 141 Type = ELF::R_AARCH64_MOVW_UABS_G2_NC; 142 break; 143 case AArch64::fixup_a64_movw_uabs_g3: 144 Type = ELF::R_AARCH64_MOVW_UABS_G3; 145 break; 146 case AArch64::fixup_a64_movw_sabs_g0: 147 Type = ELF::R_AARCH64_MOVW_SABS_G0; 148 break; 149 case AArch64::fixup_a64_movw_sabs_g1: 150 Type = ELF::R_AARCH64_MOVW_SABS_G1; 151 break; 152 case AArch64::fixup_a64_movw_sabs_g2: 153 Type = ELF::R_AARCH64_MOVW_SABS_G2; 154 break; 155 156 // TLS Local-dynamic block 157 case AArch64::fixup_a64_movw_dtprel_g2: 158 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2; 159 break; 160 case AArch64::fixup_a64_movw_dtprel_g1: 161 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1; 162 break; 163 case AArch64::fixup_a64_movw_dtprel_g1_nc: 164 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC; 165 break; 166 case AArch64::fixup_a64_movw_dtprel_g0: 167 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0; 168 break; 169 case AArch64::fixup_a64_movw_dtprel_g0_nc: 170 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC; 171 break; 172 case AArch64::fixup_a64_add_dtprel_hi12: 173 Type = ELF::R_AARCH64_TLSLD_ADD_DTPREL_HI12; 174 break; 175 case AArch64::fixup_a64_add_dtprel_lo12: 176 Type = ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12; 177 break; 178 case AArch64::fixup_a64_add_dtprel_lo12_nc: 179 Type = ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC; 180 break; 181 case AArch64::fixup_a64_ldst8_dtprel_lo12: 182 Type = ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12; 183 break; 184 case AArch64::fixup_a64_ldst8_dtprel_lo12_nc: 185 Type = ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC; 186 break; 187 case AArch64::fixup_a64_ldst16_dtprel_lo12: 188 Type = ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12; 189 break; 190 case AArch64::fixup_a64_ldst16_dtprel_lo12_nc: 191 Type = ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC; 192 break; 193 case AArch64::fixup_a64_ldst32_dtprel_lo12: 194 Type = ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12; 195 break; 196 case AArch64::fixup_a64_ldst32_dtprel_lo12_nc: 197 Type = ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC; 198 break; 199 case AArch64::fixup_a64_ldst64_dtprel_lo12: 200 Type = ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12; 201 break; 202 case AArch64::fixup_a64_ldst64_dtprel_lo12_nc: 203 Type = ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC; 204 break; 205 206 // TLS initial-exec block 207 case AArch64::fixup_a64_movw_gottprel_g1: 208 Type = ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1; 209 break; 210 case AArch64::fixup_a64_movw_gottprel_g0_nc: 211 Type = ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC; 212 break; 213 case AArch64::fixup_a64_ld64_gottprel_lo12_nc: 214 Type = ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC; 215 break; 216 217 // TLS local-exec block 218 case AArch64::fixup_a64_movw_tprel_g2: 219 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2; 220 break; 221 case AArch64::fixup_a64_movw_tprel_g1: 222 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1; 223 break; 224 case AArch64::fixup_a64_movw_tprel_g1_nc: 225 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC; 226 break; 227 case AArch64::fixup_a64_movw_tprel_g0: 228 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0; 229 break; 230 case AArch64::fixup_a64_movw_tprel_g0_nc: 231 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC; 232 break; 233 case AArch64::fixup_a64_add_tprel_hi12: 234 Type = ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12; 235 break; 236 case AArch64::fixup_a64_add_tprel_lo12: 237 Type = ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12; 238 break; 239 case AArch64::fixup_a64_add_tprel_lo12_nc: 240 Type = ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC; 241 break; 242 case AArch64::fixup_a64_ldst8_tprel_lo12: 243 Type = ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12; 244 break; 245 case AArch64::fixup_a64_ldst8_tprel_lo12_nc: 246 Type = ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC; 247 break; 248 case AArch64::fixup_a64_ldst16_tprel_lo12: 249 Type = ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12; 250 break; 251 case AArch64::fixup_a64_ldst16_tprel_lo12_nc: 252 Type = ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC; 253 break; 254 case AArch64::fixup_a64_ldst32_tprel_lo12: 255 Type = ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12; 256 break; 257 case AArch64::fixup_a64_ldst32_tprel_lo12_nc: 258 Type = ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC; 259 break; 260 case AArch64::fixup_a64_ldst64_tprel_lo12: 261 Type = ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12; 262 break; 263 case AArch64::fixup_a64_ldst64_tprel_lo12_nc: 264 Type = ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC; 265 break; 266 267 // TLS general-dynamic block 268 case AArch64::fixup_a64_tlsdesc_adr_page: 269 Type = ELF::R_AARCH64_TLSDESC_ADR_PAGE; 270 break; 271 case AArch64::fixup_a64_tlsdesc_ld64_lo12_nc: 272 Type = ELF::R_AARCH64_TLSDESC_LD64_LO12_NC; 273 break; 274 case AArch64::fixup_a64_tlsdesc_add_lo12_nc: 275 Type = ELF::R_AARCH64_TLSDESC_ADD_LO12_NC; 276 break; 277 case AArch64::fixup_a64_tlsdesc_call: 278 Type = ELF::R_AARCH64_TLSDESC_CALL; 279 break; 280 } 281 } 282 283 return Type; 284 } 285 286 MCObjectWriter *llvm::createAArch64ELFObjectWriter(raw_ostream &OS, 287 uint8_t OSABI, 288 bool IsLittleEndian) { 289 MCELFObjectTargetWriter *MOTW = new AArch64ELFObjectWriter(OSABI, IsLittleEndian); 290 return createELFObjectWriter(MOTW, OS, IsLittleEndian); 291 } 292