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
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.
12 use crate::spec
::{LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}
;
14 pub fn opts() -> TargetOptions
{
15 let mut base
= super::msvc_base
::opts();
17 let pre_link_args_msvc
= vec
![
18 // Non-standard subsystems have no default entry-point in PE+ files. We have to define
19 // one. "efi_main" seems to be a common choice amongst other implementations and the
21 "/entry:efi_main".to_string(),
22 // COFF images have a "Subsystem" field in their header, which defines what kind of
23 // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
24 // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
25 // which is very likely the most common option. Individual projects can override this
26 // with custom linker flags.
27 // The subsystem-type only has minor effects on the application. It defines the memory
28 // regions the application is loaded into (runtime-drivers need to be put into
29 // reserved areas), as well as whether a return from the entry-point is treated as
30 // exit (default for applications).
31 "/subsystem:efi_application".to_string(),
33 base
.pre_link_args
.get_mut(&LinkerFlavor
::Msvc
).unwrap().extend(pre_link_args_msvc
.clone());
35 .get_mut(&LinkerFlavor
::Lld(LldFlavor
::Link
))
37 .extend(pre_link_args_msvc
);
40 disable_redzone
: true,
41 exe_suffix
: ".efi".to_string(),
42 allows_weak_linkage
: false,
43 panic_strategy
: PanicStrategy
::Abort
,
46 linker
: Some("rust-lld".to_string()),
47 // FIXME: This should likely be `true` inherited from `msvc_base`
48 // because UEFI follows Windows ABI and uses PE/COFF.
49 // The `false` is probably causing ABI bugs right now.
50 is_like_windows
: false,
51 // FIXME: This should likely be `true` inherited from `msvc_base`
52 // because UEFI follows Windows ABI and uses PE/COFF.
53 // The `false` is probably causing ABI bugs right now.