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