[ELF2] Determine the order of entries of symbol tables in the finalize() phase.

* Move the responsibility to call SymbolBody::setDynamicSymbolTableIndex()
  from the hash table to the dynamic symbol table.
* Hash table is not longer responsible for filling the dynamic symbol table.
* The final order of symbols of both symbol tables is set before writing
  phase starts.
* Remove repeaded scan of the symbol table during writting SymbolTableSection.

Differential Revision: http://reviews.llvm.org/D13911

llvm-svn: 250864
This commit is contained in:
Igor Kudrin 2015-10-20 21:47:58 +00:00
parent 2483d8f4a7
commit ab665fc475
3 changed files with 38 additions and 40 deletions

View File

@ -250,17 +250,9 @@ static uint32_t hash(StringRef Name) {
return H;
}
template <class ELFT> void HashTableSection<ELFT>::addSymbol(SymbolBody *S) {
StringRef Name = S->getName();
Out<ELFT>::DynSymTab->addSymbol(Name);
Hashes.push_back(hash(Name));
S->setDynamicSymbolTableIndex(Hashes.size());
}
template <class ELFT> void HashTableSection<ELFT>::finalize() {
this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex;
assert(Out<ELFT>::DynSymTab->getNumSymbols() == Hashes.size() + 1);
unsigned NumEntries = 2; // nbucket and nchain.
NumEntries += Out<ELFT>::DynSymTab->getNumSymbols(); // The chain entries.
@ -280,8 +272,10 @@ template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
Elf_Word *Buckets = P;
Elf_Word *Chains = P + NumSymbols;
for (unsigned I = 1; I < NumSymbols; ++I) {
uint32_t Hash = Hashes[I - 1] % NumSymbols;
for (SymbolBody *Body : Out<ELFT>::DynSymTab->getSymbols()) {
StringRef Name = Body->getName();
unsigned I = Body->getDynamicSymbolTableIndex();
uint32_t Hash = hash(Name) % NumSymbols;
Chains[I] = Buckets[Hash];
Buckets[Hash] = I;
}
@ -696,14 +690,32 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
this->Header.sh_size = getNumSymbols() * sizeof(Elf_Sym);
this->Header.sh_link = StrTabSec.SectionIndex;
this->Header.sh_info = NumLocals + 1;
if (!StrTabSec.isDynamic()) {
std::stable_sort(Symbols.begin(), Symbols.end(),
[](SymbolBody *L, SymbolBody *R) {
return getSymbolBinding(L) == STB_LOCAL &&
getSymbolBinding(R) != STB_LOCAL;
});
return;
}
size_t I = 0;
for (SymbolBody *Body : Symbols)
Body->setDynamicSymbolTableIndex(++I);
}
template <class ELFT>
void SymbolTableSection<ELFT>::addSymbol(StringRef Name, bool isLocal) {
void SymbolTableSection<ELFT>::addLocalSymbol(StringRef Name) {
StrTabSec.add(Name);
++NumVisible;
if (isLocal)
++NumLocals;
++NumLocals;
}
template <class ELFT>
void SymbolTableSection<ELFT>::addSymbol(SymbolBody *Body) {
StrTabSec.add(Body->getName());
Symbols.push_back(Body);
++NumVisible;
}
template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
@ -754,18 +766,9 @@ template <class ELFT>
void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
// Write the internal symbol table contents to the output symbol table
// pointed by Buf.
uint8_t *Start = Buf;
for (const std::pair<StringRef, Symbol *> &P : Table.getSymbols()) {
StringRef Name = P.first;
Symbol *Sym = P.second;
SymbolBody *Body = Sym->Body;
if (!includeInSymtab<ELFT>(*Body))
continue;
if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body))
continue;
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
Buf += sizeof(*ESym);
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
for (SymbolBody *Body : Symbols) {
StringRef Name = Body->getName();
ESym->st_name = StrTabSec.getFileOff(Name);
@ -809,13 +812,9 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
ESym->st_shndx = SHN_ABS;
else if (OutSec)
ESym->st_shndx = OutSec->SectionIndex;
++ESym;
}
if (!StrTabSec.isDynamic())
std::stable_sort(
reinterpret_cast<Elf_Sym *>(Start), reinterpret_cast<Elf_Sym *>(Buf),
[](const Elf_Sym &A, const Elf_Sym &B) -> bool {
return A.getBinding() == STB_LOCAL && B.getBinding() != STB_LOCAL;
});
}
template <class ELFT>

View File

@ -172,10 +172,13 @@ public:
void finalize() override;
void writeTo(uint8_t *Buf) override;
void addSymbol(StringRef Name, bool isLocal = false);
void addLocalSymbol(StringRef Name);
void addSymbol(SymbolBody *Body);
StringTableSection<ELFT> &getStrTabSec() const { return StrTabSec; }
unsigned getNumSymbols() const { return NumVisible + 1; }
ArrayRef<SymbolBody *> getSymbols() const { return Symbols; }
private:
void writeLocalSymbols(uint8_t *&Buf);
void writeGlobalSymbols(uint8_t *Buf);
@ -184,6 +187,7 @@ private:
SymbolTable<ELFT> &Table;
StringTableSection<ELFT> &StrTabSec;
std::vector<SymbolBody *> Symbols;
unsigned NumVisible = 0;
unsigned NumLocals = 0;
};
@ -275,12 +279,8 @@ class HashTableSection final : public OutputSectionBase<ELFT> {
public:
HashTableSection();
void addSymbol(SymbolBody *S);
void finalize() override;
void writeTo(uint8_t *Buf) override;
private:
std::vector<uint32_t> Hashes;
};
template <class ELFT>

View File

@ -282,7 +282,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
StringRef SymName = *SymNameOrErr;
if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))
continue;
Out<ELFT>::SymTab->addSymbol(SymName, true);
Out<ELFT>::SymTab->addLocalSymbol(SymName);
}
}
}
@ -498,7 +498,6 @@ template <class ELFT> void Writer<ELFT>::createSections() {
// FIXME: Try to avoid the extra walk over all global symbols.
std::vector<DefinedCommon<ELFT> *> CommonSymbols;
for (auto &P : Symtab.getSymbols()) {
StringRef Name = P.first;
SymbolBody *Body = P.second->Body;
if (auto *U = dyn_cast<Undefined<ELFT>>(Body))
if (!U->isWeak() && !U->canKeepUndefined())
@ -508,10 +507,10 @@ template <class ELFT> void Writer<ELFT>::createSections() {
CommonSymbols.push_back(C);
if (!includeInSymtab<ELFT>(*Body))
continue;
Out<ELFT>::SymTab->addSymbol(Name);
Out<ELFT>::SymTab->addSymbol(Body);
if (isOutputDynamic() && includeInDynamicSymtab(*Body))
Out<ELFT>::HashTab->addSymbol(Body);
Out<ELFT>::DynSymTab->addSymbol(Body);
}
addCommonSymbols(CommonSymbols);