Skip to content

[ELF] Move elf::symtab into Ctx #109612

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions lld/ELF/Arch/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,7 @@ template <class ELFT> void ObjFile<ELFT>::importCmseSymbols() {
continue;
}

if (symtab.cmseImportLib.count(sym->getName())) {
if (ctx.symtab->cmseImportLib.count(sym->getName())) {
error("CMSE symbol '" + sym->getName() +
"' is multiply defined in import library '" + toString(this) + "'");
continue;
Expand All @@ -1227,7 +1227,7 @@ template <class ELFT> void ObjFile<ELFT>::importCmseSymbols() {
Twine(ACLESESYM_SIZE) + " bytes");
}

symtab.cmseImportLib[sym->getName()] = sym;
ctx.symtab->cmseImportLib[sym->getName()] = sym;
}
}

Expand Down Expand Up @@ -1263,9 +1263,9 @@ static std::string checkCmseSymAttributes(Symbol *acleSeSym, Symbol *sym) {
void elf::processArmCmseSymbols() {
if (!ctx.arg.cmseImplib)
return;
// Only symbols with external linkage end up in symtab, so no need to do
// Only symbols with external linkage end up in ctx.symtab, so no need to do
// linkage checks. Only check symbol type.
for (Symbol *acleSeSym : symtab.getSymbols()) {
for (Symbol *acleSeSym : ctx.symtab->getSymbols()) {
if (!acleSeSym->getName().starts_with(ACLESESYM_PREFIX))
continue;
// If input object build attributes do not support CMSE, error and disable
Expand All @@ -1279,7 +1279,7 @@ void elf::processArmCmseSymbols() {
// Try to find the associated symbol definition.
// Symbol must have external linkage.
StringRef name = acleSeSym->getName().substr(std::strlen(ACLESESYM_PREFIX));
Symbol *sym = symtab.find(name);
Symbol *sym = ctx.symtab->find(name);
if (!sym) {
error(toString(acleSeSym->file) + ": cmse special symbol '" +
acleSeSym->getName() +
Expand All @@ -1295,7 +1295,7 @@ void elf::processArmCmseSymbols() {
}

// <sym> may be redefined later in the link in .gnu.sgstubs
symtab.cmseSymMap[name] = {acleSeSym, sym};
ctx.symtab->cmseSymMap[name] = {acleSeSym, sym};
}

// If this is an Arm CMSE secure app, replace references to entry symbol <sym>
Expand All @@ -1304,8 +1304,8 @@ void elf::processArmCmseSymbols() {
MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
for (size_t i = 0, e = syms.size(); i != e; ++i) {
StringRef symName = syms[i]->getName();
if (symtab.cmseSymMap.count(symName))
syms[i] = symtab.cmseSymMap[symName].acleSeSym;
if (ctx.symtab->cmseSymMap.count(symName))
syms[i] = ctx.symtab->cmseSymMap[symName].acleSeSym;
}
});
}
Expand All @@ -1332,26 +1332,26 @@ ArmCmseSGSection::ArmCmseSGSection()
/*alignment=*/32, ".gnu.sgstubs") {
entsize = ACLESESYM_SIZE;
// The range of addresses used in the CMSE import library should be fixed.
for (auto &[_, sym] : symtab.cmseImportLib) {
for (auto &[_, sym] : ctx.symtab->cmseImportLib) {
if (impLibMaxAddr <= sym->value)
impLibMaxAddr = sym->value + sym->size;
}
if (symtab.cmseSymMap.empty())
if (ctx.symtab->cmseSymMap.empty())
return;
addMappingSymbol();
for (auto &[_, entryFunc] : symtab.cmseSymMap)
for (auto &[_, entryFunc] : ctx.symtab->cmseSymMap)
addSGVeneer(cast<Defined>(entryFunc.acleSeSym),
cast<Defined>(entryFunc.sym));
for (auto &[_, sym] : symtab.cmseImportLib) {
if (!symtab.inCMSEOutImpLib.count(sym->getName()))
for (auto &[_, sym] : ctx.symtab->cmseImportLib) {
if (!ctx.symtab->inCMSEOutImpLib.count(sym->getName()))
warn("entry function '" + sym->getName() +
"' from CMSE import library is not present in secure application");
}

if (!symtab.cmseImportLib.empty() && ctx.arg.cmseOutputLib.empty()) {
for (auto &[_, entryFunc] : symtab.cmseSymMap) {
if (!ctx.symtab->cmseImportLib.empty() && ctx.arg.cmseOutputLib.empty()) {
for (auto &[_, entryFunc] : ctx.symtab->cmseSymMap) {
Symbol *sym = entryFunc.sym;
if (!symtab.inCMSEOutImpLib.count(sym->getName()))
if (!ctx.symtab->inCMSEOutImpLib.count(sym->getName()))
warn("new entry function '" + sym->getName() +
"' introduced but no output import library specified");
}
Expand All @@ -1360,17 +1360,17 @@ ArmCmseSGSection::ArmCmseSGSection()

void ArmCmseSGSection::addSGVeneer(Symbol *acleSeSym, Symbol *sym) {
entries.emplace_back(acleSeSym, sym);
if (symtab.cmseImportLib.count(sym->getName()))
symtab.inCMSEOutImpLib[sym->getName()] = true;
if (ctx.symtab->cmseImportLib.count(sym->getName()))
ctx.symtab->inCMSEOutImpLib[sym->getName()] = true;
// Symbol addresses different, nothing to do.
if (acleSeSym->file != sym->file ||
cast<Defined>(*acleSeSym).value != cast<Defined>(*sym).value)
return;
// Only secure symbols with values equal to that of it's non-secure
// counterpart needs to be in the .gnu.sgstubs section.
ArmCmseSGVeneer *ss = nullptr;
if (symtab.cmseImportLib.count(sym->getName())) {
Defined *impSym = symtab.cmseImportLib[sym->getName()];
if (ctx.symtab->cmseImportLib.count(sym->getName())) {
Defined *impSym = ctx.symtab->cmseImportLib[sym->getName()];
ss = make<ArmCmseSGVeneer>(sym, acleSeSym, impSym->value);
} else {
ss = make<ArmCmseSGVeneer>(sym, acleSeSym);
Expand Down Expand Up @@ -1451,12 +1451,12 @@ template <typename ELFT> void elf::writeARMCmseImportLib() {
osIsPairs.emplace_back(make<OutputSection>(impSymTab->name, 0, 0), impSymTab);
osIsPairs.emplace_back(make<OutputSection>(shstrtab->name, 0, 0), shstrtab);

std::sort(symtab.cmseSymMap.begin(), symtab.cmseSymMap.end(),
std::sort(ctx.symtab->cmseSymMap.begin(), ctx.symtab->cmseSymMap.end(),
[](const auto &a, const auto &b) -> bool {
return a.second.sym->getVA() < b.second.sym->getVA();
});
// Copy the secure gateway entry symbols to the import library symbol table.
for (auto &p : symtab.cmseSymMap) {
for (auto &p : ctx.symtab->cmseSymMap) {
Defined *d = cast<Defined>(p.second.sym);
impSymTab->addSymbol(makeDefined(
ctx.internalFile, d->getName(), d->computeBinding(),
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/Arch/PPC64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ void elf::writePrefixedInstruction(uint8_t *loc, uint64_t insn) {

static bool addOptional(StringRef name, uint64_t value,
std::vector<Defined *> &defined) {
Symbol *sym = symtab.find(name);
Symbol *sym = ctx.symtab->find(name);
if (!sym || sym->isDefined())
return false;
sym->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN,
Expand Down
2 changes: 2 additions & 0 deletions lld/ELF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class InputSectionBase;
class EhInputSection;
class Defined;
class Symbol;
class SymbolTable;
class BitcodeCompiler;
class OutputSection;
class LinkerScript;
Expand Down Expand Up @@ -600,6 +601,7 @@ struct Ctx {
Defined *tlsModuleBase;
};
ElfSym sym;
std::unique_ptr<SymbolTable> symtab;

SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers;
SmallVector<ELFFileBase *, 0> objectFiles;
Expand Down
43 changes: 22 additions & 21 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ void Ctx::reset() {

in.reset();
sym = ElfSym{};
symtab = std::make_unique<SymbolTable>();

memoryBuffers.clear();
objectFiles.clear();
Expand Down Expand Up @@ -155,7 +156,6 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
context->e.cleanupCallback = []() {
elf::ctx.reset();
elf::ctx.partitions.emplace_back();
symtab = SymbolTable();

SharedFile::vernauxNum = 0;
};
Expand All @@ -167,6 +167,7 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
LinkerScript script(ctx);
ctx.script = &script;
ctx.symAux.emplace_back();
ctx.symtab = std::make_unique<SymbolTable>();

ctx.partitions.clear();
ctx.partitions.emplace_back();
Expand Down Expand Up @@ -2194,7 +2195,7 @@ static void handleUndefinedGlob(Ctx &ctx, StringRef arg) {
// Calling sym->extract() in the loop is not safe because it may add new
// symbols to the symbol table, invalidating the current iterator.
SmallVector<Symbol *, 0> syms;
for (Symbol *sym : symtab.getSymbols())
for (Symbol *sym : ctx.symtab->getSymbols())
if (!sym->isPlaceholder() && pat->match(sym->getName()))
syms.push_back(sym);

Expand All @@ -2203,7 +2204,7 @@ static void handleUndefinedGlob(Ctx &ctx, StringRef arg) {
}

static void handleLibcall(Ctx &ctx, StringRef name) {
Symbol *sym = symtab.find(name);
Symbol *sym = ctx.symtab->find(name);
if (sym && sym->isLazy() && isa<BitcodeFile>(sym->file)) {
if (!ctx.arg.whyExtract.empty())
ctx.whyExtractRecords.emplace_back("<libcall>", sym->file, *sym);
Expand Down Expand Up @@ -2390,7 +2391,7 @@ template <class ELFT>
static void findKeepUniqueSections(Ctx &ctx, opt::InputArgList &args) {
for (auto *arg : args.filtered(OPT_keep_unique)) {
StringRef name = arg->getValue();
auto *d = dyn_cast_or_null<Defined>(symtab.find(name));
auto *d = dyn_cast_or_null<Defined>(ctx.symtab->find(name));
if (!d || !d->section) {
warn("could not find symbol " + name + " to keep unique");
continue;
Expand All @@ -2405,7 +2406,7 @@ static void findKeepUniqueSections(Ctx &ctx, opt::InputArgList &args) {

// Symbols in the dynsym could be address-significant in other executables
// or DSOs, so we conservatively mark them as address-significant.
for (Symbol *sym : symtab.getSymbols())
for (Symbol *sym : ctx.symtab->getSymbols())
if (sym->includeInDynsym())
markAddrsig(sym);

Expand Down Expand Up @@ -2574,24 +2575,24 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
if (!seen.insert(name).second)
continue;

Symbol *sym = symtab.find(name);
Symbol *sym = ctx.symtab->find(name);
if (!sym)
continue;

Symbol *wrap =
symtab.addUnusedUndefined(saver().save("__wrap_" + name), sym->binding);
Symbol *wrap = ctx.symtab->addUnusedUndefined(
saver().save("__wrap_" + name), sym->binding);

// If __real_ is referenced, pull in the symbol if it is lazy. Do this after
// processing __wrap_ as that may have referenced __real_.
StringRef realName = saver().save("__real_" + name);
if (Symbol *real = symtab.find(realName)) {
symtab.addUnusedUndefined(name, sym->binding);
if (Symbol *real = ctx.symtab->find(realName)) {
ctx.symtab->addUnusedUndefined(name, sym->binding);
// Update sym's binding, which will replace real's later in
// SymbolTable::wrap.
sym->binding = real->binding;
}

Symbol *real = symtab.addUnusedUndefined(realName);
Symbol *real = ctx.symtab->addUnusedUndefined(realName);
v.push_back({sym, real, wrap});

// We want to tell LTO not to inline symbols to be overwritten
Expand Down Expand Up @@ -2626,7 +2627,7 @@ static void combineVersionedSymbol(Symbol &sym,
//
// * There is a definition of foo@v1 and foo@@v1.
// * There is a definition of foo@v1 and foo.
Defined *sym2 = dyn_cast_or_null<Defined>(symtab.find(sym.getName()));
Defined *sym2 = dyn_cast_or_null<Defined>(ctx.symtab->find(sym.getName()));
if (!sym2)
return;
const char *suffix2 = sym2->getVersionSuffix();
Expand Down Expand Up @@ -2681,7 +2682,7 @@ static void redirectSymbols(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) {
// symbols with a non-default version (foo@v1) and check whether it should be
// combined with foo or foo@@v1.
if (ctx.arg.versionDefinitions.size() > 2)
for (Symbol *sym : symtab.getSymbols())
for (Symbol *sym : ctx.symtab->getSymbols())
if (sym->hasVersionSuffix)
combineVersionedSymbol(*sym, map);

Expand All @@ -2697,7 +2698,7 @@ static void redirectSymbols(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) {

// Update pointers in the symbol table.
for (const WrappedSymbol &w : wrapped)
symtab.wrap(w.sym, w.real, w.wrap);
ctx.symtab->wrap(w.sym, w.real, w.wrap);
}

static void reportMissingFeature(StringRef config, const Twine &report) {
Expand Down Expand Up @@ -2861,22 +2862,22 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {

// Handle --trace-symbol.
for (auto *arg : args.filtered(OPT_trace_symbol))
symtab.insert(arg->getValue())->traced = true;
ctx.symtab->insert(arg->getValue())->traced = true;

ctx.internalFile = createInternalFile("<internal>");

// Handle -u/--undefined before input files. If both a.a and b.so define foo,
// -u foo a.a b.so will extract a.a.
for (StringRef name : ctx.arg.undefined)
symtab.addUnusedUndefined(name)->referenced = true;
ctx.symtab->addUnusedUndefined(name)->referenced = true;

parseFiles(files, armCmseImpLib);

// Create dynamic sections for dynamic linking and static PIE.
ctx.arg.hasDynSymTab = !ctx.sharedFiles.empty() || ctx.arg.isPic;

// If an entry symbol is in a static archive, pull out that file now.
if (Symbol *sym = symtab.find(ctx.arg.entry))
if (Symbol *sym = ctx.symtab->find(ctx.arg.entry))
handleUndefined(ctx, sym, "--entry");

// Handle the `--undefined-glob <pattern>` options.
Expand All @@ -2890,13 +2891,13 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {

// Prevent LTO from removing any definition referenced by -u.
for (StringRef name : ctx.arg.undefined)
if (Defined *sym = dyn_cast_or_null<Defined>(symtab.find(name)))
if (Defined *sym = dyn_cast_or_null<Defined>(ctx.symtab->find(name)))
sym->isUsedInRegularObj = true;

// Mark -init and -fini symbols so that the LTO doesn't eliminate them.
if (Symbol *sym = dyn_cast_or_null<Defined>(symtab.find(ctx.arg.init)))
if (Symbol *sym = dyn_cast_or_null<Defined>(ctx.symtab->find(ctx.arg.init)))
sym->isUsedInRegularObj = true;
if (Symbol *sym = dyn_cast_or_null<Defined>(symtab.find(ctx.arg.fini)))
if (Symbol *sym = dyn_cast_or_null<Defined>(ctx.symtab->find(ctx.arg.fini)))
sym->isUsedInRegularObj = true;

// If any of our inputs are bitcode files, the LTO code generator may create
Expand Down Expand Up @@ -2977,7 +2978,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// name "foo@ver1") rather do harm, so we don't call this if -r is given.
if (!ctx.arg.relocatable) {
llvm::TimeTraceScope timeScope("Process symbol versions");
symtab.scanVersionScript();
ctx.symtab->scanVersionScript();
}

// Skip the normal linked output if some LTO options are specified.
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/ICF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ template <class ELFT> void ICF<ELFT>::run() {
// cannot be merged with the later computeIsPreemptible() pass which is used
// by scanRelocations().
if (ctx.arg.hasDynSymTab)
for (Symbol *sym : symtab.getSymbols())
for (Symbol *sym : ctx.symtab->getSymbols())
sym->isPreemptible = computeIsPreemptible(*sym);

// Two text sections may have identical content and relocations but different
Expand Down Expand Up @@ -568,7 +568,7 @@ template <class ELFT> void ICF<ELFT>::run() {
d->folded = true;
}
};
for (Symbol *sym : symtab.getSymbols())
for (Symbol *sym : ctx.symtab->getSymbols())
fold(sym);
parallelForEach(ctx.objectFiles, [&](ELFFileBase *file) {
for (Symbol *sym : file->getLocalSymbols())
Expand Down
Loading
Loading