diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -69,6 +69,11 @@ {"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal}, {"fixup_aarch64_tlsdesc_call", 0, 0, 0}}; + // Fixup kinds from .reloc directive are like R_AARCH64_NONE. They do not + // require any extra processing. + if (Kind >= FirstLiteralRelocationKind) + return MCAsmBackend::getFixupKindInfo(FK_NONE); + if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); @@ -109,7 +114,6 @@ default: llvm_unreachable("Unknown fixup kind!"); - case FK_NONE: case AArch64::fixup_aarch64_tlsdesc_call: return 0; @@ -330,7 +334,6 @@ if (!valueFitsIntoFixupKind(Fixup.getTargetKind(), Value)) Ctx.reportError(Fixup.getLoc(), "fixup value too large for data type!"); LLVM_FALLTHROUGH; - case FK_NONE: case FK_SecRel_2: case FK_SecRel_4: return Value; @@ -338,9 +341,17 @@ } Optional AArch64AsmBackend::getFixupKind(StringRef Name) const { - if (TheTriple.isOSBinFormatELF() && Name == "R_AARCH64_NONE") - return FK_NONE; - return MCAsmBackend::getFixupKind(Name); + if (!TheTriple.isOSBinFormatELF()) + return None; + + unsigned Type = llvm::StringSwitch(Name) +#define ELF_RELOC(X, Y) .Case(#X, Y) +#include "llvm/BinaryFormat/ELFRelocs/AArch64.def" +#undef ELF_RELOC + .Default(-1u); + if (Type == -1u) + return None; + return static_cast(FirstLiteralRelocationKind + Type); } /// getFixupKindContainereSizeInBytes - The number of bytes of the @@ -387,9 +398,12 @@ MutableArrayRef Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const { - unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); if (!Value) return; // Doesn't change encoding. + unsigned Kind = Fixup.getKind(); + if (Kind >= FirstLiteralRelocationKind) + return; + unsigned NumBytes = getFixupKindNumBytes(Kind); MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind()); MCContext &Ctx = Asm.getContext(); int64_t SignedValue = static_cast(Value); @@ -475,7 +489,7 @@ const MCFixup &Fixup, const MCValue &Target) { unsigned Kind = Fixup.getKind(); - if (Kind == FK_NONE) + if (Kind >= FirstLiteralRelocationKind) return true; // The ADRP instruction adds some multiple of 0x1000 to the current PC & diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -106,6 +106,9 @@ const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { + unsigned Kind = Fixup.getTargetKind(); + if (Kind >= FirstLiteralRelocationKind) + return Kind - FirstLiteralRelocationKind; AArch64MCExpr::VariantKind RefKind = static_cast(Target.getRefKind()); AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind); @@ -120,7 +123,7 @@ "Should only be expression-level modifiers here"); if (IsPCRel) { - switch (Fixup.getTargetKind()) { + switch (Kind) { case FK_Data_1: Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); return ELF::R_AARCH64_NONE; @@ -185,8 +188,6 @@ if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx)) return ELF::R_AARCH64_NONE; switch (Fixup.getTargetKind()) { - case FK_NONE: - return ELF::R_AARCH64_NONE; case FK_Data_1: Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); return ELF::R_AARCH64_NONE; diff --git a/llvm/test/MC/AArch64/reloc-directive-err.s b/llvm/test/MC/AArch64/reloc-directive-err.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/reloc-directive-err.s @@ -0,0 +1,6 @@ +# RUN: llvm-mc -triple=aarch64 %s 2>&1 | FileCheck --check-prefix=PRINT %s +# RUN: not llvm-mc -filetype=obj -triple=aarch64 %s -o /dev/null 2>&1 | FileCheck %s + +# PRINT: .reloc 0, R_INVALID, 0 +# CHECK: {{.*}}.s:[[# @LINE+1]]:11: error: unknown relocation name +.reloc 0, R_INVALID, 0 diff --git a/llvm/test/MC/AArch64/reloc-directive.s b/llvm/test/MC/AArch64/reloc-directive.s --- a/llvm/test/MC/AArch64/reloc-directive.s +++ b/llvm/test/MC/AArch64/reloc-directive.s @@ -5,6 +5,9 @@ # PRINT: .reloc 8, R_AARCH64_NONE, .data # PRINT: .reloc 4, R_AARCH64_NONE, foo+4 # PRINT: .reloc 0, R_AARCH64_NONE, 8 +# PRINT: .reloc 0, R_AARCH64_ABS64, .data+2 +# PRINT: .reloc 0, R_AARCH64_TLSDESC, foo+3 +# PRINT: .reloc 0, R_AARCH64_IRELATIVE, 5 .text ret nop @@ -13,6 +16,10 @@ .reloc 4, R_AARCH64_NONE, foo+4 .reloc 0, R_AARCH64_NONE, 8 + .reloc 0, R_AARCH64_ABS64, .data+2 + .reloc 0, R_AARCH64_TLSDESC, foo+3 + .reloc 0, R_AARCH64_IRELATIVE, 5 + .data .globl foo foo: @@ -23,3 +30,6 @@ # CHECK: 0x8 R_AARCH64_NONE .data 0x0 # CHECK-NEXT: 0x4 R_AARCH64_NONE foo 0x4 # CHECK-NEXT: 0x0 R_AARCH64_NONE - 0x8 +# CHECK-NEXT: 0x0 R_AARCH64_ABS64 .data 0x2 +# CHECK-NEXT: 0x0 R_AARCH64_TLSDESC foo 0x3 +# CHECK-NEXT: 0x0 R_AARCH64_IRELATIVE - 0x5