From 55c14d6dbfd8e7b86c15d2613fea3490078e2ae4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 25 Nov 2021 14:12:34 -0800 Subject: [PATCH] [ELF] Simplify DynamicSection content computation. NFC The new code computes the content twice, but avoides the tricky std::function. Removed 13KiB code in a Release build. --- lld/ELF/SyntheticSections.cpp | 117 +++++++++++++--------------------- lld/ELF/SyntheticSections.h | 12 +--- 2 files changed, 44 insertions(+), 85 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 78d41e583e81..d251419cd73d 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1258,43 +1258,6 @@ DynamicSection::DynamicSection() this->flags = SHF_ALLOC; } -template -void DynamicSection::add(int32_t tag, std::function fn) { - entries.push_back({tag, fn}); -} - -template -void DynamicSection::addInt(int32_t tag, uint64_t val) { - entries.push_back({tag, [=] { return val; }}); -} - -template -void DynamicSection::addInSec(int32_t tag, InputSection *sec) { - entries.push_back({tag, [=] { return sec->getVA(0); }}); -} - -template -void DynamicSection::addInSecRelative(int32_t tag, InputSection *sec) { - size_t tagOffset = entries.size() * entsize; - entries.push_back( - {tag, [=] { return sec->getVA(0) - (getVA() + tagOffset); }}); -} - -template -void DynamicSection::addOutSec(int32_t tag, OutputSection *sec) { - entries.push_back({tag, [=] { return sec->addr; }}); -} - -template -void DynamicSection::addSize(int32_t tag, OutputSection *sec) { - entries.push_back({tag, [=] { return sec->size; }}); -} - -template -void DynamicSection::addSym(int32_t tag, Symbol *sym) { - entries.push_back({tag, [=] { return sym->getVA(); }}); -} - // The output section .rela.dyn may include these synthetic sections: // // - part.relaDyn @@ -1303,15 +1266,13 @@ void DynamicSection::addSym(int32_t tag, Symbol *sym) { // .rela.dyn // // DT_RELASZ is the total size of the included sections. -static std::function addRelaSz(RelocationBaseSection *relaDyn) { - return [=]() { - size_t size = relaDyn->getSize(); - if (in.relaIplt->getParent() == relaDyn->getParent()) - size += in.relaIplt->getSize(); - if (in.relaPlt->getParent() == relaDyn->getParent()) - size += in.relaPlt->getSize(); - return size; - }; +static uint64_t addRelaSz(RelocationBaseSection *relaDyn) { + size_t size = relaDyn->getSize(); + if (in.relaIplt->getParent() == relaDyn->getParent()) + size += in.relaIplt->getSize(); + if (in.relaPlt->getParent() == relaDyn->getParent()) + size += in.relaPlt->getSize(); + return size; } // A Linker script may assign the RELA relocation sections to the same @@ -1327,9 +1288,19 @@ static uint64_t addPltRelSz() { } // Add remaining entries to complete .dynamic contents. -template void DynamicSection::finalizeContents() { +template +std::vector> +DynamicSection::computeContents() { elf::Partition &part = getPartition(); bool isMain = part.name.empty(); + std::vector> entries; + + auto addInt = [&](int32_t tag, uint64_t val) { + entries.emplace_back(tag, val); + }; + auto addInSec = [&](int32_t tag, const InputSection *sec) { + entries.emplace_back(tag, sec->getVA()); + }; for (StringRef s : config->filterList) addInt(DT_FILTER, part.dynStrTab->addString(s)); @@ -1401,14 +1372,11 @@ template void DynamicSection::finalizeContents() { if (!config->shared && !config->relocatable && !config->zRodynamic) addInt(DT_DEBUG, 0); - if (OutputSection *sec = part.dynStrTab->getParent()) - this->link = sec->sectionIndex; - if (part.relaDyn->isNeeded() || (in.relaIplt->isNeeded() && part.relaDyn->getParent() == in.relaIplt->getParent())) { addInSec(part.relaDyn->dynamicTag, part.relaDyn); - entries.push_back({part.relaDyn->sizeDynamicTag, addRelaSz(part.relaDyn)}); + entries.emplace_back(part.relaDyn->sizeDynamicTag, addRelaSz(part.relaDyn)); bool isRela = config->isRela; addInt(isRela ? DT_RELAENT : DT_RELENT, @@ -1426,8 +1394,8 @@ template void DynamicSection::finalizeContents() { if (part.relrDyn && !part.relrDyn->relocs.empty()) { addInSec(config->useAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR, part.relrDyn); - addSize(config->useAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ, - part.relrDyn->getParent()); + addInt(config->useAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ, + part.relrDyn->getParent()->size); addInt(config->useAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT, sizeof(Elf_Relr)); } @@ -1439,7 +1407,7 @@ template void DynamicSection::finalizeContents() { // .rel[a].plt section. if (isMain && (in.relaPlt->isNeeded() || in.relaIplt->isNeeded())) { addInSec(DT_JMPREL, in.relaPlt); - entries.push_back({DT_PLTRELSZ, addPltRelSz}); + entries.emplace_back(DT_PLTRELSZ, addPltRelSz()); switch (config->emachine) { case EM_MIPS: addInSec(DT_MIPS_PLTGOT, in.gotPlt); @@ -1481,24 +1449,24 @@ template void DynamicSection::finalizeContents() { if (isMain) { if (Out::preinitArray) { - addOutSec(DT_PREINIT_ARRAY, Out::preinitArray); - addSize(DT_PREINIT_ARRAYSZ, Out::preinitArray); + addInt(DT_PREINIT_ARRAY, Out::preinitArray->addr); + addInt(DT_PREINIT_ARRAYSZ, Out::preinitArray->size); } if (Out::initArray) { - addOutSec(DT_INIT_ARRAY, Out::initArray); - addSize(DT_INIT_ARRAYSZ, Out::initArray); + addInt(DT_INIT_ARRAY, Out::initArray->addr); + addInt(DT_INIT_ARRAYSZ, Out::initArray->size); } if (Out::finiArray) { - addOutSec(DT_FINI_ARRAY, Out::finiArray); - addSize(DT_FINI_ARRAYSZ, Out::finiArray); + addInt(DT_FINI_ARRAY, Out::finiArray->addr); + addInt(DT_FINI_ARRAYSZ, Out::finiArray->size); } if (Symbol *b = symtab->find(config->init)) if (b->isDefined()) - addSym(DT_INIT, b); + addInt(DT_INIT, b->getVA()); if (Symbol *b = symtab->find(config->fini)) if (b->isDefined()) - addSym(DT_FINI, b); + addInt(DT_FINI, b->getVA()); } if (part.verSym && part.verSym->isNeeded()) @@ -1521,8 +1489,7 @@ template void DynamicSection::finalizeContents() { addInt(DT_MIPS_FLAGS, RHF_NOTPOT); addInt(DT_MIPS_BASE_ADDRESS, target->getImageBase()); addInt(DT_MIPS_SYMTABNO, part.dynSymTab->getNumSymbols()); - - add(DT_MIPS_LOCAL_GOTNO, [] { return in.mipsGot->getLocalEntriesNum(); }); + addInt(DT_MIPS_LOCAL_GOTNO, in.mipsGot->getLocalEntriesNum()); if (const Symbol *b = in.mipsGot->getFirstGlobalEntry()) addInt(DT_MIPS_GOTSYM, b->dynsymIndex); @@ -1534,37 +1501,39 @@ template void DynamicSection::finalizeContents() { addInSec(DT_MIPS_RLD_MAP, in.mipsRldMap); // Store the offset to the .rld_map section // relative to the address of the tag. - addInSecRelative(DT_MIPS_RLD_MAP_REL, in.mipsRldMap); + addInt(DT_MIPS_RLD_MAP_REL, + in.mipsRldMap->getVA() - (getVA() + entries.size() * entsize)); } } // DT_PPC_GOT indicates to glibc Secure PLT is used. If DT_PPC_GOT is absent, // glibc assumes the old-style BSS PLT layout which we don't support. if (config->emachine == EM_PPC) - add(DT_PPC_GOT, [] { return in.got->getVA(); }); + addInSec(DT_PPC_GOT, in.got); // Glink dynamic tag is required by the V2 abi if the plt section isn't empty. if (config->emachine == EM_PPC64 && in.plt->isNeeded()) { // The Glink tag points to 32 bytes before the first lazy symbol resolution // stub, which starts directly after the header. - entries.push_back({DT_PPC64_GLINK, [=] { - unsigned offset = target->pltHeaderSize - 32; - return in.plt->getVA(0) + offset; - }}); + addInt(DT_PPC64_GLINK, in.plt->getVA() + target->pltHeaderSize - 32); } addInt(DT_NULL, 0); + return entries; +} - getParent()->link = this->link; - this->size = entries.size() * this->entsize; +template void DynamicSection::finalizeContents() { + if (OutputSection *sec = getPartition().dynStrTab->getParent()) + getParent()->link = sec->sectionIndex; + this->size = computeContents().size() * this->entsize; } template void DynamicSection::writeTo(uint8_t *buf) { auto *p = reinterpret_cast(buf); - for (std::pair> &kv : entries) { + for (std::pair kv : computeContents()) { p->d_tag = kv.first; - p->d_un.d_val = kv.second(); + p->d_un.d_val = kv.second; ++p; } } diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index bc24922598fe..2bc9b5bf9c31 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -493,9 +493,6 @@ private: template class DynamicSection final : public SyntheticSection { LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - // finalizeContents() fills this vector with the section contents. - std::vector>> entries; - public: DynamicSection(); void finalizeContents() override; @@ -503,14 +500,7 @@ public: size_t getSize() const override { return size; } private: - void add(int32_t tag, std::function fn); - void addInt(int32_t tag, uint64_t val); - void addInSec(int32_t tag, InputSection *sec); - void addInSecRelative(int32_t tag, InputSection *sec); - void addOutSec(int32_t tag, OutputSection *sec); - void addSize(int32_t tag, OutputSection *sec); - void addSym(int32_t tag, Symbol *sym); - + std::vector> computeContents(); uint64_t size = 0; };