diff options
16 files changed, 2233 insertions, 0 deletions
diff --git a/app-arch/lld/Manifest b/app-arch/lld/Manifest new file mode 100644 index 00000000..f06920a8 --- /dev/null +++ b/app-arch/lld/Manifest @@ -0,0 +1,15 @@ +AUX patches-0/0001-Kinda-sorta-write-out-dynamic-stuff.patch 15032 SHA256 52d8fa8fde218b7e61e603eb2efdad8286726ec86967fd6551b98093432406c6 SHA512 1af0e398e1a3547d9f4da23f034c3daef5cde2da5f375207c019276e2e93c900246cb01a9592fe8ee12087602159f0685d9cdb8cb34aabba91422b479d4b0644 WHIRLPOOL 16d0a98516577cfb72900ed6729cab486b3a82a54229f30fbf85809f3d6243ddfc7c23ebbc00b52084aa4d6dc726d887d550f3ef9b0596e09daaec8a919b9e4d +AUX patches-0/0002-SharedLibraryAtom-symbolness.patch 904 SHA256 0e0c418ae7597d919495f08318c10ed7636898d09c33069b099965ffeb43a54e SHA512 8ea19e538730bf4bf3847f280dcc0ded0c93d13521cfb3640d12a1897032057676dca3719b4311d567f1ffa8e9a7e588bd7d41b7d682c39f47e0cb49e4a18a4a WHIRLPOOL f4b69aa9e1e8cf36036c8e9dbdc5b96ad2a7633043e49966824c4e1e1f01a076ee194baa52af570d0072fa12dce3cec200b9077489d3ddbe5354ac3fc4ed3ad3 +AUX patches-0/0003-Driver-GNULD-Default-to-dynamic.patch 1101 SHA256 4a149d71da314cb3a0ac6006d5e78bbb728f288247ede63ea1adc3fc56fa9333 SHA512 1b5ba5ee47254c77811c21600ae113e575c4d556c01b53ad4154b127b76fa6591783ad0014d1d6ce6b5879868ce018699ef720368e4bd318233c0abe84004b53 WHIRLPOOL 7f720fc8c8a65bb8b8ab25d75aee166e96c0f43ae86380e6b3750110b6f1de142babf7efb830fa94a8043bb7622fa5c09d33ecf92743868204e56037678acee5 +AUX patches-0/0004-ELF-Writer-Valid-dynamic-symbol-table.patch 10649 SHA256 b6b1dd61bec68aeae6ccb70907e46d092c4f2365266bdc23dac89679d8a08b12 SHA512 97342bba9e80fcc804834f033702d396d659c3929888f35f27574ce675f1b575c778e1f8f65847141e3b17271aa48002f023050cb4d75248c4fdbdfabd525a65 WHIRLPOOL cc4a63bce52660145e2f3ac3de2e15832ad53e54d7fa66fe65a39d4d087d0d887e688bcf8810cb3c81fac09890a7bf74e604dc003b3ea809926a53b68347e74b +AUX patches-0/0005-ELF-Writer-Add-dynamic-table-entries-and-interp-sect.patch 7754 SHA256 c62e8a7513dfa3c484c89d33fb3dcc8a67c2367eacdda291b4fc9c32f7cc9d28 SHA512 92afd2f74e05fe5ea5962351c74a7ab394eb77b6d10193b7c446090010a66885f54310c01fe54fed74966bc9add54fd3291251fe3c430deb6c7cd47dd0125cbc WHIRLPOOL 284bcff72448311071ebe0a44ab0df4c53df4619ccee1719ae3c502f190bd587741266e26e7fde5e0e123452732f135121d064ba59ee200f3cedf6410e6f24ce +AUX patches-0/0006-ELF-Writer-Fix-interp-phdr.patch 1489 SHA256 9bec2d7d5b8875731a132a92a88e555ee6945f4edac18ac37a4d75ae0a1360cb SHA512 a800530ac966320e7311b63dcb8b8277eeeef799b3c41bd54c1100bcb1078f01e8332ba4d3f396fb975308798af1a2bd8c4ad81eadcd4c8e67a1404b8b3fa374 WHIRLPOOL 1d5928d448829cb37a39c5f528fca8c4e0424a2d74ed7297108a3b6f33c4f46d7d4a03fcb14c1635f6ca503b944eeffe14d6dd096f75bc9b2ba796e644e77b69 +AUX patches-0/0007-PHDR.patch 1816 SHA256 0ff638ca24d43ac91e5f219aa1ac314e221398ec67c85376eb4dca3748a630b5 SHA512 9771a7a2131c3dd25cdf5d6964f409754673ee837ff89266fbf4c26685a87f89ca4c3cd5ae94dbdf9733fe700864132372a98fac52930c1e4e71bdecd2b330fe WHIRLPOOL 38ebf8a083c0cb1898d1799f50ff45f5cb49d693065dadea99b7ce1bdf2a2ee2c9b030f4b6743d662f4c6b4f1508bc6a1c18a56785886b5add0cf58351deab6d +AUX patches-0/0008-Correct-alignment.patch 901 SHA256 4cb67196a1e6f0922a84485a2a2f798edef4982cd02920ebbe59a4af6f2c6102 SHA512 d19bce07273fa053361efdd7b4b9b208df76548fdcfc7e0dfd211920827859737b44457ec0e228814c4768d8350774b40a9165fd72ca95c8eeedda510213acc7 WHIRLPOOL 4148ead2d604ea876942dd0d30ace952375298b6c9106c0d254d2d4cecf909a53b79cd0a1cd5b38a0776cd890bb135418570844fb2e670f326971f97203934a9 +AUX patches-0/0009-Make-ldd-happy.patch 4063 SHA256 9187e854a1a2d0a1eff174afad889622e4bcf8dc2b1e9ae6623e27df66565c75 SHA512 ab6876397bf7c92a4e913ea2f275c4ced78bba2b8a6718947eb988fdc57a3c5c61758646f2eeeb74f380186556dc1d16615e0cccb0cf3c9c4b91a45ae05fc90a WHIRLPOOL 03ea7aa0877a45154e44027a05ae95101b6ed91f00a1f14724e1478f003d4746879aae42c34144de7bfec1101ae89cd2b6249ea5445222b1d9556f4ae110e957 +AUX patches-0/0010-Yay-symbol-table-indicies.patch 10571 SHA256 a48776990a41d7eaa18c593f129f073042425633ff7ba3d0bd8e6d8c3758fa58 SHA512 5aa7119a6b9785a9844efaf1f760d0ed625f448c7c0d14981493be1f0d35ac46ef40f8624387848ac1e60cc857b0f99cfaf636016c3255a2645e8c1a9843e607 WHIRLPOOL fb36b6afb6fa64945663abf430573dd78dd49938e319a20cd1a94e9a0a160cd993775f01ce0eeacb65dc60ee0f579b7c87fdec08efe660b70194dabc06c5ba92 +AUX patches-0/0011-More-correct-dynamic-plt.patch 5332 SHA256 31830c7d74d006db528e6b139494ab7da53e40adc9424e132f3b5501e9c8c9d7 SHA512 e1b875af06d4afc4a28882d0cf3f72106d80599f63f60c364c1390fdc5620c8a6948251afafecd0963c16817415f739bec8cb503780389ad488391ad37a769e3 WHIRLPOOL 3baee844e50a9975f725f74ef110e1871faa6b0abd862d04ad5720b9a52009e88ddc142e454db0849934d71160e70feba6f970ca9d7606c5e5c00f66b2746d27 +AUX patches-0/0012-ELF-Writer-Dynamic-function-binding-works.patch 14746 SHA256 3b5a813200200945f10e7ec94ed9a06b8f736eb62f88331addb9ab2f0a4e7a38 SHA512 9e4028c9adfafa66d4ee179b17cc96181fef5c0ced4e90465bcc8270c7bf1f495c6aab577cd6737f694e7fa02d948b36721f54745c1f52c42ba9fca05219e71c WHIRLPOOL 99cce1ec14ad034fd77e6e6c837abbb13833edf4dd69fff4ddab584235857112962830571ac3e8509598fedf6f2d07f6222836356be7d350ed415a84e847fb14 +AUX patches-0/0013-ELF-Writer-Handle-non-pie-object-files-when-dynamic-.patch 4278 SHA256 66efb572b636f0813169f57c6d3e9b4a7457991703b9cc3a91a71e0e42eabdd8 SHA512 8fed9b8bca503ba478297383e32bb7e183310c6af2ce9fae4099ae849db556d4f2ad54d650387096d36a8f80599f3e6a425e7155ba5b7cc90aa73e06cd293e20 WHIRLPOOL 54130c539d6c664542878d870d5a87d2f322ce008109338e7f172b6577cda5c44e31a78f2932a5fd30277ac3b6bfc788fb4111478684ca41ed7305c9422aba3f +EBUILD lld-9999.ebuild 1698 SHA256 f8bd3c095e39b352a0de48ae21d9a47378882aff1f642d0f24021cf0c6695e75 SHA512 e00f42e8bb015a7d36821243fdaa6bd4b2421d1488c5cf28a8f7b420db67092b560207015c8f5f023becfcea86d2b0b27e2b937d0279e9cdca0c7562a74abf8f WHIRLPOOL 8f92b509a697b5aab100e263e5e1d44fc48fbb11bbc7f2f906f3d35849290bee109e650518a211dd804845b6047ff019aa8d20af3c0545982514c56a3c100b63 +MISC metadata.xml 251 SHA256 71226737033a1091dcc8c1dcfcce629c3dcdcd96a7ca109753e419ed0089b782 SHA512 31994542b20237c0cf5e07475018b7d3d2e820da86d36b51b30332b660421a0bcd7b3583854770c1380fd474edf8047ada5d7835a6261aad4bb1dcf1724d5607 WHIRLPOOL cf9f47c00107cf68f601d67c47f4a734f45c85c71d959cdaca5e2cf9ee26a97943837dd0ba15d0ef9a16ea94300ef62ae4daf66599455ed6aae8b61ef4ac9feb diff --git a/app-arch/lld/files/patches-0/0001-Kinda-sorta-write-out-dynamic-stuff.patch b/app-arch/lld/files/patches-0/0001-Kinda-sorta-write-out-dynamic-stuff.patch new file mode 100644 index 00000000..59a054ff --- /dev/null +++ b/app-arch/lld/files/patches-0/0001-Kinda-sorta-write-out-dynamic-stuff.patch @@ -0,0 +1,404 @@ +From 6bf2e68c2789a4b4121da3888d20771edceb6280 Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Mon, 11 Feb 2013 19:07:32 -0800 +Subject: [PATCH 01/13] Kinda sorta write out dynamic stuff. + +--- + include/lld/Core/STDExtras.h | 28 ++++++ + include/lld/ReaderWriter/ELFTargetInfo.h | 6 ++ + lib/ReaderWriter/ELF/DefaultLayout.h | 14 +-- + lib/ReaderWriter/ELF/SectionChunks.h | 43 +++++++- + lib/ReaderWriter/ELF/Writer.cpp | 110 ++++++++++++--------- + .../ELF/X86_64/X86_64TargetHandler.cpp | 1 + + lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h | 8 +- + 7 files changed, 154 insertions(+), 56 deletions(-) + create mode 100644 include/lld/Core/STDExtras.h + +diff --git a/include/lld/Core/STDExtras.h b/include/lld/Core/STDExtras.h +new file mode 100644 +index 0000000..6c82342 +--- /dev/null ++++ b/include/lld/Core/STDExtras.h +@@ -0,0 +1,28 @@ ++//===- lld/Core/STDExtra.h - Helpers for the stdlib -----------------------===// ++// ++// The LLVM Linker ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef LLD_CORE_STD_EXTRA_H ++#define LLD_CORE_STD_EXTRA_H ++ ++namespace lld { ++/// \brief Deleter for smart pointers that only calls the destructor. Memory is ++/// managed elsewhere. A common use of this is for things allocated with a ++/// BumpPtrAllocator. ++template <class T> ++struct destruct_delete { ++ void operator ()(T *ptr) { ++ ptr->~T(); ++ } ++}; ++ ++template <class T> ++using unique_bump_ptr = std::unique_ptr<T, destruct_delete<T>>; ++} // end namespace lld ++ ++#endif +diff --git a/include/lld/ReaderWriter/ELFTargetInfo.h b/include/lld/ReaderWriter/ELFTargetInfo.h +index f68387f..b1753b2 100644 +--- a/include/lld/ReaderWriter/ELFTargetInfo.h ++++ b/include/lld/ReaderWriter/ELFTargetInfo.h +@@ -49,6 +49,12 @@ public: + return false; + } + ++ /// \brief Does the output have dynamic sections. ++ bool isDynamic() const { ++ return _options._outputKind == OutputKind::DynamicExecutable || ++ _options._outputKind == OutputKind::Shared; ++ } ++ + virtual ErrorOr<Reader &> getReader(const LinkerInput &input) const; + + virtual ErrorOr<Writer &> getWriter() const; +diff --git a/lib/ReaderWriter/ELF/DefaultLayout.h b/lib/ReaderWriter/ELF/DefaultLayout.h +index 8990b62..34ce44f 100644 +--- a/lib/ReaderWriter/ELF/DefaultLayout.h ++++ b/lib/ReaderWriter/ELF/DefaultLayout.h +@@ -17,6 +17,7 @@ + #include "SegmentChunks.h" + + #include "lld/Core/LinkerOptions.h" ++#include "lld/Core/STDExtras.h" + + #include "llvm/ADT/ArrayRef.h" + #include "llvm/ADT/DenseMap.h" +@@ -26,6 +27,7 @@ + #include "llvm/ADT/StringExtras.h" + #include "llvm/ADT/StringMap.h" + #include "llvm/ADT/StringRef.h" ++#include "llvm/ADT/StringSet.h" + #include "llvm/ADT/StringSwitch.h" + + #include <map> +@@ -240,11 +242,11 @@ public: + RelocationTable<ELFT> *getRelocationTable() { + // Only create the relocation table if it is needed. + if (!_relocationTable) { +- _relocationTable = new (_allocator) +- RelocationTable<ELFT>(_targetInfo, ".rela.plt", ORDER_REL); +- addSection(_relocationTable); ++ _relocationTable.reset(new (_allocator) ++ RelocationTable<ELFT>(_targetInfo, ".rela.plt", ORDER_REL)); ++ addSection(_relocationTable.get()); + } +- return _relocationTable; ++ return _relocationTable.get(); + } + + uint64_t getTLSSize() const { +@@ -262,6 +264,7 @@ protected: + SectionOrder sectionOrder); + + private: ++ llvm::BumpPtrAllocator _allocator; + SectionMapT _sectionMap; + MergedSectionMapT _mergedSectionMap; + SegmentMapT _segmentMap; +@@ -270,9 +273,8 @@ private: + std::vector<MergedSections<ELFT> *> _mergedSections; + Header<ELFT> *_header; + ProgramHeader<ELFT> *_programHeader; +- RelocationTable<ELFT> *_relocationTable; ++ unique_bump_ptr<RelocationTable<ELFT>> _relocationTable; + std::vector<AtomLayout *> _absoluteAtoms; +- llvm::BumpPtrAllocator _allocator; + const ELFTargetInfo &_targetInfo; + }; + +diff --git a/lib/ReaderWriter/ELF/SectionChunks.h b/lib/ReaderWriter/ELF/SectionChunks.h +index 18d191b..a809875 100644 +--- a/lib/ReaderWriter/ELF/SectionChunks.h ++++ b/lib/ReaderWriter/ELF/SectionChunks.h +@@ -546,7 +546,7 @@ class SymbolTable : public Section<ELFT> { + public: + typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym; + +- SymbolTable(const ELFTargetInfo &ti, const char *str, int32_t order); ++ SymbolTable(const ELFTargetInfo &ti, const char *str, int32_t order, bool dynamic = false); + + void addSymbol(const Atom *atom, int32_t sectionIndex, uint64_t addr = 0); + +@@ -565,7 +565,7 @@ private: + /// ELF Symbol Table + template <class ELFT> + SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str, +- int32_t order) ++ int32_t order, bool dynamic) + : Section<ELFT>(ti, str) { + this->setOrder(order); + Elf_Sym *symbol = new (_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym; +@@ -716,6 +716,45 @@ public: + private: + std::vector<std::pair<const DefinedAtom &, const Reference &>> _relocs; + }; ++ ++template <class ELFT> class DynamicTable : public Section<ELFT> { ++ typedef llvm::object::Elf_Dyn_Impl<ELFT> Elf_Dyn; ++ typedef std::vector<Elf_Dyn> EntriesT; ++ ++public: ++ DynamicTable(const ELFTargetInfo &ti, StringRef str, int32_t order) ++ : Section<ELFT>(ti, str, llvm::ELF::SHT_DYNAMIC, DefinedAtom::permR__, ++ order, Section<ELFT>::K_Default) { ++ this->setOrder(order); ++ this->_entSize = sizeof(Elf_Dyn); ++ this->_align2 = llvm::alignOf<Elf_Dyn>(); ++ // Reserve space for the DT_NULL entry. ++ this->_fsize = sizeof(Elf_Dyn); ++ this->_msize = sizeof(Elf_Dyn); ++ } ++ ++ range<typename EntriesT::iterator> entries() { return _entries; } ++ ++ void addEntry(Elf_Dyn e) { ++ _entries.insert(e); ++ this->_fsize = (_entries.size() * sizeof(Elf_Dyn)) + sizeof(Elf_Dyn); ++ this->_msize = this->_fsize; ++ } ++ ++ void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) { ++ uint8_t *chunkBuffer = buffer.getBufferStart(); ++ uint8_t *dest = chunkBuffer + this->fileOffset(); ++ // Add the null entry. ++ Elf_Dyn d; ++ d.d_tag = 0; ++ d.d_un.d_val = 0; ++ _entries.push_back(d); ++ std::memcpy(dest, _entries.data(), this->_fsize); ++ } ++ ++private: ++ EntriesT _entries; ++}; + } // end namespace elf + } // end namespace lld + +diff --git a/lib/ReaderWriter/ELF/Writer.cpp b/lib/ReaderWriter/ELF/Writer.cpp +index 269607e..69c1d9b 100644 +--- a/lib/ReaderWriter/ELF/Writer.cpp ++++ b/lib/ReaderWriter/ELF/Writer.cpp +@@ -38,10 +38,10 @@ private: + void buildChunks(const File &file); + virtual error_code writeFile(const File &File, StringRef path); + void buildAtomToAddressMap(); +- void buildSymbolTable (); ++ void buildStaticSymbolTable(const File &file); ++ void buildDynamicSymbolTable(const File &file); + void buildSectionHeaderTable(); + void assignSectionsWithNoSegments(); +- void addAbsoluteUndefinedSymbols(const File &File); + void addDefaultAtoms(); + void addFiles(InputFiles&); + void finalizeDefaultAtomValues(); +@@ -52,19 +52,26 @@ private: + + void createDefaultSections(); + ++ llvm::BumpPtrAllocator _alloc; ++ + const ELFTargetInfo &_targetInfo; + TargetHandler<ELFT> &_targetHandler; + + typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress; + AtomToAddress _atomToAddressMap; +- llvm::BumpPtrAllocator _chunkAllocate; + TargetLayout<ELFT> *_layout; +- Header<ELFT> *_Header; +- ProgramHeader<ELFT> *_programHeader; +- SymbolTable<ELFT> * _symtab; +- StringTable<ELFT> *_strtab; +- StringTable<ELFT> *_shstrtab; +- SectionHeader<ELFT> *_shdrtab; ++ unique_bump_ptr<Header<ELFT>> _Header; ++ unique_bump_ptr<ProgramHeader<ELFT>> _programHeader; ++ unique_bump_ptr<SymbolTable<ELFT>> _symtab; ++ unique_bump_ptr<StringTable<ELFT>> _strtab; ++ unique_bump_ptr<StringTable<ELFT>> _shstrtab; ++ unique_bump_ptr<SectionHeader<ELFT>> _shdrtab; ++ /// \name Dynamic sections. ++ /// @{ ++ unique_bump_ptr<DynamicTable<ELFT>> _dynamicTable; ++ unique_bump_ptr<SymbolTable<ELFT>> _dynamicSymbolTable; ++ unique_bump_ptr<StringTable<ELFT>> _dynamicStringTable; ++ /// @} + CRuntimeFile<ELFT> _runtimeFile; + }; + +@@ -80,28 +87,18 @@ ExecutableWriter<ELFT>::ExecutableWriter(const ELFTargetInfo &ti) + + template <class ELFT> + void ExecutableWriter<ELFT>::buildChunks(const File &file) { +- for (const DefinedAtom *definedAtom : file.defined() ) { ++ for (const DefinedAtom *definedAtom : file.defined()) + _layout->addAtom(definedAtom); +- } +- /// Add all the absolute atoms to the layout +- for (const AbsoluteAtom *absoluteAtom : file.absolute()) { ++ for (const AbsoluteAtom *absoluteAtom : file.absolute()) + _layout->addAtom(absoluteAtom); +- } + } + + template<class ELFT> +-void ExecutableWriter<ELFT>::buildSymbolTable () { ++void ExecutableWriter<ELFT>::buildStaticSymbolTable(const File &file) { + for (auto sec : _layout->sections()) + if (auto section = dyn_cast<AtomSection<ELFT>>(sec)) + for (const auto &atom : section->atoms()) + _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr); +-} +- +-template<class ELFT> +-void +-ExecutableWriter<ELFT>::addAbsoluteUndefinedSymbols(const File &file) { +- // add all the absolute symbols that the layout contains to the output symbol +- // table + for (auto &atom : _layout->absoluteAtoms()) + _symtab->addSymbol(atom->_atom, ELF::SHN_ABS, atom->_virtualAddr); + for (const UndefinedAtom *a : file.undefined()) +@@ -109,7 +106,14 @@ ExecutableWriter<ELFT>::addAbsoluteUndefinedSymbols(const File &file) { + } + + template<class ELFT> +-void ExecutableWriter<ELFT>::buildAtomToAddressMap () { ++void ExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) { ++ for (const auto sla : file.sharedLibrary()) { ++ _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF); ++ } ++} ++ ++template<class ELFT> ++void ExecutableWriter<ELFT>::buildAtomToAddressMap() { + for (auto sec : _layout->sections()) + if (auto section = dyn_cast<AtomSection<ELFT>>(sec)) + for (const auto &atom : section->atoms()) +@@ -245,10 +249,9 @@ ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) { + buildAtomToAddressMap(); + + // Create symbol table and section string table +- buildSymbolTable(); +- +- // add other symbols +- addAbsoluteUndefinedSymbols(file); ++ buildStaticSymbolTable(file); ++ if (_targetInfo.isDynamic()) ++ buildDynamicSymbolTable(file); + + // Finalize the layout by calling the finalize() functions + _layout->finalize(); +@@ -282,7 +285,7 @@ ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) { + _Header->e_version(1); + } else { + // override the contents of the ELF Header +- _targetHandler.setHeaderInfo(_Header); ++ _targetHandler.setHeaderInfo(_Header.get()); + } + _Header->e_phoff(_programHeader->fileOffset()); + _Header->e_shoff(_shdrtab->fileOffset()); +@@ -309,25 +312,38 @@ ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) { + + template<class ELFT> + void ExecutableWriter<ELFT>::createDefaultSections() { +- _Header = new Header<ELFT>(_targetInfo); +- _programHeader = new ProgramHeader<ELFT>(_targetInfo); +- _layout->setHeader(_Header); +- _layout->setProgramHeader(_programHeader); +- +- _symtab = new SymbolTable< +- ELFT>(_targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE); +- _strtab = new StringTable< +- ELFT>(_targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE); +- _shstrtab = new StringTable<ELFT>( +- _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS); +- _shdrtab = new SectionHeader< +- ELFT>(_targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS); +- _layout->addSection(_symtab); +- _layout->addSection(_strtab); +- _layout->addSection(_shstrtab); +- _shdrtab->setStringSection(_shstrtab); +- _symtab->setStringSection(_strtab); +- _layout->addSection(_shdrtab); ++ _Header.reset(new (_alloc) Header<ELFT>(_targetInfo)); ++ _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_targetInfo)); ++ _layout->setHeader(_Header.get()); ++ _layout->setProgramHeader(_programHeader.get()); ++ ++ _symtab.reset(new (_alloc) SymbolTable<ELFT>( ++ _targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE)); ++ _strtab.reset(new (_alloc) StringTable<ELFT>( ++ _targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE)); ++ _shstrtab.reset(new (_alloc) StringTable<ELFT>( ++ _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS)); ++ _shdrtab.reset(new (_alloc) SectionHeader<ELFT>( ++ _targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS)); ++ _layout->addSection(_symtab.get()); ++ _layout->addSection(_strtab.get()); ++ _layout->addSection(_shstrtab.get()); ++ _shdrtab->setStringSection(_shstrtab.get()); ++ _symtab->setStringSection(_strtab.get()); ++ _layout->addSection(_shdrtab.get()); ++ ++ if (_targetInfo.isDynamic()) { ++ _dynamicTable.reset(new (_alloc) DynamicTable<ELFT>( ++ _targetInfo, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC)); ++ _dynamicStringTable.reset(new (_alloc) StringTable<ELFT>( ++ _targetInfo, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS)); ++ _dynamicSymbolTable.reset(new (_alloc) SymbolTable<ELFT>( ++ _targetInfo, ".dynsym", DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS, true)); ++ _layout->addSection(_dynamicTable.get()); ++ _layout->addSection(_dynamicStringTable.get()); ++ _layout->addSection(_dynamicSymbolTable.get()); ++ _dynamicSymbolTable->setStringSection(_dynamicStringTable.get()); ++ } + + // give a chance for the target to add sections + _targetHandler.createDefaultSections(); +diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp +index bad758c..69e7888 100644 +--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp ++++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp +@@ -97,6 +97,7 @@ ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation( + break; + } + // Runtime only relocations. Ignore here. ++ case R_X86_64_RELATIVE: + case R_X86_64_IRELATIVE: + break; + +diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h +index 146bd25..1db39aa 100644 +--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h ++++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h +@@ -40,7 +40,13 @@ public: + + virtual bool isRuntimeRelocation(const DefinedAtom &, + const Reference &r) const { +- return r.kind() == llvm::ELF::R_X86_64_IRELATIVE; ++ switch (r.kind()){ ++ case llvm::ELF::R_X86_64_RELATIVE: ++ case llvm::ELF::R_X86_64_IRELATIVE: ++ return true; ++ default: ++ return false; ++ } + } + + virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const; +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0002-SharedLibraryAtom-symbolness.patch b/app-arch/lld/files/patches-0/0002-SharedLibraryAtom-symbolness.patch new file mode 100644 index 00000000..2ff4f37f --- /dev/null +++ b/app-arch/lld/files/patches-0/0002-SharedLibraryAtom-symbolness.patch @@ -0,0 +1,27 @@ +From a59ad615abd97376779958da473f3c65308f7d82 Mon Sep 17 00:00:00 2001 +From: "Michael J. Spencer" <bigcheesegs@gmail.com> +Date: Tue, 12 Feb 2013 00:24:05 -0800 +Subject: [PATCH 02/13] SharedLibraryAtom symbolness. + +--- + lib/ReaderWriter/ELF/SectionChunks.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/ReaderWriter/ELF/SectionChunks.h b/lib/ReaderWriter/ELF/SectionChunks.h +index a809875..553972e 100644 +--- a/lib/ReaderWriter/ELF/SectionChunks.h ++++ b/lib/ReaderWriter/ELF/SectionChunks.h +@@ -638,6 +638,10 @@ void SymbolTable<ELFT>::addSymbol(const Atom *atom, int32_t sectionIndex, + break; + } + symbol->st_value = addr; ++ } else if (isa<const SharedLibraryAtom>(atom)) { ++ type = llvm::ELF::STT_FUNC; ++ symbol->st_shndx = llvm::ELF::SHN_UNDEF; ++ binding = llvm::ELF::STB_GLOBAL; + } else { + symbol->st_value = 0; + type = llvm::ELF::STT_NOTYPE; +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0003-Driver-GNULD-Default-to-dynamic.patch b/app-arch/lld/files/patches-0/0003-Driver-GNULD-Default-to-dynamic.patch new file mode 100644 index 00000000..beb929b6 --- /dev/null +++ b/app-arch/lld/files/patches-0/0003-Driver-GNULD-Default-to-dynamic.patch @@ -0,0 +1,30 @@ +From b53c4941ea28cf77a3cfc14dca780891d59c7597 Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Wed, 13 Feb 2013 15:18:24 -0800 +Subject: [PATCH 03/13] [Driver][GNULD] Default to dynamic. + +--- + lib/Driver/Drivers.cpp | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/lib/Driver/Drivers.cpp b/lib/Driver/Drivers.cpp +index 466b49e..76fd969 100644 +--- a/lib/Driver/Drivers.cpp ++++ b/lib/Driver/Drivers.cpp +@@ -134,6 +134,13 @@ public: + newArgs->AddJoinedArg(nullptr, _core.getOption(core::OPT_output), + "a.out"); + ++ if (llvm::opt::Arg *A = _inputArgs->getLastArg(ld::OPT_static)) ++ newArgs->AddJoinedArg(A, _core.getOption(core::OPT_output_type), ++ newArgs->MakeArgString("static")); ++ else ++ newArgs->AddJoinedArg(nullptr, _core.getOption(core::OPT_output_type), ++ newArgs->MakeArgString("dynamic")); ++ + if (llvm::opt::Arg *A = _inputArgs->getLastArg(ld::OPT_relocatable)) + newArgs->AddFlagArg(A, _core.getOption(core::OPT_relocatable)); + +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0004-ELF-Writer-Valid-dynamic-symbol-table.patch b/app-arch/lld/files/patches-0/0004-ELF-Writer-Valid-dynamic-symbol-table.patch new file mode 100644 index 00000000..8486717d --- /dev/null +++ b/app-arch/lld/files/patches-0/0004-ELF-Writer-Valid-dynamic-symbol-table.patch @@ -0,0 +1,269 @@ +From 6b26db639a0ca57856a50addbc90ab1dd71a2371 Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Wed, 13 Feb 2013 15:18:57 -0800 +Subject: [PATCH 04/13] [ELF][Writer] Valid dynamic symbol table. + +--- + include/lld/Core/STDExtras.h | 9 +++++++-- + lib/ReaderWriter/ELF/DefaultLayout.h | 2 +- + lib/ReaderWriter/ELF/DynamicFile.h | 8 ++++---- + lib/ReaderWriter/ELF/HeaderChunks.h | 1 + + lib/ReaderWriter/ELF/SectionChunks.h | 29 ++++++++++++++++++++++------- + lib/ReaderWriter/ELF/Writer.cpp | 28 ++++++++++++++-------------- + 6 files changed, 49 insertions(+), 28 deletions(-) + +diff --git a/include/lld/Core/STDExtras.h b/include/lld/Core/STDExtras.h +index 6c82342..a22e117 100644 +--- a/include/lld/Core/STDExtras.h ++++ b/include/lld/Core/STDExtras.h +@@ -21,8 +21,13 @@ struct destruct_delete { + } + }; + +-template <class T> +-using unique_bump_ptr = std::unique_ptr<T, destruct_delete<T>>; ++// Sadly VS 2012 doesn't support template aliases. ++// template <class T> ++// using unique_bump_ptr = std::unique_ptr<T, destruct_delete<T>>; ++ ++#define LLD_UNIQUE_BUMP_PTR(...) \ ++ std::unique_ptr<__VA_ARGS__, destruct_delete<__VA_ARGS__>> ++ + } // end namespace lld + + #endif +diff --git a/lib/ReaderWriter/ELF/DefaultLayout.h b/lib/ReaderWriter/ELF/DefaultLayout.h +index 34ce44f..c186b5b 100644 +--- a/lib/ReaderWriter/ELF/DefaultLayout.h ++++ b/lib/ReaderWriter/ELF/DefaultLayout.h +@@ -273,7 +273,7 @@ private: + std::vector<MergedSections<ELFT> *> _mergedSections; + Header<ELFT> *_header; + ProgramHeader<ELFT> *_programHeader; +- unique_bump_ptr<RelocationTable<ELFT>> _relocationTable; ++ LLD_UNIQUE_BUMP_PTR(RelocationTable<ELFT>) _relocationTable; + std::vector<AtomLayout *> _absoluteAtoms; + const ELFTargetInfo &_targetInfo; + }; +diff --git a/lib/ReaderWriter/ELF/DynamicFile.h b/lib/ReaderWriter/ELF/DynamicFile.h +index c513b4e..8255c81 100644 +--- a/lib/ReaderWriter/ELF/DynamicFile.h ++++ b/lib/ReaderWriter/ELF/DynamicFile.h +@@ -109,6 +109,7 @@ private: + DynamicFile(const ELFTargetInfo &ti, StringRef name) + : SharedLibraryFile(name), _targetInfo(ti) {} + ++ mutable llvm::BumpPtrAllocator _alloc; + const ELFTargetInfo &_targetInfo; + std::unique_ptr<llvm::object::ELFObjectFile<ELFT>> _objFile; + atom_collection_vector<DefinedAtom> _definedAtoms; +@@ -119,13 +120,12 @@ private: + StringRef _soname; + + struct SymAtomPair { +- const typename llvm::object::ELFObjectFile<ELFT>::Elf_Sym *_symbol = +- nullptr; +- const SharedLibraryAtom *_atom = nullptr; ++ SymAtomPair() : _symbol(nullptr), _atom(nullptr) {} ++ const typename llvm::object::ELFObjectFile<ELFT>::Elf_Sym *_symbol; ++ const SharedLibraryAtom *_atom; + }; + + mutable std::unordered_map<StringRef, SymAtomPair> _nameToSym; +- mutable llvm::BumpPtrAllocator _alloc; + }; + } // end namespace elf + } // end namespace lld +diff --git a/lib/ReaderWriter/ELF/HeaderChunks.h b/lib/ReaderWriter/ELF/HeaderChunks.h +index 27edd48..86f21e2 100644 +--- a/lib/ReaderWriter/ELF/HeaderChunks.h ++++ b/lib/ReaderWriter/ELF/HeaderChunks.h +@@ -301,6 +301,7 @@ SectionHeader<ELFT>::appendSection(MergedSections<ELFT> *section) { + template<class ELFT> + void + SectionHeader<ELFT>::updateSection(Section<ELFT> *section) { ++ assert(section->ordinal() < _sectionInfo.size() && "Invalid ordinal!"); + Elf_Shdr *shdr = _sectionInfo[section->ordinal()]; + shdr->sh_type = section->getType(); + shdr->sh_flags = section->getFlags(); +diff --git a/lib/ReaderWriter/ELF/SectionChunks.h b/lib/ReaderWriter/ELF/SectionChunks.h +index 553972e..085d843 100644 +--- a/lib/ReaderWriter/ELF/SectionChunks.h ++++ b/lib/ReaderWriter/ELF/SectionChunks.h +@@ -459,6 +459,7 @@ MergedSections<ELFT>::appendSection(Chunk<ELFT> *c) { + if (c->align2() > _align2) + _align2 = c->align2(); + if (const auto section = dyn_cast<Section<ELFT>>(c)) { ++ assert(!_link && "Section already has a link!"); + _link = section->getLink(); + _shInfo = section->getInfo(); + _entSize = section->getEntSize(); +@@ -474,7 +475,8 @@ MergedSections<ELFT>::appendSection(Chunk<ELFT> *c) { + template<class ELFT> + class StringTable : public Section<ELFT> { + public: +- StringTable(const ELFTargetInfo &, const char *str, int32_t order); ++ StringTable(const ELFTargetInfo &, const char *str, int32_t order, ++ bool dynamic = false); + + uint64_t addString(StringRef symname); + +@@ -501,7 +503,7 @@ private: + + template <class ELFT> + StringTable<ELFT>::StringTable(const ELFTargetInfo &ti, const char *str, +- int32_t order) ++ int32_t order, bool dynamic) + : Section<ELFT>(ti, str) { + // the string table has a NULL entry for which + // add an empty string +@@ -510,6 +512,10 @@ StringTable<ELFT>::StringTable(const ELFTargetInfo &ti, const char *str, + this->_align2 = 1; + this->setOrder(order); + this->_type = SHT_STRTAB; ++ if (dynamic) { ++ this->_flags = SHF_ALLOC; ++ this->_msize = this->_fsize; ++ } + } + + template <class ELFT> uint64_t StringTable<ELFT>::addString(StringRef symname) { +@@ -521,6 +527,8 @@ template <class ELFT> uint64_t StringTable<ELFT>::addString(StringRef symname) { + _strings.push_back(symname); + uint64_t offset = this->_fsize; + this->_fsize += symname.size() + 1; ++ if (this->_flags & SHF_ALLOC) ++ this->_msize = this->_fsize; + _stringMap[symname] = offset; + return offset; + } +@@ -557,15 +565,15 @@ public: + void setStringSection(StringTable<ELFT> *s) { _stringSection = s; } + + private: ++ llvm::BumpPtrAllocator _symbolAllocate; + StringTable<ELFT> *_stringSection; + std::vector<Elf_Sym*> _symbolTable; +- llvm::BumpPtrAllocator _symbolAllocate; + }; + + /// ELF Symbol Table + template <class ELFT> + SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str, +- int32_t order, bool dynamic) ++ int32_t order, bool dynamic) + : Section<ELFT>(ti, str) { + this->setOrder(order); + Elf_Sym *symbol = new (_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym; +@@ -574,7 +582,11 @@ SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str, + this->_entSize = sizeof(Elf_Sym); + this->_fsize = sizeof(Elf_Sym); + this->_align2 = sizeof(void *); +- this->_type = SHT_SYMTAB; ++ this->_type = dynamic ? SHT_DYNSYM : SHT_SYMTAB; ++ if (dynamic) { ++ this->_flags = SHF_ALLOC; ++ this->_msize = this->_fsize; ++ } + } + + template <class ELFT> +@@ -650,6 +662,8 @@ void SymbolTable<ELFT>::addSymbol(const Atom *atom, int32_t sectionIndex, + symbol->setBindingAndType(binding, type); + _symbolTable.push_back(symbol); + this->_fsize += sizeof(Elf_Sym); ++ if (this->_flags & SHF_ALLOC) ++ this->_msize = this->_fsize; + } + + template <class ELFT> void SymbolTable<ELFT>::finalize() { +@@ -727,14 +741,15 @@ template <class ELFT> class DynamicTable : public Section<ELFT> { + + public: + DynamicTable(const ELFTargetInfo &ti, StringRef str, int32_t order) +- : Section<ELFT>(ti, str, llvm::ELF::SHT_DYNAMIC, DefinedAtom::permR__, +- order, Section<ELFT>::K_Default) { ++ : Section<ELFT>(ti, str) { + this->setOrder(order); + this->_entSize = sizeof(Elf_Dyn); + this->_align2 = llvm::alignOf<Elf_Dyn>(); + // Reserve space for the DT_NULL entry. + this->_fsize = sizeof(Elf_Dyn); + this->_msize = sizeof(Elf_Dyn); ++ this->_type = SHT_DYNAMIC; ++ this->_flags = SHF_ALLOC; + } + + range<typename EntriesT::iterator> entries() { return _entries; } +diff --git a/lib/ReaderWriter/ELF/Writer.cpp b/lib/ReaderWriter/ELF/Writer.cpp +index 69c1d9b..58604f2 100644 +--- a/lib/ReaderWriter/ELF/Writer.cpp ++++ b/lib/ReaderWriter/ELF/Writer.cpp +@@ -60,17 +60,17 @@ private: + typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress; + AtomToAddress _atomToAddressMap; + TargetLayout<ELFT> *_layout; +- unique_bump_ptr<Header<ELFT>> _Header; +- unique_bump_ptr<ProgramHeader<ELFT>> _programHeader; +- unique_bump_ptr<SymbolTable<ELFT>> _symtab; +- unique_bump_ptr<StringTable<ELFT>> _strtab; +- unique_bump_ptr<StringTable<ELFT>> _shstrtab; +- unique_bump_ptr<SectionHeader<ELFT>> _shdrtab; ++ LLD_UNIQUE_BUMP_PTR(Header<ELFT>) _Header; ++ LLD_UNIQUE_BUMP_PTR(ProgramHeader<ELFT>) _programHeader; ++ LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _symtab; ++ LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _strtab; ++ LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _shstrtab; ++ LLD_UNIQUE_BUMP_PTR(SectionHeader<ELFT>) _shdrtab; + /// \name Dynamic sections. + /// @{ +- unique_bump_ptr<DynamicTable<ELFT>> _dynamicTable; +- unique_bump_ptr<SymbolTable<ELFT>> _dynamicSymbolTable; +- unique_bump_ptr<StringTable<ELFT>> _dynamicStringTable; ++ LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) _dynamicTable; ++ LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _dynamicSymbolTable; ++ LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _dynamicStringTable; + /// @} + CRuntimeFile<ELFT> _runtimeFile; + }; +@@ -146,8 +146,7 @@ void ExecutableWriter<ELFT>::assignSectionsWithNoSegments() { + _layout->assignOffsetsForMiscSections(); + for (auto sec : _layout->sections()) + if (auto section = dyn_cast<Section<ELFT>>(sec)) +- if (!DefaultLayout<ELFT>::hasOutputSegment(section)) +- _shdrtab->updateSection(section); ++ _shdrtab->updateSection(section); + } + + /// \brief Add absolute symbols by default. These are linker added +@@ -237,6 +236,9 @@ ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) { + // section string table + createDefaultSections(); + ++ if (_targetInfo.isDynamic()) ++ buildDynamicSymbolTable(file); ++ + // Set the Layout + _layout->assignSectionsToSegments(); + _layout->assignFileOffsets(); +@@ -250,8 +252,6 @@ ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) { + + // Create symbol table and section string table + buildStaticSymbolTable(file); +- if (_targetInfo.isDynamic()) +- buildDynamicSymbolTable(file); + + // Finalize the layout by calling the finalize() functions + _layout->finalize(); +@@ -336,7 +336,7 @@ void ExecutableWriter<ELFT>::createDefaultSections() { + _dynamicTable.reset(new (_alloc) DynamicTable<ELFT>( + _targetInfo, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC)); + _dynamicStringTable.reset(new (_alloc) StringTable<ELFT>( +- _targetInfo, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS)); ++ _targetInfo, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS, true)); + _dynamicSymbolTable.reset(new (_alloc) SymbolTable<ELFT>( + _targetInfo, ".dynsym", DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS, true)); + _layout->addSection(_dynamicTable.get()); +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0005-ELF-Writer-Add-dynamic-table-entries-and-interp-sect.patch b/app-arch/lld/files/patches-0/0005-ELF-Writer-Add-dynamic-table-entries-and-interp-sect.patch new file mode 100644 index 00000000..377ce2c0 --- /dev/null +++ b/app-arch/lld/files/patches-0/0005-ELF-Writer-Add-dynamic-table-entries-and-interp-sect.patch @@ -0,0 +1,233 @@ +From 5feec1b83ff50f261b221d6d38b124be04dd6faf Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Wed, 13 Feb 2013 16:45:14 -0800 +Subject: [PATCH 05/13] [ELF][Writer] Add dynamic table entries and interp + section. + +--- + include/lld/ReaderWriter/ELFTargetInfo.h | 4 ++ + lib/ReaderWriter/ELF/DefaultLayout.h | 4 ++ + lib/ReaderWriter/ELF/SectionChunks.h | 31 +++++++++++++- + lib/ReaderWriter/ELF/Writer.cpp | 71 +++++++++++++++++++++++++++++++- + 4 files changed, 107 insertions(+), 3 deletions(-) + +diff --git a/include/lld/ReaderWriter/ELFTargetInfo.h b/include/lld/ReaderWriter/ELFTargetInfo.h +index b1753b2..c2715fe 100644 +--- a/include/lld/ReaderWriter/ELFTargetInfo.h ++++ b/include/lld/ReaderWriter/ELFTargetInfo.h +@@ -49,6 +49,10 @@ public: + return false; + } + ++ virtual StringRef getInterpreter() const { ++ return "/lib/ld64.so.1"; ++ } ++ + /// \brief Does the output have dynamic sections. + bool isDynamic() const { + return _options._outputKind == OutputKind::DynamicExecutable || +diff --git a/lib/ReaderWriter/ELF/DefaultLayout.h b/lib/ReaderWriter/ELF/DefaultLayout.h +index c186b5b..60526bd 100644 +--- a/lib/ReaderWriter/ELF/DefaultLayout.h ++++ b/lib/ReaderWriter/ELF/DefaultLayout.h +@@ -239,6 +239,10 @@ public: + return _programHeader; + } + ++ bool hasRelocationTable() const { ++ return !!_relocationTable; ++ } ++ + RelocationTable<ELFT> *getRelocationTable() { + // Only create the relocation table if it is needed. + if (!_relocationTable) { +diff --git a/lib/ReaderWriter/ELF/SectionChunks.h b/lib/ReaderWriter/ELF/SectionChunks.h +index 085d843..dc2bc2e 100644 +--- a/lib/ReaderWriter/ELF/SectionChunks.h ++++ b/lib/ReaderWriter/ELF/SectionChunks.h +@@ -754,10 +754,12 @@ public: + + range<typename EntriesT::iterator> entries() { return _entries; } + +- void addEntry(Elf_Dyn e) { +- _entries.insert(e); ++ /// \returns the index of the entry. ++ std::size_t addEntry(Elf_Dyn e) { ++ _entries.push_back(e); + this->_fsize = (_entries.size() * sizeof(Elf_Dyn)) + sizeof(Elf_Dyn); + this->_msize = this->_fsize; ++ return _entries.size() - 1; + } + + void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) { +@@ -774,6 +776,31 @@ public: + private: + EntriesT _entries; + }; ++ ++template <class ELFT> class InterpSection : public Section<ELFT> { ++public: ++ InterpSection(const ELFTargetInfo &ti, StringRef str, int32_t order, ++ StringRef interp) ++ : Section<ELFT>(ti, str), ++ _interp(interp){ ++ this->setOrder(order); ++ this->_align2 = 1; ++ // + 1 for null term. ++ this->_fsize = interp.size() + 1; ++ this->_msize = this->_fsize; ++ this->_type = SHT_PROGBITS; ++ this->_flags = SHF_ALLOC; ++ } ++ ++ void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) { ++ uint8_t *chunkBuffer = buffer.getBufferStart(); ++ uint8_t *dest = chunkBuffer + this->fileOffset(); ++ std::memcpy(dest, _interp.data(), _interp.size()); ++ } ++ ++private: ++ StringRef _interp; ++}; + } // end namespace elf + } // end namespace lld + +diff --git a/lib/ReaderWriter/ELF/Writer.cpp b/lib/ReaderWriter/ELF/Writer.cpp +index 58604f2..f4d5667 100644 +--- a/lib/ReaderWriter/ELF/Writer.cpp ++++ b/lib/ReaderWriter/ELF/Writer.cpp +@@ -15,6 +15,8 @@ + + #include "lld/ReaderWriter/ELFTargetInfo.h" + ++#include "llvm/ADT/StringSet.h" ++ + using namespace llvm; + using namespace llvm::object; + namespace lld { +@@ -30,6 +32,7 @@ class ExecutableWriter : public ELFWriter { + public: + typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; + typedef Elf_Sym_Impl<ELFT> Elf_Sym; ++ typedef Elf_Dyn_Impl<ELFT> Elf_Dyn; + + ExecutableWriter(const ELFTargetInfo &ti); + +@@ -52,6 +55,44 @@ private: + + void createDefaultSections(); + ++ void createDefaultDynamicEntries() { ++ Elf_Dyn dyn; ++ dyn.d_un.d_val = 0; ++ ++ dyn.d_tag = DT_HASH; ++ _dt_hash = _dynamicTable->addEntry(dyn); ++ dyn.d_tag = DT_STRTAB; ++ _dt_strtab = _dynamicTable->addEntry(dyn); ++ dyn.d_tag = DT_SYMTAB; ++ _dt_symtab = _dynamicTable->addEntry(dyn); ++ dyn.d_tag = DT_STRSZ; ++ _dt_strsz = _dynamicTable->addEntry(dyn); ++ dyn.d_tag = DT_SYMENT; ++ _dt_syment = _dynamicTable->addEntry(dyn); ++ if (_layout->hasRelocationTable()) { ++ dyn.d_tag = DT_RELA; ++ _dt_rela = _dynamicTable->addEntry(dyn); ++ dyn.d_tag = DT_RELASZ; ++ _dt_relasz = _dynamicTable->addEntry(dyn); ++ dyn.d_tag = DT_RELAENT; ++ _dt_relaent = _dynamicTable->addEntry(dyn); ++ } ++ } ++ ++ void updateDynamicTable() { ++ auto tbl = _dynamicTable->entries(); ++ tbl[_dt_strtab].d_un.d_val = _dynamicStringTable->virtualAddr(); ++ tbl[_dt_symtab].d_un.d_val = _dynamicSymbolTable->virtualAddr(); ++ tbl[_dt_strsz].d_un.d_val = _dynamicStringTable->memSize(); ++ tbl[_dt_syment].d_un.d_val = _dynamicSymbolTable->getEntSize(); ++ if (_layout->hasRelocationTable()) { ++ auto relaTbl = _layout->getRelocationTable(); ++ tbl[_dt_rela].d_un.d_val = relaTbl->virtualAddr(); ++ tbl[_dt_relasz].d_un.d_val = relaTbl->memSize(); ++ tbl[_dt_relaent].d_un.d_val = relaTbl->getEntSize(); ++ } ++ } ++ + llvm::BumpPtrAllocator _alloc; + + const ELFTargetInfo &_targetInfo; +@@ -71,6 +112,16 @@ private: + LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) _dynamicTable; + LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _dynamicSymbolTable; + LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _dynamicStringTable; ++ LLD_UNIQUE_BUMP_PTR(InterpSection<ELFT>) _interpSection; ++ llvm::StringSet<> _soNeeded; ++ std::size_t _dt_hash; ++ std::size_t _dt_strtab; ++ std::size_t _dt_symtab; ++ std::size_t _dt_rela; ++ std::size_t _dt_relasz; ++ std::size_t _dt_relaent; ++ std::size_t _dt_strsz; ++ std::size_t _dt_syment; + /// @} + CRuntimeFile<ELFT> _runtimeFile; + }; +@@ -109,6 +160,13 @@ template<class ELFT> + void ExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) { + for (const auto sla : file.sharedLibrary()) { + _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF); ++ _soNeeded.insert(sla->loadName()); ++ } ++ for (const auto &loadName : _soNeeded) { ++ Elf_Dyn dyn; ++ dyn.d_tag = DT_NEEDED; ++ dyn.d_un.d_val = _dynamicStringTable->addString(loadName.getKey()); ++ _dynamicTable->addEntry(dyn); + } + } + +@@ -236,8 +294,10 @@ ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) { + // section string table + createDefaultSections(); + +- if (_targetInfo.isDynamic()) ++ if (_targetInfo.isDynamic()) { ++ createDefaultDynamicEntries(); + buildDynamicSymbolTable(file); ++ } + + // Set the Layout + _layout->assignSectionsToSegments(); +@@ -263,6 +323,10 @@ ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) { + // for sections with no segments + assignSectionsWithNoSegments(); + ++ if (_targetInfo.isDynamic()) { ++ updateDynamicTable(); ++ } ++ + uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize(); + + OwningPtr<FileOutputBuffer> buffer; +@@ -339,10 +403,15 @@ void ExecutableWriter<ELFT>::createDefaultSections() { + _targetInfo, ".dynstr", DefaultLayout<ELFT>::ORDER_DYNAMIC_STRINGS, true)); + _dynamicSymbolTable.reset(new (_alloc) SymbolTable<ELFT>( + _targetInfo, ".dynsym", DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS, true)); ++ _interpSection.reset(new (_alloc) InterpSection<ELFT>( ++ _targetInfo, ".interp", DefaultLayout<ELFT>::ORDER_INTERP, ++ _targetInfo.getInterpreter())); + _layout->addSection(_dynamicTable.get()); + _layout->addSection(_dynamicStringTable.get()); + _layout->addSection(_dynamicSymbolTable.get()); ++ _layout->addSection(_interpSection.get()); + _dynamicSymbolTable->setStringSection(_dynamicStringTable.get()); ++ + } + + // give a chance for the target to add sections +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0006-ELF-Writer-Fix-interp-phdr.patch b/app-arch/lld/files/patches-0/0006-ELF-Writer-Fix-interp-phdr.patch new file mode 100644 index 00000000..b1a628be --- /dev/null +++ b/app-arch/lld/files/patches-0/0006-ELF-Writer-Fix-interp-phdr.patch @@ -0,0 +1,40 @@ +From 80f91433c000f599baced23566270ac96a26ae9a Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Wed, 13 Feb 2013 16:59:57 -0800 +Subject: [PATCH 06/13] [ELF][Writer] Fix interp phdr. + +--- + include/lld/ReaderWriter/ELFTargetInfo.h | 2 +- + lib/ReaderWriter/ELF/HeaderChunks.h | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/include/lld/ReaderWriter/ELFTargetInfo.h b/include/lld/ReaderWriter/ELFTargetInfo.h +index c2715fe..9362aac 100644 +--- a/include/lld/ReaderWriter/ELFTargetInfo.h ++++ b/include/lld/ReaderWriter/ELFTargetInfo.h +@@ -50,7 +50,7 @@ public: + } + + virtual StringRef getInterpreter() const { +- return "/lib/ld64.so.1"; ++ return "/lib64/ld-linux-x86-64.so.2"; + } + + /// \brief Does the output have dynamic sections. +diff --git a/lib/ReaderWriter/ELF/HeaderChunks.h b/lib/ReaderWriter/ELF/HeaderChunks.h +index 86f21e2..49fec92 100644 +--- a/lib/ReaderWriter/ELF/HeaderChunks.h ++++ b/lib/ReaderWriter/ELF/HeaderChunks.h +@@ -182,7 +182,8 @@ bool ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) { + bool allocatedNew = false; + for (auto slice : segment->slices()) { + // If we have a TLS segment, emit a LOAD first. +- if (segment->segmentType() == llvm::ELF::PT_TLS) { ++ if (segment->segmentType() == llvm::ELF::PT_TLS || ++ segment->segmentType() == llvm::ELF::PT_DYNAMIC) { + auto phdr = allocateProgramHeader(); + if (phdr.second) + allocatedNew = true; +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0007-PHDR.patch b/app-arch/lld/files/patches-0/0007-PHDR.patch new file mode 100644 index 00000000..02ccef5b --- /dev/null +++ b/app-arch/lld/files/patches-0/0007-PHDR.patch @@ -0,0 +1,58 @@ +From a2ee934dfbcbc76bbea681854022d15c5899917a Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Wed, 13 Feb 2013 18:53:31 -0800 +Subject: [PATCH 07/13] PHDR. + +--- + lib/ReaderWriter/ELF/DefaultLayout.h | 2 ++ + lib/ReaderWriter/ELF/HeaderChunks.h | 21 +++++++++++++++++++++ + 2 files changed, 23 insertions(+) + +diff --git a/lib/ReaderWriter/ELF/DefaultLayout.h b/lib/ReaderWriter/ELF/DefaultLayout.h +index 60526bd..86f56fc 100644 +--- a/lib/ReaderWriter/ELF/DefaultLayout.h ++++ b/lib/ReaderWriter/ELF/DefaultLayout.h +@@ -592,6 +592,8 @@ DefaultLayout<ELFT>::assignVirtualAddress() { + for (auto si : _segments) { + newSegmentHeaderAdded = _programHeader->addSegment(si); + } ++ if (_programHeader->addPHDR()) ++ newSegmentHeaderAdded = true; + if (!newSegmentHeaderAdded) + break; + uint64_t fileoffset = 0; +diff --git a/lib/ReaderWriter/ELF/HeaderChunks.h b/lib/ReaderWriter/ELF/HeaderChunks.h +index 49fec92..5130f5f 100644 +--- a/lib/ReaderWriter/ELF/HeaderChunks.h ++++ b/lib/ReaderWriter/ELF/HeaderChunks.h +@@ -117,6 +117,27 @@ public: + + bool addSegment(Segment<ELFT> *segment); + ++ bool addPHDR() { ++ bool allocatedNew = false; ++ auto phdr = allocateProgramHeader(); ++ if (phdr.second) ++ allocatedNew = true; ++ ++ this->_fsize = fileSize(); ++ this->_msize = this->_fsize; ++ ++ phdr.first->p_type = llvm::ELF::PT_PHDR; ++ phdr.first->p_offset = this->fileOffset(); ++ phdr.first->p_vaddr = this->virtualAddr(); ++ phdr.first->p_paddr = this->virtualAddr(); ++ phdr.first->p_filesz = this->fileSize(); ++ phdr.first->p_memsz = this->memSize(); ++ phdr.first->p_flags = llvm::ELF::PF_R; ++ phdr.first->p_align = 8; ++ ++ return allocatedNew; ++ } ++ + void resetProgramHeaders() { + _phi = _ph.begin(); + } +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0008-Correct-alignment.patch b/app-arch/lld/files/patches-0/0008-Correct-alignment.patch new file mode 100644 index 00000000..bdaf7b63 --- /dev/null +++ b/app-arch/lld/files/patches-0/0008-Correct-alignment.patch @@ -0,0 +1,25 @@ +From 82c01b87a7fb4c72fccea79bb8892257607541b2 Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Thu, 14 Feb 2013 13:08:24 -0800 +Subject: [PATCH 08/13] Correct alignment. + +--- + lib/ReaderWriter/ELF/HeaderChunks.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/ReaderWriter/ELF/HeaderChunks.h b/lib/ReaderWriter/ELF/HeaderChunks.h +index 5130f5f..0d57172 100644 +--- a/lib/ReaderWriter/ELF/HeaderChunks.h ++++ b/lib/ReaderWriter/ELF/HeaderChunks.h +@@ -215,7 +215,7 @@ bool ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) { + phdr.first->p_filesz = slice->fileSize(); + phdr.first->p_memsz = slice->memSize(); + phdr.first->p_flags = segment->flags(); +- phdr.first->p_align = slice->align2(); ++ phdr.first->p_align = segment->pageSize(); + } + auto phdr = allocateProgramHeader(); + if (phdr.second) +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0009-Make-ldd-happy.patch b/app-arch/lld/files/patches-0/0009-Make-ldd-happy.patch new file mode 100644 index 00000000..55a0cf01 --- /dev/null +++ b/app-arch/lld/files/patches-0/0009-Make-ldd-happy.patch @@ -0,0 +1,109 @@ +From ba4ffc3a337bc0e0f32c5edd0bde3942afe7aebe Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Thu, 14 Feb 2013 14:00:04 -0800 +Subject: [PATCH 09/13] Make ldd happy. + +--- + lib/ReaderWriter/ELF/HeaderChunks.h | 3 ++- + lib/ReaderWriter/ELF/SectionChunks.h | 36 ++++++++++++++++++++++++++++++++++++ + lib/ReaderWriter/ELF/Writer.cpp | 5 +++++ + 3 files changed, 43 insertions(+), 1 deletion(-) + +diff --git a/lib/ReaderWriter/ELF/HeaderChunks.h b/lib/ReaderWriter/ELF/HeaderChunks.h +index 0d57172..b8a539c 100644 +--- a/lib/ReaderWriter/ELF/HeaderChunks.h ++++ b/lib/ReaderWriter/ELF/HeaderChunks.h +@@ -204,7 +204,8 @@ bool ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) { + for (auto slice : segment->slices()) { + // If we have a TLS segment, emit a LOAD first. + if (segment->segmentType() == llvm::ELF::PT_TLS || +- segment->segmentType() == llvm::ELF::PT_DYNAMIC) { ++ segment->segmentType() == llvm::ELF::PT_DYNAMIC || ++ segment->segmentType() == llvm::ELF::PT_INTERP) { + auto phdr = allocateProgramHeader(); + if (phdr.second) + allocatedNew = true; +diff --git a/lib/ReaderWriter/ELF/SectionChunks.h b/lib/ReaderWriter/ELF/SectionChunks.h +index dc2bc2e..47545fc 100644 +--- a/lib/ReaderWriter/ELF/SectionChunks.h ++++ b/lib/ReaderWriter/ELF/SectionChunks.h +@@ -801,6 +801,42 @@ public: + private: + StringRef _interp; + }; ++ ++template <class ELFT> class HashSection : public Section<ELFT> { ++ struct SymbolTableEntry { ++ StringRef _name; ++ uint32_t _index; ++ }; ++ ++public: ++ HashSection(const ELFTargetInfo &ti, StringRef name, int32_t order) ++ : Section<ELFT>(ti, name) { ++ this->setOrder(order); ++ this->_align2 = 4; // Alignment of Elf32_Word. ++ this->_type = SHT_HASH; ++ this->_flags = SHF_ALLOC; ++ // The size of nbucket and nchain. ++ this->_fsize = 8; ++ this->_msize = this->_fsize; ++ } ++ ++ void addSymbol(StringRef name, uint32_t index) { ++ SymbolTableEntry ste; ++ ste._name = name; ++ ste._index = index; ++ _entries.push_back(ste); ++ } ++ ++ virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) { ++ uint8_t *chunkBuffer = buffer.getBufferStart(); ++ uint8_t *dest = chunkBuffer + this->fileOffset(); ++ // Just emit an empty hash table. ++ std::memset(dest, 0, this->_fsize); ++ } ++ ++private: ++ std::vector<SymbolTableEntry> _entries; ++}; + } // end namespace elf + } // end namespace lld + +diff --git a/lib/ReaderWriter/ELF/Writer.cpp b/lib/ReaderWriter/ELF/Writer.cpp +index f4d5667..587ff12 100644 +--- a/lib/ReaderWriter/ELF/Writer.cpp ++++ b/lib/ReaderWriter/ELF/Writer.cpp +@@ -81,6 +81,7 @@ private: + + void updateDynamicTable() { + auto tbl = _dynamicTable->entries(); ++ tbl[_dt_hash].d_un.d_val = _hashTable->virtualAddr(); + tbl[_dt_strtab].d_un.d_val = _dynamicStringTable->virtualAddr(); + tbl[_dt_symtab].d_un.d_val = _dynamicSymbolTable->virtualAddr(); + tbl[_dt_strsz].d_un.d_val = _dynamicStringTable->memSize(); +@@ -113,6 +114,7 @@ private: + LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _dynamicSymbolTable; + LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _dynamicStringTable; + LLD_UNIQUE_BUMP_PTR(InterpSection<ELFT>) _interpSection; ++ LLD_UNIQUE_BUMP_PTR(HashSection<ELFT>) _hashTable; + llvm::StringSet<> _soNeeded; + std::size_t _dt_hash; + std::size_t _dt_strtab; +@@ -406,10 +408,13 @@ void ExecutableWriter<ELFT>::createDefaultSections() { + _interpSection.reset(new (_alloc) InterpSection<ELFT>( + _targetInfo, ".interp", DefaultLayout<ELFT>::ORDER_INTERP, + _targetInfo.getInterpreter())); ++ _hashTable.reset(new (_alloc) HashSection<ELFT>( ++ _targetInfo, ".hash", DefaultLayout<ELFT>::ORDER_HASH)); + _layout->addSection(_dynamicTable.get()); + _layout->addSection(_dynamicStringTable.get()); + _layout->addSection(_dynamicSymbolTable.get()); + _layout->addSection(_interpSection.get()); ++ _layout->addSection(_hashTable.get()); + _dynamicSymbolTable->setStringSection(_dynamicStringTable.get()); + + } +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0010-Yay-symbol-table-indicies.patch b/app-arch/lld/files/patches-0/0010-Yay-symbol-table-indicies.patch new file mode 100644 index 00000000..089a3087 --- /dev/null +++ b/app-arch/lld/files/patches-0/0010-Yay-symbol-table-indicies.patch @@ -0,0 +1,288 @@ +From d55cae2d59b46a54295c7b7111ae9efd7aeda6cc Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Thu, 14 Feb 2013 17:43:07 -0800 +Subject: [PATCH 10/13] Yay symbol table indicies. + +--- + lib/ReaderWriter/ELF/SectionChunks.h | 98 ++++++++++++++++++++++++------------ + lib/ReaderWriter/ELF/Writer.cpp | 10 +++- + lib/ReaderWriter/ELF/Writer.h | 3 ++ + 3 files changed, 77 insertions(+), 34 deletions(-) + +diff --git a/lib/ReaderWriter/ELF/SectionChunks.h b/lib/ReaderWriter/ELF/SectionChunks.h +index 47545fc..65afc05 100644 +--- a/lib/ReaderWriter/ELF/SectionChunks.h ++++ b/lib/ReaderWriter/ELF/SectionChunks.h +@@ -551,13 +551,36 @@ void StringTable<ELFT>::write(ELFWriter *writer, + /// \brief The SymbolTable class represents the symbol table in a ELF file + template<class ELFT> + class SymbolTable : public Section<ELFT> { +-public: ++ typedef typename llvm::object::ELFDataTypeTypedefHelper<ELFT>::Elf_Addr Elf_Addr; + typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym; + ++ struct SymbolEntry { ++ SymbolEntry(const Atom *a, const Elf_Sym &sym) ++ : _atom(a), _symbol(sym) {} ++ ++ SymbolEntry() : _atom(nullptr) {} ++ ++ const Atom *_atom; ++ Elf_Sym _symbol; ++ }; ++ ++public: + SymbolTable(const ELFTargetInfo &ti, const char *str, int32_t order, bool dynamic = false); + + void addSymbol(const Atom *atom, int32_t sectionIndex, uint64_t addr = 0); + ++ /// \brief Get the symbol table index for an Atom. If it's not in the symbol ++ /// table, return STN_UNDEF. ++ uint32_t getSymbolTableIndex(const Atom *a) { ++ auto se = std::find_if(_symbolTable.begin(), _symbolTable.end(), ++ [=](const SymbolEntry &se) { ++ return se._atom == a; ++ }); ++ if (se == _symbolTable.end()) ++ return STN_UNDEF; ++ return std::distance(_symbolTable.begin(), se); ++ } ++ + virtual void finalize(); + + virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer); +@@ -567,7 +590,7 @@ public: + private: + llvm::BumpPtrAllocator _symbolAllocate; + StringTable<ELFT> *_stringSection; +- std::vector<Elf_Sym*> _symbolTable; ++ std::vector<SymbolEntry> _symbolTable; + }; + + /// ELF Symbol Table +@@ -576,12 +599,12 @@ SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str, + int32_t order, bool dynamic) + : Section<ELFT>(ti, str) { + this->setOrder(order); +- Elf_Sym *symbol = new (_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym; +- memset((void *)symbol, 0, sizeof(Elf_Sym)); +- _symbolTable.push_back(symbol); ++ Elf_Sym symbol; ++ std::memset(&symbol, 0, sizeof(Elf_Sym)); ++ _symbolTable.push_back(SymbolEntry(nullptr, symbol)); + this->_entSize = sizeof(Elf_Sym); + this->_fsize = sizeof(Elf_Sym); +- this->_align2 = sizeof(void *); ++ this->_align2 = sizeof(Elf_Addr); + this->_type = dynamic ? SHT_DYNSYM : SHT_SYMTAB; + if (dynamic) { + this->_flags = SHF_ALLOC; +@@ -592,40 +615,40 @@ SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str, + template <class ELFT> + void SymbolTable<ELFT>::addSymbol(const Atom *atom, int32_t sectionIndex, + uint64_t addr) { +- Elf_Sym *symbol = new(_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym; ++ Elf_Sym symbol; + unsigned char binding = 0, type = 0; +- symbol->st_name = _stringSection->addString(atom->name()); +- symbol->st_size = 0; +- symbol->st_shndx = sectionIndex; +- symbol->st_value = 0; +- symbol->st_other = llvm::ELF::STV_DEFAULT; ++ symbol.st_name = _stringSection->addString(atom->name()); ++ symbol.st_size = 0; ++ symbol.st_shndx = sectionIndex; ++ symbol.st_value = 0; ++ symbol.st_other = llvm::ELF::STV_DEFAULT; + if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom)){ +- symbol->st_size = da->size(); ++ symbol.st_size = da->size(); + DefinedAtom::ContentType ct; + switch (ct = da->contentType()){ + case DefinedAtom::typeCode: + case DefinedAtom::typeStub: +- symbol->st_value = addr; ++ symbol.st_value = addr; + type = llvm::ELF::STT_FUNC; + break; + case DefinedAtom::typeResolver: +- symbol->st_value = addr; ++ symbol.st_value = addr; + type = llvm::ELF::STT_GNU_IFUNC; + break; + case DefinedAtom::typeData: + case DefinedAtom::typeConstant: + case DefinedAtom::typeGOT: +- symbol->st_value = addr; ++ symbol.st_value = addr; + type = llvm::ELF::STT_OBJECT; + break; + case DefinedAtom::typeZeroFill: + type = llvm::ELF::STT_OBJECT; +- symbol->st_value = addr; ++ symbol.st_value = addr; + break; + case DefinedAtom::typeTLVInitialData: + case DefinedAtom::typeTLVInitialZeroFill: + type = llvm::ELF::STT_TLS; +- symbol->st_value = addr; ++ symbol.st_value = addr; + break; + default: + type = llvm::ELF::STT_NOTYPE; +@@ -636,10 +659,10 @@ void SymbolTable<ELFT>::addSymbol(const Atom *atom, int32_t sectionIndex, + binding = llvm::ELF::STB_GLOBAL; + } else if (const AbsoluteAtom *aa = dyn_cast<const AbsoluteAtom>(atom)){ + type = llvm::ELF::STT_OBJECT; +- symbol->st_shndx = llvm::ELF::SHN_ABS; ++ symbol.st_shndx = llvm::ELF::SHN_ABS; + switch (aa->scope()) { + case AbsoluteAtom::scopeLinkageUnit: +- symbol->st_other = llvm::ELF::STV_HIDDEN; ++ symbol.st_other = llvm::ELF::STV_HIDDEN; + binding = llvm::ELF::STB_LOCAL; + break; + case AbsoluteAtom::scopeTranslationUnit: +@@ -649,18 +672,18 @@ void SymbolTable<ELFT>::addSymbol(const Atom *atom, int32_t sectionIndex, + binding = llvm::ELF::STB_GLOBAL; + break; + } +- symbol->st_value = addr; ++ symbol.st_value = addr; + } else if (isa<const SharedLibraryAtom>(atom)) { + type = llvm::ELF::STT_FUNC; +- symbol->st_shndx = llvm::ELF::SHN_UNDEF; ++ symbol.st_shndx = llvm::ELF::SHN_UNDEF; + binding = llvm::ELF::STB_GLOBAL; + } else { +- symbol->st_value = 0; ++ symbol.st_value = 0; + type = llvm::ELF::STT_NOTYPE; + binding = llvm::ELF::STB_WEAK; + } +- symbol->setBindingAndType(binding, type); +- _symbolTable.push_back(symbol); ++ symbol.setBindingAndType(binding, type); ++ _symbolTable.push_back(SymbolEntry(atom, symbol)); + this->_fsize += sizeof(Elf_Sym); + if (this->_flags & SHF_ALLOC) + this->_msize = this->_fsize; +@@ -670,12 +693,12 @@ template <class ELFT> void SymbolTable<ELFT>::finalize() { + // sh_info should be one greater than last symbol with STB_LOCAL binding + // we sort the symbol table to keep all local symbols at the beginning + std::stable_sort(_symbolTable.begin(), _symbolTable.end(), +- [](const Elf_Sym *A, const Elf_Sym *B) { +- return A->getBinding() < B->getBinding(); ++ [](const SymbolEntry &A, const SymbolEntry &B) { ++ return A._symbol.getBinding() < B._symbol.getBinding(); + }); + uint16_t shInfo = 0; +- for (auto i : _symbolTable) { +- if (i->getBinding() != llvm::ELF::STB_LOCAL) ++ for (const auto &i : _symbolTable) { ++ if (i._symbol.getBinding() != llvm::ELF::STB_LOCAL) + break; + shInfo++; + } +@@ -688,8 +711,8 @@ void SymbolTable<ELFT>::write(ELFWriter *writer, + llvm::FileOutputBuffer &buffer) { + uint8_t *chunkBuffer = buffer.getBufferStart(); + uint8_t *dest = chunkBuffer + this->fileOffset(); +- for (auto sti : _symbolTable) { +- memcpy(dest, sti, sizeof(Elf_Sym)); ++ for (const auto &sti : _symbolTable) { ++ memcpy(dest, &sti._symbol, sizeof(Elf_Sym)); + dest += sizeof(Elf_Sym); + } + } +@@ -699,7 +722,7 @@ public: + typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela; + + RelocationTable(const ELFTargetInfo &ti, StringRef str, int32_t order) +- : Section<ELFT>(ti, str) { ++ : Section<ELFT>(ti, str), _symbolTable(nullptr) { + this->setOrder(order); + this->_entSize = sizeof(Elf_Rela); + this->_align2 = llvm::alignOf<Elf_Rela>(); +@@ -713,12 +736,20 @@ public: + this->_msize = this->_fsize; + } + ++ void setSymbolTable(const SymbolTable<ELFT> *symbolTable) { ++ _symbolTable = symbolTable; ++ } ++ ++ virtual void finalize() { ++ this->_link = _symbolTable ? _symbolTable->ordinal() : 0; ++ } ++ + virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) { + uint8_t *chunkBuffer = buffer.getBufferStart(); + uint8_t *dest = chunkBuffer + this->fileOffset(); + for (const auto &rel : _relocs) { + Elf_Rela *r = reinterpret_cast<Elf_Rela *>(dest); +- r->setSymbolAndType(0, rel.second.kind()); ++ r->setSymbolAndType(writer->getDynSymbolIndex(rel.second.target()), rel.second.kind()); + r->r_offset = + writer->addressOfAtom(&rel.first) + rel.second.offsetInAtom(); + r->r_addend = +@@ -733,6 +764,7 @@ public: + + private: + std::vector<std::pair<const DefinedAtom &, const Reference &>> _relocs; ++ const SymbolTable<ELFT> *_symbolTable; + }; + + template <class ELFT> class DynamicTable : public Section<ELFT> { +diff --git a/lib/ReaderWriter/ELF/Writer.cpp b/lib/ReaderWriter/ELF/Writer.cpp +index 587ff12..83a0c86 100644 +--- a/lib/ReaderWriter/ELF/Writer.cpp ++++ b/lib/ReaderWriter/ELF/Writer.cpp +@@ -53,6 +53,10 @@ private: + return _atomToAddressMap[atom]; + } + ++ virtual uint32_t getDynSymbolIndex(const Atom *atom) { ++ return _dynamicSymbolTable ? _dynamicSymbolTable->getSymbolTableIndex(atom) : 0; ++ } ++ + void createDefaultSections(); + + void createDefaultDynamicEntries() { +@@ -77,6 +81,9 @@ private: + dyn.d_tag = DT_RELAENT; + _dt_relaent = _dynamicTable->addEntry(dyn); + } ++ dyn.d_tag = DT_RUNPATH; ++ dyn.d_un.d_val = _dynamicStringTable->addString("."); ++ _dynamicTable->addEntry(dyn); + } + + void updateDynamicTable() { +@@ -416,7 +423,8 @@ void ExecutableWriter<ELFT>::createDefaultSections() { + _layout->addSection(_interpSection.get()); + _layout->addSection(_hashTable.get()); + _dynamicSymbolTable->setStringSection(_dynamicStringTable.get()); +- ++ if (_layout->hasRelocationTable()) ++ _layout->getRelocationTable()->setSymbolTable(_dynamicSymbolTable.get()); + } + + // give a chance for the target to add sections +diff --git a/lib/ReaderWriter/ELF/Writer.h b/lib/ReaderWriter/ELF/Writer.h +index 7e67c31..cd0918c 100644 +--- a/lib/ReaderWriter/ELF/Writer.h ++++ b/lib/ReaderWriter/ELF/Writer.h +@@ -32,6 +32,9 @@ public: + + /// \brief Get the virtual address of \p atom after layout. + virtual uint64_t addressOfAtom(const Atom *atom) = 0; ++ ++ /// \brief Get the dynamic symbol index for a given atom. ++ virtual uint32_t getDynSymbolIndex(const Atom *atom) = 0; + }; + } // end namespace elf + } // end namespace lld +-- +1.8.1.2 + 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 + diff --git a/app-arch/lld/files/patches-0/0012-ELF-Writer-Dynamic-function-binding-works.patch b/app-arch/lld/files/patches-0/0012-ELF-Writer-Dynamic-function-binding-works.patch new file mode 100644 index 00000000..ad8cd169 --- /dev/null +++ b/app-arch/lld/files/patches-0/0012-ELF-Writer-Dynamic-function-binding-works.patch @@ -0,0 +1,373 @@ +From a977b7fb0c21e7722a636379f300a6ab8bc5a5fc Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Fri, 15 Feb 2013 17:23:17 -0800 +Subject: [PATCH 12/13] [ELF][Writer] Dynamic function binding works. + +--- + include/lld/ReaderWriter/ELFTargetInfo.h | 7 +++- + lib/ReaderWriter/ELF/DefaultLayout.h | 44 +++++++++++++++------- + lib/ReaderWriter/ELF/SectionChunks.h | 21 +++++++++-- + lib/ReaderWriter/ELF/Writer.cpp | 35 ++++++++++++++--- + .../ELF/X86_64/X86_64TargetHandler.cpp | 18 ++++++++- + lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp | 9 ++++- + lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h | 19 +++++++++- + 7 files changed, 126 insertions(+), 27 deletions(-) + +diff --git a/include/lld/ReaderWriter/ELFTargetInfo.h b/include/lld/ReaderWriter/ELFTargetInfo.h +index 9362aac..46d13ed 100644 +--- a/include/lld/ReaderWriter/ELFTargetInfo.h ++++ b/include/lld/ReaderWriter/ELFTargetInfo.h +@@ -44,11 +44,16 @@ public: + virtual StringRef getEntry() const; + virtual uint64_t getBaseAddress() const { return _options._baseAddress; } + +- virtual bool isRuntimeRelocation(const DefinedAtom &, ++ virtual bool isDynamicRelocation(const DefinedAtom &, + const Reference &) const { + return false; + } + ++ virtual bool isPLTRelocation(const DefinedAtom &, ++ const Reference &) const { ++ return false; ++ } ++ + virtual StringRef getInterpreter() const { + return "/lib64/ld-linux-x86-64.so.2"; + } +diff --git a/lib/ReaderWriter/ELF/DefaultLayout.h b/lib/ReaderWriter/ELF/DefaultLayout.h +index 86f56fc..a863d9b 100644 +--- a/lib/ReaderWriter/ELF/DefaultLayout.h ++++ b/lib/ReaderWriter/ELF/DefaultLayout.h +@@ -145,9 +145,7 @@ public: + + typedef typename std::vector<AtomLayout *>::iterator AbsoluteAtomIterT; + +- DefaultLayout(const ELFTargetInfo &ti) +- : _relocationTable(nullptr), _targetInfo(ti) { +- } ++ DefaultLayout(const ELFTargetInfo &ti) : _targetInfo(ti) {} + + /// \brief Return the section order for a input section + virtual SectionOrder getSectionOrder(StringRef name, int32_t contentType, +@@ -239,18 +237,33 @@ public: + return _programHeader; + } + +- bool hasRelocationTable() const { +- return !!_relocationTable; ++ bool hasDynamicRelocationTable() const { ++ return !!_dynamicRelocationTable; ++ } ++ ++ bool hasPLTRelocationTable() const { ++ return !!_pltRelocationTable; ++ } ++ ++ /// \brief Get or create the dynamic relocation table. All relocations in this ++ /// table are processed at startup. ++ RelocationTable<ELFT> *getDynamicRelocationTable() { ++ if (!_dynamicRelocationTable) { ++ _dynamicRelocationTable.reset(new (_allocator) ++ RelocationTable<ELFT>(_targetInfo, ".rela.dyn", ORDER_REL)); ++ addSection(_dynamicRelocationTable.get()); ++ } ++ return _dynamicRelocationTable.get(); + } + +- RelocationTable<ELFT> *getRelocationTable() { +- // Only create the relocation table if it is needed. +- if (!_relocationTable) { +- _relocationTable.reset(new (_allocator) ++ /// \brief Get or create the PLT relocation table. Referenced by DT_JMPREL. ++ RelocationTable<ELFT> *getPLTRelocationTable() { ++ if (!_pltRelocationTable) { ++ _pltRelocationTable.reset(new (_allocator) + RelocationTable<ELFT>(_targetInfo, ".rela.plt", ORDER_REL)); +- addSection(_relocationTable.get()); ++ addSection(_pltRelocationTable.get()); + } +- return _relocationTable.get(); ++ return _pltRelocationTable.get(); + } + + uint64_t getTLSSize() const { +@@ -277,7 +290,8 @@ private: + std::vector<MergedSections<ELFT> *> _mergedSections; + Header<ELFT> *_header; + ProgramHeader<ELFT> *_programHeader; +- LLD_UNIQUE_BUMP_PTR(RelocationTable<ELFT>) _relocationTable; ++ LLD_UNIQUE_BUMP_PTR(RelocationTable<ELFT>) _dynamicRelocationTable; ++ LLD_UNIQUE_BUMP_PTR(RelocationTable<ELFT>) _pltRelocationTable; + std::vector<AtomLayout *> _absoluteAtoms; + const ELFTargetInfo &_targetInfo; + }; +@@ -469,8 +483,10 @@ ErrorOr<const AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) { + getSection(sectionName, contentType, permissions); + // Add runtime relocations to the .rela section. + for (const auto &reloc : *definedAtom) +- if (_targetInfo.isRuntimeRelocation(*definedAtom, *reloc)) +- getRelocationTable()->addRelocation(*definedAtom, *reloc); ++ if (_targetInfo.isDynamicRelocation(*definedAtom, *reloc)) ++ getDynamicRelocationTable()->addRelocation(*definedAtom, *reloc); ++ else if (_targetInfo.isPLTRelocation(*definedAtom, *reloc)) ++ getPLTRelocationTable()->addRelocation(*definedAtom, *reloc); + return section->appendAtom(atom); + } else if (const AbsoluteAtom *absoluteAtom = dyn_cast<AbsoluteAtom>(atom)) { + // Absolute atoms are not part of any section, they are global for the whole +diff --git a/lib/ReaderWriter/ELF/SectionChunks.h b/lib/ReaderWriter/ELF/SectionChunks.h +index 65afc05..d12a86a 100644 +--- a/lib/ReaderWriter/ELF/SectionChunks.h ++++ b/lib/ReaderWriter/ELF/SectionChunks.h +@@ -571,7 +571,7 @@ public: + + /// \brief Get the symbol table index for an Atom. If it's not in the symbol + /// table, return STN_UNDEF. +- uint32_t getSymbolTableIndex(const Atom *a) { ++ uint32_t getSymbolTableIndex(const Atom *a) const { + auto se = std::find_if(_symbolTable.begin(), _symbolTable.end(), + [=](const SymbolEntry &se) { + return se._atom == a; +@@ -730,10 +730,25 @@ public: + this->_flags = SHF_ALLOC; + } + +- void addRelocation(const DefinedAtom &da, const Reference &r) { ++ /// \returns the index of the relocation added. ++ uint32_t addRelocation(const DefinedAtom &da, const Reference &r) { + _relocs.emplace_back(da, r); + this->_fsize = _relocs.size() * sizeof(Elf_Rela); + this->_msize = this->_fsize; ++ return _relocs.size() - 1; ++ } ++ ++ bool getRelocationIndex(const Reference &r, uint32_t &res) { ++ auto rel = std::find_if(_relocs.begin(), _relocs.end(), ++ [&](const std::pair<const DefinedAtom &, const Reference &> &p) { ++ if (&p.second == &r) ++ return true; ++ return false; ++ }); ++ if (rel == _relocs.end()) ++ return false; ++ res = std::distance(_relocs.begin(), rel); ++ return true; + } + + void setSymbolTable(const SymbolTable<ELFT> *symbolTable) { +@@ -749,7 +764,7 @@ public: + uint8_t *dest = chunkBuffer + this->fileOffset(); + for (const auto &rel : _relocs) { + Elf_Rela *r = reinterpret_cast<Elf_Rela *>(dest); +- r->setSymbolAndType(writer->getDynSymbolIndex(rel.second.target()), rel.second.kind()); ++ r->setSymbolAndType(_symbolTable->getSymbolTableIndex(rel.second.target()), rel.second.kind()); + r->r_offset = + writer->addressOfAtom(&rel.first) + rel.second.offsetInAtom(); + r->r_addend = +diff --git a/lib/ReaderWriter/ELF/Writer.cpp b/lib/ReaderWriter/ELF/Writer.cpp +index 83a0c86..4bc1545 100644 +--- a/lib/ReaderWriter/ELF/Writer.cpp ++++ b/lib/ReaderWriter/ELF/Writer.cpp +@@ -73,7 +73,7 @@ private: + _dt_strsz = _dynamicTable->addEntry(dyn); + dyn.d_tag = DT_SYMENT; + _dt_syment = _dynamicTable->addEntry(dyn); +- if (_layout->hasRelocationTable()) { ++ if (_layout->hasDynamicRelocationTable()) { + dyn.d_tag = DT_RELA; + _dt_rela = _dynamicTable->addEntry(dyn); + dyn.d_tag = DT_RELASZ; +@@ -81,6 +81,18 @@ private: + dyn.d_tag = DT_RELAENT; + _dt_relaent = _dynamicTable->addEntry(dyn); + } ++ if (_layout->hasPLTRelocationTable()) { ++ dyn.d_tag = DT_PLTRELSZ; ++ _dt_pltrelsz = _dynamicTable->addEntry(dyn); ++ dyn.d_tag = DT_PLTGOT; ++ _dt_pltgot = _dynamicTable->addEntry(dyn); ++ dyn.d_tag = DT_PLTREL; ++ dyn.d_un.d_val = DT_RELA; ++ _dt_pltrel = _dynamicTable->addEntry(dyn); ++ dyn.d_un.d_val = 0; ++ dyn.d_tag = DT_JMPREL; ++ _dt_jmprel = _dynamicTable->addEntry(dyn); ++ } + dyn.d_tag = DT_RUNPATH; + dyn.d_un.d_val = _dynamicStringTable->addString("."); + _dynamicTable->addEntry(dyn); +@@ -93,12 +105,19 @@ private: + tbl[_dt_symtab].d_un.d_val = _dynamicSymbolTable->virtualAddr(); + tbl[_dt_strsz].d_un.d_val = _dynamicStringTable->memSize(); + tbl[_dt_syment].d_un.d_val = _dynamicSymbolTable->getEntSize(); +- if (_layout->hasRelocationTable()) { +- auto relaTbl = _layout->getRelocationTable(); ++ if (_layout->hasDynamicRelocationTable()) { ++ auto relaTbl = _layout->getDynamicRelocationTable(); + tbl[_dt_rela].d_un.d_val = relaTbl->virtualAddr(); + tbl[_dt_relasz].d_un.d_val = relaTbl->memSize(); + tbl[_dt_relaent].d_un.d_val = relaTbl->getEntSize(); + } ++ if (_layout->hasPLTRelocationTable()) { ++ auto relaTbl = _layout->getPLTRelocationTable(); ++ tbl[_dt_jmprel].d_un.d_val = relaTbl->virtualAddr(); ++ tbl[_dt_pltrelsz].d_un.d_val = relaTbl->memSize(); ++ auto gotplt = _layout->findOutputSection(".got.plt"); ++ tbl[_dt_pltgot].d_un.d_val = gotplt->virtualAddr(); ++ } + } + + llvm::BumpPtrAllocator _alloc; +@@ -131,6 +150,10 @@ private: + std::size_t _dt_relaent; + std::size_t _dt_strsz; + std::size_t _dt_syment; ++ std::size_t _dt_pltrelsz; ++ std::size_t _dt_pltgot; ++ std::size_t _dt_pltrel; ++ std::size_t _dt_jmprel; + /// @} + CRuntimeFile<ELFT> _runtimeFile; + }; +@@ -423,8 +446,10 @@ void ExecutableWriter<ELFT>::createDefaultSections() { + _layout->addSection(_interpSection.get()); + _layout->addSection(_hashTable.get()); + _dynamicSymbolTable->setStringSection(_dynamicStringTable.get()); +- if (_layout->hasRelocationTable()) +- _layout->getRelocationTable()->setSymbolTable(_dynamicSymbolTable.get()); ++ if (_layout->hasDynamicRelocationTable()) ++ _layout->getDynamicRelocationTable()->setSymbolTable(_dynamicSymbolTable.get()); ++ if (_layout->hasPLTRelocationTable()) ++ _layout->getPLTRelocationTable()->setSymbolTable(_dynamicSymbolTable.get()); + } + + // give a chance for the target to add sections +diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp +index 48da692..91d8b06 100644 +--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp ++++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp +@@ -88,7 +88,8 @@ ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation( + *reinterpret_cast<llvm::support::little64_t *>(location) = result; + } + break; +- case R_X86_64_TLSLD: ++ } ++ case R_X86_64_TLSLD: { + // Rewrite to move %fs:0 into %rax. Technically we should verify that the + // next relocation is a PC32 to __tls_get_addr... + static uint8_t instr[] = { 0x66, 0x66, 0x66, 0x64, 0x48, 0x8b, 0x04, 0x25, +@@ -96,9 +97,24 @@ ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation( + std::memcpy(location - 3, instr, sizeof(instr)); + break; + } ++ case LLD_R_X86_64_GOTRELINDEX: { ++ const DefinedAtom *target = cast<const DefinedAtom>(ref.target()); ++ for (const Reference *r : *target) { ++ if (r->kind() == R_X86_64_JUMP_SLOT) { ++ uint32_t index; ++ if (!_targetInfo.getTargetHandler<X86_64ELFType>().targetLayout().getPLTRelocationTable()->getRelocationIndex(*r, index)) ++ llvm_unreachable("Relocation doesn't exist"); ++ reloc32(location, 0, index, 0); ++ break; ++ } ++ } ++ break; ++ } + // Runtime only relocations. Ignore here. + case R_X86_64_RELATIVE: + case R_X86_64_IRELATIVE: ++ case llvm::ELF::R_X86_64_JUMP_SLOT: ++ case llvm::ELF::R_X86_64_GLOB_DAT: + break; + + case lld::Reference::kindLayoutAfter: +diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp +index bf57449..15e0eee 100644 +--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp ++++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp +@@ -19,6 +19,7 @@ + #include "llvm/ADT/StringSwitch.h" + + using namespace lld; ++using namespace lld::elf; + + namespace { + using namespace llvm::ELF; +@@ -357,10 +358,11 @@ public: + if (plt != _pltMap.end()) + return plt->second; + auto ga = new (_file._alloc) GOTAtom(_file, ".got.plt"); +- ga->addReference(R_X86_64_RELATIVE, 0, a, 0); ++ ga->addReference(R_X86_64_JUMP_SLOT, 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); ++ pa->addReference(LLD_R_X86_64_GOTRELINDEX, 7, ga, 0); ++ 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); +@@ -439,6 +441,7 @@ ErrorOr<int32_t> elf::X86_64TargetInfo::relocKindFromString( + LLD_CASE(R_X86_64_TLSDESC_CALL) + LLD_CASE(R_X86_64_TLSDESC) + LLD_CASE(R_X86_64_IRELATIVE) ++ .Case("LLD_R_X86_64_GOTRELINDEX", LLD_R_X86_64_GOTRELINDEX) + .Default(-1); + + if (ret == -1) +@@ -491,6 +494,8 @@ ErrorOr<std::string> elf::X86_64TargetInfo::stringFromRelocKind( + LLD_CASE(R_X86_64_TLSDESC_CALL) + LLD_CASE(R_X86_64_TLSDESC) + LLD_CASE(R_X86_64_IRELATIVE) ++ case LLD_R_X86_64_GOTRELINDEX: ++ return std::string("LLD_R_X86_64_GOTRELINDEX"); + } + + return make_error_code(yaml_reader_error::illegal_value); +diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h +index 1db39aa..d1fdd34 100644 +--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h ++++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h +@@ -20,6 +20,12 @@ + + namespace lld { + namespace elf { ++/// \brief x86-64 internal references. ++enum { ++ /// \brief The 32 bit index of the relocation in the got this reference refers ++ /// to. ++ LLD_R_X86_64_GOTRELINDEX = 1024, ++}; + + class X86_64TargetInfo LLVM_FINAL : public ELFTargetInfo { + public: +@@ -38,7 +44,7 @@ public: + return _options._baseAddress; + } + +- virtual bool isRuntimeRelocation(const DefinedAtom &, ++ virtual bool isDynamicRelocation(const DefinedAtom &, + const Reference &r) const { + switch (r.kind()){ + case llvm::ELF::R_X86_64_RELATIVE: +@@ -49,6 +55,17 @@ public: + } + } + ++ virtual bool isPLTRelocation(const DefinedAtom &, ++ const Reference &r) const { ++ switch (r.kind()){ ++ case llvm::ELF::R_X86_64_JUMP_SLOT: ++ case llvm::ELF::R_X86_64_GLOB_DAT: ++ return true; ++ default: ++ return false; ++ } ++ } ++ + virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const; + virtual ErrorOr<std::string> stringFromRelocKind(int32_t kind) const; + +-- +1.8.1.2 + diff --git a/app-arch/lld/files/patches-0/0013-ELF-Writer-Handle-non-pie-object-files-when-dynamic-.patch b/app-arch/lld/files/patches-0/0013-ELF-Writer-Handle-non-pie-object-files-when-dynamic-.patch new file mode 100644 index 00000000..d001e197 --- /dev/null +++ b/app-arch/lld/files/patches-0/0013-ELF-Writer-Handle-non-pie-object-files-when-dynamic-.patch @@ -0,0 +1,105 @@ +From d54c783c66dc03defdd0265204beed9fdcca8be0 Mon Sep 17 00:00:00 2001 +From: Michael Spencer <bigcheesegs@gmail.com> +Date: Fri, 15 Feb 2013 17:54:57 -0800 +Subject: [PATCH 13/13] [ELF][Writer] Handle non-pie object files when dynamic + linking. + +--- + .../ELF/X86_64/X86_64TargetHandler.cpp | 4 ++-- + lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp | 25 ++++++++++++++++------ + 2 files changed, 20 insertions(+), 9 deletions(-) + +diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp +index 91d8b06..dff81f9 100644 +--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp ++++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp +@@ -113,8 +113,8 @@ ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation( + // Runtime only relocations. Ignore here. + case R_X86_64_RELATIVE: + case R_X86_64_IRELATIVE: +- case llvm::ELF::R_X86_64_JUMP_SLOT: +- case llvm::ELF::R_X86_64_GLOB_DAT: ++ case R_X86_64_JUMP_SLOT: ++ case R_X86_64_GLOB_DAT: + break; + + case lld::Reference::kindLayoutAfter: +diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp +index 15e0eee..1a93c86 100644 +--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp ++++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp +@@ -142,16 +142,15 @@ public: + template <class Derived> class GOTPLTPass : public Pass { + /// \brief Handle a specific reference. + void handleReference(const DefinedAtom &atom, const Reference &ref) { +- const DefinedAtom *da = dyn_cast_or_null<const DefinedAtom>(ref.target()); + switch (ref.kind()) { + case R_X86_64_PLT32: + static_cast<Derived *>(this)->handlePLT32(ref); + break; + case R_X86_64_PC32: +- static_cast<Derived *>(this)->handleIFUNC(ref, da); ++ static_cast<Derived *>(this)->handlePC32(ref); + break; + case R_X86_64_GOTTPOFF: // GOT Thread Pointer Offset +- static_cast<Derived *>(this)->handleGOTTPOFF(ref, da); ++ static_cast<Derived *>(this)->handleGOTTPOFF(ref); + break; + case R_X86_64_GOTPCREL: + static_cast<Derived *>(this)->handleGOTPCREL(ref); +@@ -186,7 +185,8 @@ protected: + /// + /// This create a PLT and GOT entry for the IFUNC if one does not exist. The + /// GOT entry and a IRELATIVE relocation to the original target resolver. +- ErrorOr<void> handleIFUNC(const Reference &ref, const DefinedAtom *target) { ++ ErrorOr<void> handleIFUNC(const Reference &ref) { ++ auto target = dyn_cast_or_null<const DefinedAtom>(ref.target()); + if (target && target->contentType() == DefinedAtom::typeResolver) + const_cast<Reference &>(ref).setTarget(getIFUNCPLTEntry(target)); + return error_code::success(); +@@ -210,7 +210,8 @@ protected: + + /// \brief Create a TPOFF64 GOT entry and change the relocation to a PC32 to + /// the GOT. +- void handleGOTTPOFF(const Reference &ref, const DefinedAtom *target) { ++ void handleGOTTPOFF(const Reference &ref) { ++ auto target = dyn_cast_or_null<const DefinedAtom>(ref.target()); + const_cast<Reference &>(ref).setTarget(getGOTTPOFF(target)); + const_cast<Reference &>(ref).setKind(R_X86_64_PC32); + } +@@ -327,9 +328,13 @@ public: + // Handle IFUNC. + if (const DefinedAtom *da = dyn_cast_or_null<const DefinedAtom>(ref.target())) + if (da->contentType() == DefinedAtom::typeResolver) +- return handleIFUNC(ref, da); ++ return handleIFUNC(ref); + return error_code::success(); + } ++ ++ ErrorOr<void> handlePC32(const Reference &ref) { ++ return handleIFUNC(ref); ++ } + }; + + class DynamicGOTPLTPass LLVM_FINAL : public GOTPLTPass<DynamicGOTPLTPass> { +@@ -383,10 +388,16 @@ public: + // Handle IFUNC. + if (const DefinedAtom *da = dyn_cast_or_null<const DefinedAtom>(ref.target())) + if (da->contentType() == DefinedAtom::typeResolver) +- return handleIFUNC(ref, da); ++ return handleIFUNC(ref); + const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target())); + return error_code::success(); + } ++ ++ ErrorOr<void> handlePC32(const Reference &ref) { ++ if (ref.target() && isa<SharedLibraryAtom>(ref.target())) ++ return handlePLT32(ref); ++ return handleIFUNC(ref); ++ } + }; + } // end anon namespace + +-- +1.8.1.2 + diff --git a/app-arch/lld/lld-9999.ebuild b/app-arch/lld/lld-9999.ebuild new file mode 100644 index 00000000..a185cf74 --- /dev/null +++ b/app-arch/lld/lld-9999.ebuild @@ -0,0 +1,85 @@ +# By Eroen, 2013 +# Distributed under the terms of the ISC License +# $Header: $ + +EAPI=5 + +inherit eutils flag-o-matic cmake-utils subversion + +DESCRIPTION="The LLVM Linker" +HOMEPAGE="http://lld.llvm.org/" +ESVN_REPO_URI="http://llvm.org/svn/llvm-project/lld/trunk" +SRC_URI="" + +LICENSE="UoI-NCSA" +SLOT="0" +KEYWORDS="~amd64" +IUSE="" + +LIBDEPEND=" + || ( ( >=sys-devel/clang-3.1 + sys-libs/libcxx ) + >=sys-devel/gcc-4.7 ) +" +RDEPEND="${LIBDEPEND}" +DEPEND="${LIBDEPEND}" +HDEPEND=" + >=dev-util/cmake-2.8 + " + +src_unpack() { + ESVN_PROJECT=llvm \ + subversion_fetch \ + "http://llvm.org/svn/llvm-project/llvm/trunk" + ESVN_PROJECT=lld \ + S="${S}"/tools/lld \ + subversion_fetch \ + "http://llvm.org/svn/llvm-project/lld/trunk" +} + +src_prepare() { + cd "${S}"/tools/lld + # Patches from https://github.com/Bigcheese/lold (dynamic branch) + EPATCH_FORCE=yes \ + EPATCH_SUFFIX=patch \ + epatch "${FILESDIR}"/patches-0/ + default + epatch_user +} + +src_configure() { + append-cxxflags -std=c++11 + append-ldflags -L/usr/lib64/llvm + # Shared libraries needs a release, so we can have corresponding libs + # installed. + mycmakeargs=( + -DBUILD_SHARED_LIBS=OFF + -DLLVM_BUILD_RUNTIME=OFF + -DLLVM_INCLUDE_RUNTIME=OFF + -DLLVM_ENABLE_ASSERTIONS=ON + -DLLVM_ENABLE_BACKTRACES=ON + -DLLVM_LIT_ARGS=-v + ) + #Debug use flag? + #-DLLVM_ENABLE_ASSERTIONS=OFF + #-DLLVM_ENABLE_BACKTRACES=OFF + #Figure out how targets are set in cmake + #-DLLVM_TARGETS_TO_BUILD=host:cpp + tc-export CC CXX + cmake-utils_src_configure +} + +src_compile() { + cmake-utils_src_compile lld +} + +src_test() { + # This builds (most?) of llvm too. + cd "${BUILD_DIR}" + emake check-lld +} + +src_install() { + cd "${BUILD_DIR}"/tools/lld + emake DESTDIR="${D}" install +} diff --git a/app-arch/lld/metadata.xml b/app-arch/lld/metadata.xml new file mode 100644 index 00000000..a7a544ef --- /dev/null +++ b/app-arch/lld/metadata.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd"> +<pkgmetadata> + <longdescription lang="en"> + lld is a new set of modular code for creating linker tools. + </longdescription> +</pkgmetadata> + |
