rustc-ap-rustc_target 497.0.0

Automatically published version of the package `rustc_target` in the rust-lang/rust repository from commit cdd743755adef8eb27410a9f4e480d3cf74abeaf The publishing script for this crate lives at: https://github.com/alexcrichton/rustc-auto-publish
Documentation
// This defines a base target-configuration for native UEFI systems. The UEFI specification has
// quite detailed sections on the ABI of all the supported target architectures. In almost all
// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN
// documentation.
// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic
// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated
// by the loader if the pre-chosen memory location is already in use.
// UEFI forbids running code on anything but the boot-CPU. No interrupts are allowed other than
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
// code runs in the same environment, no process separation is supported.

use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut pre_link_args = LinkArgs::new();

    pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), vec![
            // Suppress the verbose logo and authorship debugging output, which would needlessly
            // clog any log files.
            "/NOLOGO".to_string(),

            // UEFI is fully compatible to non-executable data pages. Tell the compiler that
            // non-code sections can be marked as non-executable, including stack pages. In fact,
            // firmware might enforce this, so we better let the linker know about this, so it
            // will fail if the compiler ever tries placing code on the stack (e.g., trampoline
            // constructs and alike).
            "/NXCOMPAT".to_string(),

            // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets
            // must be freestanding.
            "/nodefaultlib".to_string(),

            // Non-standard subsystems have no default entry-point in PE+ files. We have to define
            // one. "efi_main" seems to be a common choice amongst other implementations and the
            // spec.
            "/entry:efi_main".to_string(),

            // COFF images have a "Subsystem" field in their header, which defines what kind of
            // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
            // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
            // which is very likely the most common option. Individual projects can override this
            // with custom linker flags.
            // The subsystem-type only has minor effects on the application. It defines the memory
            // regions the application is loaded into (runtime-drivers need to be put into
            // reserved areas), as well as whether a return from the entry-point is treated as
            // exit (default for applications).
            "/subsystem:efi_application".to_string(),
        ]);

    TargetOptions {
        dynamic_linking: false,
        executables: true,
        disable_redzone: true,
        exe_suffix: ".efi".to_string(),
        allows_weak_linkage: false,
        panic_strategy: PanicStrategy::Abort,
        stack_probes: true,
        singlethread: true,
        emit_debug_gdb_scripts: false,

        linker: Some("rust-lld".to_string()),
        lld_flavor: LldFlavor::Link,
        pre_link_args,

        .. Default::default()
    }
}