forked from OSchip/llvm-project
[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:
parent
2483d8f4a7
commit
ab665fc475
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue