[lld] da0b9db - [ELF] Replace config-> with ctx.arg. NFC

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 17 18:30:14 PDT 2024


Author: Fangrui Song
Date: 2024-09-17T18:30:10-07:00
New Revision: da0b9db26fe06cbdd2e3b3292645e0100fc237dc

URL: https://github.com/llvm/llvm-project/commit/da0b9db26fe06cbdd2e3b3292645e0100fc237dc
DIFF: https://github.com/llvm/llvm-project/commit/da0b9db26fe06cbdd2e3b3292645e0100fc237dc.diff

LOG: [ELF] Replace config-> with ctx.arg. NFC

Added: 
    

Modified: 
    lld/ELF/Driver.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index d50eae9c0144ae..e25db0e4951275 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -82,7 +82,7 @@ ConfigWrapper elf::config;
 Ctx elf::ctx;
 
 static void setConfigs(Ctx &ctx, opt::InputArgList &args);
-static void readConfigs(opt::InputArgList &args);
+static void readConfigs(Ctx &ctx, opt::InputArgList &args);
 
 void elf::errorOrWarn(const Twine &msg) {
   if (config->noinhibitExec)
@@ -669,7 +669,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
     }
   }
 
-  readConfigs(args);
+  readConfigs(ctx, args);
   checkZOptions(args);
 
   // The behavior of -v or --version is a bit strange, but this is
@@ -681,7 +681,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
 
   // Initialize time trace profiler.
   if (ctx.arg.timeTraceEnabled)
