[clang][Driver] Clean up UEFI linker argument handling (#159639)
This makes the UEFI driver's handling of linking more canonical
in a few ways:
* Use /option:value syntax with lld-link as in the MSVC driver.
* Handle -nostdlib, -nodefaultlibs, -r and call common
subroutines when they aren't set. This covers sanitizer and
profile runtimes and their associated switches; compiler-rt
builds do not yet provide these libraries, but the driver
behavior is opt-in and supports all the opt-in/out plumbing
like other targets do. This lets command lines immediately
use the opt-out switches even when they are superfluous for
opt-in features, as build system plumbing often needs to do.
It also updates some TODO comments for how the driver behavior
will look when more runtime support is ready.
GitOrigin-RevId: fc73ef42c92bf50547d5a069e98459a4a5615872
diff --git a/lib/Driver/ToolChains/UEFI.cpp b/lib/Driver/ToolChains/UEFI.cpp
index 2b41173..75adbf1 100644
--- a/lib/Driver/ToolChains/UEFI.cpp
+++ b/lib/Driver/ToolChains/UEFI.cpp
@@ -57,29 +57,44 @@
assert((Output.isFilename() || Output.isNothing()) && "invalid output");
if (Output.isFilename())
CmdArgs.push_back(
- Args.MakeArgString(std::string("-out:") + Output.getFilename()));
+ Args.MakeArgString(std::string("/out:") + Output.getFilename()));
- CmdArgs.push_back("-nologo");
-
- // TODO: Other UEFI binary subsystems that are currently unsupported:
- // efi_boot_service_driver, efi_rom, efi_runtime_driver.
- CmdArgs.push_back("-subsystem:efi_application");
+ CmdArgs.push_back("/nologo");
// Default entry function name according to the TianoCore reference
- // implementation is EfiMain.
- // TODO: Provide a flag to override the entry function name.
- CmdArgs.push_back("-entry:EfiMain");
+ // implementation is EfiMain. -Wl,/subsystem:... or -Wl,/entry:... can
+ // override these since they will be added later in AddLinkerInputs.
+ CmdArgs.push_back("/subsystem:efi_application");
+ CmdArgs.push_back("/entry:EfiMain");
// "Terminal Service Aware" flag is not needed for UEFI applications.
- CmdArgs.push_back("-tsaware:no");
+ CmdArgs.push_back("/tsaware:no");
if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7))
- CmdArgs.push_back("-debug");
+ CmdArgs.push_back("/debug");
Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
+ // Sample these options first so they are claimed even under -nostdlib et al.
+ bool NoLibc = Args.hasArg(options::OPT_nolibc);
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
+ options::OPT_r)) {
+ addSanitizerRuntimes(TC, Args, CmdArgs);
+
+ addXRayRuntime(TC, Args, CmdArgs);
+
+ TC.addProfileRTLibs(Args, CmdArgs);
+
+ // TODO: When compiler-rt/lib/builtins is ready, enable this call:
+ // AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
+
+ if (!NoLibc) {
+ // TODO: When there is a libc ready, add it here.
+ }
+ }
+
// This should ideally be handled by ToolChain::GetLinkerPath but we need
// to special case some linker paths. In the case of lld, we need to
// translate 'lld' into 'lld-link'.
diff --git a/test/Driver/uefi-constructed-args.c b/test/Driver/uefi-constructed-args.c
index 49ede47..c06cce3 100644
--- a/test/Driver/uefi-constructed-args.c
+++ b/test/Driver/uefi-constructed-args.c
@@ -7,8 +7,8 @@
// CHECK-SAME: "-mrelocation-model" "pic" "-pic-level" "2"
// CHECK-SAME: "-mframe-pointer=all"
// CHECK-SAME: "-fms-extensions"
-// CHECK-NEXT: "-nologo"
-// CHECK-SAME: "-subsystem:efi_application"
-// CHECK-SAME: "-entry:EfiMain"
-// CHECK-SAME: "-tsaware:no"
-// CHECK-SAME: "-debug"
+// CHECK-NEXT: "/nologo"
+// CHECK-SAME: "/subsystem:efi_application"
+// CHECK-SAME: "/entry:EfiMain"
+// CHECK-SAME: "/tsaware:no"
+// CHECK-SAME: "/debug"