[clang] [Clang][Driver] Revise Cygwin ToolChain to call linker directly (PR #147960)
Tomohiro Kashiwada via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 17 06:16:58 PDT 2025
================
@@ -107,3 +110,294 @@ void Cygwin::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/w32api");
}
+
+static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) {
+ bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
+ if (HasStaticPIE && Args.hasArg(options::OPT_no_pie)) {
+ const Driver &D = TC.getDriver();
+ const llvm::opt::OptTable &Opts = D.getOpts();
+ StringRef StaticPIEName = Opts.getOptionName(options::OPT_static_pie);
+ StringRef NoPIEName = Opts.getOptionName(options::OPT_nopie);
+ D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName;
+ }
+ return HasStaticPIE;
+}
+
+static bool getStatic(const ArgList &Args) {
+ return Args.hasArg(options::OPT_static) &&
+ !Args.hasArg(options::OPT_static_pie);
+}
+
+void cygwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ const auto &ToolChain = getToolChain();
+ const Driver &D = ToolChain.getDriver();
+
+ const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
+ const bool IsVE = ToolChain.getTriple().isVE();
+ const bool IsStaticPIE = getStaticPIE(Args, ToolChain);
+ const bool IsStatic = getStatic(Args);
+
+ ArgStringList CmdArgs;
+
+ // Silence warning for "clang -g foo.o -o foo"
+ Args.ClaimAllArgs(options::OPT_g_Group);
+ // and "clang -emit-llvm foo.o -o foo"
+ Args.ClaimAllArgs(options::OPT_emit_llvm);
+ // and for "clang -w foo.o -o foo". Other warning options are already
+ // handled somewhere else.
+ Args.ClaimAllArgs(options::OPT_w);
+
+ if (!D.SysRoot.empty())
+ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+ if (Args.hasArg(options::OPT_s))
+ CmdArgs.push_back("-s");
+
+ CmdArgs.push_back("-m");
+ switch (ToolChain.getArch()) {
+ case llvm::Triple::x86:
+ CmdArgs.push_back("i386pe");
+ break;
+ case llvm::Triple::x86_64:
+ CmdArgs.push_back("i386pep");
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ // FIXME: this is incorrect for WinCE
+ CmdArgs.push_back("thumb2pe");
+ break;
+ case llvm::Triple::aarch64:
+ if (ToolChain.getEffectiveTriple().isWindowsArm64EC())
+ CmdArgs.push_back("arm64ecpe");
+ else
+ CmdArgs.push_back("arm64pe");
+ break;
+ default:
+ D.Diag(diag::err_target_unknown_triple)
+ << ToolChain.getEffectiveTriple().str();
+ }
+
+ Arg *SubsysArg =
+ Args.getLastArg(options::OPT_mwindows, options::OPT_mconsole);
+ if (SubsysArg && SubsysArg->getOption().matches(options::OPT_mwindows)) {
+ CmdArgs.push_back("--subsystem");
+ CmdArgs.push_back("windows");
+ } else if (SubsysArg &&
+ SubsysArg->getOption().matches(options::OPT_mconsole)) {
+ CmdArgs.push_back("--subsystem");
+ CmdArgs.push_back("console");
+ }
+
+ CmdArgs.push_back("--wrap=_Znwm");
+ CmdArgs.push_back("--wrap=_Znam");
+ CmdArgs.push_back("--wrap=_ZdlPv");
+ CmdArgs.push_back("--wrap=_ZdaPv");
+ CmdArgs.push_back("--wrap=_ZnwmRKSt9nothrow_t");
+ CmdArgs.push_back("--wrap=_ZnamRKSt9nothrow_t");
+ CmdArgs.push_back("--wrap=_ZdlPvRKSt9nothrow_t");
+ CmdArgs.push_back("--wrap=_ZdaPvRKSt9nothrow_t");
+
+ if (Args.hasArg(options::OPT_mdll))
+ CmdArgs.push_back("--dll");
+ else if (Args.hasArg(options::OPT_shared))
+ CmdArgs.push_back("--shared");
+ if (Args.hasArg(options::OPT_static))
+ CmdArgs.push_back("-Bstatic");
+ else
+ CmdArgs.push_back("-Bdynamic");
+
+ CmdArgs.push_back("--dll-search-prefix=cyg");
+
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
+ options::OPT_r)) {
+ if (IsVE) {
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("max-page-size=0x4000000");
+ }
+
+ const bool IsShared = Args.hasArg(options::OPT_shared);
+ if (IsShared) {
+ CmdArgs.push_back("-e");
+ CmdArgs.push_back(ToolChain.getArch() == llvm::Triple::x86
+ ? "__cygwin_dll_entry at 12"
+ : "_cygwin_dll_entry");
+ CmdArgs.push_back("--enable-auto-image-base");
+ }
+
+ if (!IsShared)
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
+ if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT) {
+ std::string crtbegin =
+ ToolChain.getCompilerRT(Args, "crtbegin", ToolChain::FT_Object);
+ if (ToolChain.getVFS().exists(crtbegin)) {
+ std::string P;
+ P = crtbegin;
+ CmdArgs.push_back(Args.MakeArgString(P));
+ }
+ }
+ if (IsShared)
+ CmdArgs.push_back(
+ Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o")));
+ else
+ CmdArgs.push_back(
+ Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")));
+
+ // Add crtfastmath.o if available and fast math is enabled.
+ ToolChain.addFastMathRuntimeIfAvailable(Args, CmdArgs);
+ }
+
+ Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});
+
+ ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+
+ if (D.isUsingLTO())
+ tools::addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs,
+ D.getLTOMode() == LTOK_Thin);
+
+ if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+ CmdArgs.push_back("--no-demangle");
+
+ bool NeedsSanitizerDeps =
+ tools::addSanitizerRuntimes(ToolChain, Args, CmdArgs);
+ bool NeedsXRayDeps = tools::addXRayRuntime(ToolChain, Args, CmdArgs);
+ tools::addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs);
+ tools::AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+ bool saw_high_entropy_va = false;
+ for (const char *Arg : CmdArgs)
+ if (StringRef(Arg) == "--high-entropy-va" ||
----------------
kikairoya wrote:
Is this check needed? Users want to override can use `-Wl,--high-entropy-va`. If you really want to handle this here, `options::OPT_fhigh_entropy_va` should be added.
https://github.com/llvm/llvm-project/pull/147960
More information about the cfe-commits
mailing list