From b33d07cfa1fe69f57797b03712ff3a16c5bc59ea Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 17 May 2019 02:51:54 +0000 Subject: [PATCH] [ARM] Support .reloc *, R_ARM_NONE, * R_ARM_NONE can be used to create references among sections. When --gc-sections is used, the referenced section will be retained if the origin section is retained. Add a generic MCFixupKind FK_NONE as this kind of no-op relocation is ubiquitous on ELF and COFF, and probably available on many other binary formats. See D62014. Reviewed By: peter.smith Differential Revision: https://reviews.llvm.org/D61992 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360980 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCFixup.h | 3 +- lib/MC/MCAsmBackend.cpp | 1 + lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 18 ++++++++- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h | 2 + .../ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 2 + .../Mips/MCTargetDesc/MipsAsmBackend.cpp | 4 +- .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 2 +- lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h | 5 +-- test/MC/ARM/reloc-directive.s | 37 +++++++++++++++++++ 9 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 test/MC/ARM/reloc-directive.s diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index 559a19e9056..accffb7f224 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -20,7 +20,8 @@ class MCExpr; /// Extensible enumeration to represent the type of a fixup. enum MCFixupKind { - FK_Data_1 = 0, ///< A one-byte fixup. + FK_NONE = 0, ///< A no-op fixup. + FK_Data_1, ///< A one-byte fixup. FK_Data_2, ///< A two-byte fixup. FK_Data_4, ///< A four-byte fixup. FK_Data_8, ///< A eight-byte fixup. diff --git a/lib/MC/MCAsmBackend.cpp b/lib/MC/MCAsmBackend.cpp index ea794cc91fe..912bec91961 100644 --- a/lib/MC/MCAsmBackend.cpp +++ b/lib/MC/MCAsmBackend.cpp @@ -64,6 +64,7 @@ Optional MCAsmBackend::getFixupKind(StringRef Name) const { const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { static const MCFixupKindInfo Builtins[] = { + {"FK_NONE", 0, 0, 0}, {"FK_Data_1", 0, 8, 0}, {"FK_Data_2", 0, 16, 0}, {"FK_Data_4", 0, 32, 0}, diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index b846ca0699b..538bc2594c3 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -46,6 +46,13 @@ public: }; } // end anonymous namespace +Optional ARMAsmBackend::getFixupKind(StringRef Name) const { + if (STI.getTargetTriple().isOSBinFormatELF() && Name == "R_ARM_NONE") + return FK_NONE; + + return MCAsmBackend::getFixupKind(Name); +} + const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = { // This table *must* be in the order that the fixup_* kinds are defined in @@ -383,6 +390,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm, default: Ctx.reportError(Fixup.getLoc(), "bad relocation fixup type"); return 0; + case FK_NONE: case FK_Data_1: case FK_Data_2: case FK_Data_4: @@ -761,7 +769,9 @@ bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm, const MCSymbolRefExpr *A = Target.getSymA(); const MCSymbol *Sym = A ? &A->getSymbol() : nullptr; const unsigned FixupKind = Fixup.getKind() ; - if ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) { + if (FixupKind == FK_NONE) + return true; + if (FixupKind == ARM::fixup_arm_thumb_bl) { assert(Sym && "How did we resolve this?"); // If the symbol is external the linker will handle it. @@ -803,6 +813,9 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { default: llvm_unreachable("Unknown fixup kind!"); + case FK_NONE: + return 0; + case FK_Data_1: case ARM::fixup_arm_thumb_bcc: case ARM::fixup_arm_thumb_cp: @@ -857,6 +870,9 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) { default: llvm_unreachable("Unknown fixup kind!"); + case FK_NONE: + return 0; + case FK_Data_1: return 1; case FK_Data_2: diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h index 52abc2f20e0..67722a5e5b6 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -37,6 +37,8 @@ public: // different. bool hasNOP() const { return STI.getFeatureBits()[ARM::HasV6T2Ops]; } + Optional getFixupKind(StringRef Name) const override; + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index a93202b8202..1d51a9696cd 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -143,6 +143,8 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, default: Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol"); return ELF::R_ARM_NONE; + case FK_NONE: + return ELF::R_ARM_NONE; case FK_Data_1: switch (Modifier) { default: diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 65e2a902182..859f9cbbca0 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -302,7 +302,7 @@ void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, Optional MipsAsmBackend::getFixupKind(StringRef Name) const { return StringSwitch>(Name) - .Case("R_MIPS_NONE", (MCFixupKind)Mips::fixup_Mips_NONE) + .Case("R_MIPS_NONE", FK_NONE) .Case("R_MIPS_32", FK_Data_4) .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE) .Case("R_MIPS_CALL_HI16", (MCFixupKind)Mips::fixup_Mips_CALL_HI16) @@ -350,7 +350,6 @@ getFixupKindInfo(MCFixupKind Kind) const { // MipsFixupKinds.h. // // name offset bits flags - { "fixup_Mips_NONE", 0, 0, 0 }, { "fixup_Mips_16", 0, 16, 0 }, { "fixup_Mips_32", 0, 32, 0 }, { "fixup_Mips_REL32", 0, 32, 0 }, @@ -430,7 +429,6 @@ getFixupKindInfo(MCFixupKind Kind) const { // MipsFixupKinds.h. // // name offset bits flags - { "fixup_Mips_NONE", 0, 0, 0 }, { "fixup_Mips_16", 16, 16, 0 }, { "fixup_Mips_32", 0, 32, 0 }, { "fixup_Mips_REL32", 0, 32, 0 }, diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index c11e2ce85e8..cf7bae98a27 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -222,7 +222,7 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, unsigned Kind = (unsigned)Fixup.getKind(); switch (Kind) { - case Mips::fixup_Mips_NONE: + case FK_NONE: return ELF::R_MIPS_NONE; case FK_Data_1: Ctx.reportError(Fixup.getLoc(), diff --git a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index 939afefabe9..b83d822bd8d 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -22,11 +22,8 @@ namespace Mips { // in MipsAsmBackend.cpp. // enum Fixups { - // Branch fixups resulting in R_MIPS_NONE. - fixup_Mips_NONE = FirstTargetFixupKind, - // Branch fixups resulting in R_MIPS_16. - fixup_Mips_16, + fixup_Mips_16 = FirstTargetFixupKind, // Pure 32 bit data fixup resulting in - R_MIPS_32. fixup_Mips_32, diff --git a/test/MC/ARM/reloc-directive.s b/test/MC/ARM/reloc-directive.s new file mode 100644 index 00000000000..0855a7c2ad8 --- /dev/null +++ b/test/MC/ARM/reloc-directive.s @@ -0,0 +1,37 @@ +# RUN: llvm-mc -triple=armv7-linux-gnueabi %s | FileCheck --check-prefix=PRINT %s +# RUN: llvm-mc -triple=armv7eb-linux-gnueabi %s | FileCheck --check-prefix=PRINT %s + +# RUN: llvm-mc -filetype=obj -triple=armv7-linux-gnueabi %s -o %t +# RUN: llvm-readobj -r %t | FileCheck %s +# RUN: llvm-readelf -x .data %t | FileCheck --check-prefix=HEX %s + +# RUN: llvm-mc -filetype=obj -triple=armv7eb-linux-gnueabi %s -o %t +# RUN: llvm-readobj -r %t | FileCheck %s +# RUN: llvm-readelf -x .data %t | FileCheck --check-prefix=HEX %s + +.text + bx lr + nop + nop + .reloc 8, R_ARM_NONE, .data + .reloc 4, R_ARM_NONE, foo+4 + .reloc 0, R_ARM_NONE, 8 + +.data +.globl foo +foo: + .word 0 + .word 0 + .word 0 + +# PRINT: .reloc 8, R_ARM_NONE, .data +# PRINT: .reloc 4, R_ARM_NONE, foo+4 +# PRINT: .reloc 0, R_ARM_NONE, 8 + +# ARM relocations use the Elf32_Rel format. Addends are neither stored in the +# relocation entries nor applied in the referenced locations. +# CHECK: 0x8 R_ARM_NONE .data 0x0 +# CHECK-NEXT: 0x4 R_ARM_NONE foo 0x0 +# CHECK-NEXT: 0x0 R_ARM_NONE - 0x0 + +# HEX: 0x00000000 00000000 00000000 -- 2.40.0