llvm-project

Форк
0
/
Driver.cpp 
1397 строк · 49.3 Кб
1
//===- Driver.cpp ---------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8

9
#include "lld/Common/Driver.h"
10
#include "Config.h"
11
#include "InputChunks.h"
12
#include "InputElement.h"
13
#include "MarkLive.h"
14
#include "SymbolTable.h"
15
#include "Writer.h"
16
#include "lld/Common/Args.h"
17
#include "lld/Common/CommonLinkerContext.h"
18
#include "lld/Common/ErrorHandler.h"
19
#include "lld/Common/Filesystem.h"
20
#include "lld/Common/Memory.h"
21
#include "lld/Common/Reproduce.h"
22
#include "lld/Common/Strings.h"
23
#include "lld/Common/Version.h"
24
#include "llvm/ADT/Twine.h"
25
#include "llvm/Config/llvm-config.h"
26
#include "llvm/Object/Wasm.h"
27
#include "llvm/Option/Arg.h"
28
#include "llvm/Option/ArgList.h"
29
#include "llvm/Support/CommandLine.h"
30
#include "llvm/Support/Parallel.h"
31
#include "llvm/Support/Path.h"
32
#include "llvm/Support/Process.h"
33
#include "llvm/Support/TarWriter.h"
34
#include "llvm/Support/TargetSelect.h"
35
#include "llvm/TargetParser/Host.h"
36
#include <optional>
37

38
#define DEBUG_TYPE "lld"
39

40
using namespace llvm;
41
using namespace llvm::object;
42
using namespace llvm::opt;
43
using namespace llvm::sys;
44
using namespace llvm::wasm;
45

46
namespace lld::wasm {
47
Configuration *config;
48
Ctx ctx;
49

50
void Ctx::reset() {
51
  objectFiles.clear();
52
  stubFiles.clear();
53
  sharedFiles.clear();
54
  bitcodeFiles.clear();
55
  syntheticFunctions.clear();
56
  syntheticGlobals.clear();
57
  syntheticTables.clear();
58
  whyExtractRecords.clear();
59
  isPic = false;
60
  legacyFunctionTable = false;
61
  emitBssSegments = false;
62
}
63

64
namespace {
65

66
// Create enum with OPT_xxx values for each option in Options.td
67
enum {
68
  OPT_INVALID = 0,
69
#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
70
#include "Options.inc"
71
#undef OPTION
72
};
73

74
// This function is called on startup. We need this for LTO since
75
// LTO calls LLVM functions to compile bitcode files to native code.
76
// Technically this can be delayed until we read bitcode files, but
77
// we don't bother to do lazily because the initialization is fast.
78
static void initLLVM() {
79
  InitializeAllTargets();
80
  InitializeAllTargetMCs();
81
  InitializeAllAsmPrinters();
82
  InitializeAllAsmParsers();
83
}
84

85
class LinkerDriver {
86
public:
87
  void linkerMain(ArrayRef<const char *> argsArr);
88

89
private:
90
  void createFiles(opt::InputArgList &args);
91
  void addFile(StringRef path);
92
  void addLibrary(StringRef name);
93

94
  // True if we are in --whole-archive and --no-whole-archive.
95
  bool inWholeArchive = false;
96

97
  // True if we are in --start-lib and --end-lib.
98
  bool inLib = false;
99

100
  std::vector<InputFile *> files;
101
};
102
} // anonymous namespace
103

104
bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
105
          llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput) {
106
  // This driver-specific context will be freed later by unsafeLldMain().
107
  auto *ctx = new CommonLinkerContext;
108

109
  ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
110
  ctx->e.cleanupCallback = []() { wasm::ctx.reset(); };
111
  ctx->e.logName = args::getFilenameWithoutExe(args[0]);
112
  ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now (use "
113
                                 "-error-limit=0 to see all errors)";
114

115
  config = make<Configuration>();
116
  symtab = make<SymbolTable>();
117

118
  initLLVM();
119
  LinkerDriver().linkerMain(args);
120

121
  return errorCount() == 0;
122
}
123

124
// Create prefix string literals used in Options.td
125
#define PREFIX(NAME, VALUE)                                                    \
126
  static constexpr StringLiteral NAME##_init[] = VALUE;                        \
127
  static constexpr ArrayRef<StringLiteral> NAME(NAME##_init,                   \
128
                                                std::size(NAME##_init) - 1);
129
#include "Options.inc"
130
#undef PREFIX
131

132
// Create table mapping all options defined in Options.td
133
static constexpr opt::OptTable::Info optInfo[] = {
134
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS,         \
135
               VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR,     \
136
               VALUES)                                                         \
137
  {PREFIX,                                                                     \
138
   NAME,                                                                       \
139
   HELPTEXT,                                                                   \
140
   HELPTEXTSFORVARIANTS,                                                       \
141
   METAVAR,                                                                    \
142
   OPT_##ID,                                                                   \
143
   opt::Option::KIND##Class,                                                   \
144
   PARAM,                                                                      \
145
   FLAGS,                                                                      \
146
   VISIBILITY,                                                                 \
147
   OPT_##GROUP,                                                                \
148
   OPT_##ALIAS,                                                                \
149
   ALIASARGS,                                                                  \
150
   VALUES},
151
#include "Options.inc"
152
#undef OPTION
153
};
154

155
namespace {
156
class WasmOptTable : public opt::GenericOptTable {
157
public:
158
  WasmOptTable() : opt::GenericOptTable(optInfo) {}
159
  opt::InputArgList parse(ArrayRef<const char *> argv);
160
};
161
} // namespace
162

163
// Set color diagnostics according to -color-diagnostics={auto,always,never}
164
// or -no-color-diagnostics flags.
165
static void handleColorDiagnostics(opt::InputArgList &args) {
166
  auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
167
                              OPT_no_color_diagnostics);
168
  if (!arg)
169
    return;
170
  if (arg->getOption().getID() == OPT_color_diagnostics) {
171
    lld::errs().enable_colors(true);
172
  } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
173
    lld::errs().enable_colors(false);
174
  } else {
175
    StringRef s = arg->getValue();
176
    if (s == "always")
177
      lld::errs().enable_colors(true);
178
    else if (s == "never")
179
      lld::errs().enable_colors(false);
180
    else if (s != "auto")
181
      error("unknown option: --color-diagnostics=" + s);
182
  }
183
}
184

185
static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &args) {
186
  if (auto *arg = args.getLastArg(OPT_rsp_quoting)) {
187
    StringRef s = arg->getValue();
188
    if (s != "windows" && s != "posix")
189
      error("invalid response file quoting: " + s);
190
    if (s == "windows")
191
      return cl::TokenizeWindowsCommandLine;
192
    return cl::TokenizeGNUCommandLine;
193
  }
194
  if (Triple(sys::getProcessTriple()).isOSWindows())
195
    return cl::TokenizeWindowsCommandLine;
196
  return cl::TokenizeGNUCommandLine;
197
}
198

199
// Find a file by concatenating given paths.
200
static std::optional<std::string> findFile(StringRef path1,
201
                                           const Twine &path2) {
202
  SmallString<128> s;
203
  path::append(s, path1, path2);
204
  if (fs::exists(s))
205
    return std::string(s);
206
  return std::nullopt;
207
}
208

