Make CommonInputSection singleton class.
All other singleton instances are accessible globally.
CommonInputSection shouldn't be an exception.
Differential Revision: https://reviews.llvm.org/D22935
llvm-svn: 277034
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 2529cbd..557d0c0 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -667,17 +667,9 @@
return S->SectionKind == InputSectionBase<ELFT>::MipsOptions;
}
-// Due to initialization order in C++ memberwise initialization or
-// construction is invoked after base class construction. This helper
-// function is needed to zero initialize Elf_Shdr, before passing it
-// to InputSection<ELFT> constructor
-template <class T> static T *zero(T *Val) {
- return static_cast<T *>(memset(Val, 0, sizeof(*Val)));
-}
-
template <class ELFT>
CommonInputSection<ELFT>::CommonInputSection()
- : InputSection<ELFT>(nullptr, zero(&Hdr)) {
+ : InputSection<ELFT>(nullptr, &Hdr) {
std::vector<DefinedCommon<ELFT> *> Symbols;
Hdr.sh_size = 0;
Hdr.sh_type = SHT_NOBITS;
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 7688950..09c87ca 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -257,17 +257,26 @@
const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo = nullptr;
};
-// A special kind of section used to store common symbols
+// Common symbols don't belong to any section. But it is easier for us
+// to handle them as if they belong to some input section. So we defined
+// this class. CommonInputSection is a virtual singleton class that
+// "contains" all common symbols.
template <class ELFT> class CommonInputSection : public InputSection<ELFT> {
typedef typename ELFT::uint uintX_t;
public:
CommonInputSection();
+ // The singleton instance of this class.
+ static CommonInputSection<ELFT> *X;
+
private:
- typename ELFT::Shdr Hdr;
+ static typename ELFT::Shdr Hdr;
};
+template <class ELFT> CommonInputSection<ELFT> *CommonInputSection<ELFT>::X;
+template <class ELFT> typename ELFT::Shdr CommonInputSection<ELFT>::Hdr;
+
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 36c8689..8642153 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -95,8 +95,7 @@
// Returns input sections filtered by given glob patterns.
template <class ELFT>
std::vector<InputSectionBase<ELFT> *>
-LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I,
- CommonInputSection<ELFT> *Common) {
+LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) {
ArrayRef<StringRef> Patterns = I->Patterns;
ArrayRef<StringRef> ExcludedFiles = I->ExcludedFiles;
std::vector<InputSectionBase<ELFT> *> Ret;
@@ -109,15 +108,14 @@
Ret.push_back(S);
if ((llvm::find(Patterns, "COMMON") != Patterns.end()))
- Ret.push_back(Common);
+ Ret.push_back(CommonInputSection<ELFT>::X);
return Ret;
}
template <class ELFT>
std::vector<OutputSectionBase<ELFT> *>
-LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory,
- CommonInputSection<ELFT> *Common) {
+LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
std::vector<OutputSectionBase<ELFT> *> Ret;
// Add input section to output section. If there is no output section yet,
@@ -134,7 +132,7 @@
for (auto &P : getSectionMap()) {
StringRef OutputName = P.first;
const InputSectionDescription *I = P.second;
- for (InputSectionBase<ELFT> *S : getInputSections(I, Common)) {
+ for (InputSectionBase<ELFT> *S : getInputSections(I)) {
if (OutputName == "/DISCARD/") {
S->Live = false;
reportDiscarded(S);
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 64f6856..103be68 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -24,7 +24,6 @@
template <class ELFT> class OutputSectionBase;
template <class ELFT> class OutputSectionFactory;
template <class ELFT> class DefinedCommon;
-template <class ELFT> class CommonInputSection;
typedef std::function<uint64_t(uint64_t)> Expr;
@@ -122,8 +121,7 @@
public:
std::vector<OutputSectionBase<ELFT> *>
- createSections(OutputSectionFactory<ELFT> &Factory,
- CommonInputSection<ELFT> *Common);
+ createSections(OutputSectionFactory<ELFT> &Factory);
std::vector<PhdrEntry<ELFT>>
createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> S);
@@ -140,7 +138,7 @@
getSectionMap();
std::vector<InputSectionBase<ELFT> *>
- getInputSections(const InputSectionDescription *, CommonInputSection<ELFT> *);
+ getInputSections(const InputSectionDescription *);
// "ScriptConfig" is a bit too long, so define a short name for it.
ScriptConfiguration &Opt = *ScriptConfig;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index f8209e0..6816946 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -72,7 +72,6 @@
BumpPtrAllocator Alloc;
std::vector<OutputSectionBase<ELFT> *> OutputSections;
- std::unique_ptr<CommonInputSection<ELFT>> CommonSection;
OutputSectionFactory<ELFT> Factory;
void addRelIpltSymbols();
@@ -222,10 +221,12 @@
copyLocalSymbols();
addReservedSymbols();
- CommonSection = llvm::make_unique<CommonInputSection<ELFT>>();
+ CommonInputSection<ELFT> Common;
+ CommonInputSection<ELFT>::X = &Common;
+
OutputSections =
ScriptConfig->DoLayout
- ? Script<ELFT>::X->createSections(Factory, CommonSection.get())
+ ? Script<ELFT>::X->createSections(Factory)
: createSections();
finalizeSections();
if (HasError)
@@ -738,8 +739,8 @@
// If linker script processor hasn't added common symbol section yet,
// then add it to .bss now.
- if (!CommonSection->OutSec) {
- Out<ELFT>::Bss->addSection(CommonSection.get());
+ if (!CommonInputSection<ELFT>::X->OutSec) {
+ Out<ELFT>::Bss->addSection(CommonInputSection<ELFT>::X);
Out<ELFT>::Bss->assignOffsets();
}