diff options
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r-- | lld/ELF/InputSection.cpp | 44 |
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>; |