209
opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> argv) {
210
  SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
211

212
  unsigned missingIndex;
213
  unsigned missingCount;
214

215
  // We need to get the quoting style for response files before parsing all
216
  // options so we parse here before and ignore all the options but
217
  // --rsp-quoting.
218
  opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount);
219

220
  // Expand response files (arguments in the form of @<filename>)
221
  // and then parse the argument again.
222
  cl::ExpandResponseFiles(saver(), getQuotingStyle(args), vec);
223
  args = this->ParseArgs(vec, missingIndex, missingCount);
224

225
  handleColorDiagnostics(args);
226
  if (missingCount)
227
    error(Twine(args.getArgString(missingIndex)) + ": missing argument");
228

229
  for (auto *arg : args.filtered(OPT_UNKNOWN))
230
    error("unknown argument: " + arg->getAsString(args));
231
  return args;
232
}
233

234
// Currently we allow a ".imports" to live alongside a library. This can
235
// be used to specify a list of symbols which can be undefined at link
236
// time (imported from the environment.  For example libc.a include an
237
// import file that lists the syscall functions it relies on at runtime.
238
// In the long run this information would be better stored as a symbol
239
// attribute/flag in the object file itself.
240
// See: https://github.com/WebAssembly/tool-conventions/issues/35
241
static void readImportFile(StringRef filename) {
242
  if (std::optional<MemoryBufferRef> buf = readFile(filename))
243
    for (StringRef sym : args::getLines(*buf))
244
      config->allowUndefinedSymbols.insert(sym);
245
}
246

247
// Returns slices of MB by parsing MB as an archive file.
248
// Each slice consists of a member file in the archive.
249
std::vector<std::pair<MemoryBufferRef, uint64_t>> static getArchiveMembers(
250
    MemoryBufferRef mb) {
251
  std::unique_ptr<Archive> file =
252
      CHECK(Archive::create(mb),
253
            mb.getBufferIdentifier() + ": failed to parse archive");
254

255
  std::vector<std::pair<MemoryBufferRef, uint64_t>> v;
256
  Error err = Error::success();
257
  for (const Archive::Child &c : file->children(err)) {
258
    MemoryBufferRef mbref =
259
        CHECK(c.getMemoryBufferRef(),
260
              mb.getBufferIdentifier() +
261
                  ": could not get the buffer for a child of the archive");
262
    v.push_back(std::make_pair(mbref, c.getChildOffset()));
263
  }
264
  if (err)
265
    fatal(mb.getBufferIdentifier() +
266
          ": Archive::children failed: " + toString(std::move(err)));
267

268
  // Take ownership of memory buffers created for members of thin archives.
269
  for (std::unique_ptr<MemoryBuffer> &mb : file->takeThinBuffers())
270
    make<std::unique_ptr<MemoryBuffer>>(std::move(mb));
271

272
  return v;
273
}
274

275
void LinkerDriver::addFile(StringRef path) {
276
  std::optional<MemoryBufferRef> buffer = readFile(path);
277
  if (!buffer)
278
    return;
279
  MemoryBufferRef mbref = *buffer;
280

281
  switch (identify_magic(mbref.getBuffer())) {
282
  case file_magic::archive: {
283
    SmallString<128> importFile = path;
284
    path::replace_extension(importFile, ".imports");
285
    if (fs::exists(importFile))
286
      readImportFile(importFile.str());
287

288
    auto members = getArchiveMembers(mbref);
289

290
    // Handle -whole-archive.
291
    if (inWholeArchive) {
292
      for (const auto &[m, offset] : members) {
293
        auto *object = createObjectFile(m, path, offset);
294
        // Mark object as live; object members are normally not
295
        // live by default but -whole-archive is designed to treat
296
        // them as such.
297
        object->markLive();
298
        files.push_back(object);
299
      }
300

301
      return;
302
    }
303

304
    std::unique_ptr<Archive> file =
305
        CHECK(Archive::create(mbref), path + ": failed to parse archive");
306

307
    for (const auto &[m, offset] : members) {
308
      auto magic = identify_magic(m.getBuffer());
309
      if (magic == file_magic::wasm_object || magic == file_magic::bitcode)
310
        files.push_back(createObjectFile(m, path, offset, true));
311
      else
312
        warn(path + ": archive member '" + m.getBufferIdentifier() +
313
             "' is neither Wasm object file nor LLVM bitcode");
314
    }
315

316
    return;
317
  }
318
  case file_magic::bitcode:
319
  case file_magic::wasm_object:
320
    files.push_back(createObjectFile(mbref, "", 0, inLib));
321
    break;
322
  case file_magic::unknown:
323
    if (mbref.getBuffer().starts_with("#STUB")) {
324
      files.push_back(make<StubFile>(mbref));
325
      break;
326
    }
327
    [[fallthrough]];
328
  default:
329
    error("unknown file type: " + mbref.getBufferIdentifier());
330
  }
331
}
332

333
static std::optional<std::string> findFromSearchPaths(StringRef path) {
334
  for (StringRef dir : config->searchPaths)
335
    if (std::optional<std::string> s = findFile(dir, path))
336
      return s;
337
  return std::nullopt;
338
}
339

340
// This is for -l<basename>. We'll look for lib<basename>.a from
341
// search paths.
342
static std::optional<std::string> searchLibraryBaseName(StringRef name) {
343
  for (StringRef dir : config->searchPaths) {
344
    if (!config->isStatic)
345
      if (std::optional<std::string> s = findFile(dir, "lib" + name + ".so"))
346
        return s;
347
    if (std::optional<std::string> s = findFile(dir, "lib" + name + ".a"))
348
      return s;
349
  }
350
  return std::nullopt;
351
}
352

353
// This is for -l<namespec>.
354
static std::optional<std::string> searchLibrary(StringRef name) {
355
  if (name.starts_with(":"))
356
    return findFromSearchPaths(name.substr(1));
357
  return searchLibraryBaseName(name);
358
}
359

360
// Add a given library by searching it from input search paths.
361
void LinkerDriver::addLibrary(StringRef name) {
362
  if (std::optional<std::string> path = searchLibrary(name))
363
    addFile(saver().save(*path));
364
  else
365
    error("unable to find library -l" + name, ErrorTag::LibNotFound, {name});
366
}
367

368
void LinkerDriver::createFiles(opt::InputArgList &args) {
369
  for (auto *arg : args) {
370
    switch (arg->getOption().getID()) {
371
    case OPT_library:
372
      addLibrary(arg->getValue());
373
      break;
374
    case OPT_INPUT:
375
      addFile(arg->getValue());
376
      break;
377
    case OPT_Bstatic:
378
      config->isStatic = true;
379
      break;
380
    case OPT_Bdynamic:
381
      config->isStatic = false;
382
      break;
383
    case OPT_whole_archive:
384
      inWholeArchive = true;
385
      break;
386
    case OPT_no_whole_archive:
387
      inWholeArchive = false;
388
      break;
389
    case OPT_start_lib:
390
      if (inLib)
391
        error("nested --start-lib");
392
      inLib = true;
393
      break;
394
    case OPT_end_lib:
395
      if (!inLib)
396
        error("stray --end-lib");
397
      inLib = false;
398
      break;
399
    }
400
  }
401
  if (files.empty() && errorCount() == 0)
402
    error("no input files");
403
}
404

