]>
Commit | Line | Data |
---|---|---|
ba9703b0 XL |
1 | // This defines a base target-configuration for native UEFI systems. The UEFI specification has |
2 | // quite detailed sections on the ABI of all the supported target architectures. In almost all | |
3 | // cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN | |
4 | // documentation. | |
5 | // UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic | |
6 | // linker is supported. As native to COFF, binaries are position-dependent, but will be relocated | |
7 | // by the loader if the pre-chosen memory location is already in use. | |
8 | // UEFI forbids running code on anything but the boot-CPU. No interrupts are allowed other than | |
9 | // the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all | |
10 | // code runs in the same environment, no process separation is supported. | |
11 | ||
f2b60f7d FG |
12 | use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy}; |
13 | use crate::spec::{StackProbeType, TargetOptions}; | |
ba9703b0 XL |
14 | |
15 | pub fn opts() -> TargetOptions { | |
16 | let mut base = super::msvc_base::opts(); | |
17 | ||
064997fb FG |
18 | base.add_pre_link_args( |
19 | LinkerFlavor::Msvc, | |
20 | &[ | |
21 | // Non-standard subsystems have no default entry-point in PE+ files. We have to define | |
22 | // one. "efi_main" seems to be a common choice amongst other implementations and the | |
23 | // spec. | |
24 | "/entry:efi_main", | |
25 | // COFF images have a "Subsystem" field in their header, which defines what kind of | |
26 | // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION, | |
27 | // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION, | |
28 | // which is very likely the most common option. Individual projects can override this | |
29 | // with custom linker flags. | |
30 | // The subsystem-type only has minor effects on the application. It defines the memory | |
31 | // regions the application is loaded into (runtime-drivers need to be put into | |
32 | // reserved areas), as well as whether a return from the entry-point is treated as | |
33 | // exit (default for applications). | |
34 | "/subsystem:efi_application", | |
35 | ], | |
36 | ); | |
ba9703b0 XL |
37 | |
38 | TargetOptions { | |
5e7ed085 | 39 | os: "uefi".into(), |
29967ef6 | 40 | linker_flavor: LinkerFlavor::Lld(LldFlavor::Link), |
ba9703b0 | 41 | disable_redzone: true, |
5e7ed085 | 42 | exe_suffix: ".efi".into(), |
ba9703b0 XL |
43 | allows_weak_linkage: false, |
44 | panic_strategy: PanicStrategy::Abort, | |
5869c6ff XL |
45 | // LLVM does not emit inline assembly because the LLVM target does not get considered as… |
46 | // "Windows". | |
47 | stack_probes: StackProbeType::Call, | |
ba9703b0 | 48 | singlethread: true, |
5e7ed085 | 49 | linker: Some("rust-lld".into()), |
ba9703b0 XL |
50 | ..base |
51 | } | |
52 | } |