summaryrefslogtreecommitdiffstats
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-04-04 14:04:16 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-04-04 14:04:16 +0000
commitccfe3cb3d63e0a8244d3d41d537c27363cacc750 (patch)
tree9bb810f41c31e90d6c37ec106f3ad5e16609e669 /lld/ELF/OutputSections.cpp
parenta9ac6d6cc225a25eb55c7edd8825780c44ee351e (diff)
downloadbcm5719-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.cpp34
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>
OpenPOWER on IntegriCloud