405
static StringRef getEntry(opt::InputArgList &args) {
406
  auto *arg = args.getLastArg(OPT_entry, OPT_no_entry);
407
  if (!arg) {
408
    if (args.hasArg(OPT_relocatable))
409
      return "";
410
    if (args.hasArg(OPT_shared))
411
      return "__wasm_call_ctors";
412
    return "_start";
413
  }
414
  if (arg->getOption().getID() == OPT_no_entry)
415
    return "";
416
  return arg->getValue();
417
}
418

419
// Determines what we should do if there are remaining unresolved
420
// symbols after the name resolution.
421
static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &args) {
422
  UnresolvedPolicy errorOrWarn = args.hasFlag(OPT_error_unresolved_symbols,
423
                                              OPT_warn_unresolved_symbols, true)
424
                                     ? UnresolvedPolicy::ReportError
425
                                     : UnresolvedPolicy::Warn;
426

427
  if (auto *arg = args.getLastArg(OPT_unresolved_symbols)) {
428
    StringRef s = arg->getValue();
429
    if (s == "ignore-all")
430
      return UnresolvedPolicy::Ignore;
431
    if (s == "import-dynamic")
432
      return UnresolvedPolicy::ImportDynamic;
433
    if (s == "report-all")
434
      return errorOrWarn;
435
    error("unknown --unresolved-symbols value: " + s);
436
  }
437

438
  return errorOrWarn;
439
}
440

441
// Parse --build-id or --build-id=<style>. We handle "tree" as a
442
// synonym for "sha1" because all our hash functions including
443
// -build-id=sha1 are actually tree hashes for performance reasons.
444
static std::pair<BuildIdKind, SmallVector<uint8_t, 0>>
445
getBuildId(opt::InputArgList &args) {
446
  auto *arg = args.getLastArg(OPT_build_id, OPT_build_id_eq);
447
  if (!arg)
448
    return {BuildIdKind::None, {}};
449

450
  if (arg->getOption().getID() == OPT_build_id)
451
    return {BuildIdKind::Fast, {}};
452

453
  StringRef s = arg->getValue();
454
  if (s == "fast")
455
    return {BuildIdKind::Fast, {}};
456
  if (s == "sha1" || s == "tree")
457
    return {BuildIdKind::Sha1, {}};
458
  if (s == "uuid")
459
    return {BuildIdKind::Uuid, {}};
460
  if (s.starts_with("0x"))
461
    return {BuildIdKind::Hexstring, parseHex(s.substr(2))};
462

463
  if (s != "none")
464
    error("unknown --build-id style: " + s);
465
  return {BuildIdKind::None, {}};
466
}
467

468
// Initializes Config members by the command line options.
469
static void readConfigs(opt::InputArgList &args) {
470
  config->bsymbolic = args.hasArg(OPT_Bsymbolic);
471
  config->checkFeatures =
472
      args.hasFlag(OPT_check_features, OPT_no_check_features, true);
473
  config->compressRelocations = args.hasArg(OPT_compress_relocations);
474
  config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
475
  config->disableVerify = args.hasArg(OPT_disable_verify);
476
  config->emitRelocs = args.hasArg(OPT_emit_relocs);
477
  config->experimentalPic = args.hasArg(OPT_experimental_pic);
478
  config->entry = getEntry(args);
479
  config->exportAll = args.hasArg(OPT_export_all);
480
  config->exportTable = args.hasArg(OPT_export_table);
481
  config->growableTable = args.hasArg(OPT_growable_table);
482

483
  if (args.hasArg(OPT_import_memory_with_name)) {
484
    config->memoryImport =
485
        args.getLastArgValue(OPT_import_memory_with_name).split(",");
486
  } else if (args.hasArg(OPT_import_memory)) {
487
    config->memoryImport =
488
        std::pair<llvm::StringRef, llvm::StringRef>(defaultModule, memoryName);
489
  } else {
490
    config->memoryImport =
491
        std::optional<std::pair<llvm::StringRef, llvm::StringRef>>();
492
  }
493

494
  if (args.hasArg(OPT_export_memory_with_name)) {
495
    config->memoryExport =
496
        args.getLastArgValue(OPT_export_memory_with_name);
497
  } else if (args.hasArg(OPT_export_memory)) {
498
    config->memoryExport = memoryName;
499
  } else {
500
    config->memoryExport = std::optional<llvm::StringRef>();
501
  }
502

503
  config->sharedMemory = args.hasArg(OPT_shared_memory);
504
  config->soName = args.getLastArgValue(OPT_soname);
505
  config->importTable = args.hasArg(OPT_import_table);
506
  config->importUndefined = args.hasArg(OPT_import_undefined);
507
  config->ltoo = args::getInteger(args, OPT_lto_O, 2);
508
  if (config->ltoo > 3)
509
    error("invalid optimization level for LTO: " + Twine(config->ltoo));
510
  unsigned ltoCgo =
511
      args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(config->ltoo));
512
  if (auto level = CodeGenOpt::getLevel(ltoCgo))
513
    config->ltoCgo = *level;
514
  else
515
    error("invalid codegen optimization level for LTO: " + Twine(ltoCgo));
516
  config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
517
  config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
518
  config->mapFile = args.getLastArgValue(OPT_Map);
519
  config->optimize = args::getInteger(args, OPT_O, 1);
520
  config->outputFile = args.getLastArgValue(OPT_o);
521
  config->relocatable = args.hasArg(OPT_relocatable);
522
  config->gcSections =
523
      args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !config->relocatable);
524
  for (auto *arg : args.filtered(OPT_keep_section))
525
    config->keepSections.insert(arg->getValue());
526
  config->mergeDataSegments =
527
      args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
528
                   !config->relocatable);
529
  config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
530
  config->printGcSections =
531
      args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
532
  config->saveTemps = args.hasArg(OPT_save_temps);
533
  config->searchPaths = args::getStrings(args, OPT_library_path);
534
  config->shared = args.hasArg(OPT_shared);
535
  config->stripAll = args.hasArg(OPT_strip_all);
536
  config->stripDebug = args.hasArg(OPT_strip_debug);
537
  config->stackFirst = args.hasArg(OPT_stack_first);
538
  config->trace = args.hasArg(OPT_trace);
539
  config->thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
540
  config->thinLTOCachePolicy = CHECK(
541
      parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)),
542
      "--thinlto-cache-policy: invalid cache policy");
543
  config->unresolvedSymbols = getUnresolvedSymbolPolicy(args);
544
  config->whyExtract = args.getLastArgValue(OPT_why_extract);
545
  errorHandler().verbose = args.hasArg(OPT_verbose);
546
  LLVM_DEBUG(errorHandler().verbose = true);
547

548
  config->tableBase = args::getInteger(args, OPT_table_base, 0);
549
  config->globalBase = args::getInteger(args, OPT_global_base, 0);
