[ELF] Merge parseSymbolVersion and computeIspreemptible

ICF needs isPreemptible, which can be combined with parseSymbolVersion.
This commit is contained in:
Fangrui Song 2024-12-08 17:50:16 -08:00
parent 18538e2134
commit 712264b83c
6 changed files with 25 additions and 18 deletions

View File

@ -2987,6 +2987,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
if (!ctx.arg.relocatable) {
llvm::TimeTraceScope timeScope("Process symbol versions");
ctx.symtab->scanVersionScript();
parseVersionAndComputeIsPreemptible(ctx);
}
// Skip the normal linked output if some LTO options are specified.

View File

@ -461,13 +461,6 @@ static void combineRelocHashes(unsigned cnt, InputSection *isec,
// The main function of ICF.
template <class ELFT> void ICF<ELFT>::run() {
// Compute isPreemptible early. We may add more symbols later, so this loop
// cannot be merged with the later computeIsPreemptible() pass which is used
// by scanRelocations().
if (ctx.arg.hasDynSymTab)
for (Symbol *sym : ctx.symtab->getSymbols())
sym->isPreemptible = computeIsPreemptible(ctx, *sym);
// Two text sections may have identical content and relocations but different
// LSDA, e.g. the two functions may have catch blocks of different types. If a
// text section is referenced by a .eh_frame FDE with LSDA, it is not

View File

@ -350,13 +350,6 @@ void SymbolTable::scanVersionScript() {
assignAsterisk(pat, &v, true);
}
// Symbol themselves might know their versions because symbols
// can contain versions in the form of <name>@<version>.
// Let them parse and update their names to exclude version suffix.
for (Symbol *sym : symVector)
if (sym->hasVersionSuffix)
sym->parseSymbolVersion(ctx);
// isPreemptible is false at this point. To correctly compute the binding of a
// Defined (which is used by includeInDynsym(ctx)), we need to know if it is
// VER_NDX_LOCAL or not. Compute symbol versions before handling

View File

@ -11,6 +11,7 @@
#include "InputFiles.h"
#include "InputSection.h"
#include "OutputSections.h"
#include "SymbolTable.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Writer.h"
@ -345,7 +346,7 @@ bool elf::computeIsPreemptible(Ctx &ctx, const Symbol &sym) {
// Only symbols with default visibility that appear in dynsym can be
// preempted. Symbols with protected visibility cannot be preempted.
if (!sym.includeInDynsym(ctx) || sym.visibility() != STV_DEFAULT)
if (sym.visibility() != STV_DEFAULT)
return false;
// At this point copy relocations have not been created yet, so any
@ -370,6 +371,20 @@ bool elf::computeIsPreemptible(Ctx &ctx, const Symbol &sym) {
return true;
}
void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
// Symbol themselves might know their versions because symbols
// can contain versions in the form of <name>@<version>.
// Let them parse and update their names to exclude version suffix.
bool hasDynSymTab = ctx.arg.hasDynSymTab;
for (Symbol *sym : ctx.symtab->getSymbols()) {
if (sym->hasVersionSuffix)
sym->parseSymbolVersion(ctx);
if (hasDynSymTab)
sym->isPreemptible =
sym->includeInDynsym(ctx) && computeIsPreemptible(ctx, *sym);
}
}
// Merge symbol properties.
//
// When we have many symbols of the same name, we choose one of them,

View File

@ -527,6 +527,7 @@ void reportDuplicate(Ctx &, const Symbol &sym, const InputFile *newFile,
InputSectionBase *errSec, uint64_t errOffset);
void maybeWarnUnorderableSymbol(Ctx &, const Symbol *sym);
bool computeIsPreemptible(Ctx &, const Symbol &sym);
void parseVersionAndComputeIsPreemptible(Ctx &);
} // namespace lld::elf

View File

@ -297,8 +297,11 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
}
}
if (ctx.arg.hasDynSymTab)
sym->isPreemptible = computeIsPreemptible(ctx, *sym);
if (ctx.arg.hasDynSymTab) {
sym->exportDynamic = sym->includeInDynsym(ctx);
sym->isPreemptible =
sym->exportDynamic && computeIsPreemptible(ctx, *sym);
}
}
}
@ -1888,7 +1891,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (ctx.in.symTab)
ctx.in.symTab->addSymbol(sym);
if (sym->includeInDynsym(ctx)) {
if (sym->exportDynamic) {
ctx.partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
if (auto *file = dyn_cast<SharedFile>(sym->file))
if (file->isNeeded && !sym->isUndefined())