Skip to content

Commit 380b16a

Browse files
committed
[LLD][COFF] Move symbol mangling and lookup helpers to SymbolTable class (NFC)
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 a8d2aee commit 380b16a

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)