550
  config->initialHeap = args::getInteger(args, OPT_initial_heap, 0);
551
  config->initialMemory = args::getInteger(args, OPT_initial_memory, 0);
552
  config->maxMemory = args::getInteger(args, OPT_max_memory, 0);
553
  config->noGrowableMemory = args.hasArg(OPT_no_growable_memory);
554
  config->zStackSize =
555
      args::getZOptionValue(args, OPT_z, "stack-size", WasmPageSize);
556

557
  // -Bdynamic by default if -pie or -shared is specified.
558
  if (config->pie || config->shared)
559
    config->isStatic = false;
560

561
  if (config->maxMemory != 0 && config->noGrowableMemory) {
562
    // Erroring out here is simpler than defining precedence rules.
563
    error("--max-memory is incompatible with --no-growable-memory");
564
  }
565

566
  // Default value of exportDynamic depends on `-shared`
567
  config->exportDynamic =
568
      args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, config->shared);
569

570
  // Parse wasm32/64.
571
  if (auto *arg = args.getLastArg(OPT_m)) {
572
    StringRef s = arg->getValue();
573
    if (s == "wasm32")
574
      config->is64 = false;
575
    else if (s == "wasm64")
576
      config->is64 = true;
577
    else
578
      error("invalid target architecture: " + s);
579
  }
580

581
  // --threads= takes a positive integer and provides the default value for
582
  // --thinlto-jobs=.
583
  if (auto *arg = args.getLastArg(OPT_threads)) {
584
    StringRef v(arg->getValue());
585
    unsigned threads = 0;
586
    if (!llvm::to_integer(v, threads, 0) || threads == 0)
587
      error(arg->getSpelling() + ": expected a positive integer, but got '" +
588
            arg->getValue() + "'");
589
    parallel::strategy = hardware_concurrency(threads);
590
    config->thinLTOJobs = v;
591
  }
592
  if (auto *arg = args.getLastArg(OPT_thinlto_jobs))
593
    config->thinLTOJobs = arg->getValue();
594

595
  if (auto *arg = args.getLastArg(OPT_features)) {
596
    config->features =
597
        std::optional<std::vector<std::string>>(std::vector<std::string>());
598
    for (StringRef s : arg->getValues())
599
      config->features->push_back(std::string(s));
600
  }
601

602
  if (auto *arg = args.getLastArg(OPT_extra_features)) {
603
    config->extraFeatures =
604
        std::optional<std::vector<std::string>>(std::vector<std::string>());
605
    for (StringRef s : arg->getValues())
606
      config->extraFeatures->push_back(std::string(s));
607
  }
608

609
  // Legacy --allow-undefined flag which is equivalent to
610
  // --unresolve-symbols=ignore + --import-undefined
611
  if (args.hasArg(OPT_allow_undefined)) {
612
    config->importUndefined = true;
613
    config->unresolvedSymbols = UnresolvedPolicy::Ignore;
614
  }
615

616
  if (args.hasArg(OPT_print_map))
617
    config->mapFile = "-";
618

619
  std::tie(config->buildId, config->buildIdVector) = getBuildId(args);
620
}
621

622
// Some Config members do not directly correspond to any particular
623
// command line options, but computed based on other Config values.
624
// This function initialize such members. See Config.h for the details
625
// of these values.
626
static void setConfigs() {
627
  ctx.isPic = config->pie || config->shared;
628

629
  if (ctx.isPic) {
630
    if (config->exportTable)
631
      error("-shared/-pie is incompatible with --export-table");
632
    config->importTable = true;
633
  } else {
634
    // Default table base.  Defaults to 1, reserving 0 for the NULL function
635
    // pointer.
636
    if (!config->tableBase)
637
      config->tableBase = 1;
638
    // The default offset for static/global data, for when --global-base is
639
    // not specified on the command line.  The precise value of 1024 is
640
    // somewhat arbitrary, and pre-dates wasm-ld (Its the value that
641
    // emscripten used prior to wasm-ld).
642
    if (!config->globalBase && !config->relocatable && !config->stackFirst)
643
      config->globalBase = 1024;
644
  }
645

646
  if (config->relocatable) {
647
    if (config->exportTable)
648
      error("--relocatable is incompatible with --export-table");
649
    if (config->growableTable)
650
      error("--relocatable is incompatible with --growable-table");
651
    // Ignore any --import-table, as it's redundant.
652
    config->importTable = true;
653
  }
654

655
  if (config->shared) {
656
    if (config->memoryExport.has_value()) {
657
      error("--export-memory is incompatible with --shared");
658
    }
659
    if (!config->memoryImport.has_value()) {
660
      config->memoryImport =
661
          std::pair<llvm::StringRef, llvm::StringRef>(defaultModule, memoryName);
662
    }
663
  }
664

665
  // If neither export-memory nor import-memory is specified, default to
666
  // exporting memory under its default name.
667
  if (!config->memoryExport.has_value() && !config->memoryImport.has_value()) {
668
    config->memoryExport = memoryName;
669
  }
670
}
671

672
// Some command line options or some combinations of them are not allowed.
673
// This function checks for such errors.
674
static void checkOptions(opt::InputArgList &args) {
675
  if (!config->stripDebug && !config->stripAll && config->compressRelocations)
676
    error("--compress-relocations is incompatible with output debug"
677
          " information. Please pass --strip-debug or --strip-all");
678

679
  if (config->ltoPartitions == 0)
680
    error("--lto-partitions: number of threads must be > 0");
681
  if (!get_threadpool_strategy(config->thinLTOJobs))
682
    error("--thinlto-jobs: invalid job count: " + config->thinLTOJobs);
683

684
  if (config->pie && config->shared)
685
    error("-shared and -pie may not be used together");
686

687
  if (config->outputFile.empty())
688
    error("no output file specified");
689

690
  if (config->importTable && config->exportTable)
691
    error("--import-table and --export-table may not be used together");
692

693
  if (config->relocatable) {
694
    if (!config->entry.empty())
695
      error("entry point specified for relocatable output file");
696
    if (config->gcSections)
697
      error("-r and --gc-sections may not be used together");
698
    if (config->compressRelocations)
699
      error("-r -and --compress-relocations may not be used together");
700
    if (args.hasArg(OPT_undefined))
701
      error("-r -and --undefined may not be used together");
702
    if (config->pie)
703
      error("-r and -pie may not be used together");
704
    if (config->sharedMemory)
705
      error("-r and --shared-memory may not be used together");
706
    if (config->globalBase)
707
      error("-r and --global-base may not by used together");
708
  }
709

710
  // To begin to prepare for Module Linking-style shared libraries, start
711
  // warning about uses of `-shared` and related flags outside of Experimental
712
  // mode, to give anyone using them a heads-up that they will be changing.
713
  //
714
  // Also, warn about flags which request explicit exports.
715
  if (!config->experimentalPic) {
716
    // -shared will change meaning when Module Linking is implemented.
717
    if (config->shared) {
718
      warn("creating shared libraries, with -shared, is not yet stable");
719
    }
720

721
    // -pie will change meaning when Module Linking is implemented.
722
    if (config->pie) {
723
      warn("creating PIEs, with -pie, is not yet stable");
724
    }
725

726
    if (config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic) {
727
      warn("dynamic imports are not yet stable "
728
           "(--unresolved-symbols=import-dynamic)");
729
    }
730
  }
731

732
  if (config->bsymbolic && !config->shared) {
733
    warn("-Bsymbolic is only meaningful when combined with -shared");
734
  }
735

736
  if (ctx.isPic) {
737
    if (config->globalBase)
738
      error("--global-base may not be used with -shared/-pie");
739
    if (config->tableBase)
740
      error("--table-base may not be used with -shared/-pie");
741
  }
742
}
743

