[lld] r248679 - [ELF2/AArch64] Support for R_AARCH64_ADR_PREL_LO21 relocation.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 27 01:45:40 PDT 2015


Author: davide
Date: Sun Sep 27 03:45:38 2015
New Revision: 248679

URL: http://llvm.org/viewvc/llvm-project?rev=248679&view=rev
Log:
[ELF2/AArch64] Support for R_AARCH64_ADR_PREL_LO21 relocation.

Added:
    lld/trunk/test/elf2/aarch64-relocs.s
Modified:
    lld/trunk/ELF/Target.cpp

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=248679&r1=248678&r2=248679&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Sun Sep 27 03:45:38 2015
@@ -220,8 +220,37 @@ void AArch64TargetInfo::writePltEntry(ui
                                       uint64_t PltEntryAddr) const {}
 bool AArch64TargetInfo::relocNeedsGot(uint32_t Type) const { return false; }
 bool AArch64TargetInfo::relocNeedsPlt(uint32_t Type) const { return false; }
+
+static void handle_ADR_PREL_LO21(uint8_t *Location, uint64_t S, int64_t A,
+                                 uint64_t P) {
+  uint64_t X = S + A - P;
+  if (!isInt<21>(X))
+    error("Relocation R_AARCH64_ADR_PREL_LO21 out of range");
+  uint32_t Imm = X & 0x1FFFFF;
+  uint32_t ImmLo = (Imm & 0x3) << 29;
+  uint32_t ImmHi = ((Imm & 0x1FFFFC) >> 2) << 5;
+  uint64_t Mask = (0x3 << 29) | (0x7FFFF << 5);
+  write32le(Location, (read32le(Location) & ~Mask) | ImmLo | ImmHi);
+}
+
 void AArch64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
                                     uint32_t Type, uint64_t BaseAddr,
-                                    uint64_t SymVA) const {}
+                                    uint64_t SymVA) const {
+  typedef ELFFile<ELF64LE>::Elf_Rela Elf_Rela;
+  auto &Rel = *reinterpret_cast<const Elf_Rela *>(RelP);
+
+  uint8_t *Location = Buf + Rel.r_offset;
+  uint64_t S = SymVA;
+  int64_t A = Rel.r_addend;
+  uint64_t P = BaseAddr + Rel.r_offset;
+  switch (Type) {
+  case R_AARCH64_ADR_PREL_LO21:
+    handle_ADR_PREL_LO21(Location, S, A, P);
+    break;
+  default:
+    error(Twine("unrecognized reloc ") + Twine(Type));
+    break;
+  }
+}
 }
 }

Added: lld/trunk/test/elf2/aarch64-relocs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/aarch64-relocs.s?rev=248679&view=auto
==============================================================================
--- lld/trunk/test/elf2/aarch64-relocs.s (added)
+++ lld/trunk/test/elf2/aarch64-relocs.s Sun Sep 27 03:45:38 2015
@@ -0,0 +1,14 @@
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t
+# RUN: lld -flavor gnu2 %t -o %t2
+# RUN: llvm-objdump -d %t2 | FileCheck %s
+# REQUIRES: arm64
+
+.globl _start
+_start:
+  adr x1,msg
+msg:  .asciz  "Hello, world\n"
+msgend:
+
+// R_AARCH64_ADR_PREL_LO21
+# CHECK: _start:
+# CHECK:   11000:       21 00 00 10     adr     x1, #4




More information about the llvm-commits mailing list