-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[clang][Driver] Clean up UEFI linker argument handling #159639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Roland McGrath (frobtech) ChangesThis makes the UEFI driver's handling of linking more canonical
It also updates some TODO comments for how the driver behavior Full diff: https://github.com/llvm/llvm-project/pull/159639.diff 2 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/UEFI.cpp b/clang/lib/Driver/ToolChains/UEFI.cpp
index 2b41173543477..75adbf149197b 100644
--- a/clang/lib/Driver/ToolChains/UEFI.cpp
+++ b/clang/lib/Driver/ToolChains/UEFI.cpp
@@ -57,29 +57,44 @@ void tools::uefi::Linker::ConstructJob(Compilation &C, const JobAction &JA,
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/clang/test/Driver/uefi-constructed-args.c b/clang/test/Driver/uefi-constructed-args.c
index 49ede47a8953e..c06cce351d654 100644
--- a/clang/test/Driver/uefi-constructed-args.c
+++ b/clang/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"
|
Is there any particular reason for using the |
It's the common convention for the tool syntax that It's also possible that the UEFI backend could be made to work with the MSVC linker instead of LLD as with the MSVC backend (if anyone cared to wire it up with |
This makes the UEFI driver's handling of linking more canonical
in a few ways:
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.