744
static const char *getReproduceOption(opt::InputArgList &args) {
745
  if (auto *arg = args.getLastArg(OPT_reproduce))
746
    return arg->getValue();
747
  return getenv("LLD_REPRODUCE");
748
}
749

750
// Force Sym to be entered in the output. Used for -u or equivalent.
751
static Symbol *handleUndefined(StringRef name, const char *option) {
752
  Symbol *sym = symtab->find(name);
753
  if (!sym)
754
    return nullptr;
755

756
  // Since symbol S may not be used inside the program, LTO may
757
  // eliminate it. Mark the symbol as "used" to prevent it.
758
  sym->isUsedInRegularObj = true;
759

760
  if (auto *lazySym = dyn_cast<LazySymbol>(sym)) {
761
    lazySym->extract();
762
    if (!config->whyExtract.empty())
763
      ctx.whyExtractRecords.emplace_back(option, sym->getFile(), *sym);
764
  }
765

766
  return sym;
767
}
768

769
static void handleLibcall(StringRef name) {
770
  Symbol *sym = symtab->find(name);
771
  if (sym && sym->isLazy() && isa<BitcodeFile>(sym->getFile())) {
772
    if (!config->whyExtract.empty())
773
      ctx.whyExtractRecords.emplace_back("<libcall>", sym->getFile(), *sym);
774
    cast<LazySymbol>(sym)->extract();
775
  }
776
}
777

778
static void writeWhyExtract() {
779
  if (config->whyExtract.empty())
780
    return;
781

782
  std::error_code ec;
783
  raw_fd_ostream os(config->whyExtract, ec, sys::fs::OF_None);
784
  if (ec) {
785
    error("cannot open --why-extract= file " + config->whyExtract + ": " +
786
          ec.message());
787
    return;
788
  }
789

790
  os << "reference\textracted\tsymbol\n";
791
  for (auto &entry : ctx.whyExtractRecords) {
792
    os << std::get<0>(entry) << '\t' << toString(std::get<1>(entry)) << '\t'
793
       << toString(std::get<2>(entry)) << '\n';
794
  }
795
}
796

797
// Equivalent of demote demoteSharedAndLazySymbols() in the ELF linker
798
static void demoteLazySymbols() {
799
  for (Symbol *sym : symtab->symbols()) {
800
    if (auto* s = dyn_cast<LazySymbol>(sym)) {
801
      if (s->signature) {
802
        LLVM_DEBUG(llvm::dbgs()
803
                   << "demoting lazy func: " << s->getName() << "\n");
804
        replaceSymbol<UndefinedFunction>(s, s->getName(), std::nullopt,
805
                                         std::nullopt, WASM_SYMBOL_BINDING_WEAK,
806
                                         s->getFile(), s->signature);
807
      }
808
    }
809
  }
810
}
811

812
static UndefinedGlobal *
813
createUndefinedGlobal(StringRef name, llvm::wasm::WasmGlobalType *type) {
814
  auto *sym = cast<UndefinedGlobal>(symtab->addUndefinedGlobal(
815
      name, std::nullopt, std::nullopt, WASM_SYMBOL_UNDEFINED, nullptr, type));
816
  config->allowUndefinedSymbols.insert(sym->getName());
817
  sym->isUsedInRegularObj = true;
818
  return sym;
819
}
820

821
static InputGlobal *createGlobal(StringRef name, bool isMutable) {
822
  llvm::wasm::WasmGlobal wasmGlobal;
823
  bool is64 = config->is64.value_or(false);
824
  wasmGlobal.Type = {uint8_t(is64 ? WASM_TYPE_I64 : WASM_TYPE_I32), isMutable};
825
  wasmGlobal.InitExpr = intConst(0, is64);
826
  wasmGlobal.SymbolName = name;
827
  return make<InputGlobal>(wasmGlobal, nullptr);
828
}
829

830
static GlobalSymbol *createGlobalVariable(StringRef name, bool isMutable) {
831
  InputGlobal *g = createGlobal(name, isMutable);
832
  return symtab->addSyntheticGlobal(name, WASM_SYMBOL_VISIBILITY_HIDDEN, g);
833
}
834

835
static GlobalSymbol *createOptionalGlobal(StringRef name, bool isMutable) {
836
  InputGlobal *g = createGlobal(name, isMutable);
837
  return symtab->addOptionalGlobalSymbol(name, g);
838
}
839

840
// Create ABI-defined synthetic symbols
841
static void createSyntheticSymbols() {
842
  if (config->relocatable)
843
    return;
844

845
  static WasmSignature nullSignature = {{}, {}};
846
  static WasmSignature i32ArgSignature = {{}, {ValType::I32}};
847
  static WasmSignature i64ArgSignature = {{}, {ValType::I64}};
848
  static llvm::wasm::WasmGlobalType globalTypeI32 = {WASM_TYPE_I32, false};
849
  static llvm::wasm::WasmGlobalType globalTypeI64 = {WASM_TYPE_I64, false};
850
  static llvm::wasm::WasmGlobalType mutableGlobalTypeI32 = {WASM_TYPE_I32,
851
                                                            true};
852
  static llvm::wasm::WasmGlobalType mutableGlobalTypeI64 = {WASM_TYPE_I64,
853
                                                            true};
854
  WasmSym::callCtors = symtab->addSyntheticFunction(
855
      "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
856
      make<SyntheticFunction>(nullSignature, "__wasm_call_ctors"));
857

858
  bool is64 = config->is64.value_or(false);
859

860
  if (ctx.isPic) {
861
    WasmSym::stackPointer =
862
        createUndefinedGlobal("__stack_pointer", config->is64.value_or(false)
863
                                                     ? &mutableGlobalTypeI64
864
                                                     : &mutableGlobalTypeI32);
865
    // For PIC code, we import two global variables (__memory_base and
866
    // __table_base) from the environment and use these as the offset at
867
    // which to load our static data and function table.
868
    // See:
869
    // https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
870
    auto *globalType = is64 ? &globalTypeI64 : &globalTypeI32;
871
    WasmSym::memoryBase = createUndefinedGlobal("__memory_base", globalType);
872
    WasmSym::tableBase = createUndefinedGlobal("__table_base", globalType);
873
    WasmSym::memoryBase->markLive();
874
    WasmSym::tableBase->markLive();
875
  } else {
876
    // For non-PIC code
877
    WasmSym::stackPointer = createGlobalVariable("__stack_pointer", true);
878
    WasmSym::stackPointer->markLive();
879
  }
880

881
  if (config->sharedMemory) {
882
    WasmSym::tlsBase = createGlobalVariable("__tls_base", true);
883
    WasmSym::tlsSize = createGlobalVariable("__tls_size", false);
884
    WasmSym::tlsAlign = createGlobalVariable("__tls_align", false);
885
    WasmSym::initTLS = symtab->addSyntheticFunction(
886
        "__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN,
887
        make<SyntheticFunction>(
888
            is64 ? i64ArgSignature : i32ArgSignature,
889
            "__wasm_init_tls"));
890
  }
891

892
  if (ctx.isPic ||
893
      config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic) {
894
    // For PIC code, or when dynamically importing addresses, we create
895
    // synthetic functions that apply relocations.  These get called from
896
    // __wasm_call_ctors before the user-level constructors.
897
    WasmSym::applyDataRelocs = symtab->addSyntheticFunction(
898
        "__wasm_apply_data_relocs",
899
        WASM_SYMBOL_VISIBILITY_DEFAULT | WASM_SYMBOL_EXPORTED,
900
        make<SyntheticFunction>(nullSignature, "__wasm_apply_data_relocs"));
901
  }
902
}
903

