Skip to content

Commit f22af59

Browse files
authored
[LLD][COFF] Move symbol mangling and lookup helpers to SymbolTable class (NFC) (#122836)
This refactor prepares for further ARM64X hybrid support, where these helpers will need to work with either the native or EC symbol table based on context.
1 parent cf2e828 commit f22af59

File tree

4 files changed

+153
-151
lines changed

4 files changed

+153
-151
lines changed

lld/COFF/Driver.cpp

Lines changed: 30 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include "llvm/Support/BinaryStreamReader.h"
3838
#include "llvm/Support/CommandLine.h"
3939
#include "llvm/Support/Debug.h"
40-
#include "llvm/Support/GlobPattern.h"
4140
#include "llvm/Support/LEB128.h"
4241
#include "llvm/Support/MathExtras.h"
4342
#include "llvm/Support/Parallel.h"
@@ -172,23 +171,10 @@ static std::future<MBErrPair> createFutureForFile(std::string path) {
172171
});
173172
}
174173

175-
// Symbol names are mangled by prepending "_" on x86.
176-
StringRef LinkerDriver::mangle(StringRef sym) {
177-
assert(ctx.config.machine != IMAGE_FILE_MACHINE_UNKNOWN);
178-
if (ctx.config.machine == I386)
179-
return saver().save("_" + sym);
180-
return sym;
181-
}
182-
183174
llvm::Triple::ArchType LinkerDriver::getArch() {
184175
return getMachineArchType(ctx.config.machine);
185176
}
186177

