[ELF] Pass Ctx & to ICF and SymbolTable

This commit is contained in:
Fangrui Song 2024-09-29 14:45:00 -07:00
parent 2ab9233f4f
commit bab5d5b6b0
6 changed files with 23 additions and 18 deletions

View File

@ -109,7 +109,7 @@ void Ctx::reset() {
in.reset();
sym = ElfSym{};
symtab = std::make_unique<SymbolTable>();
symtab = std::make_unique<SymbolTable>(*this);
memoryBuffers.clear();
objectFiles.clear();
@ -167,7 +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.symtab = std::make_unique<SymbolTable>(ctx);
ctx.partitions.clear();
ctx.partitions.emplace_back();
@ -3201,7 +3201,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// ICF runs after processSectionCommands() so that we know the output sections.
if (ctx.arg.icf != ICFLevel::None) {
findKeepUniqueSections<ELFT>(ctx, args);
doIcf<ELFT>();
doIcf<ELFT>(ctx);
}
// Read the callgraph now that we know what was gced or icfed

View File

@ -97,6 +97,7 @@ using namespace lld::elf;
namespace {
template <class ELFT> class ICF {
public:
ICF(Ctx &ctx) : ctx(ctx) {}
void run();
private:
@ -120,6 +121,7 @@ private:
void forEachClass(llvm::function_ref<void(size_t, size_t)> fn);
Ctx &ctx;
SmallVector<InputSection *, 0> sections;
// We repeat the main loop while `Repeat` is true.
@ -457,7 +459,7 @@ static void combineRelocHashes(unsigned cnt, InputSection *isec,
isec->eqClass[(cnt + 1) % 2] = hash | (1U << 31);
}
static void print(const Twine &s) {
static void print(Ctx &ctx, const Twine &s) {
if (ctx.arg.printIcfSections)
message(s);
}
@ -546,9 +548,9 @@ template <class ELFT> void ICF<ELFT>::run() {
forEachClassRange(0, sections.size(), [&](size_t begin, size_t end) {
if (end - begin == 1)
return;
print("selected section " + toString(sections[begin]));
print(ctx, "selected section " + toString(sections[begin]));
for (size_t i = begin + 1; i < end; ++i) {
print(" removing identical section " + toString(sections[i]));
print(ctx, " removing identical section " + toString(sections[i]));
sections[begin]->replace(sections[i]);
// At this point we know sections merged are fully identical and hence
@ -586,12 +588,12 @@ template <class ELFT> void ICF<ELFT>::run() {
}
// ICF entry point function.
template <class ELFT> void elf::doIcf() {
template <class ELFT> void elf::doIcf(Ctx &ctx) {
llvm::TimeTraceScope timeScope("ICF");
ICF<ELFT>().run();
ICF<ELFT>(ctx).run();
}
template void elf::doIcf<ELF32LE>();
template void elf::doIcf<ELF32BE>();
template void elf::doIcf<ELF64LE>();
template void elf::doIcf<ELF64BE>();
template void elf::doIcf<ELF32LE>(Ctx &);
template void elf::doIcf<ELF32BE>(Ctx &);
template void elf::doIcf<ELF64LE>(Ctx &);
template void elf::doIcf<ELF64BE>(Ctx &);

View File

@ -10,9 +10,9 @@
#define LLD_ELF_ICF_H
namespace lld::elf {
struct Ctx;
template <class ELFT> void doIcf();
template <class ELFT> void doIcf(Ctx &);
}
#endif

View File

@ -281,7 +281,7 @@ void BitcodeCompiler::add(BitcodeFile &f) {
// If LazyObjFile has not been added to link, emit empty index files.
// This is needed because this is what GNU gold plugin does and we have a
// distributed build system that depends on that behavior.
static void thinLTOCreateEmptyIndexFiles() {
static void thinLTOCreateEmptyIndexFiles(Ctx &ctx) {
DenseSet<StringRef> linkedBitCodeFiles;
for (BitcodeFile *f : ctx.bitcodeFiles)
linkedBitCodeFiles.insert(f->getName());
@ -345,7 +345,7 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
}
if (ctx.arg.thinLTOEmitIndexFiles)
thinLTOCreateEmptyIndexFiles();
thinLTOCreateEmptyIndexFiles(ctx);
if (ctx.arg.thinLTOIndexOnly) {
if (!ctx.arg.ltoObjPath.empty())

View File

@ -215,7 +215,7 @@ bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
// Get a list of symbols which we need to assign the version to.
SmallVector<Symbol *, 0> syms = findByVersion(ver);
auto getName = [](uint16_t ver) -> std::string {
auto getName = [&ctx = ctx](uint16_t ver) -> std::string {
if (ver == VER_NDX_LOCAL)
return "VER_NDX_LOCAL";
if (ver == VER_NDX_GLOBAL)

View File

@ -15,7 +15,7 @@
#include "llvm/Support/Compiler.h"
namespace lld::elf {
struct Ctx;
class InputFile;
class SharedFile;
@ -38,6 +38,7 @@ struct ArmCmseEntryFunction {
// is one add* function per symbol type.
class SymbolTable {
public:
SymbolTable(Ctx &ctx) : ctx(ctx) {}
ArrayRef<Symbol *> getSymbols() const { return symVector; }
void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
@ -91,6 +92,8 @@ private:
void assignWildcardVersion(SymbolVersion ver, uint16_t versionId,
bool includeNonDefault);
Ctx &ctx;
// Global symbols and a map from symbol name to the index. The order is not
// defined. We can use an arbitrary order, but it has to be deterministic even
// when cross linking.