@@ -44,7 +44,7 @@ using namespace llvm::sys;
4444using namespace llvm ::wasm;
4545
4646namespace lld ::wasm {
47- Configuration * config;
47+ ConfigWrapper config;
4848Ctx ctx;
4949
5050void errorOrWarn (const llvm::Twine &msg) {
@@ -54,7 +54,11 @@ void errorOrWarn(const llvm::Twine &msg) {
5454 error (msg);
5555}
5656
57+ Ctx::Ctx () : arg(config.c) {}
58+
5759void Ctx::reset () {
60+ arg.~Config ();
61+ new (&arg) Config ();
5862 objectFiles.clear ();
5963 stubFiles.clear ();
6064 sharedFiles.clear ();
@@ -92,13 +96,16 @@ static void initLLVM() {
9296
9397class LinkerDriver {
9498public:
99+ LinkerDriver (Ctx &);
95100 void linkerMain (ArrayRef<const char *> argsArr);
96101
97102private:
98103 void createFiles (opt::InputArgList &args);
99104 void addFile (StringRef path);
100105 void addLibrary (StringRef name);
101106
107+ Ctx &ctx;
108+
102109 // True if we are in --whole-archive and --no-whole-archive.
103110 bool inWholeArchive = false ;
104111
@@ -122,19 +129,19 @@ static bool hasZOption(opt::InputArgList &args, StringRef key) {
122129bool link (ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
123130 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput) {
124131 // This driver-specific context will be freed later by unsafeLldMain().
125- auto *ctx = new CommonLinkerContext;
132+ auto *context = new CommonLinkerContext;
126133
127- ctx->e .initialize (stdoutOS, stderrOS, exitEarly, disableOutput);
128- ctx->e .cleanupCallback = []() { wasm::ctx.reset (); };
129- ctx->e .logName = args::getFilenameWithoutExe (args[0 ]);
130- ctx->e .errorLimitExceededMsg = " too many errors emitted, stopping now (use "
131- " -error-limit=0 to see all errors)" ;
134+ context->e .initialize (stdoutOS, stderrOS, exitEarly, disableOutput);
135+ context->e .cleanupCallback = []() { ctx.reset (); };
136+ context->e .logName = args::getFilenameWithoutExe (args[0 ]);
137+ context->e .errorLimitExceededMsg =
138+ " too many errors emitted, stopping now (use "
139+ " -error-limit=0 to see all errors)" ;
132140
133- config = make<Configuration>();
134141 symtab = make<SymbolTable>();
135142
136143 initLLVM ();
137- LinkerDriver ().linkerMain (args);
144+ LinkerDriver (ctx ).linkerMain (args);
138145
139146 return errorCount () == 0 ;
140147}
@@ -1256,6 +1263,8 @@ static void checkZOptions(opt::InputArgList &args) {
12561263 warn (" unknown -z value: " + StringRef (arg->getValue ()));
12571264}
12581265
1266+ LinkerDriver::LinkerDriver (Ctx &ctx) : ctx(ctx) {}
1267+
12591268void LinkerDriver::linkerMain (ArrayRef<const char *> argsArr) {
12601269 WasmOptTable parser;
12611270 opt::InputArgList args = parser.parse (argsArr.slice (1 ));
@@ -1324,10 +1333,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
13241333 // Fail early if the output file or map file is not writable. If a user has a
13251334 // long link, e.g. due to a large LTO link, they do not wish to run it and
13261335 // find that it failed because there was a mistake in their command-line.
1327- if (auto e = tryCreateFile (config-> outputFile ))
1328- error (" cannot open output file " + config-> outputFile + " : " + e.message ());
1329- if (auto e = tryCreateFile (config-> mapFile ))
1330- error (" cannot open map file " + config-> mapFile + " : " + e.message ());
1336+ if (auto e = tryCreateFile (ctx. arg . outputFile ))
1337+ error (" cannot open output file " + ctx. arg . outputFile + " : " + e.message ());
1338+ if (auto e = tryCreateFile (ctx. arg . mapFile ))
1339+ error (" cannot open map file " + ctx. arg . mapFile + " : " + e.message ());
13311340 if (errorCount ())
13321341 return ;
13331342
@@ -1336,11 +1345,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
13361345 symtab->trace (arg->getValue ());
13371346
13381347 for (auto *arg : args.filtered (OPT_export_if_defined))
1339- config-> exportedSymbols .insert (arg->getValue ());
1348+ ctx. arg . exportedSymbols .insert (arg->getValue ());
13401349
13411350 for (auto *arg : args.filtered (OPT_export)) {
1342- config-> exportedSymbols .insert (arg->getValue ());
1343- config-> requiredExports .push_back (arg->getValue ());
1351+ ctx. arg . exportedSymbols .insert (arg->getValue ());
1352+ ctx. arg . requiredExports .push_back (arg->getValue ());
13441353 }
13451354
13461355 createSyntheticSymbols ();
@@ -1358,28 +1367,28 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
13581367
13591368 // Handle the `--export <sym>` options
13601369 // This works like --undefined but also exports the symbol if its found
1361- for (auto &iter : config-> exportedSymbols )
1370+ for (auto &iter : ctx. arg . exportedSymbols )
13621371 handleUndefined (iter.first (), " --export" );
13631372
13641373 Symbol *entrySym = nullptr ;
1365- if (!config-> relocatable && !config-> entry .empty ()) {
1366- entrySym = handleUndefined (config-> entry , " --entry" );
1374+ if (!ctx. arg . relocatable && !ctx. arg . entry .empty ()) {
1375+ entrySym = handleUndefined (ctx. arg . entry , " --entry" );
13671376 if (entrySym && entrySym->isDefined ())
13681377 entrySym->forceExport = true ;
13691378 else
13701379 error (" entry symbol not defined (pass --no-entry to suppress): " +
1371- config-> entry );
1380+ ctx. arg . entry );
13721381 }
13731382
13741383 // If the user code defines a `__wasm_call_dtors` function, remember it so
13751384 // that we can call it from the command export wrappers. Unlike
13761385 // `__wasm_call_ctors` which we synthesize, `__wasm_call_dtors` is defined
13771386 // by libc/etc., because destructors are registered dynamically with
13781387 // `__cxa_atexit` and friends.
1379- if (!config-> relocatable && !config-> shared &&
1388+ if (!ctx. arg . relocatable && !ctx. arg . shared &&
13801389 !WasmSym::callCtors->isUsedInRegularObj &&
1381- WasmSym::callCtors->getName () != config-> entry &&
1382- !config-> exportedSymbols .count (WasmSym::callCtors->getName ())) {
1390+ WasmSym::callCtors->getName () != ctx. arg . entry &&
1391+ !ctx. arg . exportedSymbols .count (WasmSym::callCtors->getName ())) {
13831392 if (Symbol *callDtors =
13841393 handleUndefined (" __wasm_call_dtors" , " <internal>" )) {
13851394 if (auto *callDtorsFunc = dyn_cast<DefinedFunction>(callDtors)) {
@@ -1437,7 +1446,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
14371446 writeWhyExtract ();
14381447
14391448 // Bail out if normal linked output is skipped due to LTO.
1440- if (config-> thinLTOIndexOnly )
1449+ if (ctx. arg . thinLTOIndexOnly )
14411450 return ;
14421451
14431452 createOptionalSymbols ();
@@ -1452,13 +1461,13 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
14521461 if (!wrapped.empty ())
14531462 wrapSymbols (wrapped);
14541463
1455- for (auto &iter : config-> exportedSymbols ) {
1464+ for (auto &iter : ctx. arg . exportedSymbols ) {
14561465 Symbol *sym = symtab->find (iter.first ());
14571466 if (sym && sym->isDefined ())
14581467 sym->forceExport = true ;
14591468 }
14601469
1461- if (!config-> relocatable && !ctx.isPic ) {
1470+ if (!ctx. arg . relocatable && !ctx.isPic ) {
14621471 // Add synthetic dummies for weak undefined functions. Must happen
14631472 // after LTO otherwise functions may not yet have signatures.
14641473 symtab->handleWeakUndefines ();
0 commit comments