187-
bool LinkerDriver::findUnderscoreMangle(StringRef sym) {
188-
Symbol *s = ctx.symtab.findMangle(mangle(sym));
189-
return s && !isa<Undefined>(s);
190-
}
191-
192178
static bool compatibleMachineType(COFFLinkerContext &ctx, MachineTypes mt) {
193179
if (mt == IMAGE_FILE_MACHINE_UNKNOWN)
194180
return true;
@@ -486,7 +472,7 @@ void LinkerDriver::parseDirectives(InputFile *file) {
486472
SmallVector<StringRef, 2> vec;
487473
e.split(vec, ',');
488474
for (StringRef sym : vec)
489-
excludedSymbols.insert(mangle(sym));
475+
excludedSymbols.insert(file->symtab.mangle(sym));
490476
}
491477

492478
// https://docs.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp?view=msvc-160
@@ -505,7 +491,8 @@ void LinkerDriver::parseDirectives(InputFile *file) {
505491
case OPT_entry:
506492
if (!arg->getValue()[0])
507493
Fatal(ctx) << "missing entry point symbol name";
508-
ctx.config.entry = file->symtab.addGCRoot(mangle(arg->getValue()), true);
494+
ctx.config.entry =
495+
file->symtab.addGCRoot(file->symtab.mangle(arg->getValue()), true);
509496
break;
510497
case OPT_failifmismatch:
511498
checkFailIfMismatch(arg->getValue(), file);
@@ -805,97 +792,6 @@ void LinkerDriver::addLibSearchPaths() {
805792
}
806793
}
807794

808-
void LinkerDriver::addUndefinedGlob(StringRef arg) {
809-
Expected<GlobPattern> pat = GlobPattern::create(arg);
810-
if (!pat) {
811-
Err(ctx) << "/includeglob: " << toString(pat.takeError());
812-
return;
813-
}
814-
815-
SmallVector<Symbol *, 0> syms;
816-
ctx.symtab.forEachSymbol([&syms, &pat](Symbol *sym) {
817-
if (pat->match(sym->getName())) {
818-
syms.push_back(sym);
819-
}
820-
});
821-
822-
for (Symbol *sym : syms)
823-
ctx.symtab.addGCRoot(sym->getName());
824-
}
825-
826-
StringRef LinkerDriver::mangleMaybe(Symbol *s) {
827-
// If the plain symbol name has already been resolved, do nothing.
828-
Undefined *unmangled = dyn_cast<Undefined>(s);
829-
if (!unmangled)
830-
return "";
831-
832-
// Otherwise, see if a similar, mangled symbol exists in the symbol table.
833-
Symbol *mangled = ctx.symtab.findMangle(unmangled->getName());
834-
if (!mangled)
835-
return "";
836-
837-
// If we find a similar mangled symbol, make this an alias to it and return
838-
// its name.
839-
Log(ctx) << unmangled->getName() << " aliased to " << mangled->getName();
840-
unmangled->setWeakAlias(ctx.symtab.addUndefined(mangled->getName()));
841-
return mangled->getName();
842-
}
843-
844-
// Windows specific -- find default entry point name.
845-
//
846-
// There are four different entry point functions for Windows executables,
847-
// each of which corresponds to a user-defined "main" function. This function
848-
// infers an entry point from a user-defined "main" function.
849-
StringRef LinkerDriver::findDefaultEntry() {
850-
assert(ctx.config.subsystem != IMAGE_SUBSYSTEM_UNKNOWN &&
851-
"must handle /subsystem before calling this");
852-
853-
if (ctx.config.mingw)
854-
return mangle(ctx.config.subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI
855-
? "WinMainCRTStartup"
856-
: "mainCRTStartup");
857-
858-
if (ctx.config.subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
859-
if (findUnderscoreMangle("wWinMain")) {
860-
if (!findUnderscoreMangle("WinMain"))
861-
return mangle("wWinMainCRTStartup");
862-
Warn(ctx) << "found both wWinMain and WinMain; using latter";
863-
}
864-
return mangle("WinMainCRTStartup");
865-
}
866-
if (findUnderscoreMangle("wmain")) {
867-
if (!findUnderscoreMangle("main"))
868-
return mangle("wmainCRTStartup");
869-
Warn(ctx) << "found both wmain and main; using latter";
870-
}
871-
return mangle("mainCRTStartup");
872-
}
873-
874-
WindowsSubsystem LinkerDriver::inferSubsystem() {
875-
if (ctx.config.dll)
876-
return IMAGE_SUBSYSTEM_WINDOWS_GUI;
877-
if (ctx.config.mingw)
878-
return IMAGE_SUBSYSTEM_WINDOWS_CUI;
879-
// Note that link.exe infers the subsystem from the presence of these
880-
// functions even if /entry: or /nodefaultlib are passed which causes them
881-
// to not be called.
882-
bool haveMain = findUnderscoreMangle("main");
883-
bool haveWMain = findUnderscoreMangle("wmain");
884-
bool haveWinMain = findUnderscoreMangle("WinMain");
885-
bool haveWWinMain = findUnderscoreMangle("wWinMain");
886-
if (haveMain || haveWMain) {
887-
if (haveWinMain || haveWWinMain) {
888-
Warn(ctx) << "found " << (haveMain ? "main" : "wmain") << " and "
889-
<< (haveWinMain ? "WinMain" : "wWinMain")
890-
<< "; defaulting to /subsystem:console";
891-
}
892-
return IMAGE_SUBSYSTEM_WINDOWS_CUI;
893-
}
894-
if (haveWinMain || haveWWinMain)
895-
return IMAGE_SUBSYSTEM_WINDOWS_GUI;
896-
return IMAGE_SUBSYSTEM_UNKNOWN;
897-
}
898-
899795
uint64_t LinkerDriver::getDefaultImageBase() {
900796
if (ctx.config.is64())
901797
return ctx.config.dll ? 0x180000000 : 0x140000000;
@@ -1539,7 +1435,7 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
15391435
SmallVector<StringRef, 2> vec;
15401436
StringRef(arg->getValue()).split(vec, ',');
15411437
for (StringRef sym : vec)
1542-
exporter.addExcludedSymbol(mangle(sym));
1438+
exporter.addExcludedSymbol(ctx.symtab.mangle(sym));
15431439
}
15441440

15451441
ctx.symtab.forEachSymbol([&](Symbol *s) {
@@ -2455,7 +2351,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
24552351
// and after the early return when just writing an import library.
24562352
if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
24572353
llvm::TimeTraceScope timeScope("Infer subsystem");
2458-
config->subsystem = inferSubsystem();
2354+
config->subsystem = ctx.symtab.inferSubsystem();
24592355
if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
24602356
Fatal(ctx) << "subsystem must be defined";
24612357
}
@@ -2466,19 +2362,21 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
24662362
if (auto *arg = args.getLastArg(OPT_entry)) {
24672363
if (!arg->getValue()[0])
24682364
Fatal(ctx) << "missing entry point symbol name";
2469-
config->entry = ctx.symtab.addGCRoot(mangle(arg->getValue()), true);
2365+
config->entry =
2366+
ctx.symtab.addGCRoot(ctx.symtab.mangle(arg->getValue()), true);
24702367
} else if (!config->entry && !config->noEntry) {
24712368
if (args.hasArg(OPT_dll)) {
24722369
StringRef s = (config->machine == I386) ? "__DllMainCRTStartup@12"
24732370
: "_DllMainCRTStartup";
24742371
config->entry = ctx.symtab.addGCRoot(s, true);
24752372
} else if (config->driverWdm) {
24762373
// /driver:wdm implies /entry:_NtProcessStartup
2477-
config->entry = ctx.symtab.addGCRoot(mangle("_NtProcessStartup"), true);
2374+
config->entry =
2375+
ctx.symtab.addGCRoot(ctx.symtab.mangle("_NtProcessStartup"), true);
24782376
} else {
24792377
// Windows specific -- If entry point name is not given, we need to
24802378
// infer that from user-defined entry name.
2481-
StringRef s = findDefaultEntry();
2379+
StringRef s = ctx.symtab.findDefaultEntry();
24822380
if (s.empty())
24832381
Fatal(ctx) << "entry point must be defined";
24842382
config->entry = ctx.symtab.addGCRoot(s, true);
@@ -2568,24 +2466,24 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
25682466
config->imageBase = getDefaultImageBase();
25692467

25702468
ctx.forEachSymtab([&](SymbolTable &symtab) {
2571-
symtab.addSynthetic(mangle("__ImageBase"), nullptr);
2469+
symtab.addSynthetic(symtab.mangle("__ImageBase"), nullptr);
25722470
if (symtab.machine == I386) {
25732471
symtab.addAbsolute("___safe_se_handler_table", 0);
25742472
symtab.addAbsolute("___safe_se_handler_count", 0);
25752473
}
25762474

2577-
symtab.addAbsolute(mangle("__guard_fids_count"), 0);
2578-
symtab.addAbsolute(mangle("__guard_fids_table"), 0);
2579-
symtab.addAbsolute(mangle("__guard_flags"), 0);
2580-
symtab.addAbsolute(mangle("__guard_iat_count"), 0);
2581-
symtab.addAbsolute(mangle("__guard_iat_table"), 0);
2582-
symtab.addAbsolute(mangle("__guard_longjmp_count"), 0);
2583-
symtab.addAbsolute(mangle("__guard_longjmp_table"), 0);
2475+
symtab.addAbsolute(symtab.mangle("__guard_fids_count"), 0);
2476+
symtab.addAbsolute(symtab.mangle("__guard_fids_table"), 0);
2477+
symtab.addAbsolute(symtab.mangle("__guard_flags"), 0);
2478+
symtab.addAbsolute(symtab.mangle("__guard_iat_count"), 0);
2479+
symtab.addAbsolute(symtab.mangle("__guard_iat_table"), 0);
2480+
symtab.addAbsolute(symtab.mangle("__guard_longjmp_count"), 0);
2481+
symtab.addAbsolute(symtab.mangle("__guard_longjmp_table"), 0);
25842482
// Needed for MSVC 2017 15.5 CRT.
2585-
symtab.addAbsolute(mangle("__enclave_config"), 0);
2483+
symtab.addAbsolute(symtab.mangle("__enclave_config"), 0);
25862484
// Needed for MSVC 2019 16.8 CRT.
2587-
symtab.addAbsolute(mangle("__guard_eh_cont_count"), 0);
2588-
symtab.addAbsolute(mangle("__guard_eh_cont_table"), 0);
2485+
symtab.addAbsolute(symtab.mangle("__guard_eh_cont_count"), 0);
2486+
symtab.addAbsolute(symtab.mangle("__guard_eh_cont_table"), 0);
25892487

25902488
if (symtab.isEC()) {
25912489
symtab.addAbsolute("__arm64x_extra_rfe_table", 0);
@@ -2606,16 +2504,16 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
26062504
}
26072505

26082506
if (config->pseudoRelocs) {
2609-
symtab.addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0);
2610-
symtab.addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0);
2507+
symtab.addAbsolute(symtab.mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0);
2508+
symtab.addAbsolute(symtab.mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0);
26112509
}
26122510
if (config->mingw) {
2613-
symtab.addAbsolute(mangle("__CTOR_LIST__"), 0);
2614-
symtab.addAbsolute(mangle("__DTOR_LIST__"), 0);
2511+
symtab.addAbsolute(symtab.mangle("__CTOR_LIST__"), 0);
2512+
symtab.addAbsolute(symtab.mangle("__DTOR_LIST__"), 0);
26152513
}
26162514
if (config->debug || config->buildIDHash != BuildIDHash::None)
26172515
if (symtab.findUnderscore("__buildid"))
2618-
symtab.addUndefined(mangle("__buildid"));
2516+
symtab.addUndefined(symtab.mangle("__buildid"));
26192517
});
26202518

26212519
// This code may add new undefined symbols to the link, which may enqueue more
@@ -2627,15 +2525,15 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
26272525
// Windows specific -- if entry point is not found,
26282526
// search for its mangled names.
26292527
if (config->entry)
2630-
mangleMaybe(config->entry);
2528+
ctx.symtab.mangleMaybe(config->entry);
26312529

26322530
// Windows specific -- Make sure we resolve all dllexported symbols.
26332531
for (Export &e : config->exports) {
26342532
if (!e.forwardTo.empty())
26352533
continue;
26362534
e.sym = ctx.symtab.addGCRoot(e.name, !e.data);
26372535
if (e.source != ExportSource::Directives)
2638-
e.symbolName = mangleMaybe(e.sym);
2536+
e.symbolName = ctx.symtab.mangleMaybe(e.sym);
26392537
}
26402538

26412539
// Add weak aliases. Weak aliases is a mechanism to give remaining
@@ -2675,7 +2573,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
26752573

26762574
// Windows specific -- if __load_config_used can be resolved, resolve it.
26772575
if (ctx.symtab.findUnderscore("_load_config_used"))
2678-
ctx.symtab.addGCRoot(mangle("_load_config_used"));
2576+
ctx.symtab.addGCRoot(ctx.symtab.mangle("_load_config_used"));
26792577

26802578
if (args.hasArg(OPT_include_optional)) {
26812579
// Handle /includeoptional
@@ -2688,7 +2586,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
26882586

26892587
// Handle /includeglob
26902588
for (StringRef pat : args::getStrings(args, OPT_incl_glob))
2691-
addUndefinedGlob(pat);
2589+
ctx.symtab.addUndefinedGlob(pat);
26922590

26932591
// Create wrapped symbols for -wrap option.
26942592
std::vector<WrappedSymbol> wrapped = addWrappedSymbols(ctx, args);

lld/COFF/Driver.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -106,18 +106,13 @@ class LinkerDriver {
106106
StringRef findLib(StringRef filename);
107107
StringRef findLibMinGW(StringRef filename);
108108

109-
bool findUnderscoreMangle(StringRef sym);
110-
111109
// Determines the location of the sysroot based on `args`, environment, etc.
112110
void detectWinSysRoot(const llvm::opt::InputArgList &args);
113111

114112
// Adds various search paths based on the sysroot. Must only be called once
115113
// config.machine has been set.
116114
void addWinSysRootLibSearchPaths();
117115

118-
// Symbol names are mangled by prepending "_" on x86.
119-
StringRef mangle(StringRef sym);
120-
121116
void setMachine(llvm::COFF::MachineTypes machine);
122117
llvm::Triple::ArchType getArch();
123118

@@ -173,20 +168,6 @@ class LinkerDriver {
173168

174169
std::set<std::string> visitedLibs;
175170

176-
void addUndefinedGlob(StringRef arg);
177-
178-
StringRef mangleMaybe(Symbol *s);
179-
180-
// Windows specific -- "main" is not the only main function in Windows.
181-
// You can choose one from these four -- {w,}{WinMain,main}.
182-
// There are four different entry point functions for them,
183-
// {w,}{WinMain,main}CRTStartup, respectively. The linker needs to
184-
// choose the right one depending on which "main" function is defined.
185-
// This function looks up the symbol table and resolve corresponding
186-
// entry point name.
187-
StringRef findDefaultEntry();
188-
WindowsSubsystem inferSubsystem();
189-
190171
void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive,
191172
bool lazy);
192173
void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName,

0 commit comments

Comments
 (0)