From c7ad42b1c0aed1527319ec087a5102398c176aec Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Thu, 2 May 2024 15:35:24 +0300 Subject: [PATCH] [ADLT] fix program header indexing lifecycle for .adlt section Signed-off-by: Khomutov Nikita Change-Id: Ie4e6c7b0561f4a45311b7a8df4e1edac5cbdde37 Signed-off-by: Khomutov Nikita --- lld/ELF/InputFiles.h | 4 +- lld/ELF/SyntheticSections.cpp | 34 +++++++++++-- lld/ELF/SyntheticSections.h | 5 ++ lld/ELF/Writer.cpp | 95 +++++++++++------------------------ 4 files changed, 68 insertions(+), 70 deletions(-) diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index b7099e5d6ae4..1db53c987f94 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -38,6 +38,7 @@ namespace elf { class InputSection; class Symbol; +struct PhdrEntry; // OHOS_LOCAL // If --reproduce is specified, all input files are written to this tar archive. extern std::unique_ptr tar; @@ -458,7 +459,8 @@ public: llvm::Optional sharedGlobalSymbolIndex; // Output information data: - llvm::SetVector programHeaderIndexes; + llvm::SetVector programHeaders; + // From input .rela.dyn, .rela.plt: llvm::SetVector dynRelIndexes; llvm::SetVector pltRelIndexes; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 8d1f83e80c43..83a593200170 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -4222,9 +4222,8 @@ AdltSection::makeSoData(const SharedFileExtended* soext) { data.relaDynIndx = soext->dynRelIndexes.getArrayRef(); data.relaPltIndx = soext->pltRelIndexes.getArrayRef(); - std::copy(soext->programHeaderIndexes.begin(), - soext->programHeaderIndexes.end(), - std::back_inserter(data.phIndexes)); + data.programHeadersAllocated = soext->programHeaders.size(); + data.programHeaders = soext->programHeaders.getArrayRef(); return data; } @@ -4286,7 +4285,7 @@ size_t AdltSection::estimateBlobSize() const { for (const auto& soData: soInputs) { blobSize += sizeof(adlt_dt_needed_index_t) * soData.dtNeededs.size(); - blobSize += sizeof(uint16_t) * soData.phIndexes.size(); + blobSize += sizeof(uint16_t) * soData.programHeadersAllocated; blobSize += sizeof(uint32_t) * soData.relaDynIndx.size(); blobSize += sizeof(uint32_t) * soData.relaPltIndx.size(); }; @@ -4337,8 +4336,18 @@ adlt_blob_array_t AdltSection::writeDtNeeded( return writeArray(buff, offset, needIndexes); } +template +void AdltSection::extractProgramHeaderIndexes() { + phdrsIndexes.clear(); + for (const auto& it : llvm::enumerate(mainPart->phdrs)) { + phdrsIndexes[it.value()] = static_cast(it.index()); + }; +} + template void AdltSection::finalizeOnWrite() { + // require optimizing Writer::removeEmptyPTLoad been called + extractProgramHeaderIndexes(); // require Writer::setPhdrs previously been called header.overallMappedSize = estimateOverallMappedSize(); @@ -4358,6 +4367,23 @@ void AdltSection::finalizeOnWrite(size_t idx, SoData& soData) { // require SymbolTableBaseSection::sortSymTabSymbolsInAdlt for .symtab called soData.sharedLocalIndex = soext->sharedLocalSymbolIndex; soData.sharedGlobalIndex = soext->sharedGlobalSymbolIndex; + + // phIndexes may shift if called before Writer::removeEmptyPTLoad + soData.phIndexes.clear(); + for (const PhdrEntry* phentry : soData.programHeaders) { + auto it = phdrsIndexes.find(phentry); + if (it != phdrsIndexes.end()) { + soData.phIndexes.push_back(it->second); + } + } + + assert(soData.phIndexes.size() <= soData.programHeadersAllocated); + if (soData.phIndexes.size() != soData.programHeadersAllocated) { + warn(Twine(".adlt section: overallocated ph-indexes for psod-") + Twine(idx) + + " allocated=" + Twine(soData.programHeadersAllocated) + + " actual=" + Twine(soData.phIndexes.size()) + ); + } } template diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 1a72f89c8edb..873f244d68bb 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -1259,7 +1259,10 @@ public: llvm::Optional sharedLocalIndex; llvm::Optional sharedGlobalIndex; + size_t programHeadersAllocated; + ArrayRef programHeaders; SmallVector phIndexes; + ArrayRef relaDynIndx; ArrayRef relaPltIndx; }; @@ -1285,6 +1288,7 @@ private: void linkInternalDtNeeded(); void extractInitFiniArray(); size_t estimateOverallMappedSize(); + void extractProgramHeaderIndexes(); Elf64_Xword calculateHash(StringRef str) const; CommonData makeCommonData(); @@ -1315,6 +1319,7 @@ private: SmallVector soInputs; llvm::DenseMap sonameToIndexMap; + llvm::DenseMap phdrsIndexes; }; } // namespace adlt diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index ee310d888053..7439ed63c644 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -117,10 +117,6 @@ static void removeEmptyPTLoad(SmallVector &phdrs) { if (removed.count(sec->ptLoad)) sec->ptLoad = nullptr; - if (config->adlt) { - assert(it == phdrs.end() && "adlt: ph-index in .adlt invalid due to shift"); - } - phdrs.erase(it, phdrs.end()); } @@ -1029,6 +1025,27 @@ 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) @@ -1039,6 +1056,15 @@ void PhdrEntry::add(OutputSection *sec) { p_align = std::max(p_align, sec->alignment); if (p_type == PT_LOAD) sec->ptLoad = this; + + if (config->adlt && (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); + } + } } // The beginning and the ending of .rel[a].plt section are marked @@ -2374,19 +2400,6 @@ static uint64_t computeFlags(uint64_t flags) { return flags; } -static 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(); -} - -struct LoadInfoForADLT { - int phIndex; // input - SmallVector phSections; -}; - // Decide which program headers to create and which sections to include in each // one. template @@ -2397,10 +2410,6 @@ SmallVector Writer::createPhdrs(Partition &part) { return ret.back(); }; - auto getCurrentIndex = [&]() -> int { - return static_cast(ret.size()) - 1; - }; - unsigned partNo = part.getNumber(); bool isMain = partNo == 1; @@ -2433,11 +2442,6 @@ SmallVector Writer::createPhdrs(Partition &part) { load = addHdr(PT_LOAD, flags); load->add(Out::elfHeader); load->add(Out::programHeaders); - if (config->adlt) // add common header for all libs - for (auto *base : ctx->sharedFilesExtended) { - auto *soFile = cast>(base); - soFile->programHeaderIndexes.insert(getCurrentIndex()); - } } } @@ -2464,9 +2468,6 @@ SmallVector Writer::createPhdrs(Partition &part) { } } - // ADLT: Collect load headers info - SmallVector adltLoadInfo; - for (OutputSection *sec : outputSections) { if (!needsPtLoad(sec)) continue; @@ -2498,45 +2499,9 @@ SmallVector Writer::createPhdrs(Partition &part) { (sameLMARegion || load->lastSec == Out::programHeaders))) { load = addHdr(PT_LOAD, newFlags); flags = newFlags; - if (config->adlt) { - adltLoadInfo.emplace_back(); - adltLoadInfo.back().phIndex = getCurrentIndex(); - } } load->add(sec); - if (config->adlt && !adltLoadInfo.empty()) - adltLoadInfo.back().phSections.push_back(sec); - } - - // ADLT: Fill load headers info - if (config->adlt) { - for (LoadInfoForADLT &info : adltLoadInfo) - for (OutputSection *sec : info.phSections) { - auto *isec = getInputSection(sec); - assert(isec); - auto *file = isec->file; - if (!file) // skip generated sections. - continue; // TODO: fix .rodata_$ADLT_POSTFIX sections. - auto *soFile = cast>(file); - soFile->programHeaderIndexes.insert(info.phIndex); - } - - // Check outputs - auto adltTraceNeeded = false; // debug hint - auto trace = [&](auto *file, auto &indexes) { - lld::outs() << "ADLT: " << file->soName << ":\n"; - for (auto &it : indexes) - lld::outs() << it << " "; - lld::outs() << '\n'; - }; - for (ELFFileBase *baseFile : ctx->sharedFilesExtended) { - auto *soFile = cast>(baseFile); - auto &indexes = soFile->programHeaderIndexes; - assert(!indexes.empty()); - if (adltTraceNeeded) - trace(soFile, indexes); - } } // Add a TLS segment if any. -- Gitee