[ELF][AArch64] Fix adrp to undefined weak reference.

In the ABI for the 64-bit Arm architecture the section on weak references
states:
During linking, the symbol value of an undefined weak reference is:
- Zero if the relocation type is absolute
- The address of the place if the relocation type is pc-relative.

The relocations associated with an ADRP are relative so we should resolve
the undefined weak reference to the place instead of 0. This matches GNU
ld.bfd behaviour.

fixes pr34928

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



git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@349024 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index 5f3df54..30a9fc2 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -671,11 +671,11 @@
     return In.MipsGot->getVA() + In.MipsGot->getTlsIndexOffset(File) -
            In.MipsGot->getGp(File);
   case R_AARCH64_PAGE_PC: {
-    uint64_t Val = Sym.isUndefWeak() ? A : Sym.getVA(A);
+    uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getVA(A);
     return getAArch64Page(Val) - getAArch64Page(P);
   }
   case R_AARCH64_PLT_PAGE_PC: {
-    uint64_t Val = Sym.isUndefWeak() ? A : Sym.getPltVA() + A;
+    uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getPltVA() + A;
     return getAArch64Page(Val) - getAArch64Page(P);
   }
   case R_RISCV_PC_INDIRECT: {
diff --git a/test/ELF/aarch64-undefined-weak.s b/test/ELF/aarch64-undefined-weak.s
index 893f99a..ef14bfc 100644
--- a/test/ELF/aarch64-undefined-weak.s
+++ b/test/ELF/aarch64-undefined-weak.s
@@ -40,7 +40,7 @@
 // CHECK-NEXT:    210008: {{.*}} b.eq    #4
 // CHECK-NEXT:    21000c: {{.*}} cbz     x1, #4
 // CHECK-NEXT:    210010: {{.*}} adr     x0, #0
-// CHECK-NEXT:    210014: {{.*}} adrp    x0, #-2162688
+// CHECK-NEXT:    210014: {{.*}} adrp    x0, #0
 // CHECK:         210018: {{.*}} .word   0x00000000
 // CHECK-NEXT:    21001c: {{.*}} .word   0x00000000
 // CHECK-NEXT:    210020: {{.*}} .word   0x00000000