1 | //===--- UEFI.cpp - UEFI ToolChain Implementations -----------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "UEFI.h" |
10 | #include "clang/Config/config.h" |
11 | #include "clang/Driver/CommonArgs.h" |
12 | #include "clang/Driver/Compilation.h" |
13 | #include "clang/Driver/Driver.h" |
14 | #include "clang/Driver/Options.h" |
15 | #include "clang/Driver/SanitizerArgs.h" |
16 | #include "llvm/Option/Arg.h" |
17 | #include "llvm/Option/ArgList.h" |
18 | #include "llvm/Support/VirtualFileSystem.h" |
19 | #include "llvm/TargetParser/Host.h" |
20 | |
21 | using namespace clang::driver; |
22 | using namespace clang::driver::toolchains; |
23 | using namespace clang; |
24 | using namespace llvm::opt; |
25 | |
26 | UEFI::UEFI(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
27 | : ToolChain(D, Triple, Args) {} |
28 | |
29 | Tool *UEFI::buildLinker() const { return new tools::uefi::Linker(*this); } |
30 | |
31 | void UEFI::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
32 | ArgStringList &CC1Args) const { |
33 | if (DriverArgs.hasArg(Ids: options::OPT_nostdinc)) |
34 | return; |
35 | |
36 | if (!DriverArgs.hasArg(Ids: options::OPT_nobuiltininc)) { |
37 | SmallString<128> Dir(getDriver().ResourceDir); |
38 | llvm::sys::path::append(path&: Dir, a: "include" ); |
39 | addSystemInclude(DriverArgs, CC1Args, Path: Dir.str()); |
40 | } |
41 | |
42 | if (DriverArgs.hasArg(Ids: options::OPT_nostdlibinc)) |
43 | return; |
44 | |
45 | if (std::optional<std::string> Path = getStdlibIncludePath()) |
46 | addSystemInclude(DriverArgs, CC1Args, Path: *Path); |
47 | } |
48 | |
49 | void tools::uefi::Linker::ConstructJob(Compilation &C, const JobAction &JA, |
50 | const InputInfo &Output, |
51 | const InputInfoList &Inputs, |
52 | const ArgList &Args, |
53 | const char *LinkingOutput) const { |
54 | ArgStringList CmdArgs; |
55 | auto &TC = static_cast<const toolchains::UEFI &>(getToolChain()); |
56 | |
57 | assert((Output.isFilename() || Output.isNothing()) && "invalid output" ); |
58 | if (Output.isFilename()) |
59 | CmdArgs.push_back( |
60 | Elt: Args.MakeArgString(Str: std::string("-out:" ) + Output.getFilename())); |
61 | |
62 | CmdArgs.push_back(Elt: "-nologo" ); |
63 | |
64 | // TODO: Other UEFI binary subsystems that are currently unsupported: |
65 | // efi_boot_service_driver, efi_rom, efi_runtime_driver. |
66 | CmdArgs.push_back(Elt: "-subsystem:efi_application" ); |
67 | |
68 | // Default entry function name according to the TianoCore reference |
69 | // implementation is EfiMain. |
70 | // TODO: Provide a flag to override the entry function name. |
71 | CmdArgs.push_back(Elt: "-entry:EfiMain" ); |
72 | |
73 | // "Terminal Service Aware" flag is not needed for UEFI applications. |
74 | CmdArgs.push_back(Elt: "-tsaware:no" ); |
75 | |
76 | if (Args.hasArg(Ids: options::OPT_g_Group, Ids: options::OPT__SLASH_Z7)) |
77 | CmdArgs.push_back(Elt: "-debug" ); |
78 | |
79 | Args.AddAllArgValues(Output&: CmdArgs, Id0: options::OPT__SLASH_link); |
80 | |
81 | AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); |
82 | |
83 | // This should ideally be handled by ToolChain::GetLinkerPath but we need |
84 | // to special case some linker paths. In the case of lld, we need to |
85 | // translate 'lld' into 'lld-link'. |
86 | StringRef Linker = |
87 | Args.getLastArgValue(Id: options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER); |
88 | if (Linker.empty() || Linker == "lld" ) |
89 | Linker = "lld-link" ; |
90 | |
91 | auto LinkerPath = TC.GetProgramPath(Name: Linker.str().c_str()); |
92 | auto LinkCmd = std::make_unique<Command>( |
93 | args: JA, args: *this, args: ResponseFileSupport::AtFileUTF16(), |
94 | args: Args.MakeArgString(Str: LinkerPath), args&: CmdArgs, args: Inputs, args: Output); |
95 | C.addCommand(C: std::move(LinkCmd)); |
96 | } |
97 | |