diff options
Diffstat (limited to 'llvm/lib/Target')
5 files changed, 32 insertions, 4 deletions
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index a04754bdda3..2abe2a0fda5 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -518,7 +518,9 @@ public: ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC || ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC || - ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) { + ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 || + ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 || + ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) { // Note that we don't range-check the addend. It's adjusted modulo page // size when converted, so there is no "out of range" condition when using // @pageoff. @@ -607,7 +609,9 @@ public: || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC - || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12; + || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 + || ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 + || ELFRefKind == AArch64MCExpr::VK_SECREL_LO12; } // If it's a constant, it should be a real immediate in range: @@ -2854,6 +2858,8 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) { .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1) .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC) .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE) + .Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12) + .Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12) .Default(AArch64MCExpr::VK_INVALID); if (RefKind == AArch64MCExpr::VK_INVALID) @@ -3466,7 +3472,9 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC || - ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) && + ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 || + ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 || + ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) && (Inst.getOpcode() == AArch64::ADDXri || Inst.getOpcode() == AArch64::ADDWri)) return false; diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp index 33698d2b8c3..25deddd5976 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp @@ -276,7 +276,8 @@ AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx, if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) { AArch64MCExpr::VariantKind RefKind = A64E->getKind(); if (RefKind == AArch64MCExpr::VK_TPREL_HI12 || - RefKind == AArch64MCExpr::VK_DTPREL_HI12) + RefKind == AArch64MCExpr::VK_DTPREL_HI12 || + RefKind == AArch64MCExpr::VK_SECREL_HI12) ShiftVal = 12; } return ShiftVal == 0 ? 0 : (1 << ShiftVal); diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp index f606d272bcb..cd937935ddb 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp @@ -70,6 +70,8 @@ StringRef AArch64MCExpr::getVariantKindName() const { case VK_GOTTPREL_G0_NC: return ":gottprel_g0_nc:"; case VK_TLSDESC: return ""; case VK_TLSDESC_PAGE: return ":tlsdesc:"; + case VK_SECREL_LO12: return ":secrel_lo12:"; + case VK_SECREL_HI12: return ":secrel_hi12:"; default: llvm_unreachable("Invalid ELF symbol kind"); } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h index 3dbf0f84a66..b6bf254d383 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h @@ -35,6 +35,7 @@ public: VK_GOTTPREL = 0x005, VK_TPREL = 0x006, VK_TLSDESC = 0x007, + VK_SECREL = 0x008, VK_SymLocBits = 0x00f, // Variants specifying which part of the final address calculation is @@ -98,6 +99,8 @@ public: VK_TPREL_LO12_NC = VK_TPREL | VK_PAGEOFF | VK_NC, VK_TLSDESC_LO12 = VK_TLSDESC | VK_PAGEOFF, VK_TLSDESC_PAGE = VK_TLSDESC | VK_PAGE, + VK_SECREL_LO12 = VK_SECREL | VK_PAGEOFF, + VK_SECREL_HI12 = VK_SECREL | VK_HI12, VK_INVALID = 0xfff }; diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp index d06c5e8862a..0d9c0de7fbb 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp @@ -8,6 +8,7 @@ //===---------------------------------------------------------------------===// #include "MCTargetDesc/AArch64FixupKinds.h" +#include "MCTargetDesc/AArch64MCExpr.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/MC/MCAsmBackend.h" @@ -46,6 +47,7 @@ unsigned AArch64WinCOFFObjectWriter::getRelocType( bool IsCrossSection, const MCAsmBackend &MAB) const { auto Modifier = Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); + const MCExpr *Expr = Fixup.getValue(); switch (static_cast<unsigned>(Fixup.getKind())) { default: { @@ -73,6 +75,13 @@ unsigned AArch64WinCOFFObjectWriter::getRelocType( return COFF::IMAGE_REL_ARM64_SECREL; case AArch64::fixup_aarch64_add_imm12: + if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) { + AArch64MCExpr::VariantKind RefKind = A64E->getKind(); + if (RefKind == AArch64MCExpr::VK_SECREL_LO12) + return COFF::IMAGE_REL_ARM64_SECREL_LOW12A; + if (RefKind == AArch64MCExpr::VK_SECREL_HI12) + return COFF::IMAGE_REL_ARM64_SECREL_HIGH12A; + } return COFF::IMAGE_REL_ARM64_PAGEOFFSET_12A; case AArch64::fixup_aarch64_ldst_imm12_scale1: @@ -80,6 +89,11 @@ unsigned AArch64WinCOFFObjectWriter::getRelocType( case AArch64::fixup_aarch64_ldst_imm12_scale4: case AArch64::fixup_aarch64_ldst_imm12_scale8: case AArch64::fixup_aarch64_ldst_imm12_scale16: + if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) { + AArch64MCExpr::VariantKind RefKind = A64E->getKind(); + if (RefKind == AArch64MCExpr::VK_SECREL_LO12) + return COFF::IMAGE_REL_ARM64_SECREL_LOW12L; + } return COFF::IMAGE_REL_ARM64_PAGEOFFSET_12L; case AArch64::fixup_aarch64_pcrel_adrp_imm21: |

