[PATCH] D54474: [LLD][AArch64] Fix resolution of R_PLT_PAGE RelExpr

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 13 07:20:35 PST 2018


peter.smith created this revision.
peter.smith added reviewers: ruiu, grimar.
Herald added subscribers: kristof.beyls, arichardson, javed.absar, emaste.
Herald added a reviewer: espindola.

The R_AARCH64_ADR_PREL_PG_HI21 relocation type is given the R_PAGE_PC RelExpr. This can be transformed to R_PLT_PAGE_PC via toPlt(). Unfortunately the resolution is identical to R_PAGE_PC so instead of getting the address of the PLT entry we get the address of the symbol which may not be correct in the case of static ifuncs (See comments in https://reviews.llvm.org/D54314 and example in https://reviews.llvm.org/D54145). The fix is simple. Just use getPltVA() + A rather than getVA() to get the address of the PLT entry.

It looks like the only way that R_PLT_PAGE_PC will be generated from compiled code is via the address of an ifunc in the same executable with non-pic code. I thought that it might be possible to generate an example by taking the address of a function in a DSO but this does not go through the toPlt() route, it uses processRelocAux()  // This handles a non PIC program call to function in a shared library.

The patch is rebased on top of https://reviews.llvm.org/D54314 and https://reviews.llvm.org/D54145, it is most likely independent of it, but makes sense to be committed afterwards.


https://reviews.llvm.org/D54474

Files:
  ELF/InputSection.cpp
  test/ELF/aarch64-gnu-ifunc3.s


Index: test/ELF/aarch64-gnu-ifunc3.s
===================================================================
--- /dev/null
+++ test/ELF/aarch64-gnu-ifunc3.s
@@ -0,0 +1,45 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
+# RUN: ld.lld -static %t.o -o %tout
+# RUN: llvm-objdump -D %tout | FileCheck %s
+# RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=RELOC
+.text
+.globl myfunc
+.type myfunc, at gnu_indirect_function
+myfunc:
+ ret
+
+.text
+.globl _start
+.type _start, at function
+_start:
+ adrp x8, myfunc
+ add  x8, x8, :lo12:myfunc
+ ret
+
+# CHECK: Disassembly of section .text:
+# CHECK-NEXT: myfunc:
+# CHECK-NEXT:   210000:	c0 03 5f d6 	ret
+# CHECK: _start:
+# adrp x8, 0x210000 + 0x10 from add == .plt entry
+# CHECK-NEXT:   210004:	08 00 00 90 	adrp	x8, #0
+# CHECK-NEXT:   210008:	08 41 00 91 	add	x8, x8, #16
+# CHECK-NEXT:   21000c:	c0 03 5f d6 	ret
+# CHECK-NEXT: Disassembly of section .plt:
+# CHECK-NEXT: .plt:
+# adrp x16, 0x220000, 0x220000 == address in .got.plt
+# CHECK-NEXT:   210010:	90 00 00 90 	adrp	x16, #65536
+# CHECK-NEXT:   210014:	11 02 40 f9 	ldr	x17, [x16]
+# CHECK-NEXT:   210018:	10 02 00 91 	add	x16, x16, #0
+# CHECK-NEXT:   21001c:	20 02 1f d6 	br	x17
+# CHECK-NEXT: Disassembly of section .got.plt:
+# CHECK-NEXT: .got.plt:
+# 0x210010 == address in .plt
+# CHECK-NEXT:   220000:	10 00 21 00
+# CHECK-NEXT:   220004:	00 00 00 00
+
+# RELOC: Relocations [
+# RELOC-NEXT:  Section (1) .rela.plt {
+# RELOC-NEXT:    0x220000 R_AARCH64_IRELATIVE - 0x210000
+# RELOC-NEXT:  }
+# RELOC-NEXT: ]
Index: ELF/InputSection.cpp
===================================================================
--- ELF/InputSection.cpp
+++ ELF/InputSection.cpp
@@ -676,6 +676,8 @@
     uint64_t Dest;
     if (Sym.isUndefWeak())
       Dest = getAArch64Page(A);
+    else if (Expr == R_PLT_PAGE_PC)
+      Dest = getAArch64Page(Sym.getPltVA() + A);
     else
       Dest = getAArch64Page(Sym.getVA(A));
     return Dest - getAArch64Page(P);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54474.173847.patch
Type: text/x-patch
Size: 2007 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181113/6aea2d32/attachment.bin>


More information about the llvm-commits mailing list