diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-06-04 19:11:14 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-06-04 19:11:14 +0000 |
| commit | 12dc4469394dac2e55a7ac6bb4105c9d0aa8e0fe (patch) | |
| tree | 06be3810e7534a41463a55e2e724dcbb2ddbf05b | |
| parent | 1fcdc23a6e7b1f7fad79f9c924958b9c16e6ee1f (diff) | |
| download | bcm5719-llvm-12dc4469394dac2e55a7ac6bb4105c9d0aa8e0fe.tar.gz bcm5719-llvm-12dc4469394dac2e55a7ac6bb4105c9d0aa8e0fe.zip | |
Fix implicit plt creation on aarch64.
We were not handling page relative relocations.
llvm-svn: 271798
| -rw-r--r-- | lld/ELF/InputSection.cpp | 1 | ||||
| -rw-r--r-- | lld/ELF/Relocations.cpp | 5 | ||||
| -rw-r--r-- | lld/ELF/Relocations.h | 1 | ||||
| -rw-r--r-- | lld/test/ELF/Inputs/aarch64-copy2.s | 5 | ||||
| -rw-r--r-- | lld/test/ELF/aarch64-copy2.s | 26 |
5 files changed, 37 insertions, 1 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index fe76388ae76..b6b09db506a 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -263,6 +263,7 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P, case R_PC: case R_RELAX_GOT_PC: return Body.getVA<ELFT>(A) - P; + case R_PLT_PAGE_PC: case R_PAGE_PC: return getAArch64Page(Body.getVA<ELFT>(A)) - getAArch64Page(P); } diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 48fb403b50e..d2f0272ed42 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -251,7 +251,8 @@ template <class ELFT> static bool isAbsolute(const SymbolBody &Body) { } static bool needsPlt(RelExpr Expr) { - return Expr == R_PLT_PC || Expr == R_PPC_PLT_OPD || Expr == R_PLT; + return Expr == R_PLT_PC || Expr == R_PPC_PLT_OPD || Expr == R_PLT || + Expr == R_PLT_PAGE_PC; } // True if this expression is of the form Sym - X, where X is a position in the @@ -311,6 +312,8 @@ static RelExpr toPlt(RelExpr Expr) { return R_PPC_PLT_OPD; if (Expr == R_PC) return R_PLT_PC; + if (Expr == R_PAGE_PC) + return R_PLT_PAGE_PC; if (Expr == R_ABS) return R_PLT; return Expr; diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h index 57f0318359d..1c24e617003 100644 --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -35,6 +35,7 @@ enum RelExpr { R_PC, R_PLT, R_PLT_PC, + R_PLT_PAGE_PC, R_PPC_OPD, R_PPC_PLT_OPD, R_PPC_TOC, diff --git a/lld/test/ELF/Inputs/aarch64-copy2.s b/lld/test/ELF/Inputs/aarch64-copy2.s new file mode 100644 index 00000000000..8f3f748366b --- /dev/null +++ b/lld/test/ELF/Inputs/aarch64-copy2.s @@ -0,0 +1,5 @@ + .global foo + .type foo, @function +foo: + .global bar +bar: diff --git a/lld/test/ELF/aarch64-copy2.s b/lld/test/ELF/aarch64-copy2.s new file mode 100644 index 00000000000..7b7adbb196f --- /dev/null +++ b/lld/test/ELF/aarch64-copy2.s @@ -0,0 +1,26 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux +// RUN: llvm-mc %p/Inputs/aarch64-copy2.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t +// RUN: llvm-readobj -t %t | FileCheck %s + + .global _start +_start: + adrp x8, foo + bl bar + +// CHECK: Name: bar +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined + +// CHECK: Name: foo +// CHECK-NEXT: Value: 0x11030 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Function +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined |

