summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-05-09 18:12:15 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-05-09 18:12:15 +0000
commit4ee6cb3a70a32ba0a13d77c551530ef9258432ea (patch)
treea12b620adf916ad151828c7e93add51d772bdccb
parente34ead826904969a0ddab4a1cc9db599671feba7 (diff)
downloadbcm5719-llvm-4ee6cb3a70a32ba0a13d77c551530ef9258432ea.tar.gz
bcm5719-llvm-4ee6cb3a70a32ba0a13d77c551530ef9258432ea.zip
Document and test the first few .got.plt entries.
llvm-svn: 268945
-rw-r--r--lld/ELF/Target.cpp4
-rw-r--r--lld/ELF/Target.h4
-rw-r--r--lld/test/ELF/got-plt-header.s30
3 files changed, 38 insertions, 0 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index ccb33132c69..f69731ac81d 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -531,6 +531,10 @@ RelExpr X86_64TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
}
void X86_64TargetInfo::writeGotPltHeader(uint8_t *Buf) const {
+ // The first entry holds the value of _DYNAMIC. It is not clear why that is
+ // required, but it is documented in the psabi and the glibc dynamic linker
+ // seems to use it (not that this is relevant for linking ld.so, not any
+ // other program).
write64le(Buf, Out<ELF64LE>::Dynamic->getVA());
}
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 2923539773f..9a2a5e753ed 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -78,7 +78,11 @@ public:
uint32_t TlsOffsetRel;
unsigned PltEntrySize = 8;
unsigned PltZeroSize = 0;
+
+ // At least on x86_64 positions 1 and 2 are used by the first plt entry
+ // to support lazy loading.
unsigned GotPltHeaderEntriesNum = 3;
+
uint32_t ThunkSize = 0;
bool UseLazyBinding = false;
diff --git a/lld/test/ELF/got-plt-header.s b/lld/test/ELF/got-plt-header.s
new file mode 100644
index 00000000000..691516d1a34
--- /dev/null
+++ b/lld/test/ELF/got-plt-header.s
@@ -0,0 +1,30 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
+
+ call foo@plt
+
+// Check that the first .got.plt entry has the address of the dynamic table.
+
+// CHECK: Type: SHT_DYNAMIC
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x2000
+
+// CHECK: Name: .got.plt
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x3000
+// CHECK-NEXT: Offset: 0x3000
+// CHECK-NEXT: Size: 32
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 8
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 00200000 00000000 00000000 00000000
OpenPOWER on IntegriCloud