1 //===-- AArch64AsmBackend.cpp - AArch64 Assembler Backend -----------------===// 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 #include "AArch64.h" 11 #include "AArch64RegisterInfo.h" 12 #include "MCTargetDesc/AArch64FixupKinds.h" 13 #include "llvm/ADT/Triple.h" 14 #include "llvm/MC/MCAsmBackend.h" 15 #include "llvm/MC/MCDirectives.h" 16 #include "llvm/MC/MCELFObjectWriter.h" 17 #include "llvm/MC/MCFixupKindInfo.h" 18 #include "llvm/MC/MCObjectWriter.h" 19 #include "llvm/MC/MCSectionELF.h" 20 #include "llvm/MC/MCSectionMachO.h" 21 #include "llvm/MC/MCValue.h" 22 #include "llvm/Support/ErrorHandling.h" 23 #include "llvm/Support/MachO.h" 24 using namespace llvm; 25 26 namespace { 27 28 class AArch64AsmBackend : public MCAsmBackend { 29 static const unsigned PCRelFlagVal = 30 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits | MCFixupKindInfo::FKF_IsPCRel; 31 public: 32 bool IsLittleEndian; 33 34 public: 35 AArch64AsmBackend(const Target &T, bool IsLittleEndian) 36 : MCAsmBackend(), IsLittleEndian(IsLittleEndian) {} 37 38 unsigned getNumFixupKinds() const override { 39 return AArch64::NumTargetFixupKinds; 40 } 41 42 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { 43 const static MCFixupKindInfo Infos[AArch64::NumTargetFixupKinds] = { 44 // This table *must* be in the order that the fixup_* kinds are defined in 45 // AArch64FixupKinds.h. 46 // 47 // Name Offset (bits) Size (bits) Flags 48 { "fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal }, 49 { "fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal }, 50 { "fixup_aarch64_add_imm12", 10, 12, 0 }, 51 { "fixup_aarch64_ldst_imm12_scale1", 10, 12, 0 }, 52 { "fixup_aarch64_ldst_imm12_scale2", 10, 12, 0 }, 53 { "fixup_aarch64_ldst_imm12_scale4", 10, 12, 0 }, 54 { "fixup_aarch64_ldst_imm12_scale8", 10, 12, 0 }, 55 { "fixup_aarch64_ldst_imm12_scale16", 10, 12, 0 }, 56 { "fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal }, 57 { "fixup_aarch64_movw", 5, 16, 0 }, 58 { "fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal }, 59 { "fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal }, 60 { "fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal }, 61 { "fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal }, 62 { "fixup_aarch64_tlsdesc_call", 0, 0, 0 } 63 }; 64 65 if (Kind < FirstTargetFixupKind) 66 return MCAsmBackend::getFixupKindInfo(Kind); 67 68 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 69 "Invalid kind!"); 70 return Infos[Kind - FirstTargetFixupKind]; 71 } 72 73 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 74 uint64_t Value, bool IsPCRel) const override; 75 76 bool mayNeedRelaxation(const MCInst &Inst) const override; 77 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, 78 const MCRelaxableFragment *DF, 79 const MCAsmLayout &Layout) const override; 80 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override; 81 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; 82 83 void HandleAssemblerFlag(MCAssemblerFlag Flag) {} 84 85 unsigned getPointerSize() const { return 8; } 86 87 unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const; 88 }; 89 90 } // end anonymous namespace 91 92 /// \brief The number of bytes the fixup may change. 93 static unsigned getFixupKindNumBytes(unsigned Kind) { 94 switch (Kind) { 95 default: 96 llvm_unreachable("Unknown fixup kind!"); 97 98 case AArch64::fixup_aarch64_tlsdesc_call: 99 return 0; 100 101 case FK_Data_1: 102 return 1; 103 104 case FK_Data_2: 105 case AArch64::fixup_aarch64_movw: 106 return 2; 107 108 case AArch64::fixup_aarch64_pcrel_branch14: 109 case AArch64::fixup_aarch64_add_imm12: 110 case AArch64::fixup_aarch64_ldst_imm12_scale1: 111 case AArch64::fixup_aarch64_ldst_imm12_scale2: 112 case AArch64::fixup_aarch64_ldst_imm12_scale4: 113 case AArch64::fixup_aarch64_ldst_imm12_scale8: 114 case AArch64::fixup_aarch64_ldst_imm12_scale16: 115 case AArch64::fixup_aarch64_ldr_pcrel_imm19: 116 case AArch64::fixup_aarch64_pcrel_branch19: 117 return 3; 118 119 case AArch64::fixup_aarch64_pcrel_adr_imm21: 120 case AArch64::fixup_aarch64_pcrel_adrp_imm21: 121 case AArch64::fixup_aarch64_pcrel_branch26: 122 case AArch64::fixup_aarch64_pcrel_call26: 123 case FK_Data_4: 124 return 4; 125 126 case FK_Data_8: 127 return 8; 128 } 129 } 130 131 static unsigned AdrImmBits(unsigned Value) { 132 unsigned lo2 = Value & 0x3; 133 unsigned hi19 = (Value & 0x1ffffc) >> 2; 134 return (hi19 << 5) | (lo2 << 29); 135 } 136 137 static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) { 138 int64_t SignedValue = static_cast<int64_t>(Value); 139 switch (Kind) { 140 default: 141 llvm_unreachable("Unknown fixup kind!"); 142 case AArch64::fixup_aarch64_pcrel_adr_imm21: 143 if (SignedValue > 2097151 || SignedValue < -2097152) 144 report_fatal_error("fixup value out of range"); 145 return AdrImmBits(Value & 0x1fffffULL); 146 case AArch64::fixup_aarch64_pcrel_adrp_imm21: 147 return AdrImmBits((Value & 0x1fffff000ULL) >> 12); 148 case AArch64::fixup_aarch64_ldr_pcrel_imm19: 149 case AArch64::fixup_aarch64_pcrel_branch19: 150 // Signed 21-bit immediate 151 if (SignedValue > 2097151 || SignedValue < -2097152) 152 report_fatal_error("fixup value out of range"); 153 // Low two bits are not encoded. 154 return (Value >> 2) & 0x7ffff; 155 case AArch64::fixup_aarch64_add_imm12: 156 case AArch64::fixup_aarch64_ldst_imm12_scale1: 157 // Unsigned 12-bit immediate 158 if (Value >= 0x1000) 159 report_fatal_error("invalid imm12 fixup value"); 160 return Value; 161 case AArch64::fixup_aarch64_ldst_imm12_scale2: 162 // Unsigned 12-bit immediate which gets multiplied by 2 163 if (Value & 1 || Value >= 0x2000) 164 report_fatal_error("invalid imm12 fixup value"); 165 return Value >> 1; 166 case AArch64::fixup_aarch64_ldst_imm12_scale4: 167 // Unsigned 12-bit immediate which gets multiplied by 4 168 if (Value & 3 || Value >= 0x4000) 169 report_fatal_error("invalid imm12 fixup value"); 170 return Value >> 2; 171 case AArch64::fixup_aarch64_ldst_imm12_scale8: 172 // Unsigned 12-bit immediate which gets multiplied by 8 173 if (Value & 7 || Value >= 0x8000) 174 report_fatal_error("invalid imm12 fixup value"); 175 return Value >> 3; 176 case AArch64::fixup_aarch64_ldst_imm12_scale16: 177 // Unsigned 12-bit immediate which gets multiplied by 16 178 if (Value & 15 || Value >= 0x10000) 179 report_fatal_error("invalid imm12 fixup value"); 180 return Value >> 4; 181 case AArch64::fixup_aarch64_movw: 182 report_fatal_error("no resolvable MOVZ/MOVK fixups supported yet"); 183 return Value; 184 case AArch64::fixup_aarch64_pcrel_branch14: 185 // Signed 16-bit immediate 186 if (SignedValue > 32767 || SignedValue < -32768) 187 report_fatal_error("fixup value out of range"); 188 // Low two bits are not encoded (4-byte alignment assumed). 189 if (Value & 0x3) 190 report_fatal_error("fixup not sufficiently aligned"); 191 return (Value >> 2) & 0x3fff; 192 case AArch64::fixup_aarch64_pcrel_branch26: 193 case AArch64::fixup_aarch64_pcrel_call26: 194 // Signed 28-bit immediate 195 if (SignedValue > 134217727 || SignedValue < -134217728) 196 report_fatal_error("fixup value out of range"); 197 // Low two bits are not encoded (4-byte alignment assumed). 198 if (Value & 0x3) 199 report_fatal_error("fixup not sufficiently aligned"); 200 return (Value >> 2) & 0x3ffffff; 201 case FK_Data_1: 202 case FK_Data_2: 203 case FK_Data_4: 204 case FK_Data_8: 205 return Value; 206 } 207 } 208 209 /// getFixupKindContainereSizeInBytes - The number of bytes of the 210 /// container involved in big endian or 0 if the item is little endian 211 unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) const { 212 if (IsLittleEndian) 213 return 0; 214 215 switch (Kind) { 216 default: 217 llvm_unreachable("Unknown fixup kind!"); 218 219 case FK_Data_1: 220 return 1; 221 case FK_Data_2: 222 return 2; 223 case FK_Data_4: 224 return 4; 225 case FK_Data_8: 226 return 8; 227 228 case AArch64::fixup_aarch64_tlsdesc_call: 229 case AArch64::fixup_aarch64_movw: 230 case AArch64::fixup_aarch64_pcrel_branch14: 231 case AArch64::fixup_aarch64_add_imm12: 232 case AArch64::fixup_aarch64_ldst_imm12_scale1: 233 case AArch64::fixup_aarch64_ldst_imm12_scale2: 234 case AArch64::fixup_aarch64_ldst_imm12_scale4: 235 case AArch64::fixup_aarch64_ldst_imm12_scale8: 236 case AArch64::fixup_aarch64_ldst_imm12_scale16: 237 case AArch64::fixup_aarch64_ldr_pcrel_imm19: 238 case AArch64::fixup_aarch64_pcrel_branch19: 239 case AArch64::fixup_aarch64_pcrel_adr_imm21: 240 case AArch64::fixup_aarch64_pcrel_adrp_imm21: 241 case AArch64::fixup_aarch64_pcrel_branch26: 242 case AArch64::fixup_aarch64_pcrel_call26: 243 // Instructions are always little endian 244 return 0; 245 } 246 } 247 248 void AArch64AsmBackend::applyFixup(const MCFixup &Fixup, char *Data, 249 unsigned DataSize, uint64_t Value, 250 bool IsPCRel) const { 251 unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); 252 if (!Value) 253 return; // Doesn't change encoding. 254 MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind()); 255 // Apply any target-specific value adjustments. 256 Value = adjustFixupValue(Fixup.getKind(), Value); 257 258 // Shift the value into position. 259 Value <<= Info.TargetOffset; 260 261 unsigned Offset = Fixup.getOffset(); 262 assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!"); 263 264 // Used to point to big endian bytes. 265 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(Fixup.getKind()); 266 267 // For each byte of the fragment that the fixup touches, mask in the 268 // bits from the fixup value. 269 if (FulleSizeInBytes == 0) { 270 // Handle as little-endian 271 for (unsigned i = 0; i != NumBytes; ++i) { 272 Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff); 273 } 274 } else { 275 // Handle as big-endian 276 assert((Offset + FulleSizeInBytes) <= DataSize && "Invalid fixup size!"); 277 assert(NumBytes <= FulleSizeInBytes && "Invalid fixup size!"); 278 for (unsigned i = 0; i != NumBytes; ++i) { 279 unsigned Idx = FulleSizeInBytes - 1 - i; 280 Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff); 281 } 282 } 283 } 284 285 bool AArch64AsmBackend::mayNeedRelaxation(const MCInst &Inst) const { 286 return false; 287 } 288 289 bool AArch64AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, 290 uint64_t Value, 291 const MCRelaxableFragment *DF, 292 const MCAsmLayout &Layout) const { 293 // FIXME: This isn't correct for AArch64. Just moving the "generic" logic 294 // into the targets for now. 295 // 296 // Relax if the value is too big for a (signed) i8. 297 return int64_t(Value) != int64_t(int8_t(Value)); 298 } 299 300 void AArch64AsmBackend::relaxInstruction(const MCInst &Inst, 301 MCInst &Res) const { 302 llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented"); 303 } 304 305 bool AArch64AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { 306 // If the count is not 4-byte aligned, we must be writing data into the text 307 // section (otherwise we have unaligned instructions, and thus have far 308 // bigger problems), so just write zeros instead. 309 OW->WriteZeros(Count % 4); 310 311 // We are properly aligned, so write NOPs as requested. 312 Count /= 4; 313 for (uint64_t i = 0; i != Count; ++i) 314 OW->write32(0xd503201f); 315 return true; 316 } 317 318 namespace { 319 320 namespace CU { 321 322 /// \brief Compact unwind encoding values. 323 enum CompactUnwindEncodings { 324 /// \brief A "frameless" leaf function, where no non-volatile registers are 325 /// saved. The return remains in LR throughout the function. 326 UNWIND_AArch64_MODE_FRAMELESS = 0x02000000, 327 328 /// \brief No compact unwind encoding available. Instead the low 23-bits of 329 /// the compact unwind encoding is the offset of the DWARF FDE in the 330 /// __eh_frame section. This mode is never used in object files. It is only 331 /// generated by the linker in final linked images, which have only DWARF info 332 /// for a function. 333 UNWIND_AArch64_MODE_DWARF = 0x03000000, 334 335 /// \brief This is a standard arm64 prologue where FP/LR are immediately 336 /// pushed on the stack, then SP is copied to FP. If there are any 337 /// non-volatile register saved, they are copied into the stack fame in pairs 338 /// in a contiguous ranger right below the saved FP/LR pair. Any subset of the 339 /// five X pairs and four D pairs can be saved, but the memory layout must be 340 /// in register number order. 341 UNWIND_AArch64_MODE_FRAME = 0x04000000, 342 343 /// \brief Frame register pair encodings. 344 UNWIND_AArch64_FRAME_X19_X20_PAIR = 0x00000001, 345 UNWIND_AArch64_FRAME_X21_X22_PAIR = 0x00000002, 346 UNWIND_AArch64_FRAME_X23_X24_PAIR = 0x00000004, 347 UNWIND_AArch64_FRAME_X25_X26_PAIR = 0x00000008, 348 UNWIND_AArch64_FRAME_X27_X28_PAIR = 0x00000010, 349 UNWIND_AArch64_FRAME_D8_D9_PAIR = 0x00000100, 350 UNWIND_AArch64_FRAME_D10_D11_PAIR = 0x00000200, 351 UNWIND_AArch64_FRAME_D12_D13_PAIR = 0x00000400, 352 UNWIND_AArch64_FRAME_D14_D15_PAIR = 0x00000800 353 }; 354 355 } // end CU namespace 356 357 // FIXME: This should be in a separate file. 358 class DarwinAArch64AsmBackend : public AArch64AsmBackend { 359 const MCRegisterInfo &MRI; 360 361 /// \brief Encode compact unwind stack adjustment for frameless functions. 362 /// See UNWIND_AArch64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h. 363 /// The stack size always needs to be 16 byte aligned. 364 uint32_t encodeStackAdjustment(uint32_t StackSize) const { 365 return (StackSize / 16) << 12; 366 } 367 368 public: 369 DarwinAArch64AsmBackend(const Target &T, const MCRegisterInfo &MRI) 370 : AArch64AsmBackend(T, /*IsLittleEndian*/true), MRI(MRI) {} 371 372 MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { 373 return createAArch64MachObjectWriter(OS, MachO::CPU_TYPE_ARM64, 374 MachO::CPU_SUBTYPE_ARM64_ALL); 375 } 376 377 /// \brief Generate the compact unwind encoding from the CFI directives. 378 uint32_t generateCompactUnwindEncoding( 379 ArrayRef<MCCFIInstruction> Instrs) const override { 380 if (Instrs.empty()) 381 return CU::UNWIND_AArch64_MODE_FRAMELESS; 382 383 bool HasFP = false; 384 unsigned StackSize = 0; 385 386 uint32_t CompactUnwindEncoding = 0; 387 for (size_t i = 0, e = Instrs.size(); i != e; ++i) { 388 const MCCFIInstruction &Inst = Instrs[i]; 389 390 switch (Inst.getOperation()) { 391 default: 392 // Cannot handle this directive: bail out. 393 return CU::UNWIND_AArch64_MODE_DWARF; 394 case MCCFIInstruction::OpDefCfa: { 395 // Defines a frame pointer. 396 assert(getXRegFromWReg(MRI.getLLVMRegNum(Inst.getRegister(), true)) == 397 AArch64::FP && 398 "Invalid frame pointer!"); 399 assert(i + 2 < e && "Insufficient CFI instructions to define a frame!"); 400 401 const MCCFIInstruction &LRPush = Instrs[++i]; 402 assert(LRPush.getOperation() == MCCFIInstruction::OpOffset && 403 "Link register not pushed!"); 404 const MCCFIInstruction &FPPush = Instrs[++i]; 405 assert(FPPush.getOperation() == MCCFIInstruction::OpOffset && 406 "Frame pointer not pushed!"); 407 408 unsigned LRReg = MRI.getLLVMRegNum(LRPush.getRegister(), true); 409 unsigned FPReg = MRI.getLLVMRegNum(FPPush.getRegister(), true); 410 411 LRReg = getXRegFromWReg(LRReg); 412 FPReg = getXRegFromWReg(FPReg); 413 414 assert(LRReg == AArch64::LR && FPReg == AArch64::FP && 415 "Pushing invalid registers for frame!"); 416 417 // Indicate that the function has a frame. 418 CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAME; 419 HasFP = true; 420 break; 421 } 422 case MCCFIInstruction::OpDefCfaOffset: { 423 assert(StackSize == 0 && "We already have the CFA offset!"); 424 StackSize = std::abs(Inst.getOffset()); 425 break; 426 } 427 case MCCFIInstruction::OpOffset: { 428 // Registers are saved in pairs. We expect there to be two consecutive 429 // `.cfi_offset' instructions with the appropriate registers specified. 430 unsigned Reg1 = MRI.getLLVMRegNum(Inst.getRegister(), true); 431 if (i + 1 == e) 432 return CU::UNWIND_AArch64_MODE_DWARF; 433 434 const MCCFIInstruction &Inst2 = Instrs[++i]; 435 if (Inst2.getOperation() != MCCFIInstruction::OpOffset) 436 return CU::UNWIND_AArch64_MODE_DWARF; 437 unsigned Reg2 = MRI.getLLVMRegNum(Inst2.getRegister(), true); 438 439 // N.B. The encodings must be in register number order, and the X 440 // registers before the D registers. 441 442 // X19/X20 pair = 0x00000001, 443 // X21/X22 pair = 0x00000002, 444 // X23/X24 pair = 0x00000004, 445 // X25/X26 pair = 0x00000008, 446 // X27/X28 pair = 0x00000010 447 Reg1 = getXRegFromWReg(Reg1); 448 Reg2 = getXRegFromWReg(Reg2); 449 450 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 && 451 (CompactUnwindEncoding & 0xF1E) == 0) 452 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X19_X20_PAIR; 453 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 && 454 (CompactUnwindEncoding & 0xF1C) == 0) 455 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X21_X22_PAIR; 456 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 && 457 (CompactUnwindEncoding & 0xF18) == 0) 458 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X23_X24_PAIR; 459 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 && 460 (CompactUnwindEncoding & 0xF10) == 0) 461 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X25_X26_PAIR; 462 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 && 463 (CompactUnwindEncoding & 0xF00) == 0) 464 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X27_X28_PAIR; 465 else { 466 Reg1 = getDRegFromBReg(Reg1); 467 Reg2 = getDRegFromBReg(Reg2); 468 469 // D8/D9 pair = 0x00000100, 470 // D10/D11 pair = 0x00000200, 471 // D12/D13 pair = 0x00000400, 472 // D14/D15 pair = 0x00000800 473 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 && 474 (CompactUnwindEncoding & 0xE00) == 0) 475 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D8_D9_PAIR; 476 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 && 477 (CompactUnwindEncoding & 0xC00) == 0) 478 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D10_D11_PAIR; 479 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 && 480 (CompactUnwindEncoding & 0x800) == 0) 481 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D12_D13_PAIR; 482 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15) 483 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D14_D15_PAIR; 484 else 485 // A pair was pushed which we cannot handle. 486 return CU::UNWIND_AArch64_MODE_DWARF; 487 } 488 489 break; 490 } 491 } 492 } 493 494 if (!HasFP) { 495 // With compact unwind info we can only represent stack adjustments of up 496 // to 65520 bytes. 497 if (StackSize > 65520) 498 return CU::UNWIND_AArch64_MODE_DWARF; 499 500 CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAMELESS; 501 CompactUnwindEncoding |= encodeStackAdjustment(StackSize); 502 } 503 504 return CompactUnwindEncoding; 505 } 506 }; 507 508 } // end anonymous namespace 509 510 namespace { 511 512 class ELFAArch64AsmBackend : public AArch64AsmBackend { 513 public: 514 uint8_t OSABI; 515 516 ELFAArch64AsmBackend(const Target &T, uint8_t OSABI, bool IsLittleEndian) 517 : AArch64AsmBackend(T, IsLittleEndian), OSABI(OSABI) {} 518 519 MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { 520 return createAArch64ELFObjectWriter(OS, OSABI, IsLittleEndian); 521 } 522 523 void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, 524 const MCFixup &Fixup, const MCFragment *DF, 525 const MCValue &Target, uint64_t &Value, 526 bool &IsResolved) override; 527 }; 528 529 void ELFAArch64AsmBackend::processFixupValue( 530 const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, 531 const MCFragment *DF, const MCValue &Target, uint64_t &Value, 532 bool &IsResolved) { 533 // The ADRP instruction adds some multiple of 0x1000 to the current PC & 534 // ~0xfff. This means that the required offset to reach a symbol can vary by 535 // up to one step depending on where the ADRP is in memory. For example: 536 // 537 // ADRP x0, there 538 // there: 539 // 540 // If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and 541 // we'll need that as an offset. At any other address "there" will be in the 542 // same page as the ADRP and the instruction should encode 0x0. Assuming the 543 // section isn't 0x1000-aligned, we therefore need to delegate this decision 544 // to the linker -- a relocation! 545 if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21) 546 IsResolved = false; 547 } 548 549 } 550 551 MCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T, 552 const MCRegisterInfo &MRI, 553 const Triple &TheTriple, 554 StringRef CPU) { 555 if (TheTriple.isOSBinFormatMachO()) 556 return new DarwinAArch64AsmBackend(T, MRI); 557 558 assert(TheTriple.isOSBinFormatELF() && "Expect either MachO or ELF target"); 559 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 560 return new ELFAArch64AsmBackend(T, OSABI, /*IsLittleEndian=*/true); 561 } 562 563 MCAsmBackend *llvm::createAArch64beAsmBackend(const Target &T, 564 const MCRegisterInfo &MRI, 565 const Triple &TheTriple, 566 StringRef CPU) { 567 assert(TheTriple.isOSBinFormatELF() && 568 "Big endian is only supported for ELF targets!"); 569 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 570 return new ELFAArch64AsmBackend(T, OSABI, 571 /*IsLittleEndian=*/false); 572 } 573