summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2016-04-08 14:10:41 +0000
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2016-04-08 14:10:41 +0000
commit15cba9e7e543ae1593f2e62ed4166c446cabbeb7 (patch)
tree46926b683ee892f8d8e7f5359dea887056d06d20
parent954ba21f852534c24dc1caf023d957adc06eef20 (diff)
downloadbcm5719-llvm-15cba9e7e543ae1593f2e62ed4166c446cabbeb7.tar.gz
bcm5719-llvm-15cba9e7e543ae1593f2e62ed4166c446cabbeb7.zip
[lld] [ELF/AARCH64] Fix dynamic relocation from PIC GOT access
This patch fixes dynamic relocation creation from GOT access in dynamic objects on aarch64. Current code creates a plt relative one (R_AARCH64_JUMP_SLOT) instead of a got relative (R_AARCH64_GLOB_DAT). It leads the programs fails with: $ cat t.cc std::string test = "hello...\n"; int main () { printf ("%s\n", test.c_str()); return 0; } $ clang++ t.cc -fpic -o t $ ./t hello... Segmentation fault (core dumped) Due the fact it will try to access the plt instead of the got for __cxa_atexit registration for the std::string destruction. It will lead in a bogus function address in atexit. llvm-svn: 265784
-rw-r--r--lld/ELF/Target.cpp5
-rw-r--r--lld/test/ELF/aarch64-fpic-got.s18
2 files changed, 23 insertions, 0 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index b5f5dd18745..5c92fbc93a7 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -170,6 +170,7 @@ public:
bool isRelRelative(uint32_t Type) const override;
bool needsCopyRelImpl(uint32_t Type) const override;
bool needsGot(uint32_t Type, const SymbolBody &S) const override;
+ bool refersToGotEntry(uint32_t Type) const override;
bool needsPltImpl(uint32_t Type) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA) const override;
@@ -1381,6 +1382,10 @@ bool AArch64TargetInfo::needsGot(uint32_t Type, const SymbolBody &S) const {
}
}
+bool AArch64TargetInfo::refersToGotEntry(uint32_t Type) const {
+ return Type == R_AARCH64_ADR_GOT_PAGE || Type == R_AARCH64_LD64_GOT_LO12_NC;
+}
+
bool AArch64TargetInfo::needsPltImpl(uint32_t Type) const {
switch (Type) {
default:
diff --git a/lld/test/ELF/aarch64-fpic-got.s b/lld/test/ELF/aarch64-fpic-got.s
new file mode 100644
index 00000000000..70b2a7a76f8
--- /dev/null
+++ b/lld/test/ELF/aarch64-fpic-got.s
@@ -0,0 +1,18 @@
+# REQUIRES: aarch64
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %p/Inputs/shared.s -o %t-lib.o
+# RUN: ld.lld -shared %t-lib.o -o %t-lib.so
+# RUN: ld.lld %t-lib.so %t.o -o %t.exe
+# RUN: llvm-readobj -dyn-relocations %t.exe | FileCheck %s
+
+## Checks if got access to dynamic objects is done through a got relative
+## dynamic relocation and not using plt relative (R_AARCH64_JUMP_SLOT).
+# CHECK: Dynamic Relocations {
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_GLOB_DAT bar 0x0
+# CHECK-NEXT: }
+
+.globl _start
+_start:
+ adrp x0, :got:bar
+ ldr x0, [x0, :got_lo12:bar]
OpenPOWER on IntegriCloud