From 9cfac8a84921f29fec08cb3832372f8ad0aed616 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 22 Nov 2016 04:13:09 +0000 Subject: [PATCH] Convert MipsOptionsSection to SyntheticSection. llvm-svn: 287615 --- lld/ELF/SyntheticSections.cpp | 89 +++++++++++++++++++++++-------------------- lld/ELF/SyntheticSections.h | 38 +++++++++--------- lld/ELF/Writer.cpp | 7 ++-- 3 files changed, 70 insertions(+), 64 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b0a5bd7..bb317c9 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -112,21 +112,6 @@ template MergeInputSection *elf::createCommentSection() { return Ret; } -// Iterate over sections of the specified type. For each section call -// provided function. After that "kill" the section by turning off -// "Live" flag, so that they won't be included in the final output. -template -static void iterateSectionContents( - uint32_t Type, - std::function *, ArrayRef)> F) { - for (InputSectionBase *Sec : Symtab::X->Sections) { - if (Sec && Sec->Live && Sec->Type == Type) { - Sec->Live = false; - F(Sec->getFile(), Sec->Data); - } - } -} - // .MIPS.abiflags section. template MipsAbiFlagsSection::MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags) @@ -181,42 +166,62 @@ MipsAbiFlagsSection *MipsAbiFlagsSection::create() { // .MIPS.options section. template -MipsOptionsSection::MipsOptionsSection() - : InputSection(SHF_ALLOC, SHT_MIPS_OPTIONS, 8, ArrayRef(), - ".MIPS.options") { - Buf.resize(sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo)); - getOptions()->kind = ODK_REGINFO; - getOptions()->size = Buf.size(); - auto Func = [this](ObjectFile *F, ArrayRef D) { +MipsOptionsSection::MipsOptionsSection(Elf_Mips_RegInfo Reginfo) + : SyntheticSection(SHF_ALLOC, SHT_MIPS_OPTIONS, 8, ".MIPS.options"), + Reginfo(Reginfo) {} + +template void MipsOptionsSection::writeTo(uint8_t *Buf) { + auto *Options = reinterpret_cast(Buf); + Options->kind = ODK_REGINFO; + Options->size = getSize(); + + if (!Config->Relocatable) + Reginfo.ri_gp_value = In::MipsGot->getVA() + MipsGPOffset; + memcpy(Buf + sizeof(Options), &Reginfo, sizeof(Reginfo)); +} + +template +MipsOptionsSection *MipsOptionsSection::create() { + // N64 ABI only. + if (!ELFT::Is64Bits) + return nullptr; + + Elf_Mips_RegInfo Reginfo = {}; + bool Create = false; + + for (InputSectionBase *Sec : Symtab::X->Sections) { + if (!Sec->Live || Sec->Type != SHT_MIPS_OPTIONS) + continue; + Sec->Live = false; + Create = true; + + std::string Filename = getFilename(Sec->getFile()); + ArrayRef D = Sec->Data; + while (!D.empty()) { if (D.size() < sizeof(Elf_Mips_Options)) { - error(getFilename(F) + ": invalid size of .MIPS.options section"); + error(Filename + ": invalid size of .MIPS.options section"); break; } - auto *O = reinterpret_cast(D.data()); - if (O->kind == ODK_REGINFO) { - if (Config->Relocatable && O->getRegInfo().ri_gp_value) - error(getFilename(F) + ": unsupported non-zero ri_gp_value"); - getOptions()->getRegInfo().ri_gprmask |= O->getRegInfo().ri_gprmask; - F->MipsGp0 = O->getRegInfo().ri_gp_value; + + auto *Opt = reinterpret_cast(D.data()); + if (Opt->kind == ODK_REGINFO) { + if (Config->Relocatable && Opt->getRegInfo().ri_gp_value) + error(Filename + ": unsupported non-zero ri_gp_value"); + Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask; + Sec->getFile()->MipsGp0 = Opt->getRegInfo().ri_gp_value; break; } - if (!O->size) - fatal(getFilename(F) + ": zero option descriptor size"); - D = D.slice(O->size); + + if (!Opt->size) + fatal(Filename + ": zero option descriptor size"); + D = D.slice(Opt->size); } }; - iterateSectionContents(SHT_MIPS_OPTIONS, Func); - - this->Data = ArrayRef(Buf); - // Section should be alive for N64 ABI only. - this->Live = ELFT::Is64Bits; -} -template void MipsOptionsSection::finalize() { - if (!Config->Relocatable) - getOptions()->getRegInfo().ri_gp_value = - In::MipsGot->getVA() + MipsGPOffset; + if (Create) + return new MipsOptionsSection(Reginfo); + return nullptr; } // MIPS .reginfo section. diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index ac1f429..4e7e975 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -17,24 +17,6 @@ namespace lld { namespace elf { -// .MIPS.options section. -template -class MipsOptionsSection final : public InputSection { - typedef llvm::object::Elf_Mips_Options Elf_Mips_Options; - typedef llvm::object::Elf_Mips_RegInfo Elf_Mips_RegInfo; - -public: - MipsOptionsSection(); - void finalize(); - -private: - std::vector Buf; - - Elf_Mips_Options *getOptions() { - return reinterpret_cast(Buf.data()); - } -}; - template class SyntheticSection : public InputSection { typedef typename ELFT::uint uintX_t; @@ -580,6 +562,26 @@ private: Elf_Mips_ABIFlags Flags; }; +// .MIPS.options section. +template +class MipsOptionsSection final : public SyntheticSection { + typedef llvm::object::Elf_Mips_Options Elf_Mips_Options; + typedef llvm::object::Elf_Mips_RegInfo Elf_Mips_RegInfo; + +public: + static MipsOptionsSection *create(); + + MipsOptionsSection(Elf_Mips_RegInfo Reginfo); + void writeTo(uint8_t *Buf) override; + + size_t getSize() const override { + return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo); + } + +private: + Elf_Mips_RegInfo Reginfo; +}; + // MIPS .reginfo section. template class MipsReginfoSection final : public SyntheticSection { diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index b2bde2d..8667b9a 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -312,10 +312,9 @@ template void Writer::createSyntheticSections() { Symtab::X->Sections.push_back(Sec); } // .MIPS.options - auto *OptSec = make>(); - if (OptSec->Live) { - In::MipsOptions = OptSec; - Symtab::X->Sections.push_back(OptSec); + if (auto *Sec = MipsOptionsSection::create()) { + In::MipsOptions = Sec; + Symtab::X->Sections.push_back(Sec); } // MIPS .reginfo if (auto *Sec = MipsReginfoSection::create()) { -- 2.7.4