diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-02-01 21:35:17 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-02-01 21:35:17 +0000 |
commit | 63b9abd1dbe002d940a818f51dd9d6e585e41c84 (patch) | |
tree | 8f257c7b94b6320186de5cc06685fbc0b7e0a93f /ELF | |
parent | b025d011dd270230aeb50d7174a2a05616fe81eb (diff) |
Notes
Diffstat (limited to 'ELF')
-rw-r--r-- | ELF/InputFiles.h | 4 | ||||
-rw-r--r-- | ELF/InputSection.cpp | 3 | ||||
-rw-r--r-- | ELF/SyntheticSections.cpp | 76 | ||||
-rw-r--r-- | ELF/SyntheticSections.h | 13 | ||||
-rw-r--r-- | ELF/Writer.cpp | 12 |
5 files changed, 59 insertions, 49 deletions
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h index 73dda7b566b8..95888061d877 100644 --- a/ELF/InputFiles.h +++ b/ELF/InputFiles.h @@ -180,10 +180,6 @@ public: // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations. uint32_t MipsGp0 = 0; - // The number is the offset in the string table. It will be used as the - // st_name of the symbol. - std::vector<std::pair<const DefinedRegular<ELFT> *, unsigned>> KeptLocalSyms; - // Name of source file obtained from STT_FILE symbol value, // or empty string if there is no such symbol in object file // symbol table. diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp index 358004248373..6b1e92891b98 100644 --- a/ELF/InputSection.cpp +++ b/ELF/InputSection.cpp @@ -246,7 +246,8 @@ void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { if (Config->Rela) P->r_addend = getAddend<ELFT>(Rel); P->r_offset = RelocatedSection->getOffset(Rel.r_offset); - P->setSymbolAndType(Body.DynsymIndex, Type, Config->Mips64EL); + P->setSymbolAndType(In<ELFT>::SymTab->getSymbolIndex(&Body), Type, + Config->Mips64EL); } } diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp index f09b60b2b494..204b5993a62a 100644 --- a/ELF/SyntheticSections.cpp +++ b/ELF/SyntheticSections.cpp @@ -1065,22 +1065,21 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() { this->OutSec->Info = this->Info = NumLocals + 1; this->OutSec->Entsize = this->Entsize; - if (Config->Relocatable) { - size_t I = NumLocals; - for (const SymbolTableEntry &S : Symbols) - S.Symbol->DynsymIndex = ++I; + if (Config->Relocatable) return; - } if (!StrTabSec.isDynamic()) { - std::stable_sort( - Symbols.begin(), Symbols.end(), - [](const SymbolTableEntry &L, const SymbolTableEntry &R) { - return L.Symbol->symbol()->computeBinding() == STB_LOCAL && - R.Symbol->symbol()->computeBinding() != STB_LOCAL; + auto GlobBegin = Symbols.begin() + NumLocals; + auto It = std::stable_partition( + GlobBegin, Symbols.end(), [](const SymbolTableEntry &S) { + return S.Symbol->symbol()->computeBinding() == STB_LOCAL; }); + // update sh_info with number of Global symbols output with computed + // binding of STB_LOCAL + this->OutSec->Info = this->Info = 1 + It - Symbols.begin(); return; } + if (In<ELFT>::GnuHashTab) // NB: It also sorts Symbols to meet the GNU hash table requirements. In<ELFT>::GnuHashTab->addSymbols(Symbols); @@ -1094,10 +1093,25 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() { S.Symbol->DynsymIndex = ++I; } -template <class ELFT> void SymbolTableSection<ELFT>::addSymbol(SymbolBody *B) { +template <class ELFT> void SymbolTableSection<ELFT>::addGlobal(SymbolBody *B) { Symbols.push_back({B, StrTabSec.addString(B->getName(), false)}); } +template <class ELFT> void SymbolTableSection<ELFT>::addLocal(SymbolBody *B) { + assert(!StrTabSec.isDynamic()); + ++NumLocals; + Symbols.push_back({B, StrTabSec.addString(B->getName())}); +} + +template <class ELFT> +size_t SymbolTableSection<ELFT>::getSymbolIndex(SymbolBody *Body) { + auto I = llvm::find_if( + Symbols, [&](const SymbolTableEntry &E) { return E.Symbol == Body; }); + if (I == Symbols.end()) + return 0; + return I - Symbols.begin() + 1; +} + template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { Buf += sizeof(Elf_Sym); @@ -1113,26 +1127,24 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) { // Iterate over all input object files to copy their local symbols // to the output symbol table pointed by Buf. - for (ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) { - for (const std::pair<const DefinedRegular<ELFT> *, size_t> &P : - File->KeptLocalSyms) { - const DefinedRegular<ELFT> &Body = *P.first; - InputSectionBase<ELFT> *Section = Body.Section; - auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); - - if (!Section) { - ESym->st_shndx = SHN_ABS; - ESym->st_value = Body.Value; - } else { - const OutputSectionBase *OutSec = Section->OutSec; - ESym->st_shndx = OutSec->SectionIndex; - ESym->st_value = OutSec->Addr + Section->getOffset(Body); - } - ESym->st_name = P.second; - ESym->st_size = Body.template getSize<ELFT>(); - ESym->setBindingAndType(STB_LOCAL, Body.Type); - Buf += sizeof(*ESym); + + for (auto I = Symbols.begin(); I != Symbols.begin() + NumLocals; ++I) { + const DefinedRegular<ELFT> &Body = *cast<DefinedRegular<ELFT>>(I->Symbol); + InputSectionBase<ELFT> *Section = Body.Section; + auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); + + if (!Section) { + ESym->st_shndx = SHN_ABS; + ESym->st_value = Body.Value; + } else { + const OutputSectionBase *OutSec = Section->OutSec; + ESym->st_shndx = OutSec->SectionIndex; + ESym->st_value = OutSec->Addr + Section->getOffset(Body); } + ESym->st_name = I->StrTabOffset; + ESym->st_size = Body.template getSize<ELFT>(); + ESym->setBindingAndType(STB_LOCAL, Body.Type); + Buf += sizeof(*ESym); } } @@ -1141,7 +1153,9 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) { // Write the internal symbol table contents to the output symbol table // pointed by Buf. auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); - for (const SymbolTableEntry &S : Symbols) { + + for (auto I = Symbols.begin() + NumLocals; I != Symbols.end(); ++I) { + const SymbolTableEntry &S = *I; SymbolBody *Body = S.Symbol; size_t StrOff = S.StrTabOffset; diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h index f7e891ec3a66..df67e079ad0e 100644 --- a/ELF/SyntheticSections.h +++ b/ELF/SyntheticSections.h @@ -366,23 +366,26 @@ public: void finalize() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override { return getNumSymbols() * sizeof(Elf_Sym); } - void addSymbol(SymbolBody *Body); + void addGlobal(SymbolBody *Body); + void addLocal(SymbolBody *Body); StringTableSection<ELFT> &getStrTabSec() const { return StrTabSec; } - unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; } + unsigned getNumSymbols() const { return Symbols.size() + 1; } + size_t getSymbolIndex(SymbolBody *Body); ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; } static const OutputSectionBase *getOutputSection(SymbolBody *Sym); - unsigned NumLocals = 0; - StringTableSection<ELFT> &StrTabSec; - private: void writeLocalSymbols(uint8_t *&Buf); void writeGlobalSymbols(uint8_t *Buf); // A vector of symbols and their string table offsets. std::vector<SymbolTableEntry> Symbols; + + StringTableSection<ELFT> &StrTabSec; + + unsigned NumLocals = 0; }; // Outputs GNU Hash section. For detailed explanation see: diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp index 4f2f91993f8d..f00fb6d11ea5 100644 --- a/ELF/Writer.cpp +++ b/ELF/Writer.cpp @@ -455,11 +455,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { InputSectionBase<ELFT> *Sec = DR->Section; if (!shouldKeepInSymtab<ELFT>(Sec, B->getName(), *B)) continue; - ++In<ELFT>::SymTab->NumLocals; - if (Config->Relocatable) - B->DynsymIndex = In<ELFT>::SymTab->NumLocals; - F->KeptLocalSyms.push_back(std::make_pair( - DR, In<ELFT>::SymTab->StrTabSec.addString(B->getName()))); + In<ELFT>::SymTab->addLocal(B); } } } @@ -1024,10 +1020,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { if (!includeInSymtab<ELFT>(*Body)) continue; if (In<ELFT>::SymTab) - In<ELFT>::SymTab->addSymbol(Body); + In<ELFT>::SymTab->addGlobal(Body); if (In<ELFT>::DynSymTab && S->includeInDynsym()) { - In<ELFT>::DynSymTab->addSymbol(Body); + In<ELFT>::DynSymTab->addGlobal(Body); if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body)) if (SS->file()->isNeeded()) In<ELFT>::VerNeed->addSymbol(SS); @@ -1466,7 +1462,7 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() { // The glibc dynamic loader rounds the size down, so we need to round up // to protect the last page. This is a no-op on FreeBSD which always // rounds up. - P.p_memsz = alignTo(P.p_memsz, Config->MaxPageSize); + P.p_memsz = alignTo(P.p_memsz, Target->PageSize); } // The TLS pointer goes after PT_TLS. At least glibc will align it, |