904
static void createOptionalSymbols() {
905
  if (config->relocatable)
906
    return;
907

908
  WasmSym::dsoHandle = symtab->addOptionalDataSymbol("__dso_handle");
909

910
  if (!config->shared)
911
    WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");
912

913
  if (!ctx.isPic) {
914
    WasmSym::stackLow = symtab->addOptionalDataSymbol("__stack_low");
915
    WasmSym::stackHigh = symtab->addOptionalDataSymbol("__stack_high");
916
    WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base");
917
    WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base");
918
    WasmSym::heapEnd = symtab->addOptionalDataSymbol("__heap_end");
919
    WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
920
    WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
921
  }
922

923
  // For non-shared memory programs we still need to define __tls_base since we
924
  // allow object files built with TLS to be linked into single threaded
925
  // programs, and such object files can contain references to this symbol.
926
  //
927
  // However, in this case __tls_base is immutable and points directly to the
928
  // start of the `.tdata` static segment.
929
  //
930
  // __tls_size and __tls_align are not needed in this case since they are only
931
  // needed for __wasm_init_tls (which we do not create in this case).
932
  if (!config->sharedMemory)
933
    WasmSym::tlsBase = createOptionalGlobal("__tls_base", false);
934
}
935

936
static void processStubLibrariesPreLTO() {
937
  log("-- processStubLibrariesPreLTO");
938
  for (auto &stub_file : ctx.stubFiles) {
939
    LLVM_DEBUG(llvm::dbgs()
940
               << "processing stub file: " << stub_file->getName() << "\n");
941
    for (auto [name, deps]: stub_file->symbolDependencies) {
942
      auto* sym = symtab->find(name);
943
      // If the symbol is not present at all (yet), or if it is present but
944
      // undefined, then mark the dependent symbols as used by a regular
945
      // object so they will be preserved and exported by the LTO process.
946
      if (!sym || sym->isUndefined()) {
947
        for (const auto dep : deps) {
948
          auto* needed = symtab->find(dep);
949
          if (needed ) {
950
            needed->isUsedInRegularObj = true;
951
          }
952
        }
953
      }
954
    }
955
  }
956
}
957

958
static bool addStubSymbolDeps(const StubFile *stub_file, Symbol *sym,
959
                              ArrayRef<StringRef> deps) {
960
  // The first stub library to define a given symbol sets this and
961
  // definitions in later stub libraries are ignored.
962
  if (sym->forceImport)
963
    return false; // Already handled
964
  sym->forceImport = true;
965
  if (sym->traced)
966
    message(toString(stub_file) + ": importing " + sym->getName());
967
  else
968
    LLVM_DEBUG(llvm::dbgs() << toString(stub_file) << ": importing "
969
                            << sym->getName() << "\n");
970
  bool depsAdded = false;
971
  for (const auto dep : deps) {
972
    auto *needed = symtab->find(dep);
973
    if (!needed) {
974
      error(toString(stub_file) + ": undefined symbol: " + dep +
975
            ". Required by " + toString(*sym));
976
    } else if (needed->isUndefined()) {
977
      error(toString(stub_file) + ": undefined symbol: " + toString(*needed) +
978
            ". Required by " + toString(*sym));
979
    } else {
980
      if (needed->traced)
981
        message(toString(stub_file) + ": exported " + toString(*needed) +
982
                " due to import of " + sym->getName());
983
      else
984
        LLVM_DEBUG(llvm::dbgs()
985
                   << "force export: " << toString(*needed) << "\n");
986
      needed->forceExport = true;
987
      if (auto *lazy = dyn_cast<LazySymbol>(needed)) {
988
        depsAdded = true;
989
        lazy->extract();
990
        if (!config->whyExtract.empty())
991
          ctx.whyExtractRecords.emplace_back(toString(stub_file),
992
                                             sym->getFile(), *sym);
993
      }
994
    }
995
  }
996
  return depsAdded;
997
}
998

999
static void processStubLibraries() {
1000
  log("-- processStubLibraries");
1001
  bool depsAdded = false;
1002
  do {
1003
    depsAdded = false;
1004
    for (auto &stub_file : ctx.stubFiles) {
1005
      LLVM_DEBUG(llvm::dbgs()
1006
                 << "processing stub file: " << stub_file->getName() << "\n");
1007

1008
      // First look for any imported symbols that directly match
1009
      // the names of the stub imports
1010
      for (auto [name, deps]: stub_file->symbolDependencies) {
1011
        auto* sym = symtab->find(name);
1012
        if (sym && sym->isUndefined()) {
1013
          depsAdded |= addStubSymbolDeps(stub_file, sym, deps);
1014
        } else {
1015
          if (sym && sym->traced)
1016
            message(toString(stub_file) + ": stub symbol not needed: " + name);
1017
          else
1018
            LLVM_DEBUG(llvm::dbgs()
1019
                       << "stub symbol not needed: `" << name << "`\n");
1020
        }
1021
      }
1022

1023
      // Secondly looks for any symbols with an `importName` that matches
1024
      for (Symbol *sym : symtab->symbols()) {
1025
        if (sym->isUndefined() && sym->importName.has_value()) {
1026
          auto it = stub_file->symbolDependencies.find(sym->importName.value());
1027
          if (it != stub_file->symbolDependencies.end()) {
1028
            depsAdded |= addStubSymbolDeps(stub_file, sym, it->second);
1029
          }
1030
        }
1031
      }
1032
    }
1033
  } while (depsAdded);
1034

1035
  log("-- done processStubLibraries");
1036
}
1037

