]>
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 | ||
5869c6ff | 12 | use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, StackProbeType, TargetOptions}; |
ba9703b0 XL |
13 | |
14 | pub fn opts() -> TargetOptions { | |
15 | let mut base = super::msvc_base::opts(); | |
16 | ||
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 | |
20 | // spec. | |
5e7ed085 | 21 | "/entry:efi_main".into(), |
ba9703b0 XL |
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). | |
5e7ed085 | 31 | "/subsystem:efi_application".into(), |
ba9703b0 | 32 | ]; |
cdc7bbd5 | 33 | base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone()); |
ba9703b0 | 34 | base.pre_link_args |
cdc7bbd5 XL |
35 | .entry(LinkerFlavor::Lld(LldFlavor::Link)) |
36 | .or_default() | |
ba9703b0 XL |
37 | .extend(pre_link_args_msvc); |
38 | ||
39 | TargetOptions { | |
5e7ed085 | 40 | os: "uefi".into(), |
29967ef6 | 41 | linker_flavor: LinkerFlavor::Lld(LldFlavor::Link), |
ba9703b0 | 42 | disable_redzone: true, |
5e7ed085 | 43 | exe_suffix: ".efi".into(), |
ba9703b0 XL |
44 | allows_weak_linkage: false, |
45 | panic_strategy: PanicStrategy::Abort, | |
5869c6ff XL |
46 | // LLVM does not emit inline assembly because the LLVM target does not get considered as… |
47 | // "Windows". | |
48 | stack_probes: StackProbeType::Call, | |
ba9703b0 | 49 | singlethread: true, |
5e7ed085 | 50 | linker: Some("rust-lld".into()), |
ba9703b0 XL |
51 | ..base |
52 | } | |
53 | } |