From 79774152c4977891312a3f089440e62e9f061eeb Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 15 May 2024 06:04:00 -0400 Subject: [PATCH] [ADLT] Refactor Writer. Tracing implement. Change-Id: If7b76dca3a84d5895c003a6cffe446f865eab1fc Signed-off-by: Anton Volkov --- lld/ELF/Config.h | 7 +- lld/ELF/Writer.cpp | 245 +++++++++++++++++++++++++++++++-------------- 2 files changed, 175 insertions(+), 77 deletions(-) diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index cd768db8a7ff..701df85adde9 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -34,6 +34,7 @@ class BinaryFile; class BitcodeFile; class ELFFileBase; class SharedFile; +template class SharedFileExtended; struct PhdrEntry; // OHOS_LOCAL class InputSectionBase; class Symbol; @@ -414,7 +415,11 @@ struct Ctx { // OHOS_LOCAL begin struct AdltCtx { - llvm::SetVector commonProgramHeaders; + template SharedFileExtended *getSoExt(InputFile *file) { + return cast>(file); + } + + llvm::SetVector commonProgramHeaders; bool withCfi = false; // From input .rela.dyn, .rela.plt: // Keep input library indexes that are needed for got/plt symbol diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index dd74a8bc98bf..6743de95cd2f 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -546,6 +546,158 @@ template void elf::createSyntheticSections() { add(*in.strTab); } +// OHOS_LOCAL begin +namespace { +static struct AdltWriter { + InputSection *getInputSection(OutputSection *sec); + StringRef phdrTypeToStr(uint32_t p_type); + + template void checkPhdrs(); + template void checkRelocs(); + + template void trackPhdr(OutputSection *sec, PhdrEntry *phdr); + template void traceRelocs(); + template void tracePhdrs(); +} adltWriter; +} // namespace + +InputSection *AdltWriter::getInputSection(OutputSection *sec) { + if (!sec || !sec->hasInputSections || sec->commands.empty()) + return nullptr; + SectionCommand *cmd = sec->commands.front(); + InputSectionDescription *isd = cast(cmd); + return isd->sections.front(); +} + +template void AdltWriter::checkPhdrs() { + for (auto *file : ctx->sharedFilesExtended) + if (auto *soFile = ctx->adlt.getSoExt(file)) + assert(!soFile->programHeaders.empty() && + "ADLT: PHdr indexes can't be empty!"); +} + +template void AdltWriter::checkRelocs() { + assert(!mainPart->relaDyn->relocs.empty() && "ADLT: relaDyn can't be empty!"); + assert(!in.relaPlt->relocs.empty() && "ADLT: relaPlt can't be empty!"); + + for (auto *file : ctx->sharedFilesExtended) + if (auto *soFile = ctx->adlt.getSoExt(file)) { + assert(!soFile->dynRelIndexes.empty() && + "ADLT: relaDyn indexes can't be empty!"); + assert(!soFile->pltRelIndexes.empty() && + "ADLT: relaPlt indexes can't be empty!"); + } +} + +template +void AdltWriter::trackPhdr(OutputSection *sec, PhdrEntry *phdr) { + auto *isec = getInputSection(sec); + if (isec && isec->file) + if (auto *soFile = ctx->adlt.getSoExt(isec->file)) { + soFile->programHeaders.insert(phdr); + return; + } + ctx->adlt.commonProgramHeaders.insert(phdr); +} + +template void AdltWriter::traceRelocs() { + lld::outs() << "[ADLT]\n"; + lld::outs() << "Dyn relocs (" << mainPart->relaDyn->relocs.size() << ")\n"; + lld::outs() << "Plt relocs (" << in.relaPlt->relocs.size() << ")\n"; + + auto printIndexes = [&](auto &vec) { + lld::outs() << ": "; + for (auto &it : vec) + lld::outs() << it << ' '; + lld::outs() << "\n"; + }; + + auto printRelocTable = [&](auto *relSec, auto &outIndexes) { + for (auto &it : outIndexes) // print relocs + if (DynamicReloc *rel = &relSec->relocs[it]) + lld::outs() << it << ":\t" << rel->inputSec->name << " + 0x" + << utohexstr(rel->offsetInSec) << "\t" + << toString(rel->type) << "\t" << rel->sym->getName() + << " + 0x" << utohexstr(rel->addend) << '\n'; + }; + + for (auto *file : ctx->sharedFilesExtended) + if (auto *soFile = ctx->adlt.getSoExt(file)) { + lld::outs() << soFile->soName << ":\n"; + lld::outs() << "Dyn relocs (" << soFile->dynRelIndexes.size() << ")"; + printIndexes(soFile->dynRelIndexes); + printRelocTable(mainPart->relaDyn.get(), soFile->dynRelIndexes); + + lld::outs() << "Plt relocs (" << soFile->pltRelIndexes.size() << ")"; + printIndexes(soFile->pltRelIndexes); + printRelocTable(in.relaPlt.get(), soFile->pltRelIndexes); + } +} + +template void AdltWriter::tracePhdrs() { + lld::outs() << "[ADLT]\n"; + lld::outs() << "Program Headers (" << mainPart->phdrs.size() << ")\n"; + + llvm::DenseMap phIndexMap; + for (auto &it : llvm::enumerate(mainPart->phdrs)) + phIndexMap[it.value()] = it.index(); + + + auto printIndexes = [&](auto &vec) { + lld::outs() << ": "; + for (auto &it : vec) + lld::outs() << phIndexMap[it] << ' '; + lld::outs() << "\n"; + }; + + auto printPhTable = [&](auto &vec) { + lld::outs() << "Idx\tType\tOffset\tVirtAddr\tAlign\tFirstSec\n"; + for (const PhdrEntry *p : vec) + lld::outs() << phIndexMap[p] << ":\t" << phdrTypeToStr(p->p_type) + << "\t0x" << utohexstr(p->p_offset) << "\t0x" + << utohexstr(p->p_vaddr) << " \t0x" << utohexstr(p->p_align) + << "\t" << p->firstSec->name << '\n'; + }; + + auto &common = ctx->adlt.commonProgramHeaders; + lld::outs() << "Common Program Headers (" << common.size() << ")"; + printIndexes(common); + printPhTable(common); + + for (auto *file : ctx->sharedFilesExtended) + if (auto *soFile = ctx->adlt.getSoExt(file)) { + auto &headers = soFile->programHeaders; + lld::outs() << soFile->soName << "\n"; + lld::outs() << "Program headers (" << headers.size() << ")"; + printIndexes(headers); + printPhTable(headers); + } +} + +StringRef AdltWriter::phdrTypeToStr(uint32_t p_type) { + switch (p_type) { + case PT_PHDR: + return "PT_PHDR"; + case PT_ADLT: + return "PT_ADLT"; + case PT_LOAD: + return "PT_LOAD"; + case PT_TLS: + return "PT_TLS"; + case PT_DYNAMIC: + return "PT_DYNAMIC"; + case PT_GNU_RELRO: + return "PT_GNU_RELRO"; + case PT_GNU_STACK: + return "PT_GNU_STACK"; + case PT_NOTE: + return "PT_NOTE"; + } + llvm_unreachable("UNKNOWN TYPE"); + return ""; +} +// OHOS_LOCAL end + // The main function of the writer. template void Writer::run() { copyLocalSymbols(); @@ -1025,27 +1177,6 @@ static bool compareSections(const SectionCommand *aCmd, return false; } -// OHOS_LOCAL begin -namespace { - -InputSection* getInputSection(OutputSection* sec) { - if (!sec || !sec->hasInputSections || sec->commands.empty()) - return nullptr; - SectionCommand* cmd = sec->commands.front(); - InputSectionDescription* isd = cast(cmd); - return isd->sections.front(); -} - -template -void addPhdrToSharedFilesExtendedContext(InputFile* file, PhdrEntry* phdr) { - if (auto* soFile = dyn_cast>(file)) { - soFile->programHeaders.insert(phdr); - } -} - -} // namespace -// OHOS_LOCAL end - void PhdrEntry::add(OutputSection *sec) { lastSec = sec; if (!firstSec) @@ -1061,20 +1192,12 @@ void PhdrEntry::add(OutputSection *sec) { if (ctx->adlt.withCfi && p_type == PT_LOAD) { // check cfi.h: LIBRARY_ALIGNMENT and _BITS constexpr uint32_t kCFILibraryAlignment = 1UL << 18; - firstSec->alignment = std::max(firstSec->alignment, kCFILibraryAlignment); - p_align = std::max(p_align, kCFILibraryAlignment); + firstSec->alignment = kCFILibraryAlignment; + p_align = kCFILibraryAlignment; } - if (p_type == PT_LOAD || p_type == PT_TLS) { - auto* insec = getInputSection(sec); - // skip generated sections. - // TODO: fix .rodata_$ADLT_POSTFIX sections. - if (insec && insec->file) { - invokeELFT(addPhdrToSharedFilesExtendedContext, insec->file, this); - } else { - ctx->adlt.commonProgramHeaders.insert(this); - } - } + if (p_type == PT_LOAD || p_type == PT_TLS) + invokeELFT(adltWriter.trackPhdr, sec, this); } // OHOS_LOCAL end } @@ -1912,44 +2035,6 @@ static void removeUnusedSyntheticSections() { }); } -template static void adltTraceRelocationIndexes() { - auto &relaDyn = mainPart->relaDyn; - assert(!relaDyn->relocs.empty() && "ADLT: relaDyn can't be empty!"); - assert(!in.relaPlt->relocs.empty() && "ADLT: relaPlt can't be empty!"); - - bool adltRelocsTrace = false; // debug hint - if (adltRelocsTrace) { - auto traceRelocInfo = [&](auto *relSec, auto &outIndexes) -> void { - bool isPlt = relSec == in.relaPlt.get(); - lld::outs() << (isPlt ? "Plt" : "Dyn") << " indexes: "; - for (auto &it : outIndexes) // simple print - lld::outs() << it << ' '; - lld::outs() << '\n'; - for (auto &it : outIndexes) // print relocs - if (DynamicReloc *rel = &relSec->relocs[it]) - lld::outs() << it << ": " << rel->inputSec->name << " + 0x" - << utohexstr(rel->offsetInSec) << "\t" - << toString(rel->type) << "\t" << rel->sym->getName() - << " + 0x" << utohexstr(rel->addend) << '\n'; - }; - lld::outs() << "[ADLT]\n"; - lld::outs() << "Dyn relocs (" << relaDyn->relocs.size() << ")\n"; - lld::outs() << "Plt relocs (" << in.relaPlt->relocs.size() << ")\n"; - for (auto *file : ctx->sharedFilesExtended) - if (auto *soFile = cast>(file)) { - lld::outs() << "[ADLT] " << soFile->soName << ":\n"; - traceRelocInfo(relaDyn.get(), soFile->dynRelIndexes); - traceRelocInfo(in.relaPlt.get(), soFile->pltRelIndexes); - } - } - for (auto *file : ctx->sharedFilesExtended) { - __attribute__((unused)) auto *soFile = cast>(file); - assert(!soFile->dynRelIndexes.empty() && - "ADLT: relaDyn indexes can't be empty!"); - assert(!soFile->pltRelIndexes.empty() && - "ADLT: relaPlt indexes can't be empty!"); - } -} // Create output section objects and add them to OutputSections. template void Writer::finalizeSections() { @@ -2257,8 +2342,16 @@ template void Writer::finalizeSections() { finalizeSynthetic(part.verNeed.get()); finalizeSynthetic(part.dynamic.get()); } - if (config->adlt) // check ouput relocation indexes - adltTraceRelocationIndexes(); + // OHOS_LOCAL begin + if (config->adlt) { // check ouput entries and indexes + adltWriter.checkPhdrs(); + adltWriter.checkRelocs(); + if (config->adltTrace) { + adltWriter.tracePhdrs(); + adltWriter.traceRelocs(); + } + } + // OHOS_LOCAL end } if (!script->hasSectionsCommand && !config->relocatable) @@ -2424,7 +2517,7 @@ SmallVector Writer::createPhdrs(Partition &part) { // OHOS_LOCAL begin auto getOwnerFileIdx = [](OutputSection* sec) -> llvm::Optional { - auto file = getInputSection(sec)->file; + auto file = adltWriter.getInputSection(sec)->file; if (!file) return llvm::None; return cast>(file)->orderIdx; @@ -2520,7 +2613,7 @@ SmallVector Writer::createPhdrs(Partition &part) { // OHOS_LOCAL begin // ALDT image sections have additional addribute: input file owner. // The ownership contiguousity allows to map only related sections - // when processing program headers that + // when processing program headers that bool sameFileOwner = config->adlt && lastOwnerIdx == getOwnerFileIdx(sec); if (config->adlt) lastOwnerIdx = getOwnerFileIdx(sec); @@ -2545,7 +2638,7 @@ SmallVector Writer::createPhdrs(Partition &part) { if (config->adlt) tlsHdr = addHdr(PT_TLS, PF_R); tlsHdr->add(sec); - } + } if (!config->adlt && tlsHdr->firstSec) ret.push_back(tlsHdr); -- Gitee