1038
// Reconstructs command line arguments so that so that you can re-run
1039
// the same command with the same inputs. This is for --reproduce.
1040
static std::string createResponseFile(const opt::InputArgList &args) {
1041
  SmallString<0> data;
1042
  raw_svector_ostream os(data);
1043

1044
  // Copy the command line to the output while rewriting paths.
1045
  for (auto *arg : args) {
1046
    switch (arg->getOption().getID()) {
1047
    case OPT_reproduce:
1048
      break;
1049
    case OPT_INPUT:
1050
      os << quote(relativeToRoot(arg->getValue())) << "\n";
1051
      break;
1052
    case OPT_o:
1053
      // If -o path contains directories, "lld @response.txt" will likely
1054
      // fail because the archive we are creating doesn't contain empty
1055
      // directories for the output path (-o doesn't create directories).
1056
      // Strip directories to prevent the issue.
1057
      os << "-o " << quote(sys::path::filename(arg->getValue())) << "\n";
1058
      break;
1059
    default:
1060
      os << toString(*arg) << "\n";
1061
    }
1062
  }
1063
  return std::string(data);
1064
}
1065

1066
// The --wrap option is a feature to rename symbols so that you can write
1067
// wrappers for existing functions. If you pass `-wrap=foo`, all
1068
// occurrences of symbol `foo` are resolved to `wrap_foo` (so, you are
1069
// expected to write `wrap_foo` function as a wrapper). The original
1070
// symbol becomes accessible as `real_foo`, so you can call that from your
1071
// wrapper.
1072
//
1073
// This data structure is instantiated for each -wrap option.
1074
struct WrappedSymbol {
1075
  Symbol *sym;
1076
  Symbol *real;
1077
  Symbol *wrap;
1078
};
1079

1080
static Symbol *addUndefined(StringRef name) {
1081
  return symtab->addUndefinedFunction(name, std::nullopt, std::nullopt,
1082
                                      WASM_SYMBOL_UNDEFINED, nullptr, nullptr,
1083
                                      false);
1084
}
1085

1086
// Handles -wrap option.
1087
//
1088
// This function instantiates wrapper symbols. At this point, they seem
1089
// like they are not being used at all, so we explicitly set some flags so
1090
// that LTO won't eliminate them.
1091
static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
1092
  std::vector<WrappedSymbol> v;
1093
  DenseSet<StringRef> seen;
1094

1095
  for (auto *arg : args.filtered(OPT_wrap)) {
1096
    StringRef name = arg->getValue();
1097
    if (!seen.insert(name).second)
1098
      continue;
1099

1100
    Symbol *sym = symtab->find(name);
1101
    if (!sym)
1102
      continue;
1103

1104
    Symbol *real = addUndefined(saver().save("__real_" + name));
1105
    Symbol *wrap = addUndefined(saver().save("__wrap_" + name));
1106
    v.push_back({sym, real, wrap});
1107

1108
    // We want to tell LTO not to inline symbols to be overwritten
1109
    // because LTO doesn't know the final symbol contents after renaming.
1110
    real->canInline = false;
1111
    sym->canInline = false;
1112

1113
    // Tell LTO not to eliminate these symbols.
1114
    sym->isUsedInRegularObj = true;
1115
    wrap->isUsedInRegularObj = true;
1116
    real->isUsedInRegularObj = false;
1117
  }
1118
  return v;
1119
}
1120

1121
// Do renaming for -wrap by updating pointers to symbols.
1122
//
1123
// When this function is executed, only InputFiles and symbol table
1124
// contain pointers to symbol objects. We visit them to replace pointers,
1125
// so that wrapped symbols are swapped as instructed by the command line.
1126
static void wrapSymbols(ArrayRef<WrappedSymbol> wrapped) {
1127
  DenseMap<Symbol *, Symbol *> map;
1128
  for (const WrappedSymbol &w : wrapped) {
1129
    map[w.sym] = w.wrap;
1130
    map[w.real] = w.sym;
1131
  }
1132

1133
  // Update pointers in input files.
1134
  parallelForEach(ctx.objectFiles, [&](InputFile *file) {
1135
    MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
1136
    for (size_t i = 0, e = syms.size(); i != e; ++i)
1137
      if (Symbol *s = map.lookup(syms[i]))
1138
        syms[i] = s;
1139
  });
1140

1141
  // Update pointers in the symbol table.
1142
  for (const WrappedSymbol &w : wrapped)
1143
    symtab->wrap(w.sym, w.real, w.wrap);
1144
}
1145

1146
static void splitSections() {
1147
  // splitIntoPieces needs to be called on each MergeInputChunk
1148
  // before calling finalizeContents().
1149
  LLVM_DEBUG(llvm::dbgs() << "splitSections\n");
1150
  parallelForEach(ctx.objectFiles, [](ObjFile *file) {
1151
    for (InputChunk *seg : file->segments) {
1152
      if (auto *s = dyn_cast<MergeInputChunk>(seg))
1153
        s->splitIntoPieces();
1154
    }
1155
    for (InputChunk *sec : file->customSections) {
1156
      if (auto *s = dyn_cast<MergeInputChunk>(sec))
1157
        s->splitIntoPieces();
1158
    }
1159
  });
1160
}
1161

1162
static bool isKnownZFlag(StringRef s) {
1163
  // For now, we only support a very limited set of -z flags
1164
  return s.starts_with("stack-size=");
1165
}
1166

1167
// Report a warning for an unknown -z option.
1168
static void checkZOptions(opt::InputArgList &args) {
1169
  for (auto *arg : args.filtered(OPT_z))
1170
    if (!isKnownZFlag(arg->getValue()))
1171
      warn("unknown -z value: " + StringRef(arg->getValue()));
1172
}
1173

1174
void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
1175
  WasmOptTable parser;
1176
  opt::InputArgList args = parser.parse(argsArr.slice(1));
1177

1178
  // Interpret these flags early because error()/warn() depend on them.
1179
  errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20);
1180
  errorHandler().fatalWarnings =
1181
      args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
1182
  checkZOptions(args);
1183

1184
  // Handle --help
1185
  if (args.hasArg(OPT_help)) {
1186
    parser.printHelp(lld::outs(),
1187
                     (std::string(argsArr[0]) + " [options] file...").c_str(),
1188
                     "LLVM Linker", false);
1189
    return;
1190
  }
1191

1192
  // Handle --version
1193
  if (args.hasArg(OPT_version) || args.hasArg(OPT_v)) {
1194
    lld::outs() << getLLDVersion() << "\n";
1195
    return;
1196
  }
1197

1198
  // Handle --reproduce
1199
  if (const char *path = getReproduceOption(args)) {
1200
    Expected<std::unique_ptr<TarWriter>> errOrWriter =
1201
        TarWriter::create(path, path::stem(path));
1202
    if (errOrWriter) {
1203
      tar = std::move(*errOrWriter);
1204
      tar->append("response.txt", createResponseFile(args));
1205
      tar->append("version.txt", getLLDVersion() + "\n");
1206
    } else {
1207
      error("--reproduce: " + toString(errOrWriter.takeError()));
1208
    }
1209
  }
1210

1211
  // Parse and evaluate -mllvm options.
1212
  std::vector<const char *> v;
1213
  v.push_back("wasm-ld (LLVM option parsing)");
1214
  for (auto *arg : args.filtered(OPT_mllvm))
1215
    v.push_back(arg->getValue());
1216
  cl::ResetAllOptionOccurrences();
1217
  cl::ParseCommandLineOptions(v.size(), v.data());
1218

1219
  readConfigs(args);
1220
  setConfigs();
1221

1222
  createFiles(args);
1223
  if (errorCount())
