From e9b9a1d3202d86d9eb2b49c6463fde0f15f9dc94 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 17 Oct 2023 13:16:50 -0700 Subject: [PATCH] [ELF] Move demoteSymbols to Writer.cpp. NFC History of demoteSharedSymbols: * https://reviews.llvm.org/D45536 demotes SharedSymbol * https://reviews.llvm.org/D111365 demotes lazy symbols * The pending #69295 will demote symbols defined in discarded sections The pass is placed after markLive just to be clear that it needs `isNeeded` information computed by markLive. The remaining passes in Driver.cpp do not use symbol information. Move the pass to Writer.cpp to be closer to other symbol-related passes. --- lld/ELF/Driver.cpp | 19 ------------------- lld/ELF/Writer.cpp | 28 +++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index d082463d34e576..5f88389a584082 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -2248,24 +2248,6 @@ static void replaceCommonSymbols() { } } -// If all references to a DSO happen to be weak, the DSO is not added to -// DT_NEEDED. If that happens, replace ShardSymbol with Undefined to avoid -// dangling references to an unneeded DSO. Use a weak binding to avoid -// --no-allow-shlib-undefined diagnostics. Similarly, demote lazy symbols. -static void demoteSharedAndLazySymbols() { - llvm::TimeTraceScope timeScope("Demote shared and lazy symbols"); - for (Symbol *sym : symtab.getSymbols()) { - auto *s = dyn_cast(sym); - if (!(s && !cast(s->file)->isNeeded) && !sym->isLazy()) - continue; - - uint8_t binding = sym->isLazy() ? sym->binding : uint8_t(STB_WEAK); - Undefined(nullptr, sym->getName(), binding, sym->stOther, sym->type) - .overwrite(*sym); - sym->versionId = VER_NDX_GLOBAL; - } -} - // The section referred to by `s` is considered address-significant. Set the // keepUnique flag on the section if appropriate. static void markAddrsig(Symbol *s) { @@ -3023,7 +3005,6 @@ void LinkerDriver::link(opt::InputArgList &args) { // Garbage collection and removal of shared symbols from unused shared objects. invokeELFT(markLive,); - demoteSharedAndLazySymbols(); // Make copies of any input sections that need to be copied into each // partition. diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 5077c972658a14..5fc4412aa49f13 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -251,6 +251,23 @@ void elf::addReservedSymbols() { ElfSym::edata2 = add("_edata", -1); } +// If all references to a DSO happen to be weak, the DSO is not added to +// DT_NEEDED. If that happens, replace ShardSymbol with Undefined to avoid +// dangling references to an unneeded DSO. Use a weak binding to avoid +// --no-allow-shlib-undefined diagnostics. Similarly, demote lazy symbols. +static void demoteSymbols() { + llvm::TimeTraceScope timeScope("Demote symbols"); + for (Symbol *sym : symtab.getSymbols()) { + auto *s = dyn_cast(sym); + if (!(s && !cast(s->file)->isNeeded) && !sym->isLazy()) + continue; + uint8_t binding = sym->isLazy() ? sym->binding : uint8_t(STB_WEAK); + Undefined(nullptr, sym->getName(), binding, sym->stOther, sym->type) + .overwrite(*sym); + sym->versionId = VER_NDX_GLOBAL; + } +} + // Fully static executables don't support MTE globals at this point in time, as // we currently rely on: // - A dynamic loader to process relocations, and @@ -1935,12 +1952,13 @@ template void Writer::finalizeSections() { for (Partition &part : partitions) finalizeSynthetic(part.ehFrame.get()); } + } - if (config->hasDynSymTab) { - parallelForEach(symtab.getSymbols(), [](Symbol *sym) { - sym->isPreemptible = computeIsPreemptible(*sym); - }); - } + demoteSymbols(); + if (config->hasDynSymTab) { + parallelForEach(symtab.getSymbols(), [](Symbol *sym) { + sym->isPreemptible = computeIsPreemptible(*sym); + }); } // Change values of linker-script-defined symbols from placeholders (assigned