[lld] 3792b36 - [lld][WebAssembly] Replace config-> with ctx.arg.
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 2 17:08:22 PST 2025
Author: Fangrui Song
Date: 2025-01-02T17:08:18-08:00
New Revision: 3792b36234b6c87d728f0a905543e284bf961460
URL: https://github.com/llvm/llvm-project/commit/3792b36234b6c87d728f0a905543e284bf961460
DIFF: https://github.com/llvm/llvm-project/commit/3792b36234b6c87d728f0a905543e284bf961460.diff
LOG: [lld][WebAssembly] Replace config-> with ctx.arg.
Change the global variable reference to a member access of another
variable `ctx`. In the future, we may pass through `ctx` to functions to
eliminate global variables.
Pull Request: https://github.com/llvm/llvm-project/pull/119835
Added:
Modified:
lld/wasm/Config.h
lld/wasm/Driver.cpp
lld/wasm/InputChunks.cpp
lld/wasm/InputChunks.h
lld/wasm/InputElement.h
lld/wasm/InputFiles.cpp
lld/wasm/InputFiles.h
lld/wasm/LTO.cpp
lld/wasm/MapFile.cpp
lld/wasm/MarkLive.cpp
lld/wasm/OutputSections.cpp
lld/wasm/Relocations.cpp
lld/wasm/SymbolTable.cpp
lld/wasm/Symbols.cpp
lld/wasm/Symbols.h
lld/wasm/SyntheticSections.cpp
lld/wasm/SyntheticSections.h
lld/wasm/Writer.cpp
Removed:
################################################################################
diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h
index 0c2ba3eebffc4f..1fa6c42d9cd860 100644
--- a/lld/wasm/Config.h
+++ b/lld/wasm/Config.h
@@ -126,17 +126,9 @@ struct Config {
llvm::SmallVector<uint8_t, 0> buildIdVector;
};
-struct ConfigWrapper {
- Config c;
- Config *operator->() { return &c; }
-};
-
-// The only instance of Configuration struct.
-extern ConfigWrapper config;
-
// The Ctx object hold all other (non-configuration) global state.
struct Ctx {
- Config &arg;
+ Config arg;
llvm::SmallVector<ObjFile *, 0> objectFiles;
llvm::SmallVector<StubFile *, 0> stubFiles;
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 02471950fb5196..c3a74dde6480ed 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -44,17 +44,16 @@ using namespace llvm::sys;
using namespace llvm::wasm;
namespace lld::wasm {
-ConfigWrapper config;
Ctx ctx;
void errorOrWarn(const llvm::Twine &msg) {
- if (config->noinhibitExec)
+ if (ctx.arg.noinhibitExec)
warn(msg);
else
error(msg);
}
-Ctx::Ctx() : arg(config.c) {}
+Ctx::Ctx() {}
void Ctx::reset() {
arg.~Config();
@@ -268,7 +267,7 @@ opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> argv) {
static void readImportFile(StringRef filename) {
if (std::optional<MemoryBufferRef> buf = readFile(filename))
for (StringRef sym : args::getLines(*buf))
- config->allowUndefinedSymbols.insert(sym);
+ ctx.arg.allowUndefinedSymbols.insert(sym);
}
// Returns slices of MB by parsing MB as an archive file.
@@ -345,7 +344,7 @@ void LinkerDriver::addFile(StringRef path) {
case file_magic::bitcode:
case file_magic::wasm_object: {
auto obj = createObjectFile(mbref, "", 0, inLib);
- if (config->isStatic && isa<SharedFile>(obj)) {
+ if (ctx.arg.isStatic && isa<SharedFile>(obj)) {
error("attempted static link of dynamic object " + path);
break;
}
@@ -364,7 +363,7 @@ void LinkerDriver::addFile(StringRef path) {
}
static std::optional<std::string> findFromSearchPaths(StringRef path) {
- for (StringRef dir : config->searchPaths)
+ for (StringRef dir : ctx.arg.searchPaths)
if (std::optional<std::string> s = findFile(dir, path))
return s;
return std::nullopt;
@@ -373,8 +372,8 @@ static std::optional<std::string> findFromSearchPaths(StringRef path) {
// This is for -l<basename>. We'll look for lib<basename>.a from
// search paths.
static std::optional<std::string> searchLibraryBaseName(StringRef name) {
- for (StringRef dir : config->searchPaths) {
- if (!config->isStatic)
+ for (StringRef dir : ctx.arg.searchPaths) {
+ if (!ctx.arg.isStatic)
if (std::optional<std::string> s = findFile(dir, "lib" + name + ".so"))
return s;
if (std::optional<std::string> s = findFile(dir, "lib" + name + ".a"))
@@ -408,10 +407,10 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
addFile(arg->getValue());
break;
case OPT_Bstatic:
- config->isStatic = true;
+ ctx.arg.isStatic = true;
break;
case OPT_Bdynamic:
- config->isStatic = false;
+ ctx.arg.isStatic = false;
break;
case OPT_whole_archive:
inWholeArchive = true;
@@ -527,99 +526,98 @@ getBuildId(opt::InputArgList &args) {
// Initializes Config members by the command line options.
static void readConfigs(opt::InputArgList &args) {
- config->allowMultipleDefinition =
+ ctx.arg.allowMultipleDefinition =
hasZOption(args, "muldefs") ||
args.hasFlag(OPT_allow_multiple_definition,
OPT_no_allow_multiple_definition, false);
- config->bsymbolic = args.hasArg(OPT_Bsymbolic);
- config->checkFeatures =
+ ctx.arg.bsymbolic = args.hasArg(OPT_Bsymbolic);
+ ctx.arg.checkFeatures =
args.hasFlag(OPT_check_features, OPT_no_check_features, true);
- config->compressRelocations = args.hasArg(OPT_compress_relocations);
- config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
- config->disableVerify = args.hasArg(OPT_disable_verify);
- config->emitRelocs = args.hasArg(OPT_emit_relocs);
- config->experimentalPic = args.hasArg(OPT_experimental_pic);
- config->entry = getEntry(args);
- config->exportAll = args.hasArg(OPT_export_all);
- config->exportTable = args.hasArg(OPT_export_table);
- config->growableTable = args.hasArg(OPT_growable_table);
- config->noinhibitExec = args.hasArg(OPT_noinhibit_exec);
+ ctx.arg.compressRelocations = args.hasArg(OPT_compress_relocations);
+ ctx.arg.demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
+ ctx.arg.disableVerify = args.hasArg(OPT_disable_verify);
+ ctx.arg.emitRelocs = args.hasArg(OPT_emit_relocs);
+ ctx.arg.experimentalPic = args.hasArg(OPT_experimental_pic);
+ ctx.arg.entry = getEntry(args);
+ ctx.arg.exportAll = args.hasArg(OPT_export_all);
+ ctx.arg.exportTable = args.hasArg(OPT_export_table);
+ ctx.arg.growableTable = args.hasArg(OPT_growable_table);
+ ctx.arg.noinhibitExec = args.hasArg(OPT_noinhibit_exec);
if (args.hasArg(OPT_import_memory_with_name)) {
- config->memoryImport =
+ ctx.arg.memoryImport =
args.getLastArgValue(OPT_import_memory_with_name).split(",");
} else if (args.hasArg(OPT_import_memory)) {
- config->memoryImport =
+ ctx.arg.memoryImport =
std::pair<llvm::StringRef, llvm::StringRef>(defaultModule, memoryName);
} else {
- config->memoryImport =
+ ctx.arg.memoryImport =
std::optional<std::pair<llvm::StringRef, llvm::StringRef>>();
}
if (args.hasArg(OPT_export_memory_with_name)) {
- config->memoryExport =
- args.getLastArgValue(OPT_export_memory_with_name);
+ ctx.arg.memoryExport = args.getLastArgValue(OPT_export_memory_with_name);
} else if (args.hasArg(OPT_export_memory)) {
- config->memoryExport = memoryName;
+ ctx.arg.memoryExport = memoryName;
} else {
- config->memoryExport = std::optional<llvm::StringRef>();
+ ctx.arg.memoryExport = std::optional<llvm::StringRef>();
}
- config->sharedMemory = args.hasArg(OPT_shared_memory);
- config->soName = args.getLastArgValue(OPT_soname);
- config->importTable = args.hasArg(OPT_import_table);
- config->importUndefined = args.hasArg(OPT_import_undefined);
- config->ltoo = args::getInteger(args, OPT_lto_O, 2);
- if (config->ltoo > 3)
- error("invalid optimization level for LTO: " + Twine(config->ltoo));
+ ctx.arg.sharedMemory = args.hasArg(OPT_shared_memory);
+ ctx.arg.soName = args.getLastArgValue(OPT_soname);
+ ctx.arg.importTable = args.hasArg(OPT_import_table);
+ ctx.arg.importUndefined = args.hasArg(OPT_import_undefined);
+ ctx.arg.ltoo = args::getInteger(args, OPT_lto_O, 2);
+ if (ctx.arg.ltoo > 3)
+ error("invalid optimization level for LTO: " + Twine(ctx.arg.ltoo));
unsigned ltoCgo =
- args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(config->ltoo));
+ args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(ctx.arg.ltoo));
if (auto level = CodeGenOpt::getLevel(ltoCgo))
- config->ltoCgo = *level;
+ ctx.arg.ltoCgo = *level;
else
error("invalid codegen optimization level for LTO: " + Twine(ltoCgo));
- config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
- config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
- config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
- config->mapFile = args.getLastArgValue(OPT_Map);
- config->optimize = args::getInteger(args, OPT_O, 1);
- config->outputFile = args.getLastArgValue(OPT_o);
- config->relocatable = args.hasArg(OPT_relocatable);
- config->gcSections =
- args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !config->relocatable);
+ ctx.arg.ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
+ ctx.arg.ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
+ ctx.arg.ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
+ ctx.arg.mapFile = args.getLastArgValue(OPT_Map);
+ ctx.arg.optimize = args::getInteger(args, OPT_O, 1);
+ ctx.arg.outputFile = args.getLastArgValue(OPT_o);
+ ctx.arg.relocatable = args.hasArg(OPT_relocatable);
+ ctx.arg.gcSections =
+ args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !ctx.arg.relocatable);
for (auto *arg : args.filtered(OPT_keep_section))
- config->keepSections.insert(arg->getValue());
- config->mergeDataSegments =
+ ctx.arg.keepSections.insert(arg->getValue());
+ ctx.arg.mergeDataSegments =
args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
- !config->relocatable);
- config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
- config->printGcSections =
+ !ctx.arg.relocatable);
+ ctx.arg.pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
+ ctx.arg.printGcSections =
args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
- config->saveTemps = args.hasArg(OPT_save_temps);
- config->searchPaths = args::getStrings(args, OPT_library_path);
- config->shared = args.hasArg(OPT_shared);
- config->shlibSigCheck = !args.hasArg(OPT_no_shlib_sigcheck);
- config->stripAll = args.hasArg(OPT_strip_all);
- config->stripDebug = args.hasArg(OPT_strip_debug);
- config->stackFirst = args.hasArg(OPT_stack_first);
- config->trace = args.hasArg(OPT_trace);
- config->thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
- config->thinLTOCachePolicy = CHECK(
+ ctx.arg.saveTemps = args.hasArg(OPT_save_temps);
+ ctx.arg.searchPaths = args::getStrings(args, OPT_library_path);
+ ctx.arg.shared = args.hasArg(OPT_shared);
+ ctx.arg.shlibSigCheck = !args.hasArg(OPT_no_shlib_sigcheck);
+ ctx.arg.stripAll = args.hasArg(OPT_strip_all);
+ ctx.arg.stripDebug = args.hasArg(OPT_strip_debug);
+ ctx.arg.stackFirst = args.hasArg(OPT_stack_first);
+ ctx.arg.trace = args.hasArg(OPT_trace);
+ ctx.arg.thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
+ ctx.arg.thinLTOCachePolicy = CHECK(
parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)),
"--thinlto-cache-policy: invalid cache policy");
- config->thinLTOEmitImportsFiles = args.hasArg(OPT_thinlto_emit_imports_files);
- config->thinLTOEmitIndexFiles = args.hasArg(OPT_thinlto_emit_index_files) ||
+ ctx.arg.thinLTOEmitImportsFiles = args.hasArg(OPT_thinlto_emit_imports_files);
+ ctx.arg.thinLTOEmitIndexFiles = args.hasArg(OPT_thinlto_emit_index_files) ||
args.hasArg(OPT_thinlto_index_only) ||
args.hasArg(OPT_thinlto_index_only_eq);
- config->thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) ||
+ ctx.arg.thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) ||
args.hasArg(OPT_thinlto_index_only_eq);
- config->thinLTOIndexOnlyArg = args.getLastArgValue(OPT_thinlto_index_only_eq);
- config->thinLTOObjectSuffixReplace =
+ ctx.arg.thinLTOIndexOnlyArg = args.getLastArgValue(OPT_thinlto_index_only_eq);
+ ctx.arg.thinLTOObjectSuffixReplace =
getOldNewOptions(args, OPT_thinlto_object_suffix_replace_eq);
- std::tie(config->thinLTOPrefixReplaceOld, config->thinLTOPrefixReplaceNew,
- config->thinLTOPrefixReplaceNativeObject) =
+ std::tie(ctx.arg.thinLTOPrefixReplaceOld, ctx.arg.thinLTOPrefixReplaceNew,
+ ctx.arg.thinLTOPrefixReplaceNativeObject) =
getOldNewOptionsExtra(args, OPT_thinlto_prefix_replace_eq);
- if (config->thinLTOEmitIndexFiles && !config->thinLTOIndexOnly) {
+ if (ctx.arg.thinLTOEmitIndexFiles && !ctx.arg.thinLTOIndexOnly) {
if (args.hasArg(OPT_thinlto_object_suffix_replace_eq))
error("--thinlto-object-suffix-replace is not supported with "
"--thinlto-emit-index-files");
@@ -627,45 +625,45 @@ static void readConfigs(opt::InputArgList &args) {
error("--thinlto-prefix-replace is not supported with "
"--thinlto-emit-index-files");
}
- if (!config->thinLTOPrefixReplaceNativeObject.empty() &&
- config->thinLTOIndexOnlyArg.empty()) {
+ if (!ctx.arg.thinLTOPrefixReplaceNativeObject.empty() &&
+ ctx.arg.thinLTOIndexOnlyArg.empty()) {
error("--thinlto-prefix-replace=old_dir;new_dir;obj_dir must be used with "
"--thinlto-index-only=");
}
- config->unresolvedSymbols = getUnresolvedSymbolPolicy(args);
- config->whyExtract = args.getLastArgValue(OPT_why_extract);
+ ctx.arg.unresolvedSymbols = getUnresolvedSymbolPolicy(args);
+ ctx.arg.whyExtract = args.getLastArgValue(OPT_why_extract);
errorHandler().verbose = args.hasArg(OPT_verbose);
LLVM_DEBUG(errorHandler().verbose = true);
- config->tableBase = args::getInteger(args, OPT_table_base, 0);
- config->globalBase = args::getInteger(args, OPT_global_base, 0);
- config->initialHeap = args::getInteger(args, OPT_initial_heap, 0);
- config->initialMemory = args::getInteger(args, OPT_initial_memory, 0);
- config->maxMemory = args::getInteger(args, OPT_max_memory, 0);
- config->noGrowableMemory = args.hasArg(OPT_no_growable_memory);
- config->zStackSize =
+ ctx.arg.tableBase = args::getInteger(args, OPT_table_base, 0);
+ ctx.arg.globalBase = args::getInteger(args, OPT_global_base, 0);
+ ctx.arg.initialHeap = args::getInteger(args, OPT_initial_heap, 0);
+ ctx.arg.initialMemory = args::getInteger(args, OPT_initial_memory, 0);
+ ctx.arg.maxMemory = args::getInteger(args, OPT_max_memory, 0);
+ ctx.arg.noGrowableMemory = args.hasArg(OPT_no_growable_memory);
+ ctx.arg.zStackSize =
args::getZOptionValue(args, OPT_z, "stack-size", WasmPageSize);
// -Bdynamic by default if -pie or -shared is specified.
- if (config->pie || config->shared)
- config->isStatic = false;
+ if (ctx.arg.pie || ctx.arg.shared)
+ ctx.arg.isStatic = false;
- if (config->maxMemory != 0 && config->noGrowableMemory) {
+ if (ctx.arg.maxMemory != 0 && ctx.arg.noGrowableMemory) {
// Erroring out here is simpler than defining precedence rules.
error("--max-memory is incompatible with --no-growable-memory");
}
// Default value of exportDynamic depends on `-shared`
- config->exportDynamic =
- args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, config->shared);
+ ctx.arg.exportDynamic =
+ args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, ctx.arg.shared);
// Parse wasm32/64.
if (auto *arg = args.getLastArg(OPT_m)) {
StringRef s = arg->getValue();
if (s == "wasm32")
- config->is64 = false;
+ ctx.arg.is64 = false;
else if (s == "wasm64")
- config->is64 = true;
+ ctx.arg.is64 = true;
else
error("invalid target architecture: " + s);
}
@@ -679,36 +677,36 @@ static void readConfigs(opt::InputArgList &args) {
error(arg->getSpelling() + ": expected a positive integer, but got '" +
arg->getValue() + "'");
parallel::strategy = hardware_concurrency(threads);
- config->thinLTOJobs = v;
+ ctx.arg.thinLTOJobs = v;
}
if (auto *arg = args.getLastArg(OPT_thinlto_jobs))
- config->thinLTOJobs = arg->getValue();
+ ctx.arg.thinLTOJobs = arg->getValue();
if (auto *arg = args.getLastArg(OPT_features)) {
- config->features =
+ ctx.arg.features =
std::optional<std::vector<std::string>>(std::vector<std::string>());
for (StringRef s : arg->getValues())
- config->features->push_back(std::string(s));
+ ctx.arg.features->push_back(std::string(s));
}
if (auto *arg = args.getLastArg(OPT_extra_features)) {
- config->extraFeatures =
+ ctx.arg.extraFeatures =
std::optional<std::vector<std::string>>(std::vector<std::string>());
for (StringRef s : arg->getValues())
- config->extraFeatures->push_back(std::string(s));
+ ctx.arg.extraFeatures->push_back(std::string(s));
}
// Legacy --allow-undefined flag which is equivalent to
// --unresolve-symbols=ignore + --import-undefined
if (args.hasArg(OPT_allow_undefined)) {
- config->importUndefined = true;
- config->unresolvedSymbols = UnresolvedPolicy::Ignore;
+ ctx.arg.importUndefined = true;
+ ctx.arg.unresolvedSymbols = UnresolvedPolicy::Ignore;
}
if (args.hasArg(OPT_print_map))
- config->mapFile = "-";
+ ctx.arg.mapFile = "-";
- std::tie(config->buildId, config->buildIdVector) = getBuildId(args);
+ std::tie(ctx.arg.buildId, ctx.arg.buildIdVector) = getBuildId(args);
}
// Some Config members do not directly correspond to any particular
@@ -716,86 +714,86 @@ static void readConfigs(opt::InputArgList &args) {
// This function initialize such members. See Config.h for the details
// of these values.
static void setConfigs() {
- ctx.isPic = config->pie || config->shared;
+ ctx.isPic = ctx.arg.pie || ctx.arg.shared;
if (ctx.isPic) {
- if (config->exportTable)
+ if (ctx.arg.exportTable)
error("-shared/-pie is incompatible with --export-table");
- config->importTable = true;
+ ctx.arg.importTable = true;
} else {
// Default table base. Defaults to 1, reserving 0 for the NULL function
// pointer.
- if (!config->tableBase)
- config->tableBase = 1;
+ if (!ctx.arg.tableBase)
+ ctx.arg.tableBase = 1;
// The default offset for static/global data, for when --global-base is
// not specified on the command line. The precise value of 1024 is
// somewhat arbitrary, and pre-dates wasm-ld (Its the value that
// emscripten used prior to wasm-ld).
- if (!config->globalBase && !config->relocatable && !config->stackFirst)
- config->globalBase = 1024;
+ if (!ctx.arg.globalBase && !ctx.arg.relocatable && !ctx.arg.stackFirst)
+ ctx.arg.globalBase = 1024;
}
- if (config->relocatable) {
- if (config->exportTable)
+ if (ctx.arg.relocatable) {
+ if (ctx.arg.exportTable)
error("--relocatable is incompatible with --export-table");
- if (config->growableTable)
+ if (ctx.arg.growableTable)
error("--relocatable is incompatible with --growable-table");
// Ignore any --import-table, as it's redundant.
- config->importTable = true;
+ ctx.arg.importTable = true;
}
- if (config->shared) {
- if (config->memoryExport.has_value()) {
+ if (ctx.arg.shared) {
+ if (ctx.arg.memoryExport.has_value()) {
error("--export-memory is incompatible with --shared");
}
- if (!config->memoryImport.has_value()) {
- config->memoryImport =
- std::pair<llvm::StringRef, llvm::StringRef>(defaultModule, memoryName);
+ if (!ctx.arg.memoryImport.has_value()) {
+ ctx.arg.memoryImport = std::pair<llvm::StringRef, llvm::StringRef>(
+ defaultModule, memoryName);
}
}
// If neither export-memory nor import-memory is specified, default to
// exporting memory under its default name.
- if (!config->memoryExport.has_value() && !config->memoryImport.has_value()) {
- config->memoryExport = memoryName;
+ if (!ctx.arg.memoryExport.has_value() && !ctx.arg.memoryImport.has_value()) {
+ ctx.arg.memoryExport = memoryName;
}
}
// Some command line options or some combinations of them are not allowed.
// This function checks for such errors.
static void checkOptions(opt::InputArgList &args) {
- if (!config->stripDebug && !config->stripAll && config->compressRelocations)
+ if (!ctx.arg.stripDebug && !ctx.arg.stripAll && ctx.arg.compressRelocations)
error("--compress-relocations is incompatible with output debug"
" information. Please pass --strip-debug or --strip-all");
- if (config->ltoPartitions == 0)
+ if (ctx.arg.ltoPartitions == 0)
error("--lto-partitions: number of threads must be > 0");
- if (!get_threadpool_strategy(config->thinLTOJobs))
- error("--thinlto-jobs: invalid job count: " + config->thinLTOJobs);
+ if (!get_threadpool_strategy(ctx.arg.thinLTOJobs))
+ error("--thinlto-jobs: invalid job count: " + ctx.arg.thinLTOJobs);
- if (config->pie && config->shared)
+ if (ctx.arg.pie && ctx.arg.shared)
error("-shared and -pie may not be used together");
- if (config->outputFile.empty() && !config->thinLTOIndexOnly)
+ if (ctx.arg.outputFile.empty() && !ctx.arg.thinLTOIndexOnly)
error("no output file specified");
- if (config->importTable && config->exportTable)
+ if (ctx.arg.importTable && ctx.arg.exportTable)
error("--import-table and --export-table may not be used together");
- if (config->relocatable) {
- if (!config->entry.empty())
+ if (ctx.arg.relocatable) {
+ if (!ctx.arg.entry.empty())
error("entry point specified for relocatable output file");
- if (config->gcSections)
+ if (ctx.arg.gcSections)
error("-r and --gc-sections may not be used together");
- if (config->compressRelocations)
+ if (ctx.arg.compressRelocations)
error("-r -and --compress-relocations may not be used together");
if (args.hasArg(OPT_undefined))
error("-r -and --undefined may not be used together");
- if (config->pie)
+ if (ctx.arg.pie)
error("-r and -pie may not be used together");
- if (config->sharedMemory)
+ if (ctx.arg.sharedMemory)
error("-r and --shared-memory may not be used together");
- if (config->globalBase)
+ if (ctx.arg.globalBase)
error("-r and --global-base may not by used together");
}
@@ -804,31 +802,31 @@ static void checkOptions(opt::InputArgList &args) {
// mode, to give anyone using them a heads-up that they will be changing.
//
// Also, warn about flags which request explicit exports.
- if (!config->experimentalPic) {
+ if (!ctx.arg.experimentalPic) {
// -shared will change meaning when Module Linking is implemented.
- if (config->shared) {
+ if (ctx.arg.shared) {
warn("creating shared libraries, with -shared, is not yet stable");
}
// -pie will change meaning when Module Linking is implemented.
- if (config->pie) {
+ if (ctx.arg.pie) {
warn("creating PIEs, with -pie, is not yet stable");
}
- if (config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic) {
+ if (ctx.arg.unresolvedSymbols == UnresolvedPolicy::ImportDynamic) {
warn("dynamic imports are not yet stable "
"(--unresolved-symbols=import-dynamic)");
}
}
- if (config->bsymbolic && !config->shared) {
+ if (ctx.arg.bsymbolic && !ctx.arg.shared) {
warn("-Bsymbolic is only meaningful when combined with -shared");
}
if (ctx.isPic) {
- if (config->globalBase)
+ if (ctx.arg.globalBase)
error("--global-base may not be used with -shared/-pie");
- if (config->tableBase)
+ if (ctx.arg.tableBase)
error("--table-base may not be used with -shared/-pie");
}
}
@@ -851,7 +849,7 @@ static Symbol *handleUndefined(StringRef name, const char *option) {
if (auto *lazySym = dyn_cast<LazySymbol>(sym)) {
lazySym->extract();
- if (!config->whyExtract.empty())
+ if (!ctx.arg.whyExtract.empty())
ctx.whyExtractRecords.emplace_back(option, sym->getFile(), *sym);
}
@@ -861,20 +859,20 @@ static Symbol *handleUndefined(StringRef name, const char *option) {
static void handleLibcall(StringRef name) {
Symbol *sym = symtab->find(name);
if (sym && sym->isLazy() && isa<BitcodeFile>(sym->getFile())) {
- if (!config->whyExtract.empty())
+ if (!ctx.arg.whyExtract.empty())
ctx.whyExtractRecords.emplace_back("<libcall>", sym->getFile(), *sym);
cast<LazySymbol>(sym)->extract();
}
}
static void writeWhyExtract() {
- if (config->whyExtract.empty())
+ if (ctx.arg.whyExtract.empty())
return;
std::error_code ec;
- raw_fd_ostream os(config->whyExtract, ec, sys::fs::OF_None);
+ raw_fd_ostream os(ctx.arg.whyExtract, ec, sys::fs::OF_None);
if (ec) {
- error("cannot open --why-extract= file " + config->whyExtract + ": " +
+ error("cannot open --why-extract= file " + ctx.arg.whyExtract + ": " +
ec.message());
return;
}
@@ -905,14 +903,14 @@ static UndefinedGlobal *
createUndefinedGlobal(StringRef name, llvm::wasm::WasmGlobalType *type) {
auto *sym = cast<UndefinedGlobal>(symtab->addUndefinedGlobal(
name, std::nullopt, std::nullopt, WASM_SYMBOL_UNDEFINED, nullptr, type));
- config->allowUndefinedSymbols.insert(sym->getName());
+ ctx.arg.allowUndefinedSymbols.insert(sym->getName());
sym->isUsedInRegularObj = true;
return sym;
}
static InputGlobal *createGlobal(StringRef name, bool isMutable) {
llvm::wasm::WasmGlobal wasmGlobal;
- bool is64 = config->is64.value_or(false);
+ bool is64 = ctx.arg.is64.value_or(false);
wasmGlobal.Type = {uint8_t(is64 ? WASM_TYPE_I64 : WASM_TYPE_I32), isMutable};
wasmGlobal.InitExpr = intConst(0, is64);
wasmGlobal.SymbolName = name;
@@ -931,7 +929,7 @@ static GlobalSymbol *createOptionalGlobal(StringRef name, bool isMutable) {
// Create ABI-defined synthetic symbols
static void createSyntheticSymbols() {
- if (config->relocatable)
+ if (ctx.arg.relocatable)
return;
static WasmSignature nullSignature = {{}, {}};
@@ -947,11 +945,11 @@ static void createSyntheticSymbols() {
"__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
make<SyntheticFunction>(nullSignature, "__wasm_call_ctors"));
- bool is64 = config->is64.value_or(false);
+ bool is64 = ctx.arg.is64.value_or(false);
if (ctx.isPic) {
WasmSym::stackPointer =
- createUndefinedGlobal("__stack_pointer", config->is64.value_or(false)
+ createUndefinedGlobal("__stack_pointer", ctx.arg.is64.value_or(false)
? &mutableGlobalTypeI64
: &mutableGlobalTypeI32);
// For PIC code, we import two global variables (__memory_base and
@@ -970,7 +968,7 @@ static void createSyntheticSymbols() {
WasmSym::stackPointer->markLive();
}
- if (config->sharedMemory) {
+ if (ctx.arg.sharedMemory) {
WasmSym::tlsBase = createGlobalVariable("__tls_base", true);
WasmSym::tlsSize = createGlobalVariable("__tls_size", false);
WasmSym::tlsAlign = createGlobalVariable("__tls_align", false);
@@ -983,12 +981,12 @@ static void createSyntheticSymbols() {
}
static void createOptionalSymbols() {
- if (config->relocatable)
+ if (ctx.arg.relocatable)
return;
WasmSym::dsoHandle = symtab->addOptionalDataSymbol("__dso_handle");
- if (!config->shared)
+ if (!ctx.arg.shared)
WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");
if (!ctx.isPic) {
@@ -1010,7 +1008,7 @@ static void createOptionalSymbols() {
//
// __tls_size and __tls_align are not needed in this case since they are only
// needed for __wasm_init_tls (which we do not create in this case).
- if (!config->sharedMemory)
+ if (!ctx.arg.sharedMemory)
WasmSym::tlsBase = createOptionalGlobal("__tls_base", false);
}
@@ -1035,7 +1033,7 @@ static void processStubLibrariesPreLTO() {
// extracted during processStubLibraries, which is too late since
// LTO has already being performed at that point.
if (needed->isLazy() && isa<BitcodeFile>(needed->getFile())) {
- if (!config->whyExtract.empty())
+ if (!ctx.arg.whyExtract.empty())
ctx.whyExtractRecords.emplace_back(toString(stub_file),
needed->getFile(), *needed);
cast<LazySymbol>(needed)->extract();
@@ -1079,7 +1077,7 @@ static bool addStubSymbolDeps(const StubFile *stub_file, Symbol *sym,
if (auto *lazy = dyn_cast<LazySymbol>(needed)) {
depsAdded = true;
lazy->extract();
- if (!config->whyExtract.empty())
+ if (!ctx.arg.whyExtract.empty())
ctx.whyExtractRecords.emplace_back(toString(stub_file),
sym->getFile(), *sym);
}
diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index 9383dcaeb4f558..ccdc92f5c8d711 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -67,7 +67,7 @@ uint32_t InputChunk::getSize() const {
return ms->builder.getSize();
if (const auto *f = dyn_cast<InputFunction>(this)) {
- if (config->compressRelocations && f->file) {
+ if (ctx.arg.compressRelocations && f->file) {
return f->getCompressedSize();
}
}
@@ -84,7 +84,7 @@ uint32_t InputChunk::getInputSize() const {
// Copy this input chunk to an mmap'ed output file and apply relocations.
void InputChunk::writeTo(uint8_t *buf) const {
if (const auto *f = dyn_cast<InputFunction>(this)) {
- if (file && config->compressRelocations)
+ if (file && ctx.arg.compressRelocations)
return f->writeCompressed(buf);
} else if (const auto *ms = dyn_cast<SyntheticMergedChunk>(this)) {
ms->builder.write(buf + outSecOff);
@@ -269,7 +269,7 @@ static unsigned getRelocWidth(const WasmRelocation &rel, uint64_t value) {
// This function only computes the final output size. It must be called
// before getSize() is used to calculate of layout of the code section.
void InputFunction::calculateSize() {
- if (!file || !config->compressRelocations)
+ if (!file || !ctx.arg.compressRelocations)
return;
LLVM_DEBUG(dbgs() << "calculateSize: " << name << "\n");
@@ -365,7 +365,7 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
LLVM_DEBUG(dbgs() << "generating runtime relocations: " << name
<< " count=" << relocations.size() << "\n");
- bool is64 = config->is64.value_or(false);
+ bool is64 = ctx.arg.is64.value_or(false);
bool generated = false;
unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST
: WASM_OPCODE_I32_CONST;
diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index d6769bcf5c8232..f545449e1246f8 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -112,7 +112,7 @@ class InputChunk {
InputChunk(ObjFile *f, Kind k, StringRef name, uint32_t alignment = 0,
uint32_t flags = 0)
: name(name), file(f), alignment(alignment), flags(flags), sectionKind(k),
- live(!config->gcSections), discarded(false) {}
+ live(!ctx.arg.gcSections), discarded(false) {}
ArrayRef<uint8_t> data() const { return rawData; }
uint64_t getTombstone() const;
@@ -156,7 +156,7 @@ class SyntheticMergedChunk;
// be found by looking at the next one).
struct SectionPiece {
SectionPiece(size_t off, uint32_t hash, bool live)
- : inputOff(off), live(live || !config->gcSections), hash(hash >> 1) {}
+ : inputOff(off), live(live || !ctx.arg.gcSections), hash(hash >> 1) {}
uint32_t inputOff;
uint32_t live : 1;
diff --git a/lld/wasm/InputElement.h b/lld/wasm/InputElement.h
index 10dc2a3e4a826a..c2a24c8ff5f4ec 100644
--- a/lld/wasm/InputElement.h
+++ b/lld/wasm/InputElement.h
@@ -24,7 +24,7 @@ namespace wasm {
class InputElement {
protected:
InputElement(StringRef name, ObjFile *f)
- : file(f), live(!config->gcSections), name(name) {}
+ : file(f), live(!ctx.arg.gcSections), name(name) {}
public:
StringRef getName() const { return name; }
@@ -65,7 +65,7 @@ class InputGlobal : public InputElement {
const WasmInitExpr &getInitExpr() const { return initExpr; }
void setPointerValue(uint64_t value) {
- initExpr = intConst(value, config->is64.value_or(false));
+ initExpr = intConst(value, ctx.arg.is64.value_or(false));
}
private:
diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index 221f02aa1c1571..614cddddd1b196 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -47,7 +47,7 @@ std::string toString(const wasm::InputFile *file) {
namespace wasm {
std::string replaceThinLTOSuffix(StringRef path) {
- auto [suffix, repl] = config->thinLTOObjectSuffixReplace;
+ auto [suffix, repl] = ctx.arg.thinLTOObjectSuffixReplace;
if (path.consume_back(suffix))
return (path + repl).str();
return std::string(path);
@@ -55,10 +55,10 @@ std::string replaceThinLTOSuffix(StringRef path) {
void InputFile::checkArch(Triple::ArchType arch) const {
bool is64 = arch == Triple::wasm64;
- if (is64 && !config->is64) {
+ if (is64 && !ctx.arg.is64) {
fatal(toString(this) +
": must specify -mwasm64 to process wasm64 object files");
- } else if (config->is64.value_or(false) != is64) {
+ } else if (ctx.arg.is64.value_or(false) != is64) {
fatal(toString(this) +
": wasm32 object file can't be linked in wasm64 mode");
}
@@ -169,7 +169,7 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
uint32_t index = getFunctionSymbol(reloc.Index)->getTableIndex();
if (reloc.Type == R_WASM_TABLE_INDEX_REL_SLEB ||
reloc.Type == R_WASM_TABLE_INDEX_REL_SLEB64)
- index -= config->tableBase;
+ index -= ctx.arg.tableBase;
return index;
}
case R_WASM_MEMORY_ADDR_LEB:
@@ -360,7 +360,7 @@ void ObjFile::addLegacyIndirectFunctionTableIfNeeded(
}
static bool shouldMerge(const WasmSection &sec) {
- if (config->optimize == 0)
+ if (ctx.arg.optimize == 0)
return false;
// Sadly we don't have section attributes yet for custom sections, so we
// currently go by the name alone.
@@ -383,7 +383,7 @@ static bool shouldMerge(const WasmSegment &seg) {
// On a regular link we don't merge sections if -O0 (default is -O1). This
// sometimes makes the linker significantly faster, although the output will
// be bigger.
- if (config->optimize == 0)
+ if (ctx.arg.optimize == 0)
return false;
// A mergeable section with size 0 is useless because they don't have
@@ -845,7 +845,7 @@ BitcodeFile::BitcodeFile(MemoryBufferRef m, StringRef archiveName,
this->archiveName = std::string(archiveName);
std::string path = mb.getBufferIdentifier().str();
- if (config->thinLTOIndexOnly)
+ if (ctx.arg.thinLTOIndexOnly)
path = replaceThinLTOSuffix(mb.getBufferIdentifier());
// ThinLTO assumes that all MemoryBufferRefs given to it have a unique
diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h
index 1b1de98d2d17a2..fd7fcb13f4426a 100644
--- a/lld/wasm/InputFiles.h
+++ b/lld/wasm/InputFiles.h
@@ -73,7 +73,7 @@ class InputFile {
protected:
InputFile(Kind k, MemoryBufferRef m)
- : mb(m), fileKind(k), live(!config->gcSections) {}
+ : mb(m), fileKind(k), live(!ctx.arg.gcSections) {}
void checkArch(llvm::Triple::ArchType arch) const;
diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp
index d9fff748bdb657..b9bd48acd6dc11 100644
--- a/lld/wasm/LTO.cpp
+++ b/lld/wasm/LTO.cpp
@@ -44,8 +44,8 @@ using namespace lld::wasm;
using namespace lld;
static std::string getThinLTOOutputFile(StringRef modulePath) {
- return lto::getThinLTOOutputFile(modulePath, config->thinLTOPrefixReplaceOld,
- config->thinLTOPrefixReplaceNew);
+ return lto::getThinLTOOutputFile(modulePath, ctx.arg.thinLTOPrefixReplaceOld,
+ ctx.arg.thinLTOPrefixReplaceNew);
}
static lto::Config createConfig() {
@@ -56,23 +56,23 @@ static lto::Config createConfig() {
c.Options.FunctionSections = true;
c.Options.DataSections = true;
- c.DisableVerify = config->disableVerify;
+ c.DisableVerify = ctx.arg.disableVerify;
c.DiagHandler = diagnosticHandler;
- c.OptLevel = config->ltoo;
+ c.OptLevel = ctx.arg.ltoo;
c.MAttrs = getMAttrs();
- c.CGOptLevel = config->ltoCgo;
- c.DebugPassManager = config->ltoDebugPassManager;
- c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty();
+ c.CGOptLevel = ctx.arg.ltoCgo;
+ c.DebugPassManager = ctx.arg.ltoDebugPassManager;
+ c.AlwaysEmitRegularLTOObj = !ctx.arg.ltoObjPath.empty();
- if (config->relocatable)
+ if (ctx.arg.relocatable)
c.RelocModel = std::nullopt;
else if (ctx.isPic)
c.RelocModel = Reloc::PIC_;
else
c.RelocModel = Reloc::Static;
- if (config->saveTemps)
- checkError(c.addSaveTemps(config->outputFile.str() + ".",
+ if (ctx.arg.saveTemps)
+ checkError(c.addSaveTemps(ctx.arg.outputFile.str() + ".",
/*UseInputModulePath*/ true));
return c;
}
@@ -81,27 +81,27 @@ namespace lld::wasm {
BitcodeCompiler::BitcodeCompiler() {
// Initialize indexFile.
- if (!config->thinLTOIndexOnlyArg.empty())
- indexFile = openFile(config->thinLTOIndexOnlyArg);
+ if (!ctx.arg.thinLTOIndexOnlyArg.empty())
+ indexFile = openFile(ctx.arg.thinLTOIndexOnlyArg);
// Initialize ltoObj.
lto::ThinBackend backend;
auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); };
- if (config->thinLTOIndexOnly) {
+ if (ctx.arg.thinLTOIndexOnly) {
backend = lto::createWriteIndexesThinBackend(
- llvm::hardware_concurrency(config->thinLTOJobs),
- std::string(config->thinLTOPrefixReplaceOld),
- std::string(config->thinLTOPrefixReplaceNew),
- std::string(config->thinLTOPrefixReplaceNativeObject),
- config->thinLTOEmitImportsFiles, indexFile.get(), onIndexWrite);
+ llvm::hardware_concurrency(ctx.arg.thinLTOJobs),
+ std::string(ctx.arg.thinLTOPrefixReplaceOld),
+ std::string(ctx.arg.thinLTOPrefixReplaceNew),
+ std::string(ctx.arg.thinLTOPrefixReplaceNativeObject),
+ ctx.arg.thinLTOEmitImportsFiles, indexFile.get(), onIndexWrite);
} else {
backend = lto::createInProcessThinBackend(
- llvm::heavyweight_hardware_concurrency(config->thinLTOJobs),
- onIndexWrite, config->thinLTOEmitIndexFiles,
- config->thinLTOEmitImportsFiles);
+ llvm::heavyweight_hardware_concurrency(ctx.arg.thinLTOJobs),
+ onIndexWrite, ctx.arg.thinLTOEmitIndexFiles,
+ ctx.arg.thinLTOEmitImportsFiles);
}
ltoObj = std::make_unique<lto::LTO>(createConfig(), backend,
- config->ltoPartitions);
+ ctx.arg.ltoPartitions);
}
BitcodeCompiler::~BitcodeCompiler() = default;
@@ -123,7 +123,7 @@ void BitcodeCompiler::add(BitcodeFile &f) {
ArrayRef<Symbol *> syms = f.getSymbols();
std::vector<lto::SymbolResolution> resols(syms.size());
- if (config->thinLTOEmitIndexFiles) {
+ if (ctx.arg.thinLTOEmitIndexFiles) {
thinIndices.insert(obj.getName());
}
@@ -139,7 +139,7 @@ void BitcodeCompiler::add(BitcodeFile &f) {
// Once IRObjectFile is fixed to report only one symbol this hack can
// be removed.
r.Prevailing = !objSym.isUndefined() && sym->getFile() == &f;
- r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj ||
+ r.VisibleToRegularObj = ctx.arg.relocatable || sym->isUsedInRegularObj ||
sym->isNoStrip() ||
(r.Prevailing && sym->isExported());
if (r.Prevailing)
@@ -175,7 +175,7 @@ static void thinLTOCreateEmptyIndexFiles() {
ModuleSummaryIndex m(/*HaveGVs*/ false);
m.setSkipModuleByDistributedBackend();
writeIndexToFile(m, *os);
- if (config->thinLTOEmitImportsFiles)
+ if (ctx.arg.thinLTOEmitImportsFiles)
openFile(path + ".imports");
}
}
@@ -191,8 +191,8 @@ std::vector<StringRef> BitcodeCompiler::compile() {
// to cache native object files for ThinLTO incremental builds. If a path was
// specified, configure LTO to use it as the cache directory.
FileCache cache;
- if (!config->thinLTOCacheDir.empty())
- cache = check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
+ if (!ctx.arg.thinLTOCacheDir.empty())
+ cache = check(localCache("ThinLTO", "Thin", ctx.arg.thinLTOCacheDir,
[&](size_t task, const Twine &moduleName,
std::unique_ptr<MemoryBuffer> mb) {
files[task] = std::move(mb);
@@ -210,16 +210,16 @@ std::vector<StringRef> BitcodeCompiler::compile() {
for (StringRef s : thinIndices) {
std::string path(s);
openFile(path + ".thinlto.bc");
- if (config->thinLTOEmitImportsFiles)
+ if (ctx.arg.thinLTOEmitImportsFiles)
openFile(path + ".imports");
}
- if (config->thinLTOEmitIndexFiles)
+ if (ctx.arg.thinLTOEmitIndexFiles)
thinLTOCreateEmptyIndexFiles();
- if (config->thinLTOIndexOnly) {
- if (!config->ltoObjPath.empty())
- saveBuffer(buf[0].second, config->ltoObjPath);
+ if (ctx.arg.thinLTOIndexOnly) {
+ if (!ctx.arg.ltoObjPath.empty())
+ saveBuffer(buf[0].second, ctx.arg.ltoObjPath);
// ThinLTO with index only option is required to generate only the index
// files. After that, we exit from linker and ThinLTO backend runs in a
@@ -229,8 +229,8 @@ std::vector<StringRef> BitcodeCompiler::compile() {
return {};
}
- if (!config->thinLTOCacheDir.empty())
- pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy, files);
+ if (!ctx.arg.thinLTOCacheDir.empty())
+ pruneCache(ctx.arg.thinLTOCacheDir, ctx.arg.thinLTOCachePolicy, files);
std::vector<StringRef> ret;
for (unsigned i = 0; i != maxTasks; ++i) {
@@ -239,7 +239,7 @@ std::vector<StringRef> BitcodeCompiler::compile() {
if (objBuf.empty())
continue;
ret.emplace_back(objBuf.data(), objBuf.size());
- if (!config->saveTemps)
+ if (!ctx.arg.saveTemps)
continue;
// If the input bitcode file is path/to/x.o and -o specifies a.out, the
@@ -248,7 +248,7 @@ std::vector<StringRef> BitcodeCompiler::compile() {
StringRef ltoObjName;
if (bitcodeFilePath == "ld-temp.o") {
ltoObjName =
- saver().save(Twine(config->outputFile) + ".lto" +
+ saver().save(Twine(ctx.arg.outputFile) + ".lto" +
(i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".o");
} else {
StringRef directory = sys::path::parent_path(bitcodeFilePath);
@@ -258,7 +258,7 @@ std::vector<StringRef> BitcodeCompiler::compile() {
StringRef baseName = bitcodeFilePath.ends_with(")")
? sys::path::filename(bitcodeFilePath)
: sys::path::stem(bitcodeFilePath);
- StringRef outputFileBaseName = sys::path::filename(config->outputFile);
+ StringRef outputFileBaseName = sys::path::filename(ctx.arg.outputFile);
SmallString<256> path;
sys::path::append(path, directory,
outputFileBaseName + ".lto." + baseName + ".o");
@@ -268,10 +268,10 @@ std::vector<StringRef> BitcodeCompiler::compile() {
saveBuffer(objBuf, ltoObjName);
}
- if (!config->ltoObjPath.empty()) {
- saveBuffer(buf[0].second, config->ltoObjPath);
+ if (!ctx.arg.ltoObjPath.empty()) {
+ saveBuffer(buf[0].second, ctx.arg.ltoObjPath);
for (unsigned i = 1; i != maxTasks; ++i)
- saveBuffer(buf[i].second, config->ltoObjPath + Twine(i));
+ saveBuffer(buf[i].second, ctx.arg.ltoObjPath + Twine(i));
}
for (std::unique_ptr<MemoryBuffer> &file : files)
diff --git a/lld/wasm/MapFile.cpp b/lld/wasm/MapFile.cpp
index c96b64cb648381..d8487e48b8c6b2 100644
--- a/lld/wasm/MapFile.cpp
+++ b/lld/wasm/MapFile.cpp
@@ -103,14 +103,14 @@ getSymbolStrings(ArrayRef<Symbol *> syms) {
}
void lld::wasm::writeMapFile(ArrayRef<OutputSection *> outputSections) {
- if (config->mapFile.empty())
+ if (ctx.arg.mapFile.empty())
return;
// Open a map file for writing.
std::error_code ec;
- raw_fd_ostream os(config->mapFile, ec, sys::fs::OF_None);
+ raw_fd_ostream os(ctx.arg.mapFile, ec, sys::fs::OF_None);
if (ec) {
- error("cannot open " + config->mapFile + ": " + ec.message());
+ error("cannot open " + ctx.arg.mapFile + ": " + ec.message());
return;
}
diff --git a/lld/wasm/MarkLive.cpp b/lld/wasm/MarkLive.cpp
index 1b99f03747fb0a..13c7a3d894fe3e 100644
--- a/lld/wasm/MarkLive.cpp
+++ b/lld/wasm/MarkLive.cpp
@@ -106,8 +106,8 @@ void MarkLive::enqueueRetainedSegments(const ObjFile *file) {
void MarkLive::run() {
// Add GC root symbols.
- if (!config->entry.empty())
- enqueue(symtab->find(config->entry));
+ if (!ctx.arg.entry.empty())
+ enqueue(symtab->find(ctx.arg.entry));
// We need to preserve any no-strip or exported symbol
for (Symbol *sym : symtab->symbols())
@@ -166,7 +166,7 @@ void MarkLive::mark() {
}
void markLive() {
- if (!config->gcSections)
+ if (!ctx.arg.gcSections)
return;
LLVM_DEBUG(dbgs() << "markLive\n");
@@ -175,7 +175,7 @@ void markLive() {
marker.run();
// Report garbage-collected sections.
- if (config->printGcSections) {
+ if (ctx.arg.printGcSections) {
for (const ObjFile *obj : ctx.objectFiles) {
for (InputChunk *c : obj->functions)
if (!c->live)
@@ -207,7 +207,7 @@ void markLive() {
bool MarkLive::isCallCtorsLive() {
// In a reloctable link, we don't call `__wasm_call_ctors`.
- if (config->relocatable)
+ if (ctx.arg.relocatable)
return false;
// In Emscripten-style PIC, we call `__wasm_call_ctors` which calls
diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index e4f75829ec4c3e..95f7ecc29de6ba 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -105,13 +105,13 @@ void DataSection::finalizeContents() {
});
#endif
- assert((config->sharedMemory || !ctx.isPic || config->extendedConst ||
+ assert((ctx.arg.sharedMemory || !ctx.isPic || ctx.arg.extendedConst ||
activeCount <= 1) &&
"output segments should have been combined by now");
writeUleb128(os, segmentCount, "data segment count");
bodySize = dataSectionHeader.size();
- bool is64 = config->is64.value_or(false);
+ bool is64 = ctx.arg.is64.value_or(false);
for (OutputSegment *segment : segments) {
if (!segment->requiredInBinary())
@@ -121,7 +121,7 @@ void DataSection::finalizeContents() {
if (segment->initFlags & WASM_DATA_SEGMENT_HAS_MEMINDEX)
writeUleb128(os, 0, "memory index");
if ((segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
- if (ctx.isPic && config->extendedConst) {
+ if (ctx.isPic && ctx.arg.extendedConst) {
writeU8(os, WASM_OPCODE_GLOBAL_GET, "global get");
writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(),
"literal (global index)");
diff --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp
index 45ad32701616a1..745dfde76ab70e 100644
--- a/lld/wasm/Relocations.cpp
+++ b/lld/wasm/Relocations.cpp
@@ -22,13 +22,13 @@ static bool requiresGOTAccess(const Symbol *sym) {
if (sym->isShared())
return true;
if (!ctx.isPic &&
- config->unresolvedSymbols != UnresolvedPolicy::ImportDynamic)
+ ctx.arg.unresolvedSymbols != UnresolvedPolicy::ImportDynamic)
return false;
if (sym->isHidden() || sym->isLocal())
return false;
// With `-Bsymbolic` (or when building an executable) as don't need to use
// the GOT for symbols that are defined within the current module.
- if (sym->isDefined() && (!config->shared || config->bsymbolic))
+ if (sym->isDefined() && (!ctx.arg.shared || ctx.arg.bsymbolic))
return false;
return true;
}
@@ -38,15 +38,15 @@ static bool allowUndefined(const Symbol* sym) {
// link time.
if (sym->isImported())
return true;
- if (isa<UndefinedFunction>(sym) && config->importUndefined)
+ if (isa<UndefinedFunction>(sym) && ctx.arg.importUndefined)
return true;
- return config->allowUndefinedSymbols.count(sym->getName()) != 0;
+ return ctx.arg.allowUndefinedSymbols.count(sym->getName()) != 0;
}
static void reportUndefined(ObjFile *file, Symbol *sym) {
if (!allowUndefined(sym)) {
- switch (config->unresolvedSymbols) {
+ switch (ctx.arg.unresolvedSymbols) {
case UnresolvedPolicy::ReportError:
error(toString(file) + ": undefined symbol: " + toString(*sym));
break;
@@ -63,8 +63,8 @@ static void reportUndefined(ObjFile *file, Symbol *sym) {
if (auto *f = dyn_cast<UndefinedFunction>(sym)) {
if (!f->stubFunction &&
- config->unresolvedSymbols != UnresolvedPolicy::ImportDynamic &&
- !config->importUndefined) {
+ ctx.arg.unresolvedSymbols != UnresolvedPolicy::ImportDynamic &&
+ !ctx.arg.importUndefined) {
f->stubFunction = symtab->createUndefinedStub(*f->getSignature());
f->stubFunction->markLive();
// Mark the function itself as a stub which prevents it from being
@@ -125,7 +125,7 @@ void scanRelocations(InputChunk *chunk) {
// In single-threaded builds TLS is lowered away and TLS data can be
// merged with normal data and allowing TLS relocation in non-TLS
// segments.
- if (config->sharedMemory) {
+ if (ctx.arg.sharedMemory) {
if (!sym->isTLS()) {
error(toString(file) + ": relocation " +
relocTypeToString(reloc.Type) +
@@ -146,7 +146,7 @@ void scanRelocations(InputChunk *chunk) {
if (ctx.isPic ||
(sym->isUndefined() &&
- config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic)) {
+ ctx.arg.unresolvedSymbols == UnresolvedPolicy::ImportDynamic)) {
switch (reloc.Type) {
case R_WASM_TABLE_INDEX_SLEB:
case R_WASM_TABLE_INDEX_SLEB64:
@@ -173,7 +173,7 @@ void scanRelocations(InputChunk *chunk) {
}
}
- if (!config->relocatable && sym->isUndefined()) {
+ if (!ctx.arg.relocatable && sym->isUndefined()) {
switch (reloc.Type) {
case R_WASM_TABLE_INDEX_REL_SLEB:
case R_WASM_TABLE_INDEX_REL_SLEB64:
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 4cbf44b4d0398a..f57359083d242f 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -53,7 +53,7 @@ void SymbolTable::addFile(InputFile *file, StringRef symName) {
return;
}
- if (config->trace)
+ if (ctx.arg.trace)
message(toString(file));
// LLVM bitcode file
@@ -125,7 +125,7 @@ std::pair<Symbol *, bool> SymbolTable::insertName(StringRef name) {
sym->canInline = true;
sym->traced = trace;
sym->forceExport = false;
- sym->referenced = !config->gcSections;
+ sym->referenced = !ctx.arg.gcSections;
symVector.emplace_back(sym);
return {sym, true};
}
@@ -235,7 +235,7 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef name,
DefinedData *SymbolTable::addOptionalDataSymbol(StringRef name,
uint64_t value) {
Symbol *s = find(name);
- if (!s && (config->exportAll || config->exportedSymbols.count(name) != 0))
+ if (!s && (ctx.arg.exportAll || ctx.arg.exportedSymbols.count(name) != 0))
s = insertName(name).first;
else if (!s || s->isDefined())
return nullptr;
@@ -317,7 +317,7 @@ static bool shouldReplace(const Symbol *existing, InputFile *newFile,
}
// Neither symbol is week. They conflict.
- if (config->allowMultipleDefinition)
+ if (ctx.arg.allowMultipleDefinition)
return false;
errorOrWarn("duplicate symbol: " + toString(*existing) + "\n>>> defined in " +
@@ -387,7 +387,7 @@ Symbol *SymbolTable::addSharedFunction(StringRef name, uint32_t flags,
checkSig = ud->isCalledDirectly;
if (checkSig && !signatureMatches(existingFunction, sig)) {
- if (config->shlibSigCheck) {
+ if (ctx.arg.shlibSigCheck) {
reportFunctionSignatureMismatch(name, existingFunction, sig, file);
} else {
// With --no-shlib-sigcheck we ignore the signature of the function as
@@ -637,7 +637,7 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
lazy->signature = sig;
} else {
lazy->extract();
- if (!config->whyExtract.empty())
+ if (!ctx.arg.whyExtract.empty())
ctx.whyExtractRecords.emplace_back(toString(file), s->getFile(), *s);
}
} else {
@@ -652,7 +652,7 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
if (isCalledDirectly && !signatureMatches(existingFunction, sig)) {
if (existingFunction->isShared()) {
// Special handling for when the existing function is a shared symbol
- if (config->shlibSigCheck) {
+ if (ctx.arg.shlibSigCheck) {
reportFunctionSignatureMismatch(name, existingFunction, sig, file);
} else {
existingFunction->signature = sig;
@@ -788,12 +788,12 @@ TableSymbol *SymbolTable::createUndefinedIndirectFunctionTable(StringRef name) {
WasmTableType *type = make<WasmTableType>();
type->ElemType = ValType::FUNCREF;
type->Limits = limits;
- uint32_t flags = config->exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
+ uint32_t flags = ctx.arg.exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
flags |= WASM_SYMBOL_UNDEFINED;
Symbol *sym =
addUndefinedTable(name, name, defaultModule, flags, nullptr, type);
sym->markLive();
- sym->forceExport = config->exportTable;
+ sym->forceExport = ctx.arg.exportTable;
return cast<TableSymbol>(sym);
}
@@ -803,10 +803,10 @@ TableSymbol *SymbolTable::createDefinedIndirectFunctionTable(StringRef name) {
WasmTableType type{ValType::FUNCREF, limits};
WasmTable desc{invalidIndex, type, name};
InputTable *table = make<InputTable>(desc, nullptr);
- uint32_t flags = config->exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
+ uint32_t flags = ctx.arg.exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
TableSymbol *sym = addSyntheticTable(name, flags, table);
sym->markLive();
- sym->forceExport = config->exportTable;
+ sym->forceExport = ctx.arg.exportTable;
return sym;
}
@@ -830,7 +830,7 @@ TableSymbol *SymbolTable::resolveIndirectFunctionTable(bool required) {
}
}
- if (config->importTable) {
+ if (ctx.arg.importTable) {
if (existing) {
existing->importModule = defaultModule;
existing->importName = functionTableName;
@@ -838,7 +838,7 @@ TableSymbol *SymbolTable::resolveIndirectFunctionTable(bool required) {
}
if (required)
return createUndefinedIndirectFunctionTable(functionTableName);
- } else if ((existing && existing->isLive()) || config->exportTable ||
+ } else if ((existing && existing->isLive()) || ctx.arg.exportTable ||
required) {
// A defined table is required. Either because the user request an exported
// table or because the table symbol is already live. The existing table is
@@ -885,7 +885,7 @@ void SymbolTable::addLazy(StringRef name, InputFile *file) {
LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
const InputFile *oldFile = s->getFile();
LazySymbol(name, 0, file).extract();
- if (!config->whyExtract.empty())
+ if (!ctx.arg.whyExtract.empty())
ctx.whyExtractRecords.emplace_back(toString(oldFile), s->getFile(), *s);
}
diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp
index e62e7bec609f54..a687fd6d6c4efb 100644
--- a/lld/wasm/Symbols.cpp
+++ b/lld/wasm/Symbols.cpp
@@ -35,7 +35,7 @@ std::string maybeDemangleSymbol(StringRef name) {
// `main` in the case where we need to pass it arguments.
if (name == "__main_argc_argv")
return "main";
- if (wasm::config->demangle)
+ if (wasm::ctx.arg.demangle)
return demangle(name);
return name.str();
}
@@ -235,10 +235,10 @@ bool Symbol::isExported() const {
// Shared libraries must export all weakly defined symbols
// in case they contain the version that will be chosen by
// the dynamic linker.
- if (config->shared && isLive() && isWeak() && !isHidden())
+ if (ctx.arg.shared && isLive() && isWeak() && !isHidden())
return true;
- if (config->exportAll || (config->exportDynamic && !isHidden()))
+ if (ctx.arg.exportAll || (ctx.arg.exportDynamic && !isHidden()))
return true;
return isExportedExplicit();
diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h
index 80b658773bd20b..b409fffc50a6c0 100644
--- a/lld/wasm/Symbols.h
+++ b/lld/wasm/Symbols.h
@@ -139,7 +139,7 @@ class Symbol {
protected:
Symbol(StringRef name, Kind k, uint32_t flags, InputFile *f)
- : name(name), file(f), symbolKind(k), referenced(!config->gcSections),
+ : name(name), file(f), symbolKind(k), referenced(!ctx.arg.gcSections),
requiresGOT(false), isUsedInRegularObj(false), forceExport(false),
forceImport(false), canInline(false), traced(false), isStub(false),
flags(flags) {}
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index 6b32d12ebeb455..715fba1ee6da54 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -55,7 +55,7 @@ class SubSection {
bool DylinkSection::isNeeded() const {
return ctx.isPic ||
- config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic ||
+ ctx.arg.unresolvedSymbols == UnresolvedPolicy::ImportDynamic ||
!ctx.sharedFiles.empty();
}
@@ -162,7 +162,7 @@ void TypeSection::writeBody() {
uint32_t ImportSection::getNumImports() const {
assert(isSealed);
uint32_t numImports = importedSymbols.size() + gotSymbols.size();
- if (config->memoryImport.has_value())
+ if (ctx.arg.memoryImport.has_value())
++numImports;
return numImports;
}
@@ -232,20 +232,20 @@ void ImportSection::writeBody() {
writeUleb128(os, getNumImports(), "import count");
- bool is64 = config->is64.value_or(false);
+ bool is64 = ctx.arg.is64.value_or(false);
- if (config->memoryImport) {
+ if (ctx.arg.memoryImport) {
WasmImport import;
- import.Module = config->memoryImport->first;
- import.Field = config->memoryImport->second;
+ import.Module = ctx.arg.memoryImport->first;
+ import.Field = ctx.arg.memoryImport->second;
import.Kind = WASM_EXTERNAL_MEMORY;
import.Memory.Flags = 0;
import.Memory.Minimum = out.memorySec->numMemoryPages;
- if (out.memorySec->maxMemoryPages != 0 || config->sharedMemory) {
+ if (out.memorySec->maxMemoryPages != 0 || ctx.arg.sharedMemory) {
import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
import.Memory.Maximum = out.memorySec->maxMemoryPages;
}
- if (config->sharedMemory)
+ if (ctx.arg.sharedMemory)
import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
if (is64)
import.Memory.Flags |= WASM_LIMITS_FLAG_IS_64;
@@ -351,14 +351,14 @@ void TableSection::assignIndexes() {
void MemorySection::writeBody() {
raw_ostream &os = bodyOutputStream;
- bool hasMax = maxMemoryPages != 0 || config->sharedMemory;
+ bool hasMax = maxMemoryPages != 0 || ctx.arg.sharedMemory;
writeUleb128(os, 1, "memory count");
unsigned flags = 0;
if (hasMax)
flags |= WASM_LIMITS_FLAG_HAS_MAX;
- if (config->sharedMemory)
+ if (ctx.arg.sharedMemory)
flags |= WASM_LIMITS_FLAG_IS_SHARED;
- if (config->is64.value_or(false))
+ if (ctx.arg.is64.value_or(false))
flags |= WASM_LIMITS_FLAG_IS_64;
writeUleb128(os, flags, "memory limits flags");
writeUleb128(os, numMemoryPages, "initial pages");
@@ -415,8 +415,8 @@ void GlobalSection::addInternalGOTEntry(Symbol *sym) {
}
void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const {
- assert(!config->extendedConst);
- bool is64 = config->is64.value_or(false);
+ assert(!ctx.arg.extendedConst);
+ bool is64 = ctx.arg.is64.value_or(false);
unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST
: WASM_OPCODE_I32_CONST;
unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD
@@ -466,7 +466,7 @@ void GlobalSection::writeBody() {
writeGlobalType(os, g->getType());
writeInitExpr(os, g->getInitExpr());
}
- bool is64 = config->is64.value_or(false);
+ bool is64 = ctx.arg.is64.value_or(false);
uint8_t itype = is64 ? WASM_TYPE_I64 : WASM_TYPE_I32;
for (const Symbol *sym : internalGotSymbols) {
bool mutable_ = false;
@@ -474,11 +474,11 @@ void GlobalSection::writeBody() {
// In the case of dynamic linking, unless we have 'extended-const'
// available, these global must to be mutable since they get updated to
// the correct runtime value during `__wasm_apply_global_relocs`.
- if (!config->extendedConst && ctx.isPic && !sym->isTLS())
+ if (!ctx.arg.extendedConst && ctx.isPic && !sym->isTLS())
mutable_ = true;
// With multi-theadeding any TLS globals must be mutable since they get
// set during `__wasm_apply_global_tls_relocs`
- if (config->sharedMemory && sym->isTLS())
+ if (ctx.arg.sharedMemory && sym->isTLS())
mutable_ = true;
}
WasmGlobalType type{itype, mutable_};
@@ -487,7 +487,7 @@ void GlobalSection::writeBody() {
bool useExtendedConst = false;
uint32_t globalIdx;
int64_t offset;
- if (config->extendedConst && ctx.isPic) {
+ if (ctx.arg.extendedConst && ctx.isPic) {
if (auto *d = dyn_cast<DefinedData>(sym)) {
if (!sym->isTLS()) {
globalIdx = WasmSym::memoryBase->getGlobalIndex();
@@ -518,7 +518,7 @@ void GlobalSection::writeBody() {
// In the sharedMemory case TLS globals are set during
// `__wasm_apply_global_tls_relocs`, but in the non-shared case
// we know the absolute value at link time.
- initExpr = intConst(d->getVA(/*absolute=*/!config->sharedMemory), is64);
+ initExpr = intConst(d->getVA(/*absolute=*/!ctx.arg.sharedMemory), is64);
else if (auto *f = dyn_cast<FunctionSymbol>(sym))
initExpr = intConst(f->isStub ? 0 : f->getTableIndex(), is64);
else {
@@ -566,7 +566,7 @@ void ElemSection::addEntry(FunctionSymbol *sym) {
// They only exist so that the calls to missing functions can validate.
if (sym->hasTableIndex() || sym->isStub)
return;
- sym->setTableIndex(config->tableBase + indirectFunctions.size());
+ sym->setTableIndex(ctx.arg.tableBase + indirectFunctions.size());
indirectFunctions.emplace_back(sym);
}
@@ -589,8 +589,8 @@ void ElemSection::writeBody() {
initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET;
initExpr.Inst.Value.Global = WasmSym::tableBase->getGlobalIndex();
} else {
- bool is64 = config->is64.value_or(false);
- initExpr = intConst(config->tableBase, is64);
+ bool is64 = ctx.arg.is64.value_or(false);
+ initExpr = intConst(ctx.arg.tableBase, is64);
}
writeInitExpr(os, initExpr);
@@ -602,7 +602,7 @@ void ElemSection::writeBody() {
}
writeUleb128(os, indirectFunctions.size(), "elem count");
- uint32_t tableIndex = config->tableBase;
+ uint32_t tableIndex = ctx.arg.tableBase;
for (const FunctionSymbol *sym : indirectFunctions) {
assert(sym->getTableIndex() == tableIndex);
(void) tableIndex;
@@ -622,7 +622,7 @@ void DataCountSection::writeBody() {
}
bool DataCountSection::isNeeded() const {
- return numSegments && config->sharedMemory;
+ return numSegments && ctx.arg.sharedMemory;
}
void LinkingSection::writeBody() {
@@ -786,9 +786,9 @@ unsigned NameSection::numNamedDataSegments() const {
void NameSection::writeBody() {
{
SubSection sub(WASM_NAMES_MODULE);
- StringRef moduleName = config->soName;
- if (config->soName.empty())
- moduleName = llvm::sys::path::filename(config->outputFile);
+ StringRef moduleName = ctx.arg.soName;
+ if (ctx.arg.soName.empty())
+ moduleName = llvm::sys::path::filename(ctx.arg.outputFile);
writeStr(sub.os, moduleName, "module name");
sub.writeTo(bodyOutputStream);
}
@@ -917,14 +917,14 @@ void RelocSection::writeBody() {
}
static size_t getHashSize() {
- switch (config->buildId) {
+ switch (ctx.arg.buildId) {
case BuildIdKind::Fast:
case BuildIdKind::Uuid:
return 16;
case BuildIdKind::Sha1:
return 20;
case BuildIdKind::Hexstring:
- return config->buildIdVector.size();
+ return ctx.arg.buildIdVector.size();
case BuildIdKind::None:
return 0;
}
diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h
index 10183e93d2a28d..068fbed11f4a75 100644
--- a/lld/wasm/SyntheticSections.h
+++ b/lld/wasm/SyntheticSections.h
@@ -228,7 +228,7 @@ class MemorySection : public SyntheticSection {
public:
MemorySection() : SyntheticSection(llvm::wasm::WASM_SEC_MEMORY) {}
- bool isNeeded() const override { return !config->memoryImport.has_value(); }
+ bool isNeeded() const override { return !ctx.arg.memoryImport.has_value(); }
void writeBody() override;
uint64_t numMemoryPages = 0;
@@ -286,7 +286,7 @@ class GlobalSection : public SyntheticSection {
// transform a `global.get` to an `i32.const`.
void addInternalGOTEntry(Symbol *sym);
bool needsRelocations() {
- if (config->extendedConst)
+ if (ctx.arg.extendedConst)
return false;
return llvm::any_of(internalGotSymbols,
[=](Symbol *sym) { return !sym->isTLS(); });
@@ -354,7 +354,7 @@ class LinkingSection : public SyntheticSection {
: SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "linking"),
initFunctions(initFunctions), dataSegments(dataSegments) {}
bool isNeeded() const override {
- return config->relocatable || config->emitRelocs;
+ return ctx.arg.relocatable || ctx.arg.emitRelocs;
}
void writeBody() override;
void addToSymtab(Symbol *sym);
@@ -373,7 +373,7 @@ class NameSection : public SyntheticSection {
: SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "name"),
segments(segments) {}
bool isNeeded() const override {
- if (config->stripAll && !config->keepSections.count(name))
+ if (ctx.arg.stripAll && !ctx.arg.keepSections.count(name))
return false;
return numNames() > 0;
}
@@ -396,7 +396,7 @@ class ProducersSection : public SyntheticSection {
ProducersSection()
: SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "producers") {}
bool isNeeded() const override {
- if (config->stripAll && !config->keepSections.count(name))
+ if (ctx.arg.stripAll && !ctx.arg.keepSections.count(name))
return false;
return fieldCount() > 0;
}
@@ -417,7 +417,7 @@ class TargetFeaturesSection : public SyntheticSection {
TargetFeaturesSection()
: SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "target_features") {}
bool isNeeded() const override {
- if (config->stripAll && !config->keepSections.count(name))
+ if (ctx.arg.stripAll && !ctx.arg.keepSections.count(name))
return false;
return features.size() > 0;
}
@@ -443,7 +443,7 @@ class BuildIdSection : public SyntheticSection {
BuildIdSection();
void writeBody() override;
bool isNeeded() const override {
- return config->buildId != BuildIdKind::None;
+ return ctx.arg.buildId != BuildIdKind::None;
}
void writeBuildId(llvm::ArrayRef<uint8_t> buf);
void writeTo(uint8_t *buf) override {
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index aeac1a51824f51..76e38f548157c4 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -132,7 +132,7 @@ class Writer {
void Writer::calculateCustomSections() {
log("calculateCustomSections");
- bool stripDebug = config->stripDebug || config->stripAll;
+ bool stripDebug = ctx.arg.stripDebug || ctx.arg.stripAll;
for (ObjFile *file : ctx.objectFiles) {
for (InputChunk *section : file->customSections) {
// Exclude COMDAT sections that are not selected for inclusion
@@ -172,7 +172,7 @@ void Writer::createCustomSections() {
LLVM_DEBUG(dbgs() << "createCustomSection: " << name << "\n");
OutputSection *sec = make<CustomSection>(std::string(name), pair.second);
- if (config->relocatable || config->emitRelocs) {
+ if (ctx.arg.relocatable || ctx.arg.emitRelocs) {
auto *sym = make<OutputSectionSymbol>(sec);
out.linkingSec->addToSymtab(sym);
sec->sectionSym = sym;
@@ -282,8 +282,8 @@ static void makeUUID(unsigned version, llvm::ArrayRef<uint8_t> fileHash,
void Writer::writeBuildId() {
if (!out.buildIdSec->isNeeded())
return;
- if (config->buildId == BuildIdKind::Hexstring) {
- out.buildIdSec->writeBuildId(config->buildIdVector);
+ if (ctx.arg.buildId == BuildIdKind::Hexstring) {
+ out.buildIdSec->writeBuildId(ctx.arg.buildIdVector);
return;
}
@@ -292,7 +292,7 @@ void Writer::writeBuildId() {
std::vector<uint8_t> buildId(hashSize);
llvm::ArrayRef<uint8_t> buf{buffer->getBufferStart(), size_t(fileSize)};
- switch (config->buildId) {
+ switch (ctx.arg.buildId) {
case BuildIdKind::Fast: {
std::vector<uint8_t> fileHash(8);
computeHash(fileHash, buf, [](uint8_t *dest, ArrayRef<uint8_t> arr) {
@@ -324,9 +324,9 @@ static void setGlobalPtr(DefinedGlobal *g, uint64_t memoryPtr) {
// to each of the input data sections as well as the explicit stack region.
// The default memory layout is as follows, from low to high.
//
-// - initialized data (starting at config->globalBase)
+// - initialized data (starting at ctx.arg.globalBase)
// - BSS data (not currently implemented in llvm)
-// - explicit stack (config->ZStackSize)
+// - explicit stack (ctx.arg.ZStackSize)
// - heap start / unallocated
//
// The --stack-first option means that stack is placed before any static data.
@@ -337,33 +337,33 @@ void Writer::layoutMemory() {
uint64_t memoryPtr = 0;
auto placeStack = [&]() {
- if (config->relocatable || ctx.isPic)
+ if (ctx.arg.relocatable || ctx.isPic)
return;
memoryPtr = alignTo(memoryPtr, stackAlignment);
if (WasmSym::stackLow)
WasmSym::stackLow->setVA(memoryPtr);
- if (config->zStackSize != alignTo(config->zStackSize, stackAlignment))
+ if (ctx.arg.zStackSize != alignTo(ctx.arg.zStackSize, stackAlignment))
error("stack size must be " + Twine(stackAlignment) + "-byte aligned");
- log("mem: stack size = " + Twine(config->zStackSize));
+ log("mem: stack size = " + Twine(ctx.arg.zStackSize));
log("mem: stack base = " + Twine(memoryPtr));
- memoryPtr += config->zStackSize;
+ memoryPtr += ctx.arg.zStackSize;
setGlobalPtr(cast<DefinedGlobal>(WasmSym::stackPointer), memoryPtr);
if (WasmSym::stackHigh)
WasmSym::stackHigh->setVA(memoryPtr);
log("mem: stack top = " + Twine(memoryPtr));
};
- if (config->stackFirst) {
+ if (ctx.arg.stackFirst) {
placeStack();
- if (config->globalBase) {
- if (config->globalBase < memoryPtr) {
+ if (ctx.arg.globalBase) {
+ if (ctx.arg.globalBase < memoryPtr) {
error("--global-base cannot be less than stack size when --stack-first is used");
return;
}
- memoryPtr = config->globalBase;
+ memoryPtr = ctx.arg.globalBase;
}
} else {
- memoryPtr = config->globalBase;
+ memoryPtr = ctx.arg.globalBase;
}
log("mem: global base = " + Twine(memoryPtr));
@@ -385,7 +385,7 @@ void Writer::layoutMemory() {
log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", seg->name,
memoryPtr, seg->size, seg->alignment));
- if (!config->relocatable && seg->isTLS()) {
+ if (!ctx.arg.relocatable && seg->isTLS()) {
if (WasmSym::tlsSize) {
auto *tlsSize = cast<DefinedGlobal>(WasmSym::tlsSize);
setGlobalPtr(tlsSize, seg->size);
@@ -394,7 +394,7 @@ void Writer::layoutMemory() {
auto *tlsAlign = cast<DefinedGlobal>(WasmSym::tlsAlign);
setGlobalPtr(tlsAlign, int64_t{1} << seg->alignment);
}
- if (!config->sharedMemory && WasmSym::tlsBase) {
+ if (!ctx.arg.sharedMemory && WasmSym::tlsBase) {
auto *tlsBase = cast<DefinedGlobal>(WasmSym::tlsBase);
setGlobalPtr(tlsBase, memoryPtr);
}
@@ -404,7 +404,7 @@ void Writer::layoutMemory() {
}
// Make space for the memory initialization flag
- if (config->sharedMemory && hasPassiveInitializedSegments()) {
+ if (ctx.arg.sharedMemory && hasPassiveInitializedSegments()) {
memoryPtr = alignTo(memoryPtr, 4);
WasmSym::initMemoryFlag = symtab->addSyntheticDataSymbol(
"__wasm_init_memory_flag", WASM_SYMBOL_VISIBILITY_HIDDEN);
@@ -423,7 +423,7 @@ void Writer::layoutMemory() {
if (ctx.isPic)
out.dylinkSec->memSize = staticDataSize;
- if (!config->stackFirst)
+ if (!ctx.arg.stackFirst)
placeStack();
if (WasmSym::heapBase) {
@@ -438,31 +438,31 @@ void Writer::layoutMemory() {
}
uint64_t maxMemorySetting = 1ULL << 32;
- if (config->is64.value_or(false)) {
+ if (ctx.arg.is64.value_or(false)) {
// TODO: Update once we decide on a reasonable limit here:
// https://github.com/WebAssembly/memory64/issues/33
maxMemorySetting = 1ULL << 34;
}
- if (config->initialHeap != 0) {
- if (config->initialHeap != alignTo(config->initialHeap, WasmPageSize))
+ if (ctx.arg.initialHeap != 0) {
+ if (ctx.arg.initialHeap != alignTo(ctx.arg.initialHeap, WasmPageSize))
error("initial heap must be " + Twine(WasmPageSize) + "-byte aligned");
uint64_t maxInitialHeap = maxMemorySetting - memoryPtr;
- if (config->initialHeap > maxInitialHeap)
+ if (ctx.arg.initialHeap > maxInitialHeap)
error("initial heap too large, cannot be greater than " +
Twine(maxInitialHeap));
- memoryPtr += config->initialHeap;
+ memoryPtr += ctx.arg.initialHeap;
}
- if (config->initialMemory != 0) {
- if (config->initialMemory != alignTo(config->initialMemory, WasmPageSize))
+ if (ctx.arg.initialMemory != 0) {
+ if (ctx.arg.initialMemory != alignTo(ctx.arg.initialMemory, WasmPageSize))
error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned");
- if (memoryPtr > config->initialMemory)
+ if (memoryPtr > ctx.arg.initialMemory)
error("initial memory too small, " + Twine(memoryPtr) + " bytes needed");
- if (config->initialMemory > maxMemorySetting)
+ if (ctx.arg.initialMemory > maxMemorySetting)
error("initial memory too large, cannot be greater than " +
Twine(maxMemorySetting));
- memoryPtr = config->initialMemory;
+ memoryPtr = ctx.arg.initialMemory;
}
memoryPtr = alignTo(memoryPtr, WasmPageSize);
@@ -479,23 +479,23 @@ void Writer::layoutMemory() {
}
uint64_t maxMemory = 0;
- if (config->maxMemory != 0) {
- if (config->maxMemory != alignTo(config->maxMemory, WasmPageSize))
+ if (ctx.arg.maxMemory != 0) {
+ if (ctx.arg.maxMemory != alignTo(ctx.arg.maxMemory, WasmPageSize))
error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
- if (memoryPtr > config->maxMemory)
+ if (memoryPtr > ctx.arg.maxMemory)
error("maximum memory too small, " + Twine(memoryPtr) + " bytes needed");
- if (config->maxMemory > maxMemorySetting)
+ if (ctx.arg.maxMemory > maxMemorySetting)
error("maximum memory too large, cannot be greater than " +
Twine(maxMemorySetting));
- maxMemory = config->maxMemory;
- } else if (config->noGrowableMemory) {
+ maxMemory = ctx.arg.maxMemory;
+ } else if (ctx.arg.noGrowableMemory) {
maxMemory = memoryPtr;
}
// If no maxMemory config was supplied but we are building with
// shared memory, we need to pick a sensible upper limit.
- if (config->sharedMemory && maxMemory == 0) {
+ if (ctx.arg.sharedMemory && maxMemory == 0) {
if (ctx.isPic)
maxMemory = maxMemorySetting;
else
@@ -552,7 +552,7 @@ void Writer::addSections() {
createCustomSections();
addSection(out.linkingSec);
- if (config->emitRelocs || config->relocatable) {
+ if (ctx.arg.emitRelocs || ctx.arg.relocatable) {
createRelocSections();
}
@@ -583,18 +583,18 @@ void Writer::populateTargetFeatures() {
allowed.insert("mutable-globals");
}
- if (config->extraFeatures.has_value()) {
- auto &extraFeatures = *config->extraFeatures;
+ if (ctx.arg.extraFeatures.has_value()) {
+ auto &extraFeatures = *ctx.arg.extraFeatures;
allowed.insert(extraFeatures.begin(), extraFeatures.end());
}
// Only infer used features if user did not specify features
- bool inferFeatures = !config->features.has_value();
+ bool inferFeatures = !ctx.arg.features.has_value();
if (!inferFeatures) {
- auto &explicitFeatures = *config->features;
+ auto &explicitFeatures = *ctx.arg.features;
allowed.insert(explicitFeatures.begin(), explicitFeatures.end());
- if (!config->checkFeatures)
+ if (!ctx.arg.checkFeatures)
goto done;
}
@@ -626,10 +626,10 @@ void Writer::populateTargetFeatures() {
for (const auto &key : used.keys())
allowed.insert(std::string(key));
- if (!config->checkFeatures)
+ if (!ctx.arg.checkFeatures)
goto done;
- if (config->sharedMemory) {
+ if (ctx.arg.sharedMemory) {
if (disallowed.count("shared-mem"))
error("--shared-memory is disallowed by " + disallowed["shared-mem"] +
" because it was not compiled with 'atomics' or 'bulk-memory' "
@@ -679,19 +679,19 @@ void Writer::populateTargetFeatures() {
// instruction, then we can also avoid including the segments.
// Finally, if we are emitting relocations, they may refer to locations within
// the bss segments, so these segments need to exist in the binary.
- if (config->emitRelocs ||
- (config->memoryImport.has_value() && !allowed.count("bulk-memory")))
+ if (ctx.arg.emitRelocs ||
+ (ctx.arg.memoryImport.has_value() && !allowed.count("bulk-memory")))
ctx.emitBssSegments = true;
if (allowed.count("extended-const"))
- config->extendedConst = true;
+ ctx.arg.extendedConst = true;
for (auto &feature : allowed)
log("Allowed feature: " + feature);
}
void Writer::checkImportExportTargetFeatures() {
- if (config->relocatable || !config->checkFeatures)
+ if (ctx.arg.relocatable || !ctx.arg.checkFeatures)
return;
if (out.targetFeaturesSec->features.count("mutable-globals") == 0) {
@@ -727,14 +727,14 @@ static bool shouldImport(Symbol *sym) {
// When a symbol is weakly defined in a shared library we need to allow
// it to be overridden by another module so need to both import
// and export the symbol.
- if (config->shared && sym->isWeak() && !sym->isUndefined() &&
+ if (ctx.arg.shared && sym->isWeak() && !sym->isUndefined() &&
!sym->isHidden())
return true;
if (sym->isShared())
return true;
if (!sym->isUndefined())
return false;
- if (sym->isWeak() && !config->relocatable && !ctx.isPic)
+ if (sym->isWeak() && !ctx.arg.relocatable && !ctx.isPic)
return false;
// In PIC mode we only need to import functions when they are called directly.
@@ -745,10 +745,10 @@ static bool shouldImport(Symbol *sym) {
return false;
}
- if (ctx.isPic || config->relocatable || config->importUndefined ||
- config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic)
+ if (ctx.isPic || ctx.arg.relocatable || ctx.arg.importUndefined ||
+ ctx.arg.unresolvedSymbols == UnresolvedPolicy::ImportDynamic)
return true;
- if (config->allowUndefinedSymbols.count(sym->getName()) != 0)
+ if (ctx.arg.allowUndefinedSymbols.count(sym->getName()) != 0)
return true;
return sym->isImported();
@@ -773,12 +773,12 @@ void Writer::calculateImports() {
}
void Writer::calculateExports() {
- if (config->relocatable)
+ if (ctx.arg.relocatable)
return;
- if (!config->relocatable && config->memoryExport.has_value()) {
+ if (!ctx.arg.relocatable && ctx.arg.memoryExport.has_value()) {
out.exportSec->exports.push_back(
- WasmExport{*config->memoryExport, WASM_EXTERNAL_MEMORY, 0});
+ WasmExport{*ctx.arg.memoryExport, WASM_EXTERNAL_MEMORY, 0});
}
unsigned globalIndex =
@@ -827,7 +827,7 @@ void Writer::calculateExports() {
}
void Writer::populateSymtab() {
- if (!config->relocatable && !config->emitRelocs)
+ if (!ctx.arg.relocatable && !ctx.arg.emitRelocs)
return;
for (Symbol *sym : symtab->symbols())
@@ -931,13 +931,13 @@ static void finalizeIndirectFunctionTable() {
out.importSec->addImport(WasmSym::indirectFunctionTable);
}
- uint32_t tableSize = config->tableBase + out.elemSec->numEntries();
+ uint32_t tableSize = ctx.arg.tableBase + out.elemSec->numEntries();
WasmLimits limits = {0, tableSize, 0};
- if (WasmSym::indirectFunctionTable->isDefined() && !config->growableTable) {
+ if (WasmSym::indirectFunctionTable->isDefined() && !ctx.arg.growableTable) {
limits.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
limits.Maximum = limits.Minimum;
}
- if (config->is64.value_or(false))
+ if (ctx.arg.is64.value_or(false))
limits.Flags |= WASM_LIMITS_FLAG_IS_64;
WasmSym::indirectFunctionTable->setLimits(limits);
}
@@ -1001,7 +1001,7 @@ static StringRef getOutputDataSegmentName(const InputChunk &seg) {
// symbols are be relative to single __tls_base.
if (seg.isTLS())
return ".tdata";
- if (!config->mergeDataSegments)
+ if (!ctx.arg.mergeDataSegments)
return seg.name;
if (seg.name.starts_with(".text."))
return ".text";
@@ -1017,9 +1017,9 @@ static StringRef getOutputDataSegmentName(const InputChunk &seg) {
OutputSegment *Writer::createOutputSegment(StringRef name) {
LLVM_DEBUG(dbgs() << "new segment: " << name << "\n");
OutputSegment *s = make<OutputSegment>(name);
- if (config->sharedMemory)
+ if (ctx.arg.sharedMemory)
s->initFlags = WASM_DATA_SEGMENT_IS_PASSIVE;
- if (!config->relocatable && name.starts_with(".bss"))
+ if (!ctx.arg.relocatable && name.starts_with(".bss"))
s->isBss = true;
segments.push_back(s);
return s;
@@ -1035,7 +1035,7 @@ void Writer::createOutputSegments() {
// When running in relocatable mode we can't merge segments that are part
// of comdat groups since the ultimate linker needs to be able exclude or
// include them individually.
- if (config->relocatable && !segment->getComdatName().empty()) {
+ if (ctx.arg.relocatable && !segment->getComdatName().empty()) {
s = createOutputSegment(name);
} else {
if (segmentMap.count(name) == 0)
@@ -1075,8 +1075,8 @@ void Writer::combineOutputSegments() {
// combines all data segments into a single .data segment.
// This restriction does not apply when the extended const extension is
// available: https://github.com/WebAssembly/extended-const
- assert(!config->extendedConst);
- assert(ctx.isPic && !config->sharedMemory);
+ assert(!ctx.arg.extendedConst);
+ assert(ctx.isPic && !ctx.arg.sharedMemory);
if (segments.size() <= 1)
return;
OutputSegment *combined = make<OutputSegment>(".data");
@@ -1117,7 +1117,7 @@ static void createFunction(DefinedFunction *func, StringRef bodyContent) {
bool Writer::needsPassiveInitialization(const OutputSegment *segment) {
// If bulk memory features is supported then we can perform bss initialization
// (via memory.fill) during `__wasm_init_memory`.
- if (config->memoryImport.has_value() && !segment->requiredInBinary())
+ if (ctx.arg.memoryImport.has_value() && !segment->requiredInBinary())
return true;
return segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE;
}
@@ -1129,7 +1129,7 @@ bool Writer::hasPassiveInitializedSegments() {
}
void Writer::createSyntheticInitFunctions() {
- if (config->relocatable)
+ if (ctx.arg.relocatable)
return;
static WasmSignature nullSignature = {{}, {}};
@@ -1146,14 +1146,14 @@ void Writer::createSyntheticInitFunctions() {
"__wasm_init_memory", WASM_SYMBOL_VISIBILITY_HIDDEN,
make<SyntheticFunction>(nullSignature, "__wasm_init_memory"));
WasmSym::initMemory->markLive();
- if (config->sharedMemory) {
+ if (ctx.arg.sharedMemory) {
// This global is assigned during __wasm_init_memory in the shared memory
// case.
WasmSym::tlsBase->markLive();
}
}
- if (config->sharedMemory) {
+ if (ctx.arg.sharedMemory) {
if (out.globalSec->needsTLSRelocations()) {
WasmSym::applyGlobalTLSRelocs = symtab->addSyntheticFunction(
"__wasm_apply_global_tls_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN,
@@ -1203,11 +1203,11 @@ void Writer::createInitMemoryFunction() {
assert(WasmSym::initMemory);
assert(hasPassiveInitializedSegments());
uint64_t flagAddress;
- if (config->sharedMemory) {
+ if (ctx.arg.sharedMemory) {
assert(WasmSym::initMemoryFlag);
flagAddress = WasmSym::initMemoryFlag->getVA();
}
- bool is64 = config->is64.value_or(false);
+ bool is64 = ctx.arg.is64.value_or(false);
std::string bodyContent;
{
raw_string_ostream os(bodyContent);
@@ -1271,7 +1271,7 @@ void Writer::createInitMemoryFunction() {
}
};
- if (config->sharedMemory) {
+ if (ctx.arg.sharedMemory) {
// With PIC code we cache the flag address in local 0
if (ctx.isPic) {
writeUleb128(os, 1, "num local decls");
@@ -1334,7 +1334,7 @@ void Writer::createInitMemoryFunction() {
// When we initialize the TLS segment we also set the `__tls_base`
// global. This allows the runtime to use this static copy of the
// TLS data for the first/main thread.
- if (config->sharedMemory && s->isTLS()) {
+ if (ctx.arg.sharedMemory && s->isTLS()) {
if (ctx.isPic) {
// Cache the result of the addionion in local 0
writeU8(os, WASM_OPCODE_LOCAL_TEE, "local.tee");
@@ -1368,7 +1368,7 @@ void Writer::createInitMemoryFunction() {
}
}
- if (config->sharedMemory) {
+ if (ctx.arg.sharedMemory) {
// Set flag to 2 to mark end of initialization
writeGetFlagAddress();
writeI32Const(os, 2, "flag value");
@@ -1407,7 +1407,7 @@ void Writer::createInitMemoryFunction() {
if (needsPassiveInitialization(s) && !s->isBss) {
// The TLS region should not be dropped since its is needed
// during the initialization of each thread (__wasm_init_tls).
- if (config->sharedMemory && s->isTLS())
+ if (ctx.arg.sharedMemory && s->isTLS())
continue;
// data.drop instruction
writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
@@ -1460,7 +1460,7 @@ void Writer::createApplyDataRelocationsFunction() {
writeUleb128(os, 0, "num locals");
bool generated = false;
for (const OutputSegment *seg : segments)
- if (!config->sharedMemory || !seg->isTLS())
+ if (!ctx.arg.sharedMemory || !seg->isTLS())
for (const InputChunk *inSeg : seg->inputSegments)
generated |= inSeg->generateRelocationCode(os);
@@ -1656,7 +1656,7 @@ void Writer::createInitTLSFunction() {
// This is then used either when creating the output linking section or to
// synthesize the "__wasm_call_ctors" function.
void Writer::calculateInitFunctions() {
- if (!config->relocatable && !WasmSym::callCtors->isLive())
+ if (!ctx.arg.relocatable && !WasmSym::callCtors->isLive())
return;
for (ObjFile *file : ctx.objectFiles) {
@@ -1708,7 +1708,7 @@ void Writer::run() {
// For PIC code the table base is assigned dynamically by the loader.
// For non-PIC, we start at 1 so that accessing table index 0 always traps.
if (!ctx.isPic && WasmSym::definedTableBase)
- WasmSym::definedTableBase->setVA(config->tableBase);
+ WasmSym::definedTableBase->setVA(ctx.arg.tableBase);
log("-- createOutputSegments");
createOutputSegments();
@@ -1717,7 +1717,7 @@ void Writer::run() {
log("-- layoutMemory");
layoutMemory();
- if (!config->relocatable) {
+ if (!ctx.arg.relocatable) {
// Create linker synthesized __start_SECNAME/__stop_SECNAME symbols
// This has to be done after memory layout is performed.
for (const OutputSegment *seg : segments) {
@@ -1725,7 +1725,7 @@ void Writer::run() {
}
}
- for (auto &pair : config->exportedSymbols) {
+ for (auto &pair : ctx.arg.exportedSymbols) {
Symbol *sym = symtab->find(pair.first());
if (sym && sym->isDefined())
sym->forceExport = true;
@@ -1733,12 +1733,12 @@ void Writer::run() {
// Delay reporting errors about explicit exports until after
// addStartStopSymbols which can create optional symbols.
- for (auto &name : config->requiredExports) {
+ for (auto &name : ctx.arg.requiredExports) {
Symbol *sym = symtab->find(name);
if (!sym || !sym->isDefined()) {
- if (config->unresolvedSymbols == UnresolvedPolicy::ReportError)
+ if (ctx.arg.unresolvedSymbols == UnresolvedPolicy::ReportError)
error(Twine("symbol exported via --export not found: ") + name);
- if (config->unresolvedSymbols == UnresolvedPolicy::Warn)
+ if (ctx.arg.unresolvedSymbols == UnresolvedPolicy::Warn)
warn(Twine("symbol exported via --export not found: ") + name);
}
}
@@ -1750,7 +1750,7 @@ void Writer::run() {
// `__memory_base` import. Unless we support the extended const expression we
// can't do addition inside the constant expression, so we much combine the
// segments into a single one that can live at `__memory_base`.
- if (ctx.isPic && !config->extendedConst && !config->sharedMemory) {
+ if (ctx.isPic && !ctx.arg.extendedConst && !ctx.arg.sharedMemory) {
// In shared memory mode all data segments are passive and initialized
// via __wasm_init_memory.
log("-- combineOutputSegments");
@@ -1774,7 +1774,7 @@ void Writer::run() {
log("-- calculateInitFunctions");
calculateInitFunctions();
- if (!config->relocatable) {
+ if (!ctx.arg.relocatable) {
// Create linker synthesized functions
if (WasmSym::applyGlobalRelocs)
createApplyGlobalRelocationsFunction();
@@ -1793,7 +1793,7 @@ void Writer::run() {
// If the input contains a call to `__wasm_call_ctors`, either in one of
// the input objects or an explicit export from the command-line, we
// assume ctors and dtors are taken care of already.
- if (!config->relocatable && !ctx.isPic &&
+ if (!ctx.arg.relocatable && !ctx.isPic &&
!WasmSym::callCtors->isUsedInRegularObj &&
!WasmSym::callCtors->isExported()) {
log("-- createCommandExportWrappers");
@@ -1861,14 +1861,14 @@ void Writer::run() {
// Open a result file.
void Writer::openFile() {
- log("writing: " + config->outputFile);
+ log("writing: " + ctx.arg.outputFile);
Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
- FileOutputBuffer::create(config->outputFile, fileSize,
+ FileOutputBuffer::create(ctx.arg.outputFile, fileSize,
FileOutputBuffer::F_executable);
if (!bufferOrErr)
- error("failed to open " + config->outputFile + ": " +
+ error("failed to open " + ctx.arg.outputFile + ": " +
toString(bufferOrErr.takeError()));
else
buffer = std::move(*bufferOrErr);
More information about the llvm-commits
mailing list