]> git.lizzy.rs Git - rust.git/blob - src/librustc_target/spec/uefi_base.rs
Auto merge of #68414 - michaelwoerister:share-drop-glue, r=alexcrichton
[rust.git] / src / librustc_target / spec / uefi_base.rs
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
12 use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
13 use std::default::Default;
14
15 pub fn opts() -> TargetOptions {
16     let mut pre_link_args = LinkArgs::new();
17
18     pre_link_args.insert(
19         LinkerFlavor::Lld(LldFlavor::Link),
20         vec![
21             // Suppress the verbose logo and authorship debugging output, which would needlessly
22             // clog any log files.
23             "/NOLOGO".to_string(),
24             // UEFI is fully compatible to non-executable data pages. Tell the compiler that
25             // non-code sections can be marked as non-executable, including stack pages. In fact,
26             // firmware might enforce this, so we better let the linker know about this, so it
27             // will fail if the compiler ever tries placing code on the stack (e.g., trampoline
28             // constructs and alike).
29             "/NXCOMPAT".to_string(),
30             // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets
31             // must be freestanding.
32             "/nodefaultlib".to_string(),
33             // Non-standard subsystems have no default entry-point in PE+ files. We have to define
34             // one. "efi_main" seems to be a common choice amongst other implementations and the
35             // spec.
36             "/entry:efi_main".to_string(),
37             // COFF images have a "Subsystem" field in their header, which defines what kind of
38             // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
39             // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
40             // which is very likely the most common option. Individual projects can override this
41             // with custom linker flags.
42             // The subsystem-type only has minor effects on the application. It defines the memory
43             // regions the application is loaded into (runtime-drivers need to be put into
44             // reserved areas), as well as whether a return from the entry-point is treated as
45             // exit (default for applications).
46             "/subsystem:efi_application".to_string(),
47         ],
48     );
49
50     TargetOptions {
51         dynamic_linking: false,
52         executables: true,
53         disable_redzone: true,
54         exe_suffix: ".efi".to_string(),
55         allows_weak_linkage: false,
56         panic_strategy: PanicStrategy::Abort,
57         stack_probes: true,
58         singlethread: true,
59         emit_debug_gdb_scripts: false,
60
61         linker: Some("rust-lld".to_string()),
62         lld_flavor: LldFlavor::Link,
63         pre_link_args,
64
65         ..Default::default()
66     }
67 }