summaryrefslogtreecommitdiffstats
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r--lld/ELF/InputSection.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 7ac25bca43c..2529cbd1c8b 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -14,6 +14,7 @@
#include "InputFiles.h"
#include "LinkerScript.h"
#include "OutputSections.h"
+#include "SymbolTable.h"
#include "Target.h"
#include "Thunks.h"
@@ -666,6 +667,44 @@ bool MipsOptionsInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
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)) {
+ std::vector<DefinedCommon<ELFT> *> Symbols;
+ Hdr.sh_size = 0;
+ Hdr.sh_type = SHT_NOBITS;
+ Hdr.sh_flags = SHF_ALLOC | SHF_WRITE;
+ this->Live = true;
+
+ for (Symbol *S : Symtab<ELFT>::X->getSymbols())
+ if (auto *C = dyn_cast<DefinedCommon<ELFT>>(S->body()))
+ Symbols.push_back(C);
+
+ std::stable_sort(
+ Symbols.begin(), Symbols.end(),
+ [](const DefinedCommon<ELFT> *A, const DefinedCommon<ELFT> *B) {
+ return A->Alignment > B->Alignment;
+ });
+
+ for (DefinedCommon<ELFT> *C : Symbols) {
+ this->Alignment = std::max<uintX_t>(this->Alignment, C->Alignment);
+ Hdr.sh_size = alignTo(Hdr.sh_size, C->Alignment);
+
+ // Compute symbol offset relative to beginning of input section.
+ C->Offset = Hdr.sh_size;
+ C->Section = this;
+ Hdr.sh_size += C->Size;
+ }
+}
+
template class elf::InputSectionBase<ELF32LE>;
template class elf::InputSectionBase<ELF32BE>;
template class elf::InputSectionBase<ELF64LE>;
@@ -695,3 +734,8 @@ template class elf::MipsOptionsInputSection<ELF32LE>;
template class elf::MipsOptionsInputSection<ELF32BE>;
template class elf::MipsOptionsInputSection<ELF64LE>;
template class elf::MipsOptionsInputSection<ELF64BE>;
+
+template class elf::CommonInputSection<ELF32LE>;
+template class elf::CommonInputSection<ELF32BE>;
+template class elf::CommonInputSection<ELF64LE>;
+template class elf::CommonInputSection<ELF64BE>;
OpenPOWER on IntegriCloud