summaryrefslogtreecommitdiff
path: root/app-arch
diff options
context:
space:
mode:
Diffstat (limited to 'app-arch')
-rw-r--r--app-arch/lld/Manifest15
-rw-r--r--app-arch/lld/files/patches-0/0001-Kinda-sorta-write-out-dynamic-stuff.patch404
-rw-r--r--app-arch/lld/files/patches-0/0002-SharedLibraryAtom-symbolness.patch27
-rw-r--r--app-arch/lld/files/patches-0/0003-Driver-GNULD-Default-to-dynamic.patch30
-rw-r--r--app-arch/lld/files/patches-0/0004-ELF-Writer-Valid-dynamic-symbol-table.patch269
-rw-r--r--app-arch/lld/files/patches-0/0005-ELF-Writer-Add-dynamic-table-entries-and-interp-sect.patch233
-rw-r--r--app-arch/lld/files/patches-0/0006-ELF-Writer-Fix-interp-phdr.patch40
-rw-r--r--app-arch/lld/files/patches-0/0007-PHDR.patch58
-rw-r--r--app-arch/lld/files/patches-0/0008-Correct-alignment.patch25
-rw-r--r--app-arch/lld/files/patches-0/0009-Make-ldd-happy.patch109
-rw-r--r--app-arch/lld/files/patches-0/0010-Yay-symbol-table-indicies.patch288
-rw-r--r--app-arch/lld/files/patches-0/0011-More-correct-dynamic-plt.patch164
-rw-r--r--app-arch/lld/files/patches-0/0012-ELF-Writer-Dynamic-function-binding-works.patch373
-rw-r--r--app-arch/lld/files/patches-0/0013-ELF-Writer-Handle-non-pie-object-files-when-dynamic-.patch105
-rw-r--r--app-arch/lld/lld-9999.ebuild85
-rw-r--r--app-arch/lld/metadata.xml8
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>
+