1224
    return;
1225

1226
  checkOptions(args);
1227
  if (errorCount())
1228
    return;
1229

1230
  if (auto *arg = args.getLastArg(OPT_allow_undefined_file))
1231
    readImportFile(arg->getValue());
1232

1233
  // Fail early if the output file or map file is not writable. If a user has a
1234
  // long link, e.g. due to a large LTO link, they do not wish to run it and
1235
  // find that it failed because there was a mistake in their command-line.
1236
  if (auto e = tryCreateFile(config->outputFile))
1237
    error("cannot open output file " + config->outputFile + ": " + e.message());
1238
  if (auto e = tryCreateFile(config->mapFile))
1239
    error("cannot open map file " + config->mapFile + ": " + e.message());
1240
  if (errorCount())
1241
    return;
1242

1243
  // Handle --trace-symbol.
1244
  for (auto *arg : args.filtered(OPT_trace_symbol))
1245
    symtab->trace(arg->getValue());
1246

1247
  for (auto *arg : args.filtered(OPT_export_if_defined))
1248
    config->exportedSymbols.insert(arg->getValue());
1249

1250
  for (auto *arg : args.filtered(OPT_export)) {
1251
    config->exportedSymbols.insert(arg->getValue());
1252
    config->requiredExports.push_back(arg->getValue());
1253
  }
1254

1255
  createSyntheticSymbols();
1256

1257
  // Add all files to the symbol table. This will add almost all
1258
  // symbols that we need to the symbol table.
1259
  for (InputFile *f : files)
1260
    symtab->addFile(f);
1261
  if (errorCount())
1262
    return;
1263

1264
  // Handle the `--undefined <sym>` options.
1265
  for (auto *arg : args.filtered(OPT_undefined))
1266
    handleUndefined(arg->getValue(), "<internal>");
1267

1268
  // Handle the `--export <sym>` options
1269
  // This works like --undefined but also exports the symbol if its found
1270
  for (auto &iter : config->exportedSymbols)
1271
    handleUndefined(iter.first(), "--export");
1272

1273
  Symbol *entrySym = nullptr;
1274
  if (!config->relocatable && !config->entry.empty()) {
1275
    entrySym = handleUndefined(config->entry, "--entry");
1276
    if (entrySym && entrySym->isDefined())
1277
      entrySym->forceExport = true;
1278
    else
1279
      error("entry symbol not defined (pass --no-entry to suppress): " +
1280
            config->entry);
1281
  }
1282

1283
  // If the user code defines a `__wasm_call_dtors` function, remember it so
1284
  // that we can call it from the command export wrappers. Unlike
1285
  // `__wasm_call_ctors` which we synthesize, `__wasm_call_dtors` is defined
1286
  // by libc/etc., because destructors are registered dynamically with
1287
  // `__cxa_atexit` and friends.
1288
  if (!config->relocatable && !config->shared &&
1289
      !WasmSym::callCtors->isUsedInRegularObj &&
1290
      WasmSym::callCtors->getName() != config->entry &&
1291
      !config->exportedSymbols.count(WasmSym::callCtors->getName())) {
1292
    if (Symbol *callDtors =
1293
            handleUndefined("__wasm_call_dtors", "<internal>")) {
1294
      if (auto *callDtorsFunc = dyn_cast<DefinedFunction>(callDtors)) {
1295
        if (callDtorsFunc->signature &&
1296
            (!callDtorsFunc->signature->Params.empty() ||
1297
             !callDtorsFunc->signature->Returns.empty())) {
1298
          error("__wasm_call_dtors must have no argument or return values");
1299
        }
1300
        WasmSym::callDtors = callDtorsFunc;
1301
      } else {
1302
        error("__wasm_call_dtors must be a function");
1303
      }
1304
    }
1305
  }
1306

1307
  if (errorCount())
1308
    return;
1309

1310
  // Create wrapped symbols for -wrap option.
1311
  std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);
1312

1313
  // If any of our inputs are bitcode files, the LTO code generator may create
1314
  // references to certain library functions that might not be explicit in the
1315
  // bitcode file's symbol table. If any of those library functions are defined
1316
  // in a bitcode file in an archive member, we need to arrange to use LTO to
1317
  // compile those archive members by adding them to the link beforehand.
1318
  //
1319
  // We only need to add libcall symbols to the link before LTO if the symbol's
1320
  // definition is in bitcode. Any other required libcall symbols will be added
1321
  // to the link after LTO when we add the LTO object file to the link.
1322
  if (!ctx.bitcodeFiles.empty())
1323
    for (auto *s : lto::LTO::getRuntimeLibcallSymbols())
1324
      handleLibcall(s);
1325
  if (errorCount())
1326
    return;
1327

1328
  // We process the stub libraries once beofore LTO to ensure that any possible
1329
  // required exports are preserved by the LTO process.
1330
  processStubLibrariesPreLTO();
1331

1332
  // Do link-time optimization if given files are LLVM bitcode files.
1333
  // This compiles bitcode files into real object files.
1334
  symtab->compileBitcodeFiles();
1335
  if (errorCount())
1336
    return;
1337

1338
  // The LTO process can generate new undefined symbols, specifically libcall
1339
  // functions.  Because those symbols might be declared in a stub library we
1340
  // need the process the stub libraries once again after LTO to handle all
1341
  // undefined symbols, including ones that didn't exist prior to LTO.
1342
  processStubLibraries();
1343

1344
  writeWhyExtract();
1345

1346
  createOptionalSymbols();
1347

1348
  // Resolve any variant symbols that were created due to signature
1349
  // mismatchs.
1350
  symtab->handleSymbolVariants();
1351
  if (errorCount())
1352
    return;
1353

1354
  // Apply symbol renames for -wrap.
1355
  if (!wrapped.empty())
1356
    wrapSymbols(wrapped);
1357

1358
  for (auto &iter : config->exportedSymbols) {
1359
    Symbol *sym = symtab->find(iter.first());
1360
    if (sym && sym->isDefined())
1361
      sym->forceExport = true;
1362
  }
1363

1364
  if (!config->relocatable && !ctx.isPic) {
1365
    // Add synthetic dummies for weak undefined functions.  Must happen
1366
    // after LTO otherwise functions may not yet have signatures.
1367
    symtab->handleWeakUndefines();
1368
  }
1369

1370
  if (entrySym)
1371
    entrySym->setHidden(false);
1372

1373
  if (errorCount())
1374
    return;
1375

1376
  // Split WASM_SEG_FLAG_STRINGS sections into pieces in preparation for garbage
1377
  // collection.
1378
  splitSections();
1379

1380
  // Any remaining lazy symbols should be demoted to Undefined
1381
  demoteLazySymbols();
1382

1383
  // Do size optimizations: garbage collection
1384
  markLive();
1385

1386
  // Provide the indirect function table if needed.
1387
  WasmSym::indirectFunctionTable =
1388
      symtab->resolveIndirectFunctionTable(/*required =*/false);
1389

1390
  if (errorCount())
1391
    return;
1392

1393
  // Write the result to the file.
1394
  writeResult();
1395
}
1396

1397
} // namespace lld::wasm
1398

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.