[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"