]> granicus.if.org Git - llvm/commitdiff
[AArch64] Support .reloc *, R_AARCH64_NONE, *
authorFangrui Song <maskray@google.com>
Fri, 17 May 2019 03:05:07 +0000 (03:05 +0000)
committerFangrui Song <maskray@google.com>
Fri, 17 May 2019 03:05:07 +0000 (03:05 +0000)
Summary:
This 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.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D61973

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360981 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
test/MC/AArch64/reloc-directive.s [new file with mode: 0644]

index b50659aec2d15145ef21f9fb61b3802f86bcb848..df94c3187eb853bdebf5cc79c77f7e3ca796b20a 100644 (file)
@@ -41,6 +41,8 @@ public:
     return AArch64::NumTargetFixupKinds;
   }
 
+  Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
+
   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
     const static MCFixupKindInfo Infos[AArch64::NumTargetFixupKinds] = {
         // This table *must* be in the order that the fixup_* kinds are defined
@@ -103,6 +105,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
   default:
     llvm_unreachable("Unknown fixup kind!");
 
+  case FK_NONE:
   case AArch64::fixup_aarch64_tlsdesc_call:
     return 0;
 
@@ -304,6 +307,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
     if (Value & 0x3)
       Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
     return (Value >> 2) & 0x3ffffff;
+  case FK_NONE:
   case FK_Data_1:
   case FK_Data_2:
   case FK_Data_4:
@@ -314,6 +318,12 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
   }
 }
 
+Optional<MCFixupKind> AArch64AsmBackend::getFixupKind(StringRef Name) const {
+  if (TheTriple.isOSBinFormatELF() && Name == "R_AARCH64_NONE")
+    return FK_NONE;
+  return MCAsmBackend::getFixupKind(Name);
+}
+
 /// getFixupKindContainereSizeInBytes - The number of bytes of the
 /// container involved in big endian or 0 if the item is little endian
 unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) const {
@@ -445,6 +455,10 @@ bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
 bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
                                               const MCFixup &Fixup,
                                               const MCValue &Target) {
+  unsigned Kind = Fixup.getKind();
+  if (Kind == FK_NONE)
+    return true;
+
   // The ADRP instruction adds some multiple of 0x1000 to the current PC &
   // ~0xfff. This means that the required offset to reach a symbol can vary by
   // up to one step depending on where the ADRP is in memory. For example:
@@ -457,14 +471,14 @@ bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
   // same page as the ADRP and the instruction should encode 0x0. Assuming the
   // section isn't 0x1000-aligned, we therefore need to delegate this decision
   // to the linker -- a relocation!
-  if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21)
+  if (Kind == AArch64::fixup_aarch64_pcrel_adrp_imm21)
     return true;
 
   AArch64MCExpr::VariantKind RefKind =
       static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
   AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
   // LDR GOT relocations need a relocation
-  if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_ldr_pcrel_imm19 &&
+  if (Kind == AArch64::fixup_aarch64_ldr_pcrel_imm19 &&
       SymLoc == AArch64MCExpr::VK_GOT)
     return true;
   return false;
index d7361809e6d37c8b601353e854478e9b0a16934b..c871e2c62eac8ab034795ddccb6836d4eb1cc74e 100644 (file)
@@ -185,6 +185,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
     if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx))
       return ELF::R_AARCH64_NONE;
     switch ((unsigned)Fixup.getKind()) {
+    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/test/MC/AArch64/reloc-directive.s b/test/MC/AArch64/reloc-directive.s
new file mode 100644 (file)
index 0000000..e10a90a
--- /dev/null
@@ -0,0 +1,25 @@
+# RUN: llvm-mc -triple=aarch64-linux-musl %s | FileCheck --check-prefix=PRINT %s
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-musl %s | llvm-readobj -r | FileCheck %s
+
+# PRINT: .reloc 8, R_AARCH64_NONE, .data
+# PRINT: .reloc 4, R_AARCH64_NONE, foo+4
+# PRINT: .reloc 0, R_AARCH64_NONE, 8
+.text
+  ret
+  nop
+  nop
+  .reloc 8, R_AARCH64_NONE, .data
+  .reloc 4, R_AARCH64_NONE, foo+4
+  .reloc 0, R_AARCH64_NONE, 8
+
+.data
+.globl foo
+foo:
+  .word 0
+  .word 0
+  .word 0
+
+# CHECK:      0x8 R_AARCH64_NONE .data 0x0
+# CHECK-NEXT: 0x4 R_AARCH64_NONE foo 0x4
+# CHECK-NEXT: 0x0 R_AARCH64_NONE - 0x8