summaryrefslogtreecommitdiff
path: root/app-arch/lld/files/patches-0/0011-More-correct-dynamic-plt.patch
diff options
context:
space:
mode:
Diffstat (limited to 'app-arch/lld/files/patches-0/0011-More-correct-dynamic-plt.patch')
-rw-r--r--app-arch/lld/files/patches-0/0011-More-correct-dynamic-plt.patch164
1 files changed, 164 insertions, 0 deletions
diff --git a/app-arch/lld/files/patches-0/0011-More-correct-dynamic-plt.patch b/app-arch/lld/files/patches-0/0011-More-correct-dynamic-plt.patch
new file mode 100644
index 00000000..7b8c29e8
--- /dev/null
+++ b/app-arch/lld/files/patches-0/0011-More-correct-dynamic-plt.patch
@@ -0,0 +1,164 @@
+From 1e9305ac78fa7ce232c8982b96bec845fead3390 Mon Sep 17 00:00:00 2001
+From: Michael Spencer <bigcheesegs@gmail.com>
+Date: Fri, 15 Feb 2013 15:21:28 -0800
+Subject: [PATCH 11/13] More correct dynamic plt.
+
+---
+ .../ELF/X86_64/X86_64TargetHandler.cpp | 2 +-
+ lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp | 69 ++++++++++++++++++++--
+ 2 files changed, 65 insertions(+), 6 deletions(-)
+
+diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
+index 69e7888..48da692 100644
+--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
++++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
+@@ -132,7 +132,7 @@ public:
+
+ virtual SectionChoice sectionChoice() const { return sectionCustomRequired; }
+
+- virtual StringRef customSectionName() const { return ".got"; }
++ virtual StringRef customSectionName() const { return ".got.plt"; }
+
+ virtual ContentType contentType() const { return typeGOT; }
+
+diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
+index cf2aa04..bf57449 100644
+--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
++++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
+@@ -90,8 +90,7 @@ public:
+ }
+
+ virtual Alignment alignment() const {
+- // The alignment should be 4 byte aligned
+- return Alignment(2);
++ return Alignment(4); // 16
+ }
+
+ #ifndef NDEBUG
+@@ -105,10 +104,31 @@ public:
+
+ const uint8_t PLTAtom::_defaultContent[16] = {
+ 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *gotatom(%rip)
+- 0x68, 0x00, 0x00, 0x00, 0x00, // pushq pltentry
++ 0x68, 0x00, 0x00, 0x00, 0x00, // pushq reloc-index
+ 0xe9, 0x00, 0x00, 0x00, 0x00 // jmpq plt[-1]
+ };
+
++class PLT0Atom : public PLTAtom {
++ static const uint8_t _plt0Content[16];
++
++public:
++ PLT0Atom(const File &f) : PLTAtom(f, ".plt") {
++#ifndef NDEBUG
++ _name = ".PLT0";
++#endif
++ }
++
++ virtual ArrayRef<uint8_t> rawContent() const {
++ return ArrayRef<uint8_t>(_plt0Content, 16);
++ }
++};
++
++const uint8_t PLT0Atom::_plt0Content[16] = {
++ 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip)
++ 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip)
++ 0x90, 0x90, 0x90, 0x90 // nopnopnop
++};
++
+ class ELFPassFile : public SimpleFile {
+ public:
+ ELFPassFile(const ELFTargetInfo &eti) : SimpleFile(eti, "ELFPassFile") {}
+@@ -197,7 +217,7 @@ protected:
+ /// \brief Create a GOT entry containing 0.
+ const GOTAtom *getNullGOT() {
+ if (!_null) {
+- _null = new (_file._alloc) GOTAtom(_file, ".got");
++ _null = new (_file._alloc) GOTAtom(_file, ".got.plt");
+ #ifndef NDEBUG
+ _null->_name = "__got_null";
+ #endif
+@@ -231,7 +251,9 @@ protected:
+ }
+
+ public:
+- GOTPLTPass(const ELFTargetInfo &ti) : _file(ti), _null(nullptr) {}
++ GOTPLTPass(const ELFTargetInfo &ti)
++ : _file(ti), _null(nullptr), _PLT0(nullptr), _got0(nullptr),
++ _got1(nullptr) {}
+
+ /// \brief Do the pass.
+ ///
+@@ -250,6 +272,11 @@ public:
+ // Add all created atoms to the link.
+ if (_null)
+ mf.addAtom(*_null);
++ if (_PLT0) {
++ mf.addAtom(*_PLT0);
++ mf.addAtom(*_got0);
++ mf.addAtom(*_got1);
++ }
+ for (const auto &got : _gotMap)
+ mf.addAtom(*got.second);
+ for (const auto &plt : _pltMap)
+@@ -259,12 +286,23 @@ public:
+ protected:
+ /// \brief Owner of all the Atoms created by this pass.
+ ELFPassFile _file;
++
+ /// \brief Map Atoms to their GOT entries.
+ llvm::DenseMap<const Atom *, const GOTAtom *> _gotMap;
++
+ /// \brief Map Atoms to their PLT entries.
+ llvm::DenseMap<const Atom *, const PLTAtom *> _pltMap;
++
+ /// \brief GOT entry that is always 0. Used for undefined weaks.
+ GOTAtom *_null;
++
++ /// \brief The got and plt entries for .PLT0. This is used to call into the
++ /// dynamic linker for symbol resolution.
++ /// @{
++ PLT0Atom *_PLT0;
++ GOTAtom *_got0;
++ GOTAtom *_got1;
++ /// @}
+ };
+
+ /// This implements the static relocation model. Meaning GOT and PLT entries are
+@@ -297,6 +335,23 @@ class DynamicGOTPLTPass LLVM_FINAL : public GOTPLTPass<DynamicGOTPLTPass> {
+ public:
+ DynamicGOTPLTPass(const elf::X86_64TargetInfo &ti) : GOTPLTPass(ti) {}
+
++ const PLT0Atom *getPLT0() {
++ if (_PLT0)
++ return _PLT0;
++ // Fill in the null entry.
++ getNullGOT();
++ _PLT0 = new (_file._alloc) PLT0Atom(_file);
++ _got0 = new (_file._alloc) GOTAtom(_file, ".got.plt");
++ _got1 = new (_file._alloc) GOTAtom(_file, ".got.plt");
++ _PLT0->addReference(R_X86_64_PC32, 2, _got0, -4);
++ _PLT0->addReference(R_X86_64_PC32, 8, _got1, -4);
++#ifndef NDEBUG
++ _got0->_name = "__got0";
++ _got1->_name = "__got1";
++#endif
++ return _PLT0;
++ }
++
+ const PLTAtom *getPLTEntry(const Atom *a) {
+ auto plt = _pltMap.find(a);
+ if (plt != _pltMap.end())
+@@ -305,6 +360,10 @@ public:
+ ga->addReference(R_X86_64_RELATIVE, 0, a, 0);
+ auto pa = new (_file._alloc) PLTAtom(_file, ".plt");
+ pa->addReference(R_X86_64_PC32, 2, ga, -4);
++ pa->addReference(R_X86_64_PC32, 12, getPLT0(), -4);
++ // Set the starting address of the got entry to the second instruction in
++ // the plt entry.
++ ga->addReference(R_X86_64_64, 0, pa, 6);
+ #ifndef NDEBUG
+ ga->_name = "__got_";
+ ga->_name += a->name();
+--
+1.8.1.2
+