From b71cae90de41655bbd96e9d5f8b0dd39c445f919 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 22 Nov 2016 03:57:08 +0000 Subject: [PATCH] Convert MipsReginfoSection to SyntheticSection. llvm-svn: 287614 --- lld/ELF/SyntheticSections.cpp | 58 ++++++++++++++++++++++------------- lld/ELF/SyntheticSections.h | 29 ++++++++++-------- lld/ELF/Writer.cpp | 13 +++----- 3 files changed, 58 insertions(+), 42 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index ec46173bf2fa..b0a5bd7da1ca 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -221,30 +221,46 @@ template void MipsOptionsSection::finalize() { // MIPS .reginfo section. template -MipsReginfoSection::MipsReginfoSection() - : InputSection(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ArrayRef(), - ".reginfo") { - auto Func = [this](ObjectFile *F, ArrayRef D) { - if (D.size() != sizeof(Elf_Mips_RegInfo)) { - error(getFilename(F) + ": invalid size of .reginfo section"); - return; - } - auto *R = reinterpret_cast(D.data()); - if (Config->Relocatable && R->ri_gp_value) - error(getFilename(F) + ": unsupported non-zero ri_gp_value"); - Reginfo.ri_gprmask |= R->ri_gprmask; - F->MipsGp0 = R->ri_gp_value; - }; - iterateSectionContents(SHT_MIPS_REGINFO, Func); +MipsReginfoSection::MipsReginfoSection(Elf_Mips_RegInfo Reginfo) + : SyntheticSection(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ".reginfo"), + Reginfo(Reginfo) {} - this->Data = ArrayRef((const uint8_t *)&Reginfo, sizeof(Reginfo)); - // Section should be alive for O32 and N32 ABIs only. - this->Live = !ELFT::Is64Bits; -} - -template void MipsReginfoSection::finalize() { +template void MipsReginfoSection::writeTo(uint8_t *Buf) { if (!Config->Relocatable) Reginfo.ri_gp_value = In::MipsGot->getVA() + MipsGPOffset; + memcpy(Buf, &Reginfo, sizeof(Reginfo)); +} + +template +MipsReginfoSection *MipsReginfoSection::create() { + // Section should be alive for O32 and N32 ABIs 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_REGINFO) + continue; + Sec->Live = false; + Create = true; + + if (Sec->Data.size() != sizeof(Elf_Mips_RegInfo)) { + error(getFilename(Sec->getFile()) + ": invalid size of .reginfo section"); + return nullptr; + } + auto *R = reinterpret_cast(Sec->Data.data()); + if (Config->Relocatable && R->ri_gp_value) + error(getFilename(Sec->getFile()) + ": unsupported non-zero ri_gp_value"); + + Reginfo.ri_gprmask |= R->ri_gprmask; + Sec->getFile()->MipsGp0 = R->ri_gp_value; + }; + + if (Create) + return make>(Reginfo); + return nullptr; } static ArrayRef createInterp() { diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index c2d9adcf23c9..ac1f4297cde9 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -35,19 +35,6 @@ private: } }; -// MIPS .reginfo section. -template -class MipsReginfoSection final : public InputSection { - typedef llvm::object::Elf_Mips_RegInfo Elf_Mips_RegInfo; - -public: - MipsReginfoSection(); - void finalize(); - -private: - Elf_Mips_RegInfo Reginfo = {}; -}; - template class SyntheticSection : public InputSection { typedef typename ELFT::uint uintX_t; @@ -593,6 +580,22 @@ private: Elf_Mips_ABIFlags Flags; }; +// MIPS .reginfo section. +template +class MipsReginfoSection final : public SyntheticSection { + typedef llvm::object::Elf_Mips_RegInfo Elf_Mips_RegInfo; + +public: + static MipsReginfoSection *create(); + + MipsReginfoSection(Elf_Mips_RegInfo Reginfo); + size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); } + void writeTo(uint8_t *Buf) override; + +private: + Elf_Mips_RegInfo Reginfo; +}; + template InputSection *createCommonSection(); template InputSection *createInterpSection(); template MergeInputSection *createCommentSection(); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 6927b002591a..b2bde2d8e644 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -318,10 +318,9 @@ template void Writer::createSyntheticSections() { Symtab::X->Sections.push_back(OptSec); } // MIPS .reginfo - auto *RegSec = make>(); - if (RegSec->Live) { - In::MipsReginfo = RegSec; - Symtab::X->Sections.push_back(RegSec); + if (auto *Sec = MipsReginfoSection::create()) { + In::MipsReginfo = Sec; + Symtab::X->Sections.push_back(Sec); } } @@ -1500,10 +1499,8 @@ template void Writer::writeSectionsBinary() { template void Writer::writeSections() { uint8_t *Buf = Buffer->getBufferStart(); - // Finalize MIPS .reginfo and .MIPS.options sections - // because they contain offsets to .got and _gp. - if (In::MipsReginfo) - In::MipsReginfo->finalize(); + // Finalize MIPS .MIPS.options sections because that contains + // offsets to .got and _gp. if (In::MipsOptions) In::MipsOptions->finalize();