[lld] r249195 - [ELF2/AArch64] Add support for R_AARCH64_ADR_PREL_PG_H121

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 15:00:42 PDT 2015


Author: davide
Date: Fri Oct  2 17:00:42 2015
New Revision: 249195

URL: http://llvm.org/viewvc/llvm-project?rev=249195&view=rev
Log:
[ELF2/AArch64] Add support for R_AARCH64_ADR_PREL_PG_H121

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

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=249195&r1=249194&r2=249195&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Oct  2 17:00:42 2015
@@ -253,16 +253,31 @@ bool AArch64TargetInfo::relocNeedsPlt(ui
   return false;
 }
 
+static void AArch64UpdateAdr(uint8_t *Location, uint64_t Imm) {
+  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);
+}
+
+static uint64_t AArch64GetPage(uint64_t Address) {
+  return (Address & (~static_cast<uint64_t>(0xFFF)));
+}
+
 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);
+  AArch64UpdateAdr(Location, X & 0x1FFFFF);
+}
+
+static void handle_ADR_PREL_PG_HI21(uint8_t *Location, uint64_t S, int64_t A,
+                                    uint64_t P) {
+  uint64_t X = AArch64GetPage(S + A) - AArch64GetPage(P);
+  if (!isInt<33>(X))
+    error("Relocation R_AARCH64_ADR_PREL_PG_HI21 out of range");
+  AArch64UpdateAdr(Location, (X >> 12) & 0x1FFFFF); // X[32:12]
 }
 
 void AArch64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
@@ -279,6 +294,9 @@ void AArch64TargetInfo::relocateOne(uint
   case R_AARCH64_ADR_PREL_LO21:
     handle_ADR_PREL_LO21(Location, S, A, P);
     break;
+  case R_AARCH64_ADR_PREL_PG_HI21:
+    handle_ADR_PREL_PG_HI21(Location, S, A, P);
+    break;
   default:
     error(Twine("unrecognized reloc ") + Twine(Type));
     break;

Modified: lld/trunk/test/elf2/aarch64-relocs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/aarch64-relocs.s?rev=249195&r1=249194&r2=249195&view=diff
==============================================================================
--- lld/trunk/test/elf2/aarch64-relocs.s (original)
+++ lld/trunk/test/elf2/aarch64-relocs.s Fri Oct  2 17:00:42 2015
@@ -16,3 +16,17 @@ msgend:
 # CHECK: msg:
 # CHECK:        4:
 # #4 is the adr immediate value.
+
+.section .R_AARCH64_ADR_PREL_PG_H121,"ax", at progbits
+  adrp x1,mystr
+mystr:
+  .asciz "blah"
+  .size mystr, 4
+
+# S = 0x11012, A = 0x4, P = 0x11012
+# PAGE(S + A) = 0x11000
+# PAGE(P) = 0x11000
+#
+# CHECK: Disassembly of section .R_AARCH64_ADR_PREL_PG_H121:
+# CHECK-NEXT: $x.2:
+# CHECK-NEXT:   11012:       01 00 00 90     adrp    x1, #0




More information about the llvm-commits mailing list