diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-04-04 14:04:16 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-04-04 14:04:16 +0000 |
commit | ccfe3cb3d63e0a8244d3d41d537c27363cacc750 (patch) | |
tree | 9bb810f41c31e90d6c37ec106f3ad5e16609e669 /lld/ELF/OutputSections.cpp | |
parent | a9ac6d6cc225a25eb55c7edd8825780c44ee351e (diff) | |
download | bcm5719-llvm-ccfe3cb3d63e0a8244d3d41d537c27363cacc750.tar.gz bcm5719-llvm-ccfe3cb3d63e0a8244d3d41d537c27363cacc750.zip |
Don't store an Elf_Sym for most symbols.
Our symbol representation was redundant, and some times would get out of
sync. It had an Elf_Sym, but some fields were copied to SymbolBody.
Different parts of the code were checking the bits in SymbolBody and
others were checking Elf_Sym.
There are two general approaches to fix this:
* Copy the required information and don't store and Elf_Sym.
* Don't copy the information and always use the Elf_Smy.
The second way sounds tempting, but has a big problem: we would have to
template SymbolBody. I started doing it, but it requires templeting
*everything* and creates a bit chicken and egg problem at the driver
where we have to find ELFT before we can create an ArchiveFile for
example.
As much as possible I compared the test differences with what gold and
bfd produce to make sure they are still valid. In most cases we are just
adding hidden visibility to a local symbol, which is harmless.
In most tests this is a small speedup. The only slowdown was scylla
(1.006X). The largest speedup was clang with no --build-id, -O3 or
--gc-sections (i.e.: focus on the relocations): 1.019X.
llvm-svn: 265293
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r-- | lld/ELF/OutputSections.cpp | 34 |
1 files changed, 13 insertions, 21 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index b5aed1c2c0b..c019fa0f444 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1426,22 +1426,23 @@ 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 (const std::unique_ptr<ObjectFile<ELFT>> &File : Table.getObjectFiles()) { - for (const std::pair<const Elf_Sym *, size_t> &P : File->KeptLocalSyms) { - const Elf_Sym *Sym = P.first; - + 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 (Sym->st_shndx == SHN_ABS) { + + if (!Section) { ESym->st_shndx = SHN_ABS; - ESym->st_value = Sym->st_value; + ESym->st_value = Body.Value; } else { - InputSectionBase<ELFT> *Section = File->getSection(*Sym); const OutputSectionBase<ELFT> *OutSec = Section->OutSec; ESym->st_shndx = OutSec->SectionIndex; - ESym->st_value = OutSec->getVA() + Section->getOffset(*Sym); + ESym->st_value = OutSec->getVA() + Section->getOffset(Body); } ESym->st_name = P.second; - ESym->st_size = Sym->st_size; - ESym->setBindingAndType(Sym->getBinding(), Sym->getType()); + ESym->st_size = Body.template getSize<ELFT>(); + ESym->setBindingAndType(Body.Binding, Body.Type); Buf += sizeof(*ESym); } } @@ -1456,15 +1457,8 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) { SymbolBody *Body = P.first; size_t StrOff = P.second; - uint8_t Type = STT_NOTYPE; - uintX_t Size = 0; - if (const Elf_Sym *InputSym = Body->getElfSym<ELFT>()) { - Type = InputSym->getType(); - Size = InputSym->st_size; - } else if (auto *C = dyn_cast<DefinedCommon>(Body)) { - Type = STT_OBJECT; - Size = C->Size; - } + uint8_t Type = Body->Type; + uintX_t Size = Body->getSize<ELFT>(); ESym->setBindingAndType(getSymbolBinding(Body), Type); ESym->st_size = Size; @@ -1521,11 +1515,9 @@ uint8_t SymbolTableSection<ELFT>::getSymbolBinding(SymbolBody *Body) { uint8_t Visibility = Body->getVisibility(); if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) return STB_LOCAL; - if (const Elf_Sym *ESym = Body->getElfSym<ELFT>()) - return ESym->getBinding(); if (isa<DefinedSynthetic<ELFT>>(Body)) return STB_LOCAL; - return Body->isWeak() ? STB_WEAK : STB_GLOBAL; + return Body->Binding; } template <class ELFT> |