From 1acabd17df3f821cc5fdcb2408ee2749c3cff73d Mon Sep 17 00:00:00 2001 From: likholatovevgeny Date: Fri, 3 May 2024 16:27:35 +0300 Subject: [PATCH 1/4] Resolved duplicates for adlt. Signed-off-by: likholatovevgeny --- lld/ELF/Config.h | 2 ++ lld/ELF/Driver.cpp | 5 +++++ lld/ELF/InputFiles.cpp | 27 +++++++++++++++++++++++++++ lld/ELF/InputFiles.h | 2 ++ lld/ELF/Writer.cpp | 7 ++++--- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 6583d7d8e562..d96a9d0d229f 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -399,6 +399,8 @@ struct Ctx { // A tuple of (reference, extractedFile, sym). Used by --why-extract=. SmallVector, 0> whyExtractRecords; + // Map of symbols frequency (only defined) + llvm::DenseMap eSymsFreqMap; // A mapping from a symbol to an InputFile referencing it backward. Used by // --warn-backrefs. llvm::DenseMapundefined) addUnusedUndefined(name)->referenced = true; + // Fill sym frequensy map for defined syms, This will help to find duplicates. + if (config->adlt) + for (auto *file : files) + fillSymsFreqMap(file); + // Add all files to the symbol table. This will add almost all // symbols that we need to the symbol table. This process might // add files to the link, via autolinking, these files are always diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 0c9a7e006822..899221f45057 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -158,6 +158,18 @@ static bool isCompatible(InputFile *file) { return false; } +template static void doFillSymsFreqMap(InputFile *file) { + if (!isCompatible(file)) + return; + if (auto *f = dyn_cast>(file)) { + f->fillSymsFreqMap(); + } +} + +void elf::fillSymsFreqMap(InputFile *file) { + invokeELFT(doFillSymsFreqMap, file); +} + template static void doParseFile(InputFile *file) { if (!isCompatible(file)) return; @@ -1034,6 +1046,16 @@ InputSectionBase *ObjFile::createInputSection(uint32_t idx, return make(*this, sec, name); } +template void ObjFile::fillSymsFreqMap() { + ArrayRef eSyms = this->getELFSyms(); + for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) { + if (!eSyms[i].isDefined()) + continue; + StringRef name = CHECK(eSyms[i].getName(stringTable), this); + ctx->eSymsFreqMap[name]++; + } +} + // Initialize this->Symbols. this->Symbols is a parallel array as // its corresponding ELF symbol table. template @@ -1052,6 +1074,11 @@ void ObjFile::initializeSymbols(const object::ELFFile &obj) { if (!ctx->adltWithCfi) ctx->adltWithCfi = true; } + if (config->adlt && eSyms[i].isDefined() && + ctx->eSymsFreqMap[name] > 1) { + auto *f = cast>(this); + name = f->addAdltPostfix(name); + } symbols[i] = symtab.insert(name); } diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 1db53c987f94..3366ca5c0348 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -47,6 +47,7 @@ extern std::unique_ptr tar; llvm::Optional readFile(StringRef path); // Add symbols in File to the symbol table. +void fillSymsFreqMap(InputFile *file); void parseFile(InputFile *file); // The root class of input files. @@ -292,6 +293,7 @@ public: // Get cached DWARF information. DWARFCache *getDwarf(); + void fillSymsFreqMap(); void initializeLocalSymbols(); void postParse(); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 7439ed63c644..47a6bef1a9b0 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2110,9 +2110,10 @@ template void Writer::finalizeSections() { if (sym->includeInDynsym()) { partitions[sym->partition - 1].dynSymTab->addSymbol(sym); - if (auto *file = dyn_cast_or_null(sym->file)) - if (file->isNeeded && !sym->isUndefined()) - addVerneed(sym); + if(!config->adlt) // TODO: fix for adlt. + if (auto *file = dyn_cast_or_null(sym->file)) + if (file->isNeeded && !sym->isUndefined()) + addVerneed(sym); } } -- Gitee From fed5699f0f9f4023d03a0cdd7ca6631cde85e3bf Mon Sep 17 00:00:00 2001 From: likholatovevgeny Date: Fri, 3 May 2024 17:25:35 +0300 Subject: [PATCH 2/4] Changed resolve of duplicates. Signed-off-by: likholatovevgeny --- lld/ELF/InputFiles.cpp | 20 +++++++++----------- lld/ELF/Writer.cpp | 7 +++---- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 899221f45057..4724d1833d70 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -161,9 +161,8 @@ static bool isCompatible(InputFile *file) { template static void doFillSymsFreqMap(InputFile *file) { if (!isCompatible(file)) return; - if (auto *f = dyn_cast>(file)) { + if (auto *f = dyn_cast>(file)) f->fillSymsFreqMap(); - } } void elf::fillSymsFreqMap(InputFile *file) { @@ -1069,15 +1068,14 @@ void ObjFile::initializeSymbols(const object::ELFFile &obj) { for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) if (!symbols[i]) { StringRef name = CHECK(eSyms[i].getName(stringTable), this); - if (config->adlt && name == "__cfi_check") { - name = this->getUniqueName(name); - if (!ctx->adltWithCfi) - ctx->adltWithCfi = true; - } - if (config->adlt && eSyms[i].isDefined() && - ctx->eSymsFreqMap[name] > 1) { - auto *f = cast>(this); - name = f->addAdltPostfix(name); + if (config->adlt) { + if (name == "__cfi_check") { + name = this->getUniqueName(name); + if (!ctx->adltWithCfi) + ctx->adltWithCfi = true; + } else if (eSyms[i].isDefined() && ctx->eSymsFreqMap[name] > 1) { + name = this->getUniqueName(name); + } } symbols[i] = symtab.insert(name); } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 47a6bef1a9b0..7439ed63c644 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2110,10 +2110,9 @@ template void Writer::finalizeSections() { if (sym->includeInDynsym()) { partitions[sym->partition - 1].dynSymTab->addSymbol(sym); - if(!config->adlt) // TODO: fix for adlt. - if (auto *file = dyn_cast_or_null(sym->file)) - if (file->isNeeded && !sym->isUndefined()) - addVerneed(sym); + if (auto *file = dyn_cast_or_null(sym->file)) + if (file->isNeeded && !sym->isUndefined()) + addVerneed(sym); } } -- Gitee From 7ec2301844271a24d2214eb7abc66d5e112aaa95 Mon Sep 17 00:00:00 2001 From: likholatovevgeny Date: Fri, 3 May 2024 17:49:02 +0300 Subject: [PATCH 3/4] United resolving duplicates for cfi and other symbols. Signed-off-by: likholatovevgeny --- lld/ELF/InputFiles.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 4724d1833d70..4494999331f2 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1068,18 +1068,16 @@ void ObjFile::initializeSymbols(const object::ELFFile &obj) { for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) if (!symbols[i]) { StringRef name = CHECK(eSyms[i].getName(stringTable), this); - if (config->adlt) { - if (name == "__cfi_check") { - name = this->getUniqueName(name); - if (!ctx->adltWithCfi) - ctx->adltWithCfi = true; - } else if (eSyms[i].isDefined() && ctx->eSymsFreqMap[name] > 1) { - name = this->getUniqueName(name); - } + if (config->adlt && eSyms[i].isDefined() && ctx->eSymsFreqMap[name] > 1) { + if (name == "__cfi_check") + ctx->adltWithCfi = true; + name = this->getUniqueName(name); } symbols[i] = symtab.insert(name); } + + // Perform symbol resolution on non-local symbols. SmallVector undefineds; for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) { -- Gitee From 17d3c99ce6dbfe827b6e6a1b2eed837e3b705989 Mon Sep 17 00:00:00 2001 From: likholatovevgeny Date: Tue, 7 May 2024 11:25:18 +0300 Subject: [PATCH 4/4] Changed DenseMap to DenseSet in Ctx. Signed-off-by: likholatovevgeny --- lld/ELF/Config.h | 5 +++-- lld/ELF/Driver.cpp | 12 +++++++++--- lld/ELF/InputFiles.cpp | 21 +++++++++++---------- lld/ELF/InputFiles.h | 4 ++-- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index d96a9d0d229f..1ea2f4dbe39f 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -399,8 +399,9 @@ struct Ctx { // A tuple of (reference, extractedFile, sym). Used by --why-extract=. SmallVector, 0> whyExtractRecords; - // Map of symbols frequency (only defined) - llvm::DenseMap eSymsFreqMap; + // Store duplicate symbols (only defined). + typedef llvm::DenseMap eSymsCntMap; + llvm::DenseSet eSymsHist; // A mapping from a symbol to an InputFile referencing it backward. Used by // --warn-backrefs. llvm::DenseMapundefined) addUnusedUndefined(name)->referenced = true; - // Fill sym frequensy map for defined syms, This will help to find duplicates. - if (config->adlt) + // Fill eSymsHist for defined syms. This will help to find duplicates. + if (config->adlt) { + Ctx::eSymsCntMap eSymsHist; for (auto *file : files) - fillSymsFreqMap(file); + buildSymsHist(file, eSymsHist); + for (auto eSym : eSymsHist) + if (eSym.second > 1) + ctx->eSymsHist.insert(eSym.first); + eSymsHist.clear(); + } // Add all files to the symbol table. This will add almost all // symbols that we need to the symbol table. This process might diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 4494999331f2..aa908ea4c550 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -158,15 +158,16 @@ static bool isCompatible(InputFile *file) { return false; } -template static void doFillSymsFreqMap(InputFile *file) { +template +static void doBuildSymsHist(InputFile *file, Ctx::eSymsCntMap &eSymsHist) { if (!isCompatible(file)) return; if (auto *f = dyn_cast>(file)) - f->fillSymsFreqMap(); + f->buildSymsHist(eSymsHist); } -void elf::fillSymsFreqMap(InputFile *file) { - invokeELFT(doFillSymsFreqMap, file); +void elf::buildSymsHist(InputFile *file, Ctx::eSymsCntMap &eSymsHist) { + invokeELFT(doBuildSymsHist, file, eSymsHist); } template static void doParseFile(InputFile *file) { @@ -1045,13 +1046,14 @@ InputSectionBase *ObjFile::createInputSection(uint32_t idx, return make(*this, sec, name); } -template void ObjFile::fillSymsFreqMap() { +template +void ObjFile::buildSymsHist(Ctx::eSymsCntMap &eSymsHist) { ArrayRef eSyms = this->getELFSyms(); for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) { if (!eSyms[i].isDefined()) continue; StringRef name = CHECK(eSyms[i].getName(stringTable), this); - ctx->eSymsFreqMap[name]++; + eSymsHist[CachedHashStringRef(name)]++; } } @@ -1068,16 +1070,15 @@ void ObjFile::initializeSymbols(const object::ELFFile &obj) { for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) if (!symbols[i]) { StringRef name = CHECK(eSyms[i].getName(stringTable), this); - if (config->adlt && eSyms[i].isDefined() && ctx->eSymsFreqMap[name] > 1) { - if (name == "__cfi_check") + if (config->adlt && eSyms[i].isDefined() && + ctx->eSymsHist.count(CachedHashStringRef(name)) != 0) { + if (!ctx->adltWithCfi && name == "__cfi_check") ctx->adltWithCfi = true; name = this->getUniqueName(name); } symbols[i] = symtab.insert(name); } - - // Perform symbol resolution on non-local symbols. SmallVector undefineds; for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) { diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 3366ca5c0348..65152c337279 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -47,7 +47,7 @@ extern std::unique_ptr tar; llvm::Optional readFile(StringRef path); // Add symbols in File to the symbol table. -void fillSymsFreqMap(InputFile *file); +void buildSymsHist(InputFile *file, Ctx::eSymsCntMap &eSymsHist); void parseFile(InputFile *file); // The root class of input files. @@ -293,7 +293,7 @@ public: // Get cached DWARF information. DWARFCache *getDwarf(); - void fillSymsFreqMap(); + void buildSymsHist(Ctx::eSymsCntMap &eSymsHist); void initializeLocalSymbols(); void postParse(); -- Gitee