@@ -44,7 +44,7 @@ using namespace llvm::sys;
44
44
using namespace llvm ::wasm;
45
45
46
46
namespace lld ::wasm {
47
- Configuration * config;
47
+ ConfigWrapper config;
48
48
Ctx ctx;
49
49
50
50
void errorOrWarn (const llvm::Twine &msg) {
@@ -54,7 +54,11 @@ void errorOrWarn(const llvm::Twine &msg) {
54
54
error (msg);
55
55
}
56
56
57
+ Ctx::Ctx () : arg(config.c) {}
58
+
57
59
void Ctx::reset () {
60
+ arg.~Config ();
61
+ new (&arg) Config ();
58
62
objectFiles.clear ();
59
63
stubFiles.clear ();
60
64
sharedFiles.clear ();
@@ -92,13 +96,16 @@ static void initLLVM() {
92
96
93
97
class LinkerDriver {
94
98
public:
99
+ LinkerDriver (Ctx &);
95
100
void linkerMain (ArrayRef<const char *> argsArr);
96
101
97
102
private:
98
103
void createFiles (opt::InputArgList &args);
99
104
void addFile (StringRef path);
100
105
void addLibrary (StringRef name);
101
106
107
+ Ctx &ctx;
108
+
102
109
// True if we are in --whole-archive and --no-whole-archive.
103
110
bool inWholeArchive = false ;
104
111
@@ -122,19 +129,19 @@ static bool hasZOption(opt::InputArgList &args, StringRef key) {
122
129
bool link (ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
123
130
llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput) {
124
131
// This driver-specific context will be freed later by unsafeLldMain().
125
- auto *ctx = new CommonLinkerContext;
132
+ auto *context = new CommonLinkerContext;
126
133
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)" ;
132
140
133
- config = make<Configuration>();
134
141
symtab = make<SymbolTable>();
135
142
136
143
initLLVM ();
137
- LinkerDriver ().linkerMain (args);
144
+ LinkerDriver (ctx ).linkerMain (args);
138
145
139
146
return errorCount () == 0 ;
140
147
}
@@ -1256,6 +1263,8 @@ static void checkZOptions(opt::InputArgList &args) {
1256
1263
warn (" unknown -z value: " + StringRef (arg->getValue ()));
1257
1264
}
1258
1265
1266
+ LinkerDriver::LinkerDriver (Ctx &ctx) : ctx(ctx) {}
1267
+
1259
1268
void LinkerDriver::linkerMain (ArrayRef<const char *> argsArr) {
1260
1269
WasmOptTable parser;
1261
1270
opt::InputArgList args = parser.parse (argsArr.slice (1 ));
@@ -1324,10 +1333,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
1324
1333
// Fail early if the output file or map file is not writable. If a user has a
1325
1334
// long link, e.g. due to a large LTO link, they do not wish to run it and
1326
1335
// 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 ());
1331
1340
if (errorCount ())
1332
1341
return ;
1333
1342
@@ -1336,11 +1345,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
1336
1345
symtab->trace (arg->getValue ());
1337
1346
1338
1347
for (auto *arg : args.filtered (OPT_export_if_defined))
1339
- config-> exportedSymbols .insert (arg->getValue ());
1348
+ ctx. arg . exportedSymbols .insert (arg->getValue ());
1340
1349
1341
1350
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 ());
1344
1353
}
1345
1354
1346
1355
createSyntheticSymbols ();
@@ -1358,28 +1367,28 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
1358
1367
1359
1368
// Handle the `--export <sym>` options
1360
1369
// 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 )
1362
1371
handleUndefined (iter.first (), " --export" );
1363
1372
1364
1373
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" );
1367
1376
if (entrySym && entrySym->isDefined ())
1368
1377
entrySym->forceExport = true ;
1369
1378
else
1370
1379
error (" entry symbol not defined (pass --no-entry to suppress): " +
1371
- config-> entry );
1380
+ ctx. arg . entry );
1372
1381
}
1373
1382
1374
1383
// If the user code defines a `__wasm_call_dtors` function, remember it so
1375
1384
// that we can call it from the command export wrappers. Unlike
1376
1385
// `__wasm_call_ctors` which we synthesize, `__wasm_call_dtors` is defined
1377
1386
// by libc/etc., because destructors are registered dynamically with
1378
1387
// `__cxa_atexit` and friends.
1379
- if (!config-> relocatable && !config-> shared &&
1388
+ if (!ctx. arg . relocatable && !ctx. arg . shared &&
1380
1389
!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 ())) {
1383
1392
if (Symbol *callDtors =
1384
1393
handleUndefined (" __wasm_call_dtors" , " <internal>" )) {
1385
1394
if (auto *callDtorsFunc = dyn_cast<DefinedFunction>(callDtors)) {
@@ -1437,7 +1446,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
1437
1446
writeWhyExtract ();
1438
1447
1439
1448
// Bail out if normal linked output is skipped due to LTO.
1440
- if (config-> thinLTOIndexOnly )
1449
+ if (ctx. arg . thinLTOIndexOnly )
1441
1450
return ;
1442
1451
1443
1452
createOptionalSymbols ();
@@ -1452,13 +1461,13 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
1452
1461
if (!wrapped.empty ())
1453
1462
wrapSymbols (wrapped);
1454
1463
1455
- for (auto &iter : config-> exportedSymbols ) {
1464
+ for (auto &iter : ctx. arg . exportedSymbols ) {
1456
1465
Symbol *sym = symtab->find (iter.first ());
1457
1466
if (sym && sym->isDefined ())
1458
1467
sym->forceExport = true ;
1459
1468
}
1460
1469
1461
- if (!config-> relocatable && !ctx.isPic ) {
1470
+ if (!ctx. arg . relocatable && !ctx.isPic ) {
1462
1471
// Add synthetic dummies for weak undefined functions. Must happen
1463
1472
// after LTO otherwise functions may not yet have signatures.
1464
1473
symtab->handleWeakUndefines ();
0 commit comments