diff options
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.patch | 164 |
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 + |
