From 2bb72e52afebff8466847059a79da9518dc6daa2 Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Tue, 16 Apr 2024 10:32:17 +0300 Subject: [PATCH] [ADLT] shared-symbol-indexes - impelemted SO-local symbol sorting in .symtab - extracted shared-local-symbol-index and shared-global-symbol-index, written to .adlt - impl sysv hash for .adlt - cleaups Signed-off-by: Khomutov Nikita Change-Id: I8127bc662d0f4b9a6cccf9c48a6247db7a5cbde4 Signed-off-by: Khomutov Nikita --- lld/ELF/InputFiles.cpp | 1 + lld/ELF/InputFiles.h | 7 +++ lld/ELF/SyntheticSections.cpp | 100 +++++++++++++++++++++++++++++++--- lld/ELF/SyntheticSections.h | 9 ++- lld/ELF/Writer.cpp | 2 +- 5 files changed, 106 insertions(+), 13 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 30b466825036..8ff0f4361e8f 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -186,6 +186,7 @@ template static void doParseFile(InputFile *file) { // .so file if (config->adlt) if (auto *f = dyn_cast>(file)) { + f->orderIdx = ctx->sharedFilesExtended.size(); ctx->sharedFilesExtended.push_back(cast(file)); f->parseForAdlt(); return; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 5517c153a9b0..6279f81ad150 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -444,11 +444,18 @@ public: void traceSection(const SectionBase &sec, StringRef title = "") const; public: + // the input order of the file as it presented in ADLT image + size_t orderIdx; int dynSymSecIdx = 0; int symTabSecIdx = 0; int symTabShndxSecIdx = 0; int eFirstGlobal = 0; + // .symtab's start of local symbols owned by library + llvm::Optional sharedLocalSymbolIndex; + // .symtab's start of global symbols owned by library + llvm::Optional sharedGlobalSymbolIndex; + // Output information data: llvm::SetVector programHeaderIndexes; // TODO: dynamic relocation indexes diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 4e368aadf62a..73a11c1aedd7 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2243,6 +2243,11 @@ void SymbolTableBaseSection::sortSymTabSymbols() { size_t numLocals = e - symbols.begin(); getParent()->info = numLocals + 1; + if (config->adlt && this->type == SHT_SYMTAB) { + invokeELFT(sortSymTabSymbolsInAdlt, numLocals); + return; + } + // We want to group the local symbols by file. For that we rebuild the local // part of the symbols vector. We do not need to care about the STT_FILE // symbols, they are already naturally placed first in each group. That @@ -2258,6 +2263,50 @@ void SymbolTableBaseSection::sortSymTabSymbols() { *i++ = entry; } +template +void SymbolTableBaseSection::sortSymTabSymbolsInAdlt(size_t numLocals) { + auto localEnd = symbols.begin() + numLocals; + + using SortKey = std::tuple; + auto makeKey = [](const SymbolTableEntry& ent) -> SortKey { + const InputFile* file = ent.sym->file; + if(auto* soext = dyn_cast_or_null>(file)) { + return {static_cast(soext->orderIdx), file}; + } + return {-1, file}; + }; + + for (InputFile* file : ctx->sharedFilesExtended) { + auto* soext = cast>(file); + soext->sharedLocalSymbolIndex = llvm::None; + soext->sharedGlobalSymbolIndex = llvm::None; + } + + // sort local symbols + llvm::stable_sort(llvm::make_range(symbols.begin(), localEnd), + [makeKey](const SymbolTableEntry& lhs, const SymbolTableEntry& rhs) { + return makeKey(lhs) <= makeKey(rhs); + }); + + // sort global symbols + llvm::stable_sort(llvm::make_range(localEnd, symbols.end()), + [makeKey](const SymbolTableEntry& lhs, const SymbolTableEntry& rhs) { + return makeKey(lhs) <= makeKey(rhs); + }); + + // extract file boundaries for local symbols + for (auto iter = symbols.begin(); iter != localEnd; ++iter) + if (auto* soext = dyn_cast_or_null>(iter->sym->file)) + if (!soext->sharedLocalSymbolIndex) + soext->sharedLocalSymbolIndex = std::distance(symbols.begin(), iter); + + // extract file boundaries for global symbols + for (auto iter = localEnd; iter != symbols.end(); ++iter) + if (auto* soext = dyn_cast_or_null>(iter->sym->file)) + if (!soext->sharedGlobalSymbolIndex) + soext->sharedGlobalSymbolIndex = std::distance(symbols.begin(), iter); +} + void SymbolTableBaseSection::addSymbol(Symbol *b) { // Adding a local symbol to a .dynsym is a bug. assert(this->type != SHT_DYNSYM || !b->isLocal()); @@ -4016,6 +4065,16 @@ static_assert( "adlt_relocations_segment_t size is 16 bytes" ); +static_assert( + sizeof(adlt_cross_section_ref_t) == 16, + "adlt_cross_section_ref_t size is 16 bytes" +); + +static_assert( + sizeof(adlt_cross_section_array_t) == 24, + "adlt_cross_section_ref_t size is 24 bytes" +); + static_assert( sizeof(adlt_hash_type_t) == sizeof(Elf64_Byte), "String hash type enum should occupy only one byte" @@ -4062,6 +4121,7 @@ void AdltSection::finalizeContents() { common = makeCommonData(); + std::memset(&header, 0, sizeof(header)); header = adlt_section_header_t{ adltSchemaVersion, // .schemaVersion sizeof(adlt_section_header_t), // .schemaHeaderSize @@ -4149,6 +4209,7 @@ AdltSection::makeCommonData() { return CommonData { {}, // .relaDynSegs {}, // .relaPltSegs + UINT32_MAX, // .symtabSecIndex, filled in writeTo }; } @@ -4170,8 +4231,6 @@ AdltSection::makeSoData(const SharedFileExtended* soext) { data.initArrayName = soext->addAdltPostfix(".init_array"); data.finiArrayName = soext->addAdltPostfix(".fini_array"); - // TODO: fill data.sharedLocalIndex - // TODO: fill data.sharedGlobalIndex // TODO: fill data.relaDynSegs // TODO: fill data.relaPltSegs @@ -4189,6 +4248,8 @@ Elf64_Xword AdltSection::calculateHash(StringRef str) const { return 0x0; case ADLT_HASH_TYPE_GNU_HASH: return hashGnu(str); + case ADLT_HASH_TYPE_SYSV_HASH: + return hashSysV(str); case ADLT_HASH_TYPE_DEBUG_CONST: return 0xdeadbeef1337c0de; default: @@ -4212,8 +4273,14 @@ adlt_psod_t AdltSection::serialize(const SoData& soData) const { soData.finiArraySec->size, // size } : adlt_cross_section_array_t{}, adlt_blob_array_t {}, // .dtNeeded, filled in writeTo - adlt_cross_section_ref_t {}, // .sharedLocalSymbolIndex TODO - adlt_cross_section_ref_t {}, // .sharedGlobalSymbolIndex TOOD + adlt_cross_section_ref_t { + soData.sharedLocalIndex ? common.symtabSecIndex : UINT32_MAX, + soData.sharedLocalIndex.value_or(0), + }, // .sharedLocalSymbolIndex + adlt_cross_section_ref_t { + soData.sharedGlobalIndex ? common.symtabSecIndex : UINT32_MAX, + soData.sharedGlobalIndex.value_or(0), + }, // .sharedGlobalSymbolIndex adlt_blob_u16_array_t {}, // .phIndexes, filled in writeTo adlt_blob_array_t {}, // .relaDynSegs, filled in writeTo adlt_blob_array_t {}, // .relaPltSegs, filled in writeTo @@ -4276,22 +4343,37 @@ template void AdltSection::finalizeOnWrite() { // require Writer::setPhdrs previously been called header.overallMappedSize = estimateOverallMappedSize(); + + if (OutputSection* osec = findOutSection(".symtab")) { + common.symtabSecIndex = osec->sectionIndex; + } + + for (auto& it: llvm::enumerate(soInputs)) { + finalizeOnWrite(it.index(), it.value()); + } +} + +template +void AdltSection::finalizeOnWrite(size_t idx, SoData& soData) { + auto* soext = cast>(ctx->sharedFilesExtended[idx]); + + // require SymbolTableBaseSection::sortSymTabSymbolsInAdlt for .symtab called + soData.sharedLocalIndex = soext->sharedLocalSymbolIndex; + soData.sharedGlobalIndex = soext->sharedGlobalSymbolIndex; } template void AdltSection::writeTo(uint8_t* buf) { // TODO: take care of endianness, use write32 / write64 etc. + finalizeOnWrite(); + // pre-serialized SoData, enriched with offsets during blob writing SmallVector psods; - for (const auto& it: llvm::enumerate(soInputs)) { const SoData& soData = it.value(); - adlt_psod_t psod = serialize(soData); - psods.push_back(psod); + psods.push_back(serialize(soData)); } - finalizeOnWrite(); - // serialize blob data { uint8_t* const blobBuf = buf + header.blobStart; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index a93ff052cfe3..9afb747f29c2 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -645,6 +645,7 @@ public: protected: void sortSymTabSymbols(); + template void sortSymTabSymbolsInAdlt(size_t numLocals); // A vector of symbols and their string table offsets. SmallVector symbols; @@ -1253,10 +1254,10 @@ public: OutputSection* initArraySec; OutputSection* finiArraySec; - Elf64_Off sharedLocalIndex; // TODO - Elf64_Off sharedGlobalIndex; // TODO + llvm::Optional sharedLocalIndex; + llvm::Optional sharedGlobalIndex; - SmallVector phIndexes; // TODO + SmallVector phIndexes; SmallVector relaDynSegs; // TODO SmallVector relaPltSegs; // TODO }; @@ -1265,6 +1266,7 @@ public: struct CommonData { SmallVector relaDynSegs; // TODO SmallVector relaPltSegs; // TODO + uint32_t symtabSecIndex = UINT32_MAX; }; public: @@ -1291,6 +1293,7 @@ private: size_t estimateBlobSize() const; void finalizeOnWrite(); + void finalizeOnWrite(size_t idx, SoData& sodata); template adlt_blob_array_t writeArray(uint8_t* buff, size_t offset, diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 3b176ab56020..fb2f260f3d94 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2462,7 +2462,7 @@ SmallVector Writer::createPhdrs(Partition &part) { // Check outputs for (ELFFileBase *baseFile : ctx->sharedFilesExtended) { - auto *soFile = cast>(baseFile); + __attribute__((unused)) auto *soFile = cast>(baseFile); assert(!soFile->programHeaderIndexes.empty()); } } -- Gitee