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
This commit is contained in:
Rui Ueyama 2016-07-28 21:05:04 +00:00
parent 3d32b7ed0d
commit ad10c3d8d4
5 changed files with 24 additions and 26 deletions

View File

@ -667,17 +667,9 @@ bool MipsOptionsInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
return S->SectionKind == InputSectionBase<ELFT>::MipsOptions; 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> template <class ELFT>
CommonInputSection<ELFT>::CommonInputSection() CommonInputSection<ELFT>::CommonInputSection()
: InputSection<ELFT>(nullptr, zero(&Hdr)) { : InputSection<ELFT>(nullptr, &Hdr) {
std::vector<DefinedCommon<ELFT> *> Symbols; std::vector<DefinedCommon<ELFT> *> Symbols;
Hdr.sh_size = 0; Hdr.sh_size = 0;
Hdr.sh_type = SHT_NOBITS; Hdr.sh_type = SHT_NOBITS;

View File

@ -257,17 +257,26 @@ public:
const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo = nullptr; 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> { template <class ELFT> class CommonInputSection : public InputSection<ELFT> {
typedef typename ELFT::uint uintX_t; typedef typename ELFT::uint uintX_t;
public: public:
CommonInputSection(); CommonInputSection();
// The singleton instance of this class.
static CommonInputSection<ELFT> *X;
private: 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 elf
} // namespace lld } // namespace lld

View File

@ -95,8 +95,7 @@ LinkerScript<ELFT>::getSectionMap() {
// Returns input sections filtered by given glob patterns. // Returns input sections filtered by given glob patterns.
template <class ELFT> template <class ELFT>
std::vector<InputSectionBase<ELFT> *> std::vector<InputSectionBase<ELFT> *>
LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I, LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) {
CommonInputSection<ELFT> *Common) {
ArrayRef<StringRef> Patterns = I->Patterns; ArrayRef<StringRef> Patterns = I->Patterns;
ArrayRef<StringRef> ExcludedFiles = I->ExcludedFiles; ArrayRef<StringRef> ExcludedFiles = I->ExcludedFiles;
std::vector<InputSectionBase<ELFT> *> Ret; std::vector<InputSectionBase<ELFT> *> Ret;
@ -109,15 +108,14 @@ LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I,
Ret.push_back(S); Ret.push_back(S);
if ((llvm::find(Patterns, "COMMON") != Patterns.end())) if ((llvm::find(Patterns, "COMMON") != Patterns.end()))
Ret.push_back(Common); Ret.push_back(CommonInputSection<ELFT>::X);
return Ret; return Ret;
} }
template <class ELFT> template <class ELFT>
std::vector<OutputSectionBase<ELFT> *> std::vector<OutputSectionBase<ELFT> *>
LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory, LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
CommonInputSection<ELFT> *Common) {
std::vector<OutputSectionBase<ELFT> *> Ret; std::vector<OutputSectionBase<ELFT> *> Ret;
// Add input section to output section. If there is no output section yet, // Add input section to output section. If there is no output section yet,
@ -134,7 +132,7 @@ LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory,
for (auto &P : getSectionMap()) { for (auto &P : getSectionMap()) {
StringRef OutputName = P.first; StringRef OutputName = P.first;
const InputSectionDescription *I = P.second; const InputSectionDescription *I = P.second;
for (InputSectionBase<ELFT> *S : getInputSections(I, Common)) { for (InputSectionBase<ELFT> *S : getInputSections(I)) {
if (OutputName == "/DISCARD/") { if (OutputName == "/DISCARD/") {
S->Live = false; S->Live = false;
reportDiscarded(S); reportDiscarded(S);

View File

@ -24,7 +24,6 @@ template <class ELFT> class InputSectionBase;
template <class ELFT> class OutputSectionBase; template <class ELFT> class OutputSectionBase;
template <class ELFT> class OutputSectionFactory; template <class ELFT> class OutputSectionFactory;
template <class ELFT> class DefinedCommon; template <class ELFT> class DefinedCommon;
template <class ELFT> class CommonInputSection;
typedef std::function<uint64_t(uint64_t)> Expr; typedef std::function<uint64_t(uint64_t)> Expr;
@ -122,8 +121,7 @@ template <class ELFT> class LinkerScript {
public: public:
std::vector<OutputSectionBase<ELFT> *> std::vector<OutputSectionBase<ELFT> *>
createSections(OutputSectionFactory<ELFT> &Factory, createSections(OutputSectionFactory<ELFT> &Factory);
CommonInputSection<ELFT> *Common);
std::vector<PhdrEntry<ELFT>> std::vector<PhdrEntry<ELFT>>
createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> S); createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> S);
@ -140,7 +138,7 @@ private:
getSectionMap(); getSectionMap();
std::vector<InputSectionBase<ELFT> *> 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. // "ScriptConfig" is a bit too long, so define a short name for it.
ScriptConfiguration &Opt = *ScriptConfig; ScriptConfiguration &Opt = *ScriptConfig;

View File

@ -72,7 +72,6 @@ private:
BumpPtrAllocator Alloc; BumpPtrAllocator Alloc;
std::vector<OutputSectionBase<ELFT> *> OutputSections; std::vector<OutputSectionBase<ELFT> *> OutputSections;
std::unique_ptr<CommonInputSection<ELFT>> CommonSection;
OutputSectionFactory<ELFT> Factory; OutputSectionFactory<ELFT> Factory;
void addRelIpltSymbols(); void addRelIpltSymbols();
@ -222,10 +221,12 @@ template <class ELFT> void Writer<ELFT>::run() {
copyLocalSymbols(); copyLocalSymbols();
addReservedSymbols(); addReservedSymbols();
CommonSection = llvm::make_unique<CommonInputSection<ELFT>>(); CommonInputSection<ELFT> Common;
CommonInputSection<ELFT>::X = &Common;
OutputSections = OutputSections =
ScriptConfig->DoLayout ScriptConfig->DoLayout
? Script<ELFT>::X->createSections(Factory, CommonSection.get()) ? Script<ELFT>::X->createSections(Factory)
: createSections(); : createSections();
finalizeSections(); finalizeSections();
if (HasError) if (HasError)
@ -738,8 +739,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// If linker script processor hasn't added common symbol section yet, // If linker script processor hasn't added common symbol section yet,
// then add it to .bss now. // then add it to .bss now.
if (!CommonSection->OutSec) { if (!CommonInputSection<ELFT>::X->OutSec) {
Out<ELFT>::Bss->addSection(CommonSection.get()); Out<ELFT>::Bss->addSection(CommonInputSection<ELFT>::X);
Out<ELFT>::Bss->assignOffsets(); Out<ELFT>::Bss->assignOffsets();
} }