-    timeTraceProfilerInitialize(ctx.arg.timeTraceGranularity, config->progName);
+    timeTraceProfilerInitialize(ctx.arg.timeTraceGranularity, ctx.arg.progName);
 
   {
     llvm::TimeTraceScope timeScope("ExecuteLinker");
@@ -714,14 +714,14 @@ static std::string getRpath(opt::InputArgList &args) {
 
 // Determines what we should do if there are remaining unresolved
 // symbols after the name resolution.
-static void setUnresolvedSymbolPolicy(opt::InputArgList &args) {
+static void setUnresolvedSymbolPolicy(Ctx &ctx, opt::InputArgList &args) {
   UnresolvedPolicy errorOrWarn = args.hasFlag(OPT_error_unresolved_symbols,
                                               OPT_warn_unresolved_symbols, true)
                                      ? UnresolvedPolicy::ReportError
                                      : UnresolvedPolicy::Warn;
   // -shared implies --unresolved-symbols=ignore-all because missing
   // symbols are likely to be resolved at runtime.
-  bool diagRegular = !config->shared, diagShlib = !config->shared;
+  bool diagRegular = !ctx.arg.shared, diagShlib = !ctx.arg.shared;
 
   for (const opt::Arg *arg : args) {
     switch (arg->getOption().getID()) {
@@ -765,9 +765,9 @@ static void setUnresolvedSymbolPolicy(opt::InputArgList &args) {
     }
   }
 
-  config->unresolvedSymbols =
+  ctx.arg.unresolvedSymbols =
       diagRegular ? errorOrWarn : UnresolvedPolicy::Ignore;
-  config->unresolvedSymbolsInShlib =
+  ctx.arg.unresolvedSymbolsInShlib =
       diagShlib ? errorOrWarn : UnresolvedPolicy::Ignore;
 }
 
@@ -804,25 +804,25 @@ static DiscardPolicy getDiscard(opt::InputArgList &args) {
   return DiscardPolicy::None;
 }
 
-static StringRef getDynamicLinker(opt::InputArgList &args) {
+static StringRef getDynamicLinker(Ctx &ctx, opt::InputArgList &args) {
   auto *arg = args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker);
   if (!arg)
     return "";
   if (arg->getOption().getID() == OPT_no_dynamic_linker) {
     // --no-dynamic-linker suppresses undefined weak symbols in .dynsym
-    config->noDynamicLinker = true;
+    ctx.arg.noDynamicLinker = true;
     return "";
   }
   return arg->getValue();
 }
 
-static int getMemtagMode(opt::InputArgList &args) {
+static int getMemtagMode(Ctx &ctx, opt::InputArgList &args) {
   StringRef memtagModeArg = args.getLastArgValue(OPT_android_memtag_mode);
   if (memtagModeArg.empty()) {
-    if (config->androidMemtagStack)
+    if (ctx.arg.androidMemtagStack)
       warn("--android-memtag-mode is unspecified, leaving "
            "--android-memtag-stack a no-op");
-    else if (config->androidMemtagHeap)
+    else if (ctx.arg.androidMemtagHeap)
       warn("--android-memtag-mode is unspecified, leaving "
            "--android-memtag-heap a no-op");
     return ELF::NT_MEMTAG_LEVEL_NONE;
@@ -1247,140 +1247,141 @@ static bool remapInputs(StringRef line, const Twine &location) {
 }
 
 // Initializes Config members by the command line options.
-static void readConfigs(opt::InputArgList &args) {
+static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
   errorHandler().verbose = args.hasArg(OPT_verbose);
   errorHandler().vsDiagnostics =
       args.hasArg(OPT_visual_studio_diagnostics_format, false);
 
-  config->allowMultipleDefinition =
+  ctx.arg.allowMultipleDefinition =
       hasZOption(args, "muldefs") ||
       args.hasFlag(OPT_allow_multiple_definition,
                    OPT_no_allow_multiple_definition, false);
-  config->androidMemtagHeap =
+  ctx.arg.androidMemtagHeap =
       args.hasFlag(OPT_android_memtag_heap, OPT_no_android_memtag_heap, false);
-  config->androidMemtagStack = args.hasFlag(OPT_android_memtag_stack,
+  ctx.arg.androidMemtagStack = args.hasFlag(OPT_android_memtag_stack,
                                             OPT_no_android_memtag_stack, false);
-  config->fatLTOObjects =
+  ctx.arg.fatLTOObjects =
       args.hasFlag(OPT_fat_lto_objects, OPT_no_fat_lto_objects, false);
-  config->androidMemtagMode = getMemtagMode(args);
-  config->auxiliaryList = args::getStrings(args, OPT_auxiliary);
-  config->armBe8 = args.hasArg(OPT_be8);
+  ctx.arg.androidMemtagMode = getMemtagMode(ctx, args);
+  ctx.arg.auxiliaryList = args::getStrings(args, OPT_auxiliary);
+  ctx.arg.armBe8 = args.hasArg(OPT_be8);
   if (opt::Arg *arg = args.getLastArg(
           OPT_Bno_symbolic, OPT_Bsymbolic_non_weak_functions,
           OPT_Bsymbolic_functions, OPT_Bsymbolic_non_weak, OPT_Bsymbolic)) {
     if (arg->getOption().matches(OPT_Bsymbolic_non_weak_functions))
-      config->bsymbolic = BsymbolicKind::NonWeakFunctions;
+      ctx.arg.bsymbolic = BsymbolicKind::NonWeakFunctions;
     else if (arg->getOption().matches(OPT_Bsymbolic_functions))
-      config->bsymbolic = BsymbolicKind::Functions;
+      ctx.arg.bsymbolic = BsymbolicKind::Functions;
     else if (arg->getOption().matches(OPT_Bsymbolic_non_weak))
-      config->bsymbolic = BsymbolicKind::NonWeak;
+      ctx.arg.bsymbolic = BsymbolicKind::NonWeak;
     else if (arg->getOption().matches(OPT_Bsymbolic))
-      config->bsymbolic = BsymbolicKind::All;
+      ctx.arg.bsymbolic = BsymbolicKind::All;
   }
-  config->callGraphProfileSort = getCGProfileSortKind(args);
-  config->checkSections =
+  ctx.arg.callGraphProfileSort = getCGProfileSortKind(args);
+  ctx.arg.checkSections =
       args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
-  config->chroot = args.getLastArgValue(OPT_chroot);
+  ctx.arg.chroot = args.getLastArgValue(OPT_chroot);
   if (auto *arg = args.getLastArg(OPT_compress_debug_sections)) {
-    config->compressDebugSections =
+    ctx.arg.compressDebugSections =
         getCompressionType(arg->getValue(), "--compress-debug-sections");
   }
-  config->cref = args.hasArg(OPT_cref);
-  config->optimizeBBJumps =
+  ctx.arg.cref = args.hasArg(OPT_cref);
+  ctx.arg.optimizeBBJumps =
       args.hasFlag(OPT_optimize_bb_jumps, OPT_no_optimize_bb_jumps, false);
-  config->debugNames = args.hasFlag(OPT_debug_names, OPT_no_debug_names, false);
-  config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
-  config->dependencyFile = args.getLastArgValue(OPT_dependency_file);
-  config->dependentLibraries = args.hasFlag(OPT_dependent_libraries, OPT_no_dependent_libraries, true);
-  config->disableVerify = args.hasArg(OPT_disable_verify);
-  config->discard = getDiscard(args);
-  config->dwoDir = args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
-  config->dynamicLinker = getDynamicLinker(args);
-  config->ehFrameHdr =
+  ctx.arg.debugNames = args.hasFlag(OPT_debug_names, OPT_no_debug_names, false);
+  ctx.arg.demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
+  ctx.arg.dependencyFile = args.getLastArgValue(OPT_dependency_file);
+  ctx.arg.dependentLibraries =
+      args.hasFlag(OPT_dependent_libraries, OPT_no_dependent_libraries, true);
+  ctx.arg.disableVerify = args.hasArg(OPT_disable_verify);
+  ctx.arg.discard = getDiscard(args);
+  ctx.arg.dwoDir = args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
+  ctx.arg.dynamicLinker = getDynamicLinker(ctx, args);
+  ctx.arg.ehFrameHdr =
       args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
-  config->emitLLVM = args.hasArg(OPT_lto_emit_llvm);
-  config->emitRelocs = args.hasArg(OPT_emit_relocs);
-  config->enableNewDtags =
+  ctx.arg.emitLLVM = args.hasArg(OPT_lto_emit_llvm);
+  ctx.arg.emitRelocs = args.hasArg(OPT_emit_relocs);
+  ctx.arg.enableNewDtags =
       args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
-  config->enableNonContiguousRegions =
+  ctx.arg.enableNonContiguousRegions =
       args.hasArg(OPT_enable_non_contiguous_regions);
-  config->entry = args.getLastArgValue(OPT_entry);
+  ctx.arg.entry = args.getLastArgValue(OPT_entry);
 
   errorHandler().errorHandlingScript =
       args.getLastArgValue(OPT_error_handling_script);
 
-  config->executeOnly =
+  ctx.arg.executeOnly =
       args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
-  config->exportDynamic =
+  ctx.arg.exportDynamic =
       args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false) ||
       args.hasArg(OPT_shared);
-  config->filterList = args::getStrings(args, OPT_filter);
-  config->fini = args.getLastArgValue(OPT_fini, "_fini");
-  config->fixCortexA53Errata843419 = args.hasArg(OPT_fix_cortex_a53_843419) &&
-                                     !args.hasArg(OPT_relocatable);
-  config->cmseImplib = args.hasArg(OPT_cmse_implib);
-  config->cmseInputLib = args.getLastArgValue(OPT_in_implib);
-  config->cmseOutputLib = args.getLastArgValue(OPT_out_implib);
-  config->fixCortexA8 =
+  ctx.arg.filterList = args::getStrings(args, OPT_filter);
+  ctx.arg.fini = args.getLastArgValue(OPT_fini, "_fini");
+  ctx.arg.fixCortexA53Errata843419 =
+      args.hasArg(OPT_fix_cortex_a53_843419) && !args.hasArg(OPT_relocatable);
+  ctx.arg.cmseImplib = args.hasArg(OPT_cmse_implib);
+  ctx.arg.cmseInputLib = args.getLastArgValue(OPT_in_implib);
+  ctx.arg.cmseOutputLib = args.getLastArgValue(OPT_out_implib);
+  ctx.arg.fixCortexA8 =
       args.hasArg(OPT_fix_cortex_a8) && !args.hasArg(OPT_relocatable);
-  config->fortranCommon =
+  ctx.arg.fortranCommon =
       args.hasFlag(OPT_fortran_common, OPT_no_fortran_common, false);
-  config->gcSections = args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
-  config->gnuUnique = args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true);
-  config->gdbIndex = args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
-  config->icf = getICF(args);
-  config->ignoreDataAddressEquality =
+  ctx.arg.gcSections = args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
+  ctx.arg.gnuUnique = args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true);
+  ctx.arg.gdbIndex = args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
+  ctx.arg.icf = getICF(args);
+  ctx.arg.ignoreDataAddressEquality =
       args.hasArg(OPT_ignore_data_address_equality);
-  config->ignoreFunctionAddressEquality =
+  ctx.arg.ignoreFunctionAddressEquality =
       args.hasArg(OPT_ignore_function_address_equality);
-  config->init = args.getLastArgValue(OPT_init, "_init");
-  config->ltoAAPipeline = args.getLastArgValue(OPT_lto_aa_pipeline);
-  config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate);
-  config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file);
-  config->ltoPGOWarnMismatch = args.hasFlag(OPT_lto_pgo_warn_mismatch,
+  ctx.arg.init = args.getLastArgValue(OPT_init, "_init");
+  ctx.arg.ltoAAPipeline = args.getLastArgValue(OPT_lto_aa_pipeline);
+  ctx.arg.ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate);
+  ctx.arg.ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file);
+  ctx.arg.ltoPGOWarnMismatch = args.hasFlag(OPT_lto_pgo_warn_mismatch,
                                             OPT_no_lto_pgo_warn_mismatch, true);
-  config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
-  config->ltoEmitAsm = args.hasArg(OPT_lto_emit_asm);
-  config->ltoNewPmPasses = args.getLastArgValue(OPT_lto_newpm_passes);
-  config->ltoWholeProgramVisibility =
+  ctx.arg.ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
+  ctx.arg.ltoEmitAsm = args.hasArg(OPT_lto_emit_asm);
+  ctx.arg.ltoNewPmPasses = args.getLastArgValue(OPT_lto_newpm_passes);
+  ctx.arg.ltoWholeProgramVisibility =
       args.hasFlag(OPT_lto_whole_program_visibility,
                    OPT_no_lto_whole_program_visibility, false);
-  config->ltoValidateAllVtablesHaveTypeInfos =
+  ctx.arg.ltoValidateAllVtablesHaveTypeInfos =
       args.hasFlag(OPT_lto_validate_all_vtables_have_type_infos,
                    OPT_no_lto_validate_all_vtables_have_type_infos, false);
-  config->ltoo = args::getInteger(args, OPT_lto_O, 2);
-  if (config->ltoo > 3)
-    error("invalid optimization level for LTO: " + Twine(config->ltoo));
+  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->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
-  config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
-  config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
-  config->ltoBBAddrMap =
+  ctx.arg.ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
+  ctx.arg.ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
+  ctx.arg.ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
+  ctx.arg.ltoBBAddrMap =
       args.hasFlag(OPT_lto_basic_block_address_map,
                    OPT_no_lto_basic_block_address_map, false);
-  config->ltoBasicBlockSections =
+  ctx.arg.ltoBasicBlockSections =
       args.getLastArgValue(OPT_lto_basic_block_sections);
-  config->ltoUniqueBasicBlockSectionNames =
+  ctx.arg.ltoUniqueBasicBlockSectionNames =
       args.hasFlag(OPT_lto_unique_basic_block_section_names,
                    OPT_no_lto_unique_basic_block_section_names, false);
-  config->mapFile = args.getLastArgValue(OPT_Map);
-  config->mipsGotSize = args::getInteger(args, OPT_mips_got_size, 0xfff0);
-  config->mergeArmExidx =
+  ctx.arg.mapFile = args.getLastArgValue(OPT_Map);
+  ctx.arg.mipsGotSize = args::getInteger(args, OPT_mips_got_size, 0xfff0);
+  ctx.arg.mergeArmExidx =
       args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true);
-  config->mmapOutputFile =
+  ctx.arg.mmapOutputFile =
       args.hasFlag(OPT_mmap_output_file, OPT_no_mmap_output_file, true);
-  config->nmagic = args.hasFlag(OPT_nmagic, OPT_no_nmagic, false);
-  config->noinhibitExec = args.hasArg(OPT_noinhibit_exec);
-  config->nostdlib = args.hasArg(OPT_nostdlib);
-  config->oFormatBinary = isOutputFormatBinary(args);
-  config->omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
-  config->optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
-  config->optStatsFilename = args.getLastArgValue(OPT_plugin_opt_stats_file);
+  ctx.arg.nmagic = args.hasFlag(OPT_nmagic, OPT_no_nmagic, false);
+  ctx.arg.noinhibitExec = args.hasArg(OPT_noinhibit_exec);
+  ctx.arg.nostdlib = args.hasArg(OPT_nostdlib);
+  ctx.arg.oFormatBinary = isOutputFormatBinary(args);
+  ctx.arg.omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
+  ctx.arg.optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
+  ctx.arg.optStatsFilename = args.getLastArgValue(OPT_plugin_opt_stats_file);
 
   // Parse remarks hotness threshold. Valid value is either integer or 'auto'.
   if (auto *arg = args.getLastArg(OPT_opt_remarks_hotness_threshold)) {
@@ -1389,77 +1390,77 @@ static void readConfigs(opt::InputArgList &args) {
       error(arg->getSpelling() + ": invalid argument '" + arg->getValue() +
             "', only integer or 'auto' is supported");
     else
-      config->optRemarksHotnessThreshold = *resultOrErr;
-  }
-
-  config->optRemarksPasses = args.getLastArgValue(OPT_opt_remarks_passes);
-  config->optRemarksWithHotness = args.hasArg(OPT_opt_remarks_with_hotness);
-  config->optRemarksFormat = args.getLastArgValue(OPT_opt_remarks_format);
-  config->optimize = args::getInteger(args, OPT_O, 1);
-  config->orphanHandling = getOrphanHandling(args);
-  config->outputFile = args.getLastArgValue(OPT_o);
-  config->packageMetadata = args.getLastArgValue(OPT_package_metadata);
-  config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
-  config->printIcfSections =
+      ctx.arg.optRemarksHotnessThreshold = *resultOrErr;
+  }
+
+  ctx.arg.optRemarksPasses = args.getLastArgValue(OPT_opt_remarks_passes);
+  ctx.arg.optRemarksWithHotness = args.hasArg(OPT_opt_remarks_with_hotness);
+  ctx.arg.optRemarksFormat = args.getLastArgValue(OPT_opt_remarks_format);
+  ctx.arg.optimize = args::getInteger(args, OPT_O, 1);
+  ctx.arg.orphanHandling = getOrphanHandling(args);
+  ctx.arg.outputFile = args.getLastArgValue(OPT_o);
+  ctx.arg.packageMetadata = args.getLastArgValue(OPT_package_metadata);
+  ctx.arg.pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
+  ctx.arg.printIcfSections =
       args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
-  config->printGcSections =
+  ctx.arg.printGcSections =
       args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
-  config->printMemoryUsage = args.hasArg(OPT_print_memory_usage);
-  config->printArchiveStats = args.getLastArgValue(OPT_print_archive_stats);
-  config->printSymbolOrder =
-      args.getLastArgValue(OPT_print_symbol_order);
-  config->rejectMismatch = !args.hasArg(OPT_no_warn_mismatch);
-  config->relax = args.hasFlag(OPT_relax, OPT_no_relax, true);
-  config->relaxGP = args.hasFlag(OPT_relax_gp, OPT_no_relax_gp, false);
-  config->rpath = getRpath(args);
-  config->relocatable = args.hasArg(OPT_relocatable);
-  config->resolveGroups =
+  ctx.arg.printMemoryUsage = args.hasArg(OPT_print_memory_usage);
+  ctx.arg.printArchiveStats = args.getLastArgValue(OPT_print_archive_stats);
+  ctx.arg.printSymbolOrder = args.getLastArgValue(OPT_print_symbol_order);
+  ctx.arg.rejectMismatch = !args.hasArg(OPT_no_warn_mismatch);
+  ctx.arg.relax = args.hasFlag(OPT_relax, OPT_no_relax, true);
+  ctx.arg.relaxGP = args.hasFlag(OPT_relax_gp, OPT_no_relax_gp, false);
+  ctx.arg.rpath = getRpath(args);
+  ctx.arg.relocatable = args.hasArg(OPT_relocatable);
+  ctx.arg.resolveGroups =
       !args.hasArg(OPT_relocatable) || args.hasArg(OPT_force_group_allocation);
 
   if (args.hasArg(OPT_save_temps)) {
     // --save-temps implies saving all temps.
     for (const char *s : saveTempsValues)
-      config->saveTempsArgs.insert(s);
+      ctx.arg.saveTempsArgs.insert(s);
   } else {
     for (auto *arg : args.filtered(OPT_save_temps_eq)) {
       StringRef s = arg->getValue();
       if (llvm::is_contained(saveTempsValues, s))
-        config->saveTempsArgs.insert(s);
+        ctx.arg.saveTempsArgs.insert(s);
       else
         error("unknown --save-temps value: " + s);
     }
   }
 
-  config->searchPaths = args::getStrings(args, OPT_library_path);
-  config->sectionStartMap = getSectionStartMap(args);
-  config->shared = args.hasArg(OPT_shared);
-  config->singleRoRx = !args.hasFlag(OPT_rosegment, OPT_no_rosegment, true);
-  config->soName = args.getLastArgValue(OPT_soname);
-  config->sortSection = getSortSection(args);
-  config->splitStackAdjustSize = args::getInteger(args, OPT_split_stack_adjust_size, 16384);
-  config->zSectionHeader =
+  ctx.arg.searchPaths = args::getStrings(args, OPT_library_path);
+  ctx.arg.sectionStartMap = getSectionStartMap(args);
+  ctx.arg.shared = args.hasArg(OPT_shared);
+  ctx.arg.singleRoRx = !args.hasFlag(OPT_rosegment, OPT_no_rosegment, true);
+  ctx.arg.soName = args.getLastArgValue(OPT_soname);
+  ctx.arg.sortSection = getSortSection(args);
+  ctx.arg.splitStackAdjustSize =
+      args::getInteger(args, OPT_split_stack_adjust_size, 16384);
+  ctx.arg.zSectionHeader =
       getZFlag(args, "sectionheader", "nosectionheader", true);
-  config->strip = getStrip(args); // needs zSectionHeader
-  config->sysroot = args.getLastArgValue(OPT_sysroot);
-  config->target1Rel = args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
-  config->target2 = getTarget2(args);
-  config->thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
-  config->thinLTOCachePolicy = CHECK(
+  ctx.arg.strip = getStrip(args); // needs zSectionHeader
+  ctx.arg.sysroot = args.getLastArgValue(OPT_sysroot);
+  ctx.arg.target1Rel = args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
+  ctx.arg.target2 = getTarget2(args);
+  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");
@@ -1467,69 +1468,69 @@ 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->thinLTOModulesToCompile =
+  ctx.arg.thinLTOModulesToCompile =
       args::getStrings(args, OPT_thinlto_single_module_eq);
-  config->timeTraceEnabled = args.hasArg(OPT_time_trace_eq);
-  config->timeTraceGranularity =
+  ctx.arg.timeTraceEnabled = args.hasArg(OPT_time_trace_eq);
+  ctx.arg.timeTraceGranularity =
       args::getInteger(args, OPT_time_trace_granularity, 500);
-  config->trace = args.hasArg(OPT_trace);
-  config->undefined = args::getStrings(args, OPT_undefined);
-  config->undefinedVersion =
+  ctx.arg.trace = args.hasArg(OPT_trace);
+  ctx.arg.undefined = args::getStrings(args, OPT_undefined);
+  ctx.arg.undefinedVersion =
       args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, false);
-  config->unique = args.hasArg(OPT_unique);
-  config->useAndroidRelrTags = args.hasFlag(
+  ctx.arg.unique = args.hasArg(OPT_unique);
+  ctx.arg.useAndroidRelrTags = args.hasFlag(
       OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false);
-  config->warnBackrefs =
+  ctx.arg.warnBackrefs =
       args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
-  config->warnCommon = args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
-  config->warnSymbolOrdering =
+  ctx.arg.warnCommon = args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
+  ctx.arg.warnSymbolOrdering =
       args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
-  config->whyExtract = args.getLastArgValue(OPT_why_extract);
-  config->zCombreloc = getZFlag(args, "combreloc", "nocombreloc", true);
-  config->zCopyreloc = getZFlag(args, "copyreloc", "nocopyreloc", true);
-  config->zForceBti = hasZOption(args, "force-bti");
-  config->zForceIbt = hasZOption(args, "force-ibt");
-  config->zGcs = getZGcs(args);
-  config->zGlobal = hasZOption(args, "global");
-  config->zGnustack = getZGnuStack(args);
-  config->zHazardplt = hasZOption(args, "hazardplt");
-  config->zIfuncNoplt = hasZOption(args, "ifunc-noplt");
-  config->zInitfirst = hasZOption(args, "initfirst");
-  config->zInterpose = hasZOption(args, "interpose");
-  config->zKeepTextSectionPrefix = getZFlag(
+  ctx.arg.whyExtract = args.getLastArgValue(OPT_why_extract);
+  ctx.arg.zCombreloc = getZFlag(args, "combreloc", "nocombreloc", true);
+  ctx.arg.zCopyreloc = getZFlag(args, "copyreloc", "nocopyreloc", true);
+  ctx.arg.zForceBti = hasZOption(args, "force-bti");
+  ctx.arg.zForceIbt = hasZOption(args, "force-ibt");
+  ctx.arg.zGcs = getZGcs(args);
+  ctx.arg.zGlobal = hasZOption(args, "global");
+  ctx.arg.zGnustack = getZGnuStack(args);
+  ctx.arg.zHazardplt = hasZOption(args, "hazardplt");
+  ctx.arg.zIfuncNoplt = hasZOption(args, "ifunc-noplt");
+  ctx.arg.zInitfirst = hasZOption(args, "initfirst");
+  ctx.arg.zInterpose = hasZOption(args, "interpose");
+  ctx.arg.zKeepTextSectionPrefix = getZFlag(
       args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
-  config->zLrodataAfterBss =
+  ctx.arg.zLrodataAfterBss =
       getZFlag(args, "lrodata-after-bss", "nolrodata-after-bss", false);
-  config->zNodefaultlib = hasZOption(args, "nodefaultlib");
-  config->zNodelete = hasZOption(args, "nodelete");
-  config->zNodlopen = hasZOption(args, "nodlopen");
-  config->zNow = getZFlag(args, "now", "lazy", false);
-  config->zOrigin = hasZOption(args, "origin");
-  config->zPacPlt = hasZOption(args, "pac-plt");
-  config->zRelro = getZFlag(args, "relro", "norelro", true);
-  config->zRetpolineplt = hasZOption(args, "retpolineplt");
-  config->zRodynamic = hasZOption(args, "rodynamic");
-  config->zSeparate = getZSeparate(args);
-  config->zShstk = hasZOption(args, "shstk");
-  config->zStackSize = args::getZOptionValue(args, OPT_z, "stack-size", 0);
-  config->zStartStopGC =
+  ctx.arg.zNodefaultlib = hasZOption(args, "nodefaultlib");
+  ctx.arg.zNodelete = hasZOption(args, "nodelete");
+  ctx.arg.zNodlopen = hasZOption(args, "nodlopen");
+  ctx.arg.zNow = getZFlag(args, "now", "lazy", false);
+  ctx.arg.zOrigin = hasZOption(args, "origin");
+  ctx.arg.zPacPlt = hasZOption(args, "pac-plt");
+  ctx.arg.zRelro = getZFlag(args, "relro", "norelro", true);
+  ctx.arg.zRetpolineplt = hasZOption(args, "retpolineplt");
+  ctx.arg.zRodynamic = hasZOption(args, "rodynamic");
+  ctx.arg.zSeparate = getZSeparate(args);
+  ctx.arg.zShstk = hasZOption(args, "shstk");
+  ctx.arg.zStackSize = args::getZOptionValue(args, OPT_z, "stack-size", 0);
+  ctx.arg.zStartStopGC =
       getZFlag(args, "start-stop-gc", "nostart-stop-gc", true);
-  config->zStartStopVisibility = getZStartStopVisibility(args);
-  config->zText = getZFlag(args, "text", "notext", true);
-  config->zWxneeded = hasZOption(args, "wxneeded");
-  setUnresolvedSymbolPolicy(args);
-  config->power10Stubs = args.getLastArgValue(OPT_power10_stubs_eq) != "no";
+  ctx.arg.zStartStopVisibility = getZStartStopVisibility(args);
+  ctx.arg.zText = getZFlag(args, "text", "notext", true);
+  ctx.arg.zWxneeded = hasZOption(args, "wxneeded");
+  setUnresolvedSymbolPolicy(ctx, args);
+  ctx.arg.power10Stubs = args.getLastArgValue(OPT_power10_stubs_eq) != "no";
 
   if (opt::Arg *arg = args.getLastArg(OPT_eb, OPT_el)) {
     if (arg->getOption().matches(OPT_eb))
-      config->optEB = true;
+      ctx.arg.optEB = true;
     else
-      config->optEL = true;
+      ctx.arg.optEL = true;
   }
 
   for (opt::Arg *arg : args.filtered(OPT_remap_inputs)) {
@@ -1560,15 +1561,15 @@ static void readConfigs(opt::InputArgList &args) {
     if (!to_integer(kv.second, v))
       error(errPrefix + "expected an integer, but got '" + kv.second + "'");
     else if (Expected<GlobPattern> pat = GlobPattern::create(kv.first))
-      config->shuffleSections.emplace_back(std::move(*pat), uint32_t(v));
+      ctx.arg.shuffleSections.emplace_back(std::move(*pat), uint32_t(v));
     else
       error(errPrefix + toString(pat.takeError()) + ": " + kv.first);
   }
 
-  auto reports = {std::make_pair("bti-report", &config->zBtiReport),
-                  std::make_pair("cet-report", &config->zCetReport),
-                  std::make_pair("gcs-report", &config->zGcsReport),
-                  std::make_pair("pauth-report", &config->zPauthReport)};
+  auto reports = {std::make_pair("bti-report", &ctx.arg.zBtiReport),
+                  std::make_pair("cet-report", &ctx.arg.zCetReport),
+                  std::make_pair("gcs-report", &ctx.arg.zGcsReport),
+                  std::make_pair("pauth-report", &ctx.arg.zPauthReport)};
   for (opt::Arg *arg : args.filtered(OPT_z)) {
     std::pair<StringRef, StringRef> option =
         StringRef(arg->getValue()).split('=');
@@ -1603,7 +1604,7 @@ static void readConfigs(opt::InputArgList &args) {
             levelStr + "'");
     }
     if (Expected<GlobPattern> pat = GlobPattern::create(fields[0])) {
-      config->compressSections.emplace_back(std::move(*pat), type, level);
+      ctx.arg.compressSections.emplace_back(std::move(*pat), type, level);
     } else {
       error(arg->getSpelling() + ": " + toString(pat.takeError()));
       continue;
@@ -1627,7 +1628,7 @@ static void readConfigs(opt::InputArgList &args) {
       error(errPrefix + "expected a non-negative integer, but got '" +
             kv.second + "'");
     else if (Expected<GlobPattern> pat = GlobPattern::create(kv.first))
-      config->deadRelocInNonAlloc.emplace_back(std::move(*pat), v);
+      ctx.arg.deadRelocInNonAlloc.emplace_back(std::move(*pat), v);
     else
       error(errPrefix + toString(pat.takeError()) + ": " + kv.first);
   }
@@ -1653,23 +1654,23 @@ static void readConfigs(opt::InputArgList &args) {
             "'");
   }
 
-  config->passPlugins = args::getStrings(args, OPT_load_pass_plugins);
+  ctx.arg.passPlugins = args::getStrings(args, OPT_load_pass_plugins);
 
   // Parse -mllvm options.
   for (const auto *arg : args.filtered(OPT_mllvm)) {
     parseClangOption(arg->getValue(), arg->getSpelling());
-    config->mllvmOpts.emplace_back(arg->getValue());
+    ctx.arg.mllvmOpts.emplace_back(arg->getValue());
   }
 
-  config->ltoKind = LtoKind::Default;
+  ctx.arg.ltoKind = LtoKind::Default;
   if (auto *arg = args.getLastArg(OPT_lto)) {
     StringRef s = arg->getValue();
     if (s == "thin")
-      config->ltoKind = LtoKind::UnifiedThin;
+      ctx.arg.ltoKind = LtoKind::UnifiedThin;
     else if (s == "full")
-      config->ltoKind = LtoKind::UnifiedRegular;
+      ctx.arg.ltoKind = LtoKind::UnifiedRegular;
     else if (s == "default")
-      config->ltoKind = LtoKind::Default;
+      ctx.arg.ltoKind = LtoKind::Default;
     else
       error("unknown LTO mode: " + s);
   }
@@ -1685,21 +1686,21 @@ 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;
   } else if (parallel::strategy.compute_thread_count() > 16) {
     log("set maximum concurrency to 16, specify --threads= to change");
     parallel::strategy = hardware_concurrency(16);
   }
   if (auto *arg = args.getLastArg(OPT_thinlto_jobs_eq))
-    config->thinLTOJobs = arg->getValue();
-  config->threadCount = parallel::strategy.compute_thread_count();
+    ctx.arg.thinLTOJobs = arg->getValue();
+  ctx.arg.threadCount = parallel::strategy.compute_thread_count();
 
-  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->splitStackAdjustSize < 0)
+  if (ctx.arg.splitStackAdjustSize < 0)
     error("--split-stack-adjust-size: size must be >= 0");
 
   // The text segment is traditionally the first segment, whose address equals
@@ -1713,42 +1714,42 @@ static void readConfigs(opt::InputArgList &args) {
   // Parse ELF{32,64}{LE,BE} and CPU type.
   if (auto *arg = args.getLastArg(OPT_m)) {
     StringRef s = arg->getValue();
-    std::tie(config->ekind, config->emachine, config->osabi) =
+    std::tie(ctx.arg.ekind, ctx.arg.emachine, ctx.arg.osabi) =
         parseEmulation(s);
-    config->mipsN32Abi =
+    ctx.arg.mipsN32Abi =
         (s.starts_with("elf32btsmipn32") || s.starts_with("elf32ltsmipn32"));
-    config->emulation = s;
+    ctx.arg.emulation = s;
   }
 
   // Parse --hash-style={sysv,gnu,both}.
   if (auto *arg = args.getLastArg(OPT_hash_style)) {
     StringRef s = arg->getValue();
     if (s == "sysv")
-      config->sysvHash = true;
+      ctx.arg.sysvHash = true;
     else if (s == "gnu")
-      config->gnuHash = true;
+      ctx.arg.gnuHash = true;
     else if (s == "both")
-      config->sysvHash = config->gnuHash = true;
+      ctx.arg.sysvHash = ctx.arg.gnuHash = true;
     else
       error("unknown --hash-style: " + s);
   }
 
   if (args.hasArg(OPT_print_map))
-    config->mapFile = "-";
+    ctx.arg.mapFile = "-";
 
   // Page alignment can be disabled by the -n (--nmagic) and -N (--omagic).
   // As PT_GNU_RELRO relies on Paging, do not create it when we have disabled
   // it. Also disable RELRO for -r.
-  if (config->nmagic || config->omagic || config->relocatable)
-    config->zRelro = false;
+  if (ctx.arg.nmagic || ctx.arg.omagic || ctx.arg.relocatable)
+    ctx.arg.zRelro = false;
 
-  std::tie(config->buildId, config->buildIdVector) = getBuildId(args);
+  std::tie(ctx.arg.buildId, ctx.arg.buildIdVector) = getBuildId(args);
 
   if (getZFlag(args, "pack-relative-relocs", "nopack-relative-relocs", false)) {
-    config->relrGlibc = true;
-    config->relrPackDynRelocs = true;
+    ctx.arg.relrGlibc = true;
+    ctx.arg.relrPackDynRelocs = true;
   } else {
-    std::tie(config->androidPackDynRelocs, config->relrPackDynRelocs) =
+    std::tie(ctx.arg.androidPackDynRelocs, ctx.arg.relrPackDynRelocs) =
         getPackDynRelocs(args);
   }
 
@@ -1757,34 +1758,34 @@ static void readConfigs(opt::InputArgList &args) {
       error("--symbol-ordering-file and --call-graph-order-file "
             "may not be used together");
     if (std::optional<MemoryBufferRef> buffer = readFile(arg->getValue())) {
-      config->symbolOrderingFile = getSymbolOrderingFile(*buffer);
+      ctx.arg.symbolOrderingFile = getSymbolOrderingFile(*buffer);
       // Also need to disable CallGraphProfileSort to prevent
       // LLD order symbols with CGProfile
-      config->callGraphProfileSort = CGProfileSortKind::None;
+      ctx.arg.callGraphProfileSort = CGProfileSortKind::None;
     }
   }
 
-  assert(config->versionDefinitions.empty());
-  config->versionDefinitions.push_back(
+  assert(ctx.arg.versionDefinitions.empty());
+  ctx.arg.versionDefinitions.push_back(
       {"local", (uint16_t)VER_NDX_LOCAL, {}, {}});
-  config->versionDefinitions.push_back(
+  ctx.arg.versionDefinitions.push_back(
       {"global", (uint16_t)VER_NDX_GLOBAL, {}, {}});
 
   // If --retain-symbol-file is used, we'll keep only the symbols listed in
   // the file and discard all others.
   if (auto *arg = args.getLastArg(OPT_retain_symbols_file)) {
-    config->versionDefinitions[VER_NDX_LOCAL].nonLocalPatterns.push_back(
+    ctx.arg.versionDefinitions[VER_NDX_LOCAL].nonLocalPatterns.push_back(
         {"*", /*isExternCpp=*/false, /*hasWildcard=*/true});
     if (std::optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
       for (StringRef s : args::getLines(*buffer))
-        config->versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(
+        ctx.arg.versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(
             {s, /*isExternCpp=*/false, /*hasWildcard=*/false});
   }
 
   for (opt::Arg *arg : args.filtered(OPT_warn_backrefs_exclude)) {
     StringRef pattern(arg->getValue());
     if (Expected<GlobPattern> pat = GlobPattern::create(pattern))
-      config->warnBackrefsExclude.push_back(std::move(*pat));
+      ctx.arg.warnBackrefsExclude.push_back(std::move(*pat));
     else
       error(arg->getSpelling() + ": " + toString(pat.takeError()) + ": " +
             pattern);
@@ -1796,15 +1797,15 @@ static void readConfigs(opt::InputArgList &args) {
   // even if other options express a symbolic intention: -Bsymbolic,
   // -Bsymbolic-functions (if STT_FUNC), --dynamic-list.
   for (auto *arg : args.filtered(OPT_export_dynamic_symbol))
-    config->dynamicList.push_back(
+    ctx.arg.dynamicList.push_back(
         {arg->getValue(), /*isExternCpp=*/false,
          /*hasWildcard=*/hasWildcard(arg->getValue())});
 
   // --export-dynamic-symbol-list specifies a list of --export-dynamic-symbol
   // patterns. --dynamic-list is --export-dynamic-symbol-list plus -Bsymbolic
   // like semantics.
-  config->symbolic =
-      config->bsymbolic == BsymbolicKind::All || args.hasArg(OPT_dynamic_list);
+  ctx.arg.symbolic =
+      ctx.arg.bsymbolic == BsymbolicKind::All || args.hasArg(OPT_dynamic_list);
   for (auto *arg :
        args.filtered(OPT_dynamic_list, OPT_export_dynamic_symbol_list))
     if (std::optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
@@ -2067,14 +2068,14 @@ void LinkerDriver::inferMachineType() {
 
 // Parse -z max-page-size=<value>. The default value is defined by
 // each target.
-static uint64_t getMaxPageSize(opt::InputArgList &args) {
+static uint64_t getMaxPageSize(Ctx &ctx, opt::InputArgList &args) {
   uint64_t val = args::getZOptionValue(args, OPT_z, "max-page-size",
                                        ctx.target->defaultMaxPageSize);
   if (!isPowerOf2_64(val)) {
     error("max-page-size: value isn't a power of 2");
     return ctx.target->defaultMaxPageSize;
   }
-  if (config->nmagic || config->omagic) {
+  if (ctx.arg.nmagic || ctx.arg.omagic) {
     if (val != ctx.target->defaultMaxPageSize)
       warn("-z max-page-size set, but paging disabled by omagic or nmagic");
     return 1;
@@ -2084,7 +2085,7 @@ static uint64_t getMaxPageSize(opt::InputArgList &args) {
 
 // Parse -z common-page-size=<value>. The default value is defined by
 // each target.
-static uint64_t getCommonPageSize(opt::InputArgList &args) {
+static uint64_t getCommonPageSize(Ctx &ctx, opt::InputArgList &args) {
   uint64_t val = args::getZOptionValue(args, OPT_z, "common-page-size",
                                        ctx.target->defaultCommonPageSize);
   if (!isPowerOf2_64(val)) {
@@ -2103,7 +2104,7 @@ static uint64_t getCommonPageSize(opt::InputArgList &args) {
 }
 
 // Parses --image-base option.
-static std::optional<uint64_t> getImageBase(opt::InputArgList &args) {
+static std::optional<uint64_t> getImageBase(Ctx &ctx, opt::InputArgList &args) {
   // Because we are using "Config->maxPageSize" here, this function has to be
   // called after the variable is initialized.
   auto *arg = args.getLastArg(OPT_image_base);
@@ -2116,7 +2117,7 @@ static std::optional<uint64_t> getImageBase(opt::InputArgList &args) {
     error("--image-base: number expected, but got " + s);
     return 0;
   }
-  if ((v % config->maxPageSize) != 0)
+  if ((v % ctx.arg.maxPageSize) != 0)
     warn("--image-base: address isn't multiple of page size: " + s);
   return v;
 }
@@ -2169,7 +2170,7 @@ static void excludeLibs(opt::InputArgList &args) {
 }
 
 // Force Sym to be entered in the output.
-static void handleUndefined(Symbol *sym, const char *option) {
+static void handleUndefined(Ctx &ctx, Symbol *sym, const char *option) {
   // Since a symbol may not be used inside the program, LTO may
   // eliminate it. Mark the symbol as "used" to prevent it.
   sym->isUsedInRegularObj = true;
@@ -2177,14 +2178,14 @@ static void handleUndefined(Symbol *sym, const char *option) {
   if (!sym->isLazy())
     return;
   sym->extract();
-  if (!config->whyExtract.empty())
+  if (!ctx.arg.whyExtract.empty())
     ctx.whyExtractRecords.emplace_back(option, sym->file, *sym);
 }
 
 // As an extension to GNU linkers, lld supports a variant of `-u`
 // which accepts wildcard patterns. All symbols that match a given
 // pattern are handled as if they were given by `-u`.
-static void handleUndefinedGlob(StringRef arg) {
+static void handleUndefinedGlob(Ctx &ctx, StringRef arg) {
   Expected<GlobPattern> pat = GlobPattern::create(arg);
   if (!pat) {
     error("--undefined-glob: " + toString(pat.takeError()) + ": " + arg);
@@ -2199,26 +2200,26 @@ static void handleUndefinedGlob(StringRef arg) {
       syms.push_back(sym);
 
   for (Symbol *sym : syms)
-    handleUndefined(sym, "--undefined-glob");
+    handleUndefined(ctx, sym, "--undefined-glob");
 }
 
-static void handleLibcall(StringRef name) {
+static void handleLibcall(Ctx &ctx, StringRef name) {
   Symbol *sym = symtab.find(name);
   if (sym && sym->isLazy() && isa<BitcodeFile>(sym->file)) {
-    if (!config->whyExtract.empty())
+    if (!ctx.arg.whyExtract.empty())
       ctx.whyExtractRecords.emplace_back("<libcall>", sym->file, *sym);
     sym->extract();
   }
 }
 
-static void writeArchiveStats() {
-  if (config->printArchiveStats.empty())
+static void writeArchiveStats(Ctx &ctx) {
+  if (ctx.arg.printArchiveStats.empty())
     return;
 
   std::error_code ec;
-  raw_fd_ostream os = ctx.openAuxiliaryFile(config->printArchiveStats, ec);
+  raw_fd_ostream os = ctx.openAuxiliaryFile(ctx.arg.printArchiveStats, ec);
   if (ec) {
-    error("--print-archive-stats=: cannot open " + config->printArchiveStats +
+    error("--print-archive-stats=: cannot open " + ctx.arg.printArchiveStats +
           ": " + ec.message());
     return;
   }
@@ -2241,14 +2242,14 @@ static void writeArchiveStats() {
   }
 }
 
-static void writeWhyExtract() {
-  if (config->whyExtract.empty())
+static void writeWhyExtract(Ctx &ctx) {
+  if (ctx.arg.whyExtract.empty())
     return;
 
   std::error_code ec;
-  raw_fd_ostream os = ctx.openAuxiliaryFile(config->whyExtract, ec);
+  raw_fd_ostream os = ctx.openAuxiliaryFile(ctx.arg.whyExtract, ec);
   if (ec) {
-    error("cannot open --why-extract= file " + config->whyExtract + ": " +
+    error("cannot open --why-extract= file " + ctx.arg.whyExtract + ": " +
           ec.message());
     return;
   }
@@ -2260,7 +2261,7 @@ static void writeWhyExtract() {
   }
 }
 
-static void reportBackrefs() {
+static void reportBackrefs(Ctx &ctx) {
   for (auto &ref : ctx.backwardReferences) {
     const Symbol &sym = *ref.first;
     std::string to = toString(ref.second.second);
@@ -2268,7 +2269,7 @@ static void reportBackrefs() {
     // with --warn-backrefs-exclude=. The value may look like (for --start-lib)
     // *.o or (archive member) *.a(*.o).
     bool exclude = false;
-    for (const llvm::GlobPattern &pat : config->warnBackrefsExclude)
+    for (const llvm::GlobPattern &pat : ctx.arg.warnBackrefsExclude)
       if (pat.match(to)) {
         exclude = true;
         break;
@@ -2303,11 +2304,11 @@ static void reportBackrefs() {
 // part of your program. By using --dependency-file option, you can make
 // lld to dump dependency info so that you can maintain exact dependencies
 // easily.
-static void writeDependencyFile() {
+static void writeDependencyFile(Ctx &ctx) {
   std::error_code ec;
-  raw_fd_ostream os = ctx.openAuxiliaryFile(config->dependencyFile, ec);
+  raw_fd_ostream os = ctx.openAuxiliaryFile(ctx.arg.dependencyFile, ec);
   if (ec) {
-    error("cannot open " + config->dependencyFile + ": " + ec.message());
+    error("cannot open " + ctx.arg.dependencyFile + ": " + ec.message());
     return;
   }
 
@@ -2334,14 +2335,14 @@ static void writeDependencyFile() {
     }
   };
 
-  os << config->outputFile << ":";
-  for (StringRef path : config->dependencyFiles) {
+  os << ctx.arg.outputFile << ":";
+  for (StringRef path : ctx.arg.dependencyFiles) {
     os << " \\\n ";
     printFilename(os, path);
   }
   os << "\n";
 
-  for (StringRef path : config->dependencyFiles) {
+  for (StringRef path : ctx.arg.dependencyFiles) {
     os << "\n";
     printFilename(os, path);
     os << ":\n";
@@ -2352,7 +2353,7 @@ static void writeDependencyFile() {
 // This function is called after all symbol names are resolved. As a
 // result, the passes after the symbol resolution won't see any
 // symbols of type CommonSymbol.
-static void replaceCommonSymbols() {
+static void replaceCommonSymbols(Ctx &ctx) {
   llvm::TimeTraceScope timeScope("Replace common symbols");
   for (ELFFileBase *file : ctx.objectFiles) {
     if (!file->hasCommonSyms)
@@ -2387,7 +2388,7 @@ static void markAddrsig(Symbol *s) {
 // and symbols referred to by address-significance tables. These sections are
 // ineligible for ICF.
 template <class ELFT>
-static void findKeepUniqueSections(opt::InputArgList &args) {
+static void findKeepUniqueSections(Ctx &ctx, opt::InputArgList &args) {
   for (auto *arg : args.filtered(OPT_keep_unique)) {
     StringRef name = arg->getValue();
     auto *d = dyn_cast_or_null<Defined>(symtab.find(name));
@@ -2400,7 +2401,7 @@ static void findKeepUniqueSections(opt::InputArgList &args) {
 
   // --icf=all --ignore-data-address-equality means that we can ignore
   // the dynsym and address-significance tables entirely.
-  if (config->icf == ICFLevel::All && config->ignoreDataAddressEquality)
+  if (ctx.arg.icf == ICFLevel::All && ctx.arg.ignoreDataAddressEquality)
     return;
 
   // Symbols in the dynsym could be address-significant in other executables
@@ -2669,7 +2670,7 @@ static void combineVersionedSymbol(Symbol &sym,
 // When this function is executed, only InputFiles and symbol table
 // contain pointers to symbol objects. We visit them to replace pointers,
 // so that wrapped symbols are swapped as instructed by the command line.
-static void redirectSymbols(ArrayRef<WrappedSymbol> wrapped) {
+static void redirectSymbols(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) {
   llvm::TimeTraceScope timeScope("Redirect symbols");
   DenseMap<Symbol *, Symbol *> map;
   for (const WrappedSymbol &w : wrapped) {
@@ -2680,7 +2681,7 @@ static void redirectSymbols(ArrayRef<WrappedSymbol> wrapped) {
   // If there are version definitions (versionDefinitions.size() > 2), enumerate
   // symbols with a non-default version (foo at v1) and check whether it should be
   // combined with foo or foo@@v1.
-  if (config->versionDefinitions.size() > 2)
+  if (ctx.arg.versionDefinitions.size() > 2)
     for (Symbol *sym : symtab.getSymbols())
       if (sym->hasVersionSuffix)
         combineVersionedSymbol(*sym, map);
@@ -2877,11 +2878,11 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
 
   // If an entry symbol is in a static archive, pull out that file now.
   if (Symbol *sym = symtab.find(ctx.arg.entry))
-    handleUndefined(sym, "--entry");
+    handleUndefined(ctx, sym, "--entry");
 
   // Handle the `--undefined-glob <pattern>` options.
   for (StringRef pat : args::getStrings(args, OPT_undefined_glob))
-    handleUndefinedGlob(pat);
+    handleUndefinedGlob(ctx, pat);
 
   // After potential archive member extraction involving ENTRY and
   // -u/--undefined-glob, check whether PROVIDE symbols should be defined (the
@@ -2919,7 +2920,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   if (!ctx.bitcodeFiles.empty()) {
     llvm::Triple TT(ctx.bitcodeFiles.front()->obj->getTargetTriple());
     for (auto *s : lto::LTO::getRuntimeLibcallSymbols(TT))
-      handleLibcall(s);
+      handleLibcall(ctx, s);
   }
 
   // Archive members defining __wrap symbols may be extracted.
@@ -3006,9 +3007,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
 
   // Symbol resolution finished. Report backward reference problems,
   // --print-archive-stats=, and --why-extract=.
-  reportBackrefs();
-  writeArchiveStats();
-  writeWhyExtract();
+  reportBackrefs(ctx);
+  writeArchiveStats(ctx);
+  writeWhyExtract(ctx);
   if (errorCount())
     return;
 
@@ -3050,10 +3051,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   processArmCmseSymbols();
 
   // Apply symbol renames for --wrap and combine foo at v1 and foo@@v1.
-  redirectSymbols(wrapped);
+  redirectSymbols(ctx, wrapped);
 
   // Replace common symbols with regular symbols.
-  replaceCommonSymbols();
+  replaceCommonSymbols(ctx);
 
   {
     llvm::TimeTraceScope timeScope("Aggregate sections");
@@ -3104,7 +3105,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   // Since we now have a complete set of input files, we can create
   // a .d file to record build dependencies.
   if (!ctx.arg.dependencyFile.empty())
-    writeDependencyFile();
+    writeDependencyFile(ctx);
 
   // Now that the number of partitions is fixed, save a pointer to the main
   // partition.
@@ -3124,15 +3125,15 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   // the output can be run on. For example if the OS can use 4k or 64k page
   // sizes then maxPageSize must be 64k for the output to be useable on both.
   // All important alignment decisions must use this value.
-  ctx.arg.maxPageSize = getMaxPageSize(args);
+  ctx.arg.maxPageSize = getMaxPageSize(ctx, args);
   // commonPageSize is the most common page size that the output will be run on.
   // For example if an OS can use 4k or 64k page sizes and 4k is more common
   // than 64k then commonPageSize is set to 4k. commonPageSize can be used for
   // optimizations such as DATA_SEGMENT_ALIGN in linker scripts. LLD's use of it
   // is limited to writing trap instructions on the last executable segment.
-  ctx.arg.commonPageSize = getCommonPageSize(args);
+  ctx.arg.commonPageSize = getCommonPageSize(ctx, args);
 
-  ctx.arg.imageBase = getImageBase(args);
+  ctx.arg.imageBase = getImageBase(ctx, args);
 
   // This adds a .comment section containing a version string.
   if (!ctx.arg.relocatable)
@@ -3195,7 +3196,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   // Two input sections with 
diff erent output sections should not be folded.
   // ICF runs after processSectionCommands() so that we know the output sections.
   if (ctx.arg.icf != ICFLevel::None) {
-    findKeepUniqueSections<ELFT>(args);
+    findKeepUniqueSections<ELFT>(ctx, args);
     doIcf<ELFT>();
   }
 


        


More information about the llvm-commits mailing list