summaryrefslogtreecommitdiff
path: root/app-arch/lld/files/patches-0/0010-Yay-symbol-table-indicies.patch
diff options
context:
space:
mode:
Diffstat (limited to 'app-arch/lld/files/patches-0/0010-Yay-symbol-table-indicies.patch')
-rw-r--r--app-arch/lld/files/patches-0/0010-Yay-symbol-table-indicies.patch288
1 files changed, 288 insertions, 0 deletions
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
+