Skip to content

Commit f860fe3

Browse files
committed
[LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext. See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html Differential Revision: https://reviews.llvm.org/D108850
1 parent 070d103 commit f860fe3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+495
-394
lines changed

lld/COFF/COFFLinkerContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
#include "InputFiles.h"
1616
#include "SymbolTable.h"
1717
#include "Writer.h"
18+
#include "lld/Common/CommonLinkerContext.h"
1819
#include "lld/Common/Timer.h"
1920

2021
namespace lld {
2122
namespace coff {
2223

23-
class COFFLinkerContext {
24+
class COFFLinkerContext : public CommonLinkerContext {
2425
public:
2526
COFFLinkerContext();
2627
COFFLinkerContext(const COFFLinkerContext &) = delete;

lld/COFF/Chunks.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "SymbolTable.h"
1313
#include "Symbols.h"
1414
#include "Writer.h"
15-
#include "lld/Common/ErrorHandler.h"
1615
#include "llvm/ADT/Twine.h"
1716
#include "llvm/BinaryFormat/COFF.h"
1817
#include "llvm/Object/COFF.h"
@@ -430,7 +429,7 @@ void SectionChunk::sortRelocations() {
430429
return;
431430
warn("some relocations in " + file->getName() + " are not sorted");
432431
MutableArrayRef<coff_relocation> newRelocs(
433-
bAlloc.Allocate<coff_relocation>(relocsSize), relocsSize);
432+
bAlloc().Allocate<coff_relocation>(relocsSize), relocsSize);
434433
memcpy(newRelocs.data(), relocsData, relocsSize * sizeof(coff_relocation));
435434
llvm::sort(newRelocs, cmpByVa);
436435
setRelocs(newRelocs);

lld/COFF/DLL.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,14 +659,14 @@ void DelayLoadContents::create(COFFLinkerContext &ctx, Defined *h) {
659659
// Add a syntentic symbol for this load thunk, using the "__imp_load"
660660
// prefix, in case this thunk needs to be added to the list of valid
661661
// call targets for Control Flow Guard.
662-
StringRef symName = saver.save("__imp_load_" + extName);
662+
StringRef symName = saver().save("__imp_load_" + extName);
663663
s->loadThunkSym =
664664
cast<DefinedSynthetic>(ctx.symtab.addSynthetic(symName, t));
665665
}
666666
}
667667
thunks.push_back(tm);
668668
StringRef tmName =
669-
saver.save("__tailMerge_" + syms[0]->getDLLName().lower());
669+
saver().save("__tailMerge_" + syms[0]->getDLLName().lower());
670670
ctx.symtab.addSynthetic(tmName, tm);
671671
// Terminate with null values.
672672
addresses.push_back(make<NullChunk>(8));

lld/COFF/Driver.cpp

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
#include "Writer.h"
2020
#include "lld/Common/Args.h"
2121
#include "lld/Common/Driver.h"
22-
#include "lld/Common/ErrorHandler.h"
2322
#include "lld/Common/Filesystem.h"
24-
#include "lld/Common/Memory.h"
2523
#include "lld/Common/Timer.h"
2624
#include "lld/Common/Version.h"
2725
#include "llvm/ADT/Optional.h"
@@ -63,36 +61,23 @@ namespace coff {
6361
std::unique_ptr<Configuration> config;
6462
std::unique_ptr<LinkerDriver> driver;
6563

66-
bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &stdoutOS,
67-
raw_ostream &stderrOS) {
68-
lld::stdoutOS = &stdoutOS;
69-
lld::stderrOS = &stderrOS;
64+
bool link(ArrayRef<const char *> args, raw_ostream &stdoutOS,
65+
raw_ostream &stderrOS, bool exitEarly, bool disableOutput) {
66+
// This driver-specific context will be freed later by lldMain().
67+
// It is created on the heap to avoid destructors if 'exitEarly' is set.
68+
auto *ctx = new COFFLinkerContext;
7069

71-
errorHandler().cleanupCallback = []() {
72-
freeArena();
73-
};
74-
75-
errorHandler().logName = args::getFilenameWithoutExe(args[0]);
76-
errorHandler().errorLimitExceededMsg =
77-
"too many errors emitted, stopping now"
78-
" (use /errorlimit:0 to see all errors)";
79-
errorHandler().exitEarly = canExitEarly;
80-
stderrOS.enable_colors(stderrOS.has_colors());
70+
ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
71+
ctx->e.logName = args::getFilenameWithoutExe(args[0]);
72+
ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now"
73+
" (use /errorlimit:0 to see all errors)";
8174

82-
COFFLinkerContext ctx;
8375
config = std::make_unique<Configuration>();
84-
driver = std::make_unique<LinkerDriver>(ctx);
76+
driver = std::make_unique<LinkerDriver>(*ctx);
8577

8678
driver->linkerMain(args);
8779

88-
// Call exit() if we can to avoid calling destructors.
89-
if (canExitEarly)
90-
exitLld(errorCount() ? 1 : 0);
91-
92-
bool ret = errorCount() == 0;
93-
if (!canExitEarly)
94-
errorHandler().reset();
95-
return ret;
80+
return errorCount() == 0;
9681
}
9782

9883
// Parse options of the form "old;new".
@@ -162,7 +147,7 @@ static std::future<MBErrPair> createFutureForFile(std::string path) {
162147
static StringRef mangle(StringRef sym) {
163148
assert(config->machine != IMAGE_FILE_MACHINE_UNKNOWN);
164149
if (config->machine == I386)
165-
return saver.save("_" + sym);
150+
return saver().save("_" + sym);
166151
return sym;
167152
}
168153

@@ -358,9 +343,9 @@ void LinkerDriver::parseDirectives(InputFile *file) {
358343
Export exp = parseExport(e);
359344
if (config->machine == I386 && config->mingw) {
360345
if (!isDecorated(exp.name))
361-
exp.name = saver.save("_" + exp.name);
346+
exp.name = saver().save("_" + exp.name);
362347
if (!exp.extName.empty() && !isDecorated(exp.extName))
363-
exp.extName = saver.save("_" + exp.extName);
348+
exp.extName = saver().save("_" + exp.extName);
364349
}
365350
exp.directives = true;
366351
config->exports.push_back(exp);
@@ -442,11 +427,11 @@ StringRef LinkerDriver::doFindFile(StringRef filename) {
442427
SmallString<128> path = dir;
443428
sys::path::append(path, filename);
444429
if (sys::fs::exists(path.str()))
445-
return saver.save(path.str());
430+
return saver().save(path.str());
446431
if (!hasExt) {
447432
path.append(".obj");
448433
if (sys::fs::exists(path.str()))
449-
return saver.save(path.str());
434+
return saver().save(path.str());
450435
}
451436
}
452437
return filename;
@@ -483,7 +468,7 @@ StringRef LinkerDriver::doFindLibMinGW(StringRef filename) {
483468

484469
SmallString<128> s = filename;
485470
sys::path::replace_extension(s, ".a");
486-
StringRef libName = saver.save("lib" + s.str());
471+
StringRef libName = saver().save("lib" + s.str());
487472
return doFindFile(libName);
488473
}
489474

@@ -492,7 +477,7 @@ StringRef LinkerDriver::doFindLib(StringRef filename) {
492477
// Add ".lib" to Filename if that has no file extension.
493478
bool hasExt = filename.contains('.');
494479
if (!hasExt)
495-
filename = saver.save(filename + ".lib");
480+
filename = saver().save(filename + ".lib");
496481
StringRef ret = doFindFile(filename);
497482
// For MinGW, if the find above didn't turn up anything, try
498483
// looking for a MinGW formatted library name.
@@ -525,7 +510,7 @@ void LinkerDriver::addLibSearchPaths() {
525510
Optional<std::string> envOpt = Process::GetEnv("LIB");
526511
if (!envOpt.hasValue())
527512
return;
528-
StringRef env = saver.save(*envOpt);
513+
StringRef env = saver().save(*envOpt);
529514
while (!env.empty()) {
530515
StringRef path;
531516
std::tie(path, env) = env.split(';');
@@ -872,8 +857,8 @@ static void parseModuleDefs(StringRef path) {
872857
driver->takeBuffer(std::move(mb));
873858

874859
if (config->outputFile.empty())
875-
config->outputFile = std::string(saver.save(m.OutputFile));
876-
config->importName = std::string(saver.save(m.ImportName));
860+
config->outputFile = std::string(saver().save(m.OutputFile));
861+
config->importName = std::string(saver().save(m.ImportName));
877862
if (m.ImageBase)
878863
config->imageBase = m.ImageBase;
879864
if (m.StackReserve)
@@ -901,13 +886,13 @@ static void parseModuleDefs(StringRef path) {
901886
// DLL instead. This is supported by both MS and GNU linkers.
902887
if (!e1.ExtName.empty() && e1.ExtName != e1.Name &&
903888
StringRef(e1.Name).contains('.')) {
904-
e2.name = saver.save(e1.ExtName);
905-
e2.forwardTo = saver.save(e1.Name);
889+
e2.name = saver().save(e1.ExtName);
890+
e2.forwardTo = saver().save(e1.Name);
906891
config->exports.push_back(e2);
907892
continue;
908893
}
909-
e2.name = saver.save(e1.Name);
910-
e2.extName = saver.save(e1.ExtName);
894+
e2.name = saver().save(e1.Name);
895+
e2.extName = saver().save(e1.ExtName);
911896
e2.ordinal = e1.Ordinal;
912897
e2.noname = e1.Noname;
913898
e2.data = e1.Data;
@@ -1904,9 +1889,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
19041889
Export e = parseExport(arg->getValue());
19051890
if (config->machine == I386) {
19061891
if (!isDecorated(e.name))
1907-
e.name = saver.save("_" + e.name);
1892+
e.name = saver().save("_" + e.name);
19081893
if (!e.extName.empty() && !isDecorated(e.extName))
1909-
e.extName = saver.save("_" + e.extName);
1894+
e.extName = saver().save("_" + e.extName);
19101895
}
19111896
config->exports.push_back(e);
19121897
}

lld/COFF/DriverUtils.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ const uint16_t RT_MANIFEST = 24;
4848

4949
class Executor {
5050
public:
51-
explicit Executor(StringRef s) : prog(saver.save(s)) {}
52-
void add(StringRef s) { args.push_back(saver.save(s)); }
53-
void add(std::string &s) { args.push_back(saver.save(s)); }
54-
void add(Twine s) { args.push_back(saver.save(s)); }
55-
void add(const char *s) { args.push_back(saver.save(s)); }
51+
explicit Executor(StringRef s) : prog(saver().save(s)) {}
52+
void add(StringRef s) { args.push_back(saver().save(s)); }
53+
void add(std::string &s) { args.push_back(saver().save(s)); }
54+
void add(Twine s) { args.push_back(saver().save(s)); }
55+
void add(const char *s) { args.push_back(saver().save(s)); }
5656

5757
void run() {
5858
ErrorOr<std::string> exeOrErr = sys::findProgramByName(prog);
5959
if (auto ec = exeOrErr.getError())
6060
fatal("unable to find " + prog + " in PATH: " + ec.message());
61-
StringRef exe = saver.save(*exeOrErr);
61+
StringRef exe = saver().save(*exeOrErr);
6262
args.insert(args.begin(), exe);
6363

6464
if (sys::ExecuteAndWait(args[0], args) != 0)
@@ -636,14 +636,14 @@ static StringRef killAt(StringRef sym, bool prefix) {
636636
sym = sym.substr(0, sym.find('@', 1));
637637
if (!sym.startswith("@")) {
638638
if (prefix && !sym.startswith("_"))
639-
return saver.save("_" + sym);
639+
return saver().save("_" + sym);
640640
return sym;
641641
}
642642
// For fastcall, remove the leading @ and replace it with an
643643
// underscore, if prefixes are used.
644644
sym = sym.substr(1);
645645
if (prefix)
646-
sym = saver.save("_" + sym);
646+
sym = saver().save("_" + sym);
647647
return sym;
648648
}
649649

@@ -854,7 +854,7 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
854854
argv.data() + argv.size());
855855
if (!args.hasArg(OPT_lldignoreenv))
856856
addLINK(expandedArgv);
857-
cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv);
857+
cl::ExpandResponseFiles(saver(), getQuotingStyle(args), expandedArgv);
858858
args = optTable.ParseArgs(makeArrayRef(expandedArgv).drop_front(),
859859
missingIndex, missingCount);
860860

@@ -901,7 +901,7 @@ ParsedDirectives ArgParser::parseDirectives(StringRef s) {
901901
// Handle /EXPORT and /INCLUDE in a fast path. These directives can appear for
902902
// potentially every symbol in the object, so they must be handled quickly.
903903
SmallVector<StringRef, 16> tokens;
904-
cl::TokenizeWindowsCommandLineNoCopy(s, saver, tokens);
904+
cl::TokenizeWindowsCommandLineNoCopy(s, saver(), tokens);
905905
for (StringRef tok : tokens) {
906906
if (tok.startswith_insensitive("/export:") ||
907907
tok.startswith_insensitive("-export:"))
@@ -914,7 +914,7 @@ ParsedDirectives ArgParser::parseDirectives(StringRef s) {
914914
// already copied quoted arguments for us, so those do not need to be
915915
// copied again.
916916
bool HasNul = tok.end() != s.end() && tok.data()[tok.size()] == '\0';
917-
rest.push_back(HasNul ? tok.data() : saver.save(tok).data());
917+
rest.push_back(HasNul ? tok.data() : saver().save(tok).data());
918918
}
919919
}
920920

@@ -948,7 +948,7 @@ void ArgParser::addLINK(SmallVector<const char *, 256> &argv) {
948948

949949
std::vector<const char *> ArgParser::tokenize(StringRef s) {
950950
SmallVector<const char *, 16> tokens;
951-
cl::TokenizeWindowsCommandLine(s, saver, tokens);
951+
cl::TokenizeWindowsCommandLine(s, saver(), tokens);
952952
return std::vector<const char *>(tokens.begin(), tokens.end());
953953
}
954954

lld/COFF/InputFiles.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
#include "SymbolTable.h"
1616
#include "Symbols.h"
1717
#include "lld/Common/DWARF.h"
18-
#include "lld/Common/ErrorHandler.h"
19-
#include "lld/Common/Memory.h"
2018
#include "llvm-c/lto.h"
2119
#include "llvm/ADT/SmallVector.h"
2220
#include "llvm/ADT/Triple.h"
@@ -905,7 +903,7 @@ ObjFile::getVariableLocation(StringRef var) {
905903
Optional<std::pair<std::string, unsigned>> ret = dwarf->getVariableLoc(var);
906904
if (!ret)
907905
return None;
908-
return std::make_pair(saver.save(ret->first), ret->second);
906+
return std::make_pair(saver().save(ret->first), ret->second);
909907
}
910908

911909
// Used only for DWARF debug info, which is not common (except in MinGW
@@ -940,8 +938,8 @@ void ImportFile::parse() {
940938
fatal("broken import library");
941939

942940
// Read names and create an __imp_ symbol.
943-
StringRef name = saver.save(StringRef(buf + sizeof(*hdr)));
944-
StringRef impName = saver.save("__imp_" + name);
941+
StringRef name = saver().save(StringRef(buf + sizeof(*hdr)));
942+
StringRef impName = saver().save("__imp_" + name);
945943
const char *nameStart = buf + sizeof(coff_import_header) + name.size() + 1;
946944
dllName = std::string(StringRef(nameStart));
947945
StringRef extName;
@@ -995,11 +993,12 @@ BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
995993
// into consideration at LTO time (which very likely causes undefined
996994
// symbols later in the link stage). So we append file offset to make
997995
// filename unique.
998-
MemoryBufferRef mbref(
999-
mb.getBuffer(),
1000-
saver.save(archiveName.empty() ? path
1001-
: archiveName + sys::path::filename(path) +
1002-
utostr(offsetInArchive)));
996+
MemoryBufferRef mbref(mb.getBuffer(),
997+
saver().save(archiveName.empty()
998+
? path
999+
: archiveName +
1000+
sys::path::filename(path) +
1001+
utostr(offsetInArchive)));
10031002

10041003
obj = check(lto::InputFile::create(mbref));
10051004
}
@@ -1035,6 +1034,7 @@ FakeSectionChunk ltoDataSectionChunk(&ltoDataSection.section);
10351034
} // namespace
10361035

10371036
void BitcodeFile::parse() {
1037+
llvm::StringSaver &saver = lld::saver();
10381038
std::vector<std::pair<Symbol *, bool>> comdat(obj->getComdatTable().size());
10391039
for (size_t i = 0; i != obj->getComdatTable().size(); ++i)
10401040
// FIXME: Check nodeduplicate
@@ -1156,11 +1156,11 @@ void DLLFile::parse() {
11561156
s->nameType = ImportNameType::IMPORT_NAME;
11571157

11581158
if (coffObj->getMachine() == I386) {
1159-
s->symbolName = symbolName = saver.save("_" + symbolName);
1159+
s->symbolName = symbolName = saver().save("_" + symbolName);
11601160
s->nameType = ImportNameType::IMPORT_NAME_NOPREFIX;
11611161
}
11621162

1163-
StringRef impName = saver.save("__imp_" + symbolName);
1163+
StringRef impName = saver().save("__imp_" + symbolName);
11641164
ctx.symtab.addLazyDLLSymbol(this, s, impName);
11651165
if (code)
11661166
ctx.symtab.addLazyDLLSymbol(this, s, symbolName);
@@ -1179,7 +1179,7 @@ void DLLFile::makeImport(DLLFile::Symbol *s) {
11791179

11801180
size_t impSize = s->dllName.size() + s->symbolName.size() + 2; // +2 for NULs
11811181
size_t size = sizeof(coff_import_header) + impSize;
1182-
char *buf = bAlloc.Allocate<char>(size);
1182+
char *buf = bAlloc().Allocate<char>(size);
11831183
memset(buf, 0, size);
11841184
char *p = buf;
11851185
auto *imp = reinterpret_cast<coff_import_header *>(p);

lld/COFF/LTO.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "InputFiles.h"
1212
#include "Symbols.h"
1313
#include "lld/Common/Args.h"
14-
#include "lld/Common/ErrorHandler.h"
14+
#include "lld/Common/CommonLinkerContext.h"
1515
#include "lld/Common/Strings.h"
1616
#include "lld/Common/TargetOptionsCommandFlags.h"
1717
#include "llvm/ADT/STLExtras.h"
@@ -209,8 +209,8 @@ std::vector<InputFile *> BitcodeCompiler::compile(COFFLinkerContext &ctx) {
209209
// - foo.exe.lto.1.obj
210210
// - ...
211211
StringRef ltoObjName =
212-
saver.save(Twine(config->outputFile) + ".lto" +
213-
(i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".obj");
212+
saver().save(Twine(config->outputFile) + ".lto" +
213+
(i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".obj");
214214

215215
// Get the native object contents either from the cache or from memory. Do
216216
// not use the cached MemoryBuffer directly, or the PDB will not be

0 commit comments

Comments
 (0)