diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp b/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp index 5f276f79357..134c85e822b 100644 --- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp +++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SystemZMCFixups.h" #include "MCTargetDesc/SystemZMCTargetDesc.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCFixupKindInfo.h" @@ -49,7 +50,10 @@ public: unsigned getNumFixupKinds() const override { return SystemZ::NumTargetFixupKinds; } + Optional getFixupKind(StringRef Name) const override; const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; + bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, + const MCValue &Target) override; void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef Data, uint64_t Value, bool IsResolved, @@ -67,6 +71,22 @@ public: }; } // end anonymous namespace +Optional SystemZMCAsmBackend::getFixupKind(StringRef Name) const { + unsigned Type = llvm::StringSwitch(Name) +#define ELF_RELOC(X, Y) .Case(#X, Y) +#include "llvm/BinaryFormat/ELFRelocs/SystemZ.def" +#undef ELF_RELOC + .Case("BFD_RELOC_NONE", ELF::R_390_NONE) + .Case("BFD_RELOC_8", ELF::R_390_8) + .Case("BFD_RELOC_16", ELF::R_390_16) + .Case("BFD_RELOC_32", ELF::R_390_32) + .Case("BFD_RELOC_64", ELF::R_390_64) + .Default(-1u); + if (Type != -1u) + return static_cast(FirstLiteralRelocationKind + Type); + return None; +} + const MCFixupKindInfo & SystemZMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[SystemZ::NumTargetFixupKinds] = { @@ -77,6 +97,11 @@ SystemZMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { { "FK_390_TLS_CALL", 0, 0, 0 } }; + // Fixup kinds from .reloc directive are like R_390_NONE. They + // do not require any extra processing. + if (Kind >= FirstLiteralRelocationKind) + return MCAsmBackend::getFixupKindInfo(FK_NONE); + if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); @@ -85,6 +110,12 @@ SystemZMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { return Infos[Kind - FirstTargetFixupKind]; } +bool SystemZMCAsmBackend::shouldForceRelocation(const MCAssembler &, + const MCFixup &Fixup, + const MCValue &) { + return Fixup.getKind() >= FirstLiteralRelocationKind; +} + void SystemZMCAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, @@ -92,6 +123,8 @@ void SystemZMCAsmBackend::applyFixup(const MCAssembler &Asm, bool IsResolved, const MCSubtargetInfo *STI) const { MCFixupKind Kind = Fixup.getKind(); + if (Kind >= FirstLiteralRelocationKind) + return; unsigned Offset = Fixup.getOffset(); unsigned BitSize = getFixupKindInfo(Kind).TargetSize; unsigned Size = (BitSize + 7) / 8; diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp b/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp index 49b6fc49033..0b3e7b15df1 100644 --- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp +++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp @@ -117,8 +117,10 @@ unsigned SystemZObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { - MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); unsigned Kind = Fixup.getKind(); + if (Kind >= FirstLiteralRelocationKind) + return Kind - FirstLiteralRelocationKind; + MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); switch (Modifier) { case MCSymbolRefExpr::VK_None: if (IsPCRel) diff --git a/test/MC/SystemZ/reloc-directive.s b/test/MC/SystemZ/reloc-directive.s new file mode 100644 index 00000000000..7a4b6daaa24 --- /dev/null +++ b/test/MC/SystemZ/reloc-directive.s @@ -0,0 +1,51 @@ +# RUN: llvm-mc -triple=s390x-linux-gnu %s | FileCheck --check-prefix=PRINT %s + +# RUN: llvm-mc -filetype=obj -triple=s390x-linux-gnu %s -o %t +# RUN: llvm-readobj -r %t | FileCheck %s + +# PRINT: .reloc 2, R_390_NONE, .data +# PRINT-NEXT: .reloc 1, R_390_NONE, foo+4 +# PRINT-NEXT: .reloc 0, R_390_NONE, 8 +# PRINT-NEXT: .reloc 0, R_390_64, .data+2 +# PRINT-NEXT: .reloc 0, R_390_GOTENT, foo+3 +# PRINT-NEXT: .reloc 0, R_390_PC32DBL, 6 +# PRINT: .reloc 0, BFD_RELOC_NONE, 9 +# PRINT-NEXT: .reloc 0, BFD_RELOC_8, 9 +# PRINT-NEXT: .reloc 0, BFD_RELOC_16, 9 +# PRINT-NEXT: .reloc 0, BFD_RELOC_32, 9 +# PRINT-NEXT: .reloc 0, BFD_RELOC_64, 9 + +# CHECK: 0x2 R_390_NONE .data 0x0 +# CHECK-NEXT: 0x1 R_390_NONE foo 0x4 +# CHECK-NEXT: 0x0 R_390_NONE - 0x8 +# CHECK-NEXT: 0x0 R_390_64 .data 0x2 +# CHECK-NEXT: 0x0 R_390_GOTENT foo 0x3 +# CHECK-NEXT: 0x0 R_390_PC32DBL - 0x6 +# CHECK-NEXT: 0x0 R_390_NONE - 0x9 +# CHECK-NEXT: 0x0 R_390_8 - 0x9 +# CHECK-NEXT: 0x0 R_390_16 - 0x9 +# CHECK-NEXT: 0x0 R_390_32 - 0x9 +# CHECK-NEXT: 0x0 R_390_64 - 0x9 + +.text + br %r14 + nop + nop + .reloc 2, R_390_NONE, .data + .reloc 1, R_390_NONE, foo+4 + .reloc 0, R_390_NONE, 8 + .reloc 0, R_390_64, .data+2 + .reloc 0, R_390_GOTENT, foo+3 + .reloc 0, R_390_PC32DBL, 6 + + .reloc 0, BFD_RELOC_NONE, 9 + .reloc 0, BFD_RELOC_8, 9 + .reloc 0, BFD_RELOC_16, 9 + .reloc 0, BFD_RELOC_32, 9 + .reloc 0, BFD_RELOC_64, 9 + +.data +.globl foo +foo: + .word 0 + .word 0