forked from OSchip/llvm-project
Split SymbolTableSection::writeGlobalSymbols.
Previously, we added garbage-collected symbols to the symbol table and filter them out when we were writing symbols to the file. In this patch, garbage-collected symbols are filtered out from beginning. llvm-svn: 261064
This commit is contained in:
parent
84047896b9
commit
874e7aee29
|
@ -1456,38 +1456,7 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
|
|||
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
|
||||
for (const std::pair<SymbolBody *, unsigned> &P : Symbols) {
|
||||
SymbolBody *Body = P.first;
|
||||
const OutputSectionBase<ELFT> *OutSec = nullptr;
|
||||
|
||||
switch (Body->kind()) {
|
||||
case SymbolBody::DefinedSyntheticKind:
|
||||
OutSec = &cast<DefinedSynthetic<ELFT>>(Body)->Section;
|
||||
break;
|
||||
case SymbolBody::DefinedRegularKind: {
|
||||
auto *Sym = cast<DefinedRegular<ELFT>>(Body->repl());
|
||||
if (InputSectionBase<ELFT> *Sec = Sym->Section) {
|
||||
if (!Sec->isLive())
|
||||
continue;
|
||||
OutSec = Sec->OutSec;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SymbolBody::DefinedCommonKind:
|
||||
OutSec = Out<ELFT>::Bss;
|
||||
break;
|
||||
case SymbolBody::SharedKind: {
|
||||
if (cast<SharedSymbol<ELFT>>(Body)->needsCopy())
|
||||
OutSec = Out<ELFT>::Bss;
|
||||
break;
|
||||
}
|
||||
case SymbolBody::UndefinedElfKind:
|
||||
case SymbolBody::UndefinedKind:
|
||||
case SymbolBody::LazyKind:
|
||||
break;
|
||||
case SymbolBody::DefinedBitcodeKind:
|
||||
llvm_unreachable("Should have been replaced");
|
||||
}
|
||||
|
||||
ESym->st_name = P.second;
|
||||
unsigned SymIdx = P.second;
|
||||
|
||||
unsigned char Type = STT_NOTYPE;
|
||||
uintX_t Size = 0;
|
||||
|
@ -1501,18 +1470,46 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
|
|||
|
||||
ESym->setBindingAndType(getSymbolBinding(Body), Type);
|
||||
ESym->st_size = Size;
|
||||
ESym->st_name = SymIdx;
|
||||
ESym->setVisibility(Body->getVisibility());
|
||||
ESym->st_value = Body->getVA<ELFT>();
|
||||
|
||||
if (OutSec)
|
||||
if (const OutputSectionBase<ELFT> *OutSec = getOutputSection(Body))
|
||||
ESym->st_shndx = OutSec->SectionIndex;
|
||||
else if (isa<DefinedRegular<ELFT>>(Body))
|
||||
ESym->st_shndx = SHN_ABS;
|
||||
|
||||
++ESym;
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
const OutputSectionBase<ELFT> *
|
||||
SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
|
||||
switch (Sym->kind()) {
|
||||
case SymbolBody::DefinedSyntheticKind:
|
||||
return &cast<DefinedSynthetic<ELFT>>(Sym)->Section;
|
||||
case SymbolBody::DefinedRegularKind: {
|
||||
auto *D = cast<DefinedRegular<ELFT>>(Sym->repl());
|
||||
if (D->Section)
|
||||
return D->Section->OutSec;
|
||||
break;
|
||||
}
|
||||
case SymbolBody::DefinedCommonKind:
|
||||
return Out<ELFT>::Bss;
|
||||
case SymbolBody::SharedKind:
|
||||
if (cast<SharedSymbol<ELFT>>(Sym)->needsCopy())
|
||||
return Out<ELFT>::Bss;
|
||||
break;
|
||||
case SymbolBody::UndefinedElfKind:
|
||||
case SymbolBody::UndefinedKind:
|
||||
case SymbolBody::LazyKind:
|
||||
break;
|
||||
case SymbolBody::DefinedBitcodeKind:
|
||||
llvm_unreachable("Should have been replaced");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
uint8_t SymbolTableSection<ELFT>::getSymbolBinding(SymbolBody *Body) {
|
||||
uint8_t Visibility = Body->getVisibility();
|
||||
|
|
|
@ -241,6 +241,7 @@ private:
|
|||
void writeLocalSymbols(uint8_t *&Buf);
|
||||
void writeGlobalSymbols(uint8_t *Buf);
|
||||
|
||||
const OutputSectionBase<ELFT> *getOutputSection(SymbolBody *Sym);
|
||||
static uint8_t getSymbolBinding(SymbolBody *Body);
|
||||
|
||||
SymbolTable<ELFT> &Table;
|
||||
|
|
|
@ -780,11 +780,14 @@ template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {
|
|||
if (!B.isUsedInRegularObj())
|
||||
return false;
|
||||
|
||||
// Don't include synthetic symbols like __init_array_start in every output.
|
||||
if (auto *U = dyn_cast<DefinedRegular<ELFT>>(&B))
|
||||
if (&U->Sym == &ElfSym<ELFT>::Ignored)
|
||||
if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&B)) {
|
||||
// Don't include synthetic symbols like __init_array_start in every output.
|
||||
if (&D->Sym == &ElfSym<ELFT>::Ignored)
|
||||
return false;
|
||||
|
||||
// Exclude symbols pointing to garbage-collected sections.
|
||||
if (D->Section && !D->Section->isLive())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue