[lld] [LLD] [MinGW] Fall back to using default target if no -m flag given. (PR #134700)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 8 17:47:54 PDT 2025
jeremyd2019 wrote:
This particular case isn't too bad, but for Cygwin there are others. Unfortunately, it looks like GNU ld "knows" the target at build time and does some different things between Cygwin and MinGW.
for example, @mati865's patch
```patch
diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp
index 131bacdf1468..94acd68abd12 100644
--- a/lld/MinGW/Driver.cpp
+++ b/lld/MinGW/Driver.cpp
@@ -546,6 +546,10 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
add("-exclude-symbols:" + StringRef(a->getValue()));
std::vector<StringRef> searchPaths;
+ #ifdef __CYGWIN__
+ searchPaths.push_back("/usr/lib");
+ searchPaths.push_back("/usr/lib/w32api");
+ #endif
for (auto *a : args.filtered(OPT_L)) {
searchPaths.push_back(a->getValue());
add("-libpath:" + StringRef(a->getValue()));
--
2.47.1.windows.2
```
and my patch (which also includes the changes in this PR)
```patch
--- a/lld/MinGW/Driver.cpp 2025-04-07 14:55:18.420801800 -0700
+++ b/lld/MinGW/Driver.cpp 2025-04-07 17:27:27.318509600 -0700
@@ -177,6 +177,24 @@
return "";
}
+static inline bool isI386Target(const opt::InputArgList &args,
+ const Triple &defaultTarget) {
+ auto *a = args.getLastArg(OPT_m);
+ if (a)
+ return StringRef(a->getValue()) == "i386pe";
+ return defaultTarget.getArch() == Triple::x86;
+}
+
+static inline bool is64bitTarget(const opt::InputArgList &args,
+ const Triple &defaultTarget) {
+ auto *a = args.getLastArg(OPT_m);
+ if (a) {
+ StringRef s = a->getValue();
+ return s == "i386pep" || s == "arm64pe" || s == "arm64ecpe";
+ }
+ return defaultTarget.isArch64Bit();
+}
+
namespace lld {
namespace coff {
bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
@@ -222,6 +240,9 @@
return false;
}
+ Triple defaultTarget(Triple::normalize(sys::getDefaultTargetTriple()));
+ bool isCygwinTarget = defaultTarget.isWindowsCygwinEnvironment();
+
std::vector<std::string> linkArgs;
auto add = [&](const Twine &s) { linkArgs.push_back(s.str()); };
@@ -230,7 +251,7 @@
if (auto *a = args.getLastArg(OPT_entry)) {
StringRef s = a->getValue();
- if (args.getLastArgValue(OPT_m) == "i386pe" && s.starts_with("_"))
+ if (isI386Target(args, defaultTarget) && s.starts_with("_"))
add("-entry:" + s.substr(1));
else if (!s.empty())
add("-entry:" + s);
@@ -287,6 +308,26 @@
add("-output-def:" + StringRef(a->getValue()));
if (auto *a = args.getLastArg(OPT_image_base))
add("-base:" + StringRef(a->getValue()));
+ else if (isCygwinTarget) {
+ if (args.hasFlag(OPT_enable_auto_image_base, OPT_disable_auto_image_base,
+ false) && args.hasArg(OPT_shared)) {
+ hash_code outhash;
+ uint64_t autobase;
+ if (auto *a = args.getLastArg(OPT_o))
+ outhash = hash_value(StringRef(a->getValue()));
+ else
+ outhash = hash_value(StringRef("a.dll"));
+ if (is64bitTarget(args, defaultTarget))
+ autobase =
+ 0x400000000ULL + (((uint64_t)outhash << 16) & 0x1ffff0000ULL);
+ else
+ autobase =
+ (uint32_t)(0x61500000 + (((uint32_t)outhash << 16) & 0x0FFC0000));
+ add("-base:0x" + Twine::utohexstr(autobase));
+ } else if (is64bitTarget(args, defaultTarget)) {
+ add(args.hasArg(OPT_shared) ? "-base:0x400000000" : "-base:0x100400000");
+ }
+ }
if (auto *a = args.getLastArg(OPT_map))
add("-lldmap:" + StringRef(a->getValue()));
if (auto *a = args.getLastArg(OPT_reproduce))
@@ -373,14 +414,17 @@
if (args.hasFlag(OPT_no_seh, OPT_disable_no_seh, false))
add("-noseh");
- if (args.getLastArgValue(OPT_m) != "thumb2pe" &&
- args.getLastArgValue(OPT_m) != "arm64pe" &&
- args.getLastArgValue(OPT_m) != "arm64ecpe" &&
- args.hasFlag(OPT_disable_dynamicbase, OPT_dynamicbase, false))
+ if ((args.getLastArgValue(OPT_m) != "thumb2pe" &&
+ args.getLastArgValue(OPT_m) != "arm64pe" &&
+ args.getLastArgValue(OPT_m) != "arm64ecpe" &&
+ args.hasFlag(OPT_disable_dynamicbase, OPT_dynamicbase, false)) ||
+ (isCygwinTarget && !args.hasArg(OPT_dynamicbase)))
add("-dynamicbase:no");
- if (args.hasFlag(OPT_disable_high_entropy_va, OPT_high_entropy_va, false))
+ if (args.hasFlag(OPT_disable_high_entropy_va, OPT_high_entropy_va, false) ||
+ (isCygwinTarget && !args.hasArg(OPT_high_entropy_va)))
add("-highentropyva:no");
- if (args.hasFlag(OPT_disable_nxcompat, OPT_nxcompat, false))
+ if (args.hasFlag(OPT_disable_nxcompat, OPT_nxcompat, false) ||
+ (isCygwinTarget && !args.hasArg(OPT_nxcompat)))
add("-nxcompat:no");
if (args.hasFlag(OPT_disable_tsaware, OPT_tsaware, false))
add("-tsaware:no");
@@ -527,7 +568,7 @@
for (auto *a : args.filtered(OPT_Xlink))
add(a->getValue());
- if (args.getLastArgValue(OPT_m) == "i386pe")
+ if (isI386Target(args, defaultTarget))
add("-alternatename:__image_base__=___ImageBase");
else
add("-alternatename:__image_base__=__ImageBase");
--- a/lld/MinGW/Options.td 2025-04-07 14:55:18.388986300 -0700
+++ b/lld/MinGW/Options.td 2025-04-07 17:03:20.201184300 -0700
@@ -59,6 +59,7 @@
defm demangle: B<"demangle",
"Demangle symbol names (default)",
"Do not demangle symbol names">;
+def disable_auto_image_base: F<"disable-auto-image-base">;
def disable_auto_import: F<"disable-auto-import">,
HelpText<"Don't automatically import data symbols from other DLLs without dllimport">;
def disable_runtime_pseudo_reloc: F<"disable-runtime-pseudo-reloc">,
@@ -68,6 +69,7 @@
defm dll_search_prefix: EEq<"dll-search-prefix",
"Prefer DLL with this prefix if importlib is missing">;
defm dynamicbase: B_disable<"dynamicbase", "Enable ASLR", "Disable ASLR">;
+def enable_auto_image_base: F<"enable-auto-image-base">;
def enable_auto_import: F<"enable-auto-import">,
HelpText<"Automatically import data symbols from other DLLs where needed">;
def enable_runtime_pseudo_reloc: F<"enable-runtime-pseudo-reloc">,
@@ -238,8 +240,6 @@
// Ignored options
def: Joined<["-"], "O">;
def: F<"as-needed">;
-def: F<"disable-auto-image-base">;
-def: F<"enable-auto-image-base">;
def: F<"end-group">;
def: Flag<["--"], "full-shutdown">;
defm: EqNoHelp<"major-image-version">;
```
https://github.com/llvm/llvm-project/pull/134700
More information about the llvm-commits
mailing list