[lld] r314495 - [ELF] Simpler scheme for handling common symbols
Ben Dunbobbin via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 29 02:08:26 PDT 2017
Author: bd1976llvm
Date: Fri Sep 29 02:08:26 2017
New Revision: 314495
URL: http://llvm.org/viewvc/llvm-project?rev=314495&view=rev
Log:
[ELF] Simpler scheme for handling common symbols
Convert all common symbols to regular symbols after scan.
This means that the downstream code does not to handle common symbols as a special case.
Differential Revision: https://reviews.llvm.org/D38137
Added:
lld/trunk/ELF/SyntheticSections.cpp~RF2791d30b.TMP
- copied, changed from r314440, lld/trunk/ELF/SyntheticSections.cpp
Modified:
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/MarkLive.cpp
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=314495&r1=314494&r2=314495&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Sep 29 02:08:26 2017
@@ -1086,6 +1086,14 @@ template <class ELFT> void LinkerDriver:
if (!Config->Relocatable)
InputSections.push_back(createCommentSection<ELFT>());
+ // Create a .bss section for each common symbol and then replace the common
+ // symbol with a DefinedRegular symbol. As a result, all common symbols are
+ // "instantiated" as regular defined symbols, so that we don't need to care
+ // about common symbols beyond this point. Note that if -r is given, we just
+ // need to pass through common symbols as-is.
+ if (Config->DefineCommon)
+ createCommonSections<ELFT>();
+
// Do size optimizations: garbage collection, merging of SHF_MERGE sections
// and identical code folding.
if (Config->GcSections)
Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=314495&r1=314494&r2=314495&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Fri Sep 29 02:08:26 2017
@@ -64,11 +64,6 @@ static void resolveReloc(InputSectionBas
std::function<void(InputSectionBase *, uint64_t)> Fn) {
SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
- if (auto *Sym = dyn_cast<DefinedCommon>(&B)) {
- Sym->Live = true;
- return;
- }
-
if (auto *D = dyn_cast<DefinedRegular>(&B)) {
if (!D->Section)
return;
@@ -223,13 +218,9 @@ template <class ELFT> void elf::markLive
};
auto MarkSymbol = [&](SymbolBody *Sym) {
- if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym)) {
+ if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
Enqueue(IS, D->Value);
- return;
- }
- if (auto *S = dyn_cast_or_null<DefinedCommon>(Sym))
- S->Live = true;
};
// Add GC root symbols.
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=314495&r1=314494&r2=314495&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Fri Sep 29 02:08:26 2017
@@ -99,14 +99,8 @@ static uint64_t getSymVA(const SymbolBod
}
return VA;
}
- case SymbolBody::DefinedCommonKind: {
- if (!Config->DefineCommon)
- return 0;
- auto DC = cast<DefinedCommon>(Body);
- if (!DC.Live)
- return 0;
- return DC.Section->getParent()->Addr + DC.Section->OutSecOff;
- }
+ case SymbolBody::DefinedCommonKind:
+ llvm_unreachable("common are converted to bss");
case SymbolBody::SharedKind: {
auto &SS = cast<SharedSymbol>(Body);
if (SS.CopyRelSec)
@@ -286,7 +280,7 @@ DefinedCommon::DefinedCommon(StringRef N
uint8_t StOther, uint8_t Type)
: Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
Type),
- Live(!Config->GcSections), Alignment(Alignment), Size(Size) {}
+ Alignment(Alignment), Size(Size) {}
// If a shared symbol is referred via a copy relocation, its alignment
// becomes part of the ABI. This function returns a symbol alignment.
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=314495&r1=314494&r2=314495&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Sep 29 02:08:26 2017
@@ -167,11 +167,6 @@ public:
return S->kind() == SymbolBody::DefinedCommonKind;
}
- // True if this symbol is not GC'ed. Liveness is usually a notion of
- // input sections and not of symbols, but since common symbols don't
- // belong to any input section, their liveness is managed by this bit.
- bool Live;
-
// The maximum alignment we have seen for this symbol.
uint32_t Alignment;
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=314495&r1=314494&r2=314495&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Sep 29 02:08:26 2017
@@ -54,24 +54,28 @@ uint64_t SyntheticSection::getVA() const
return 0;
}
-std::vector<InputSection *> elf::createCommonSections() {
- if (!Config->DefineCommon)
- return {};
-
- std::vector<InputSection *> Ret;
+// Create a .bss section for each common section and replace the common symbol
+// with a DefinedRegular symbol.
+template <class ELFT> void elf::createCommonSections() {
for (Symbol *S : Symtab->getSymbols()) {
auto *Sym = dyn_cast<DefinedCommon>(S->body());
- if (!Sym || !Sym->Live)
+
+ if (!Sym)
continue;
- Sym->Section = make<BssSection>("COMMON");
- size_t Pos = Sym->Section->reserveSpace(Sym->Size, Sym->Alignment);
- assert(Pos == 0);
- (void)Pos;
- Sym->Section->File = Sym->getFile();
- Ret.push_back(Sym->Section);
+ // Create a synthetic section for the common data.
+ auto *Section = make<BssSection>("COMMON");
+ Section->File = Sym->getFile();
+ Section->Live = !Config->GcSections;
+ Section->reserveSpace(Sym->Size, Sym->Alignment);
+ InputSections.push_back(Section);
+
+ // Replace all DefinedCommon symbols with DefinedRegular symbols so that we
+ // don't have to care about DefinedCommon symbols beyond this point.
+ replaceBody<DefinedRegular>(S, Sym->getFile(), Sym->getName(),
+ static_cast<bool>(Sym->IsLocal), Sym->StOther,
+ Sym->Type, 0, Sym->getSize<ELFT>(), Section);
}
- return Ret;
}
// Returns an LLD version string.
@@ -2378,6 +2382,11 @@ template void PltSection::addEntry<ELF32
template void PltSection::addEntry<ELF64LE>(SymbolBody &Sym);
template void PltSection::addEntry<ELF64BE>(SymbolBody &Sym);
+template void elf::createCommonSections<ELF32LE>();
+template void elf::createCommonSections<ELF32BE>();
+template void elf::createCommonSections<ELF64LE>();
+template void elf::createCommonSections<ELF64BE>();
+
template MergeInputSection *elf::createCommentSection<ELF32LE>();
template MergeInputSection *elf::createCommentSection<ELF32BE>();
template MergeInputSection *elf::createCommentSection<ELF64LE>();
Copied: lld/trunk/ELF/SyntheticSections.cpp~RF2791d30b.TMP (from r314440, lld/trunk/ELF/SyntheticSections.cpp)
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp%7ERF2791d30b.TMP?p2=lld/trunk/ELF/SyntheticSections.cpp%7ERF2791d30b.TMP&p1=lld/trunk/ELF/SyntheticSections.cpp&r1=314440&r2=314495&rev=314495&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp~RF2791d30b.TMP Fri Sep 29 02:08:26 2017
@@ -54,24 +54,28 @@ uint64_t SyntheticSection::getVA() const
return 0;
}
-std::vector<InputSection *> elf::createCommonSections() {
- if (!Config->DefineCommon)
- return {};
-
- std::vector<InputSection *> Ret;
+// Create a .bss section for each common section and replace the common symbol
+// with a DefinedRegular symbol.
+template <class ELFT> void elf::createCommonSections() {
for (Symbol *S : Symtab->getSymbols()) {
auto *Sym = dyn_cast<DefinedCommon>(S->body());
- if (!Sym || !Sym->Live)
+
+ if (!Sym)
continue;
- Sym->Section = make<BssSection>("COMMON");
- size_t Pos = Sym->Section->reserveSpace(Sym->Size, Sym->Alignment);
- assert(Pos == 0);
- (void)Pos;
- Sym->Section->File = Sym->getFile();
- Ret.push_back(Sym->Section);
+ // Create a synthetic section for the common data.
+ auto *Section = make<BssSection>("COMMON");
+ Section->File = Sym->getFile();
+ Section->Live = !Config->GcSections;
+ Section->reserveSpace(Sym->Size, Sym->Alignment);
+ InputSections.push_back(Section);
+
+ // Replace all DefinedCommon symbols with DefinedRegular symbols so that we
+ // don't have to care about DefinedCommon symbols beyond this point.
+ replaceBody<DefinedRegular>(S, Sym->getFile(), Sym->getName(), Sym->IsLocal,
+ Sym->StOther, Sym->Type, 0,
+ Sym->getSize<ELFT>(), Section);
}
- return Ret;
}
// Returns an LLD version string.
@@ -1119,8 +1123,8 @@ template <class ELFT> void DynamicSectio
add({DT_TEXTREL, (uint64_t)0});
if (InX::GnuHashTab)
add({DT_GNU_HASH, InX::GnuHashTab});
- if (InX::HashTab)
- add({DT_HASH, InX::HashTab});
+ if (In<ELFT>::HashTab)
+ add({DT_HASH, In<ELFT>::HashTab});
if (Out::PreinitArray) {
add({DT_PREINIT_ARRAY, Out::PreinitArray});
@@ -1355,24 +1359,18 @@ void SymbolTableBaseSection::addSymbol(S
}
size_t SymbolTableBaseSection::getSymbolIndex(SymbolBody *Body) {
- // Initializes symbol lookup tables lazily. This is used only
- // for -r or -emit-relocs.
- llvm::call_once(OnceFlag, [&] {
- SymbolIndexMap.reserve(Symbols.size());
- size_t I = 0;
- for (const SymbolTableEntry &E : Symbols) {
- if (E.Symbol->Type == STT_SECTION)
- SectionIndexMap[E.Symbol->getOutputSection()] = ++I;
- else
- SymbolIndexMap[E.Symbol] = ++I;
- }
+ auto I = llvm::find_if(Symbols, [&](const SymbolTableEntry &E) {
+ if (E.Symbol == Body)
+ return true;
+ // This is used for -r, so we have to handle multiple section
+ // symbols being combined.
+ if (Body->Type == STT_SECTION && E.Symbol->Type == STT_SECTION)
+ return Body->getOutputSection() == E.Symbol->getOutputSection();
+ return false;
});
-
- // Section symbols are mapped based on their output sections
- // to maintain their semantics.
- if (Body->Type == STT_SECTION)
- return SectionIndexMap.lookup(Body->getOutputSection());
- return SymbolIndexMap.lookup(Body);
+ if (I == Symbols.end())
+ return 0;
+ return I - Symbols.begin() + 1;
}
template <class ELFT>
@@ -1612,12 +1610,13 @@ void GnuHashTableSection::addSymbols(std
V.push_back({Ent.Body, Ent.StrTabOffset});
}
-HashTableSection::HashTableSection()
+template <class ELFT>
+HashTableSection<ELFT>::HashTableSection()
: SyntheticSection(SHF_ALLOC, SHT_HASH, 4, ".hash") {
this->Entsize = 4;
}
-void HashTableSection::finalizeContents() {
+template <class ELFT> void HashTableSection<ELFT>::finalizeContents() {
getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
unsigned NumEntries = 2; // nbucket and nchain.
@@ -1630,15 +1629,18 @@ void HashTableSection::finalizeContents(
this->Size = NumEntries * 4;
}
-void HashTableSection::writeTo(uint8_t *Buf) {
+template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
+ // A 32-bit integer type in the target endianness.
+ typedef typename ELFT::Word Elf_Word;
+
unsigned NumSymbols = InX::DynSymTab->getNumSymbols();
- uint32_t *P = reinterpret_cast<uint32_t *>(Buf);
- write32(P++, NumSymbols, Config->Endianness); // nbucket
- write32(P++, NumSymbols, Config->Endianness); // nchain
+ auto *P = reinterpret_cast<Elf_Word *>(Buf);
+ *P++ = NumSymbols; // nbucket
+ *P++ = NumSymbols; // nchain
- uint32_t *Buckets = P;
- uint32_t *Chains = P + NumSymbols;
+ Elf_Word *Buckets = P;
+ Elf_Word *Chains = P + NumSymbols;
for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {
SymbolBody *Body = S.Symbol;
@@ -1646,7 +1648,7 @@ void HashTableSection::writeTo(uint8_t *
unsigned I = Body->DynsymIndex;
uint32_t Hash = hashSysV(Name) % NumSymbols;
Chains[I] = Buckets[Hash];
- write32(Buckets + Hash, I, Config->Endianness);
+ Buckets[Hash] = I;
}
}
@@ -2187,11 +2189,13 @@ void MergeSyntheticSection::addSection(M
Sections.push_back(MS);
}
-size_t MergeSyntheticSection::getSize() const { return Builder.getSize(); }
-
void MergeSyntheticSection::writeTo(uint8_t *Buf) { Builder.write(Buf); }
-void MergeTailSection::finalizeContents() {
+bool MergeSyntheticSection::shouldTailMerge() const {
+ return (this->Flags & SHF_STRINGS) && Config->Optimize >= 2;
+}
+
+void MergeSyntheticSection::finalizeTailMerge() {
// Add all string pieces to the string table builder to create section
// contents.
for (MergeInputSection *Sec : Sections)
@@ -2211,7 +2215,7 @@ void MergeTailSection::finalizeContents(
Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I));
}
-void MergeNoTailSection::finalizeContents() {
+void MergeSyntheticSection::finalizeNoTailMerge() {
// Add all string pieces to the string table builder to create section
// contents. Because we are not tail-optimizing, offsets of strings are
// fixed when they are added to the builder (string table builder contains
@@ -2224,16 +2228,15 @@ void MergeNoTailSection::finalizeContent
Builder.finalizeInOrder();
}
-static MergeSyntheticSection *createMergeSynthetic(StringRef Name,
- uint32_t Type,
- uint64_t Flags,
- uint32_t Alignment) {
- bool ShouldTailMerge = (Flags & SHF_STRINGS) && Config->Optimize >= 2;
- if (ShouldTailMerge)
- return make<MergeTailSection>(Name, Type, Flags, Alignment);
- return make<MergeNoTailSection>(Name, Type, Flags, Alignment);
+void MergeSyntheticSection::finalizeContents() {
+ if (shouldTailMerge())
+ finalizeTailMerge();
+ else
+ finalizeNoTailMerge();
}
+size_t MergeSyntheticSection::getSize() const { return Builder.getSize(); }
+
// This function decompresses compressed sections and scans over the input
// sections to create mergeable synthetic sections. It removes
// MergeInputSections from the input section array and adds new synthetic
@@ -2271,8 +2274,8 @@ void elf::decompressAndMergeSections() {
Sec->Alignment == Alignment;
});
if (I == MergeSections.end()) {
- MergeSyntheticSection *Syn =
- createMergeSynthetic(OutsecName, MS->Type, MS->Flags, Alignment);
+ MergeSyntheticSection *Syn = make<MergeSyntheticSection>(
+ OutsecName, MS->Type, MS->Flags, Alignment);
MergeSections.push_back(Syn);
I = std::prev(MergeSections.end());
S = Syn;
@@ -2358,7 +2361,6 @@ GdbIndexSection *InX::GdbIndex;
GotSection *InX::Got;
GotPltSection *InX::GotPlt;
GnuHashTableSection *InX::GnuHashTab;
-HashTableSection *InX::HashTab;
IgotPltSection *InX::IgotPlt;
MipsGotSection *InX::MipsGot;
MipsRldMapSection *InX::MipsRldMap;
@@ -2378,6 +2380,11 @@ template void PltSection::addEntry<ELF32
template void PltSection::addEntry<ELF64LE>(SymbolBody &Sym);
template void PltSection::addEntry<ELF64BE>(SymbolBody &Sym);
+template void elf::createCommonSections<ELF32LE>();
+template void elf::createCommonSections<ELF32BE>();
+template void elf::createCommonSections<ELF64LE>();
+template void elf::createCommonSections<ELF64BE>();
+
template MergeInputSection *elf::createCommentSection<ELF32LE>();
template MergeInputSection *elf::createCommentSection<ELF32BE>();
template MergeInputSection *elf::createCommentSection<ELF64LE>();
@@ -2413,6 +2420,11 @@ template class elf::SymbolTableSection<E
template class elf::SymbolTableSection<ELF64LE>;
template class elf::SymbolTableSection<ELF64BE>;
+template class elf::HashTableSection<ELF32LE>;
+template class elf::HashTableSection<ELF32BE>;
+template class elf::HashTableSection<ELF64LE>;
+template class elf::HashTableSection<ELF64BE>;
+
template class elf::EhFrameHeader<ELF32LE>;
template class elf::EhFrameHeader<ELF32BE>;
template class elf::EhFrameHeader<ELF64LE>;
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=314495&r1=314494&r2=314495&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Fri Sep 29 02:08:26 2017
@@ -786,7 +786,7 @@ private:
size_t Size = 0;
};
-std::vector<InputSection *> createCommonSections();
+template <class ELFT> void createCommonSections();
InputSection *createInterpSection();
template <class ELFT> MergeInputSection *createCommentSection();
void decompressAndMergeSections();
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=314495&r1=314494&r2=314495&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Sep 29 02:08:26 2017
@@ -290,9 +290,6 @@ template <class ELFT> void Writer<ELFT>:
Add(InX::BuildId);
}
- for (InputSection *S : createCommonSections())
- Add(S);
-
InX::Bss = make<BssSection>(".bss");
Add(InX::Bss);
InX::BssRelRo = make<BssSection>(".bss.rel.ro");
@@ -441,11 +438,7 @@ static bool includeInSymtab(const Symbol
if (auto *S = dyn_cast<MergeInputSection>(Sec))
if (!S->getSectionPiece(D->Value)->Live)
return false;
- return true;
}
-
- if (auto *Sym = dyn_cast<DefinedCommon>(&B))
- return Sym->Live;
return true;
}
More information about the llvm-commits
mailing list