diff --git a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs new file mode 100644 index 0000000000000..1b7161fbb85c5 --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs @@ -0,0 +1,26 @@ +use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelroLevel, Target, TargetOptions}; + +const LINKER_SCRIPT: &str = include_str!("./aarch64_nintendo_switch_freestanding_linker_script.ld"); + +/// A base target for Nintendo Switch devices using a pure LLVM toolchain. +pub fn target() -> Target { + Target { + llvm_target: "aarch64-unknown-none".into(), + pointer_width: 64, + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), + arch: "aarch64".into(), + options: TargetOptions { + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker: Some("rust-lld".into()), + link_script: Some(LINKER_SCRIPT.into()), + os: "horizon".into(), + max_atomic_width: Some(128), + panic_strategy: PanicStrategy::Abort, + position_independent_executables: true, + dynamic_linking: true, + executables: true, + relro_level: RelroLevel::Off, + ..Default::default() + }, + } +} diff --git a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding_linker_script.ld b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding_linker_script.ld new file mode 100644 index 0000000000000..f3441e6593782 --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding_linker_script.ld @@ -0,0 +1,78 @@ +OUTPUT_FORMAT(elf64-littleaarch64) +OUTPUT_ARCH(aarch64) +ENTRY(_start) + +PHDRS +{ + text PT_LOAD FLAGS(5); + rodata PT_LOAD FLAGS(4); + data PT_LOAD FLAGS(6); + bss PT_LOAD FLAGS(6); + dynamic PT_DYNAMIC; +} + +SECTIONS +{ + . = 0; + + .text : ALIGN(0x1000) { + HIDDEN(__text_start = .); + KEEP(*(.text.jmp)) + + . = 0x80; + + *(.text .text.*) + *(.plt .plt.*) + } + + /* Read-only sections */ + + . = ALIGN(0x1000); + + .module_name : { *(.module_name) } :rodata + + .rodata : { *(.rodata .rodata.*) } :rodata + .hash : { *(.hash) } + .dynsym : { *(.dynsym .dynsym.*) } + .dynstr : { *(.dynstr .dynstr.*) } + .rela.dyn : { *(.rela.dyn) } + + .eh_frame : { + HIDDEN(__eh_frame_start = .); + *(.eh_frame .eh_frame.*) + HIDDEN(__eh_frame_end = .); + } + + .eh_frame_hdr : { + HIDDEN(__eh_frame_hdr_start = .); + *(.eh_frame_hdr .eh_frame_hdr.*) + HIDDEN(__eh_frame_hdr_end = .); + } + + /* Read-write sections */ + + . = ALIGN(0x1000); + + .data : { + *(.data .data.*) + *(.got .got.*) + *(.got.plt .got.plt.*) + } :data + + .dynamic : { + HIDDEN(__dynamic_start = .); + *(.dynamic) + } + + /* BSS section */ + + . = ALIGN(0x1000); + + .bss : { + HIDDEN(__bss_start = .); + *(.bss .bss.*) + *(COMMON) + . = ALIGN(8); + HIDDEN(__bss_end = .); + } :bss +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index ef49fc8e968a8..1a6bb4a2eaf34 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1035,6 +1035,8 @@ supported_targets! { ("armv6k-nintendo-3ds", armv6k_nintendo_3ds), + ("aarch64-nintendo-switch-freestanding", aarch64_nintendo_switch_freestanding), + ("armv7-unknown-linux-uclibceabi", armv7_unknown_linux_uclibceabi), ("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf), diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 62dd9a6b36502..ea0f78e2a6be9 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -411,7 +411,7 @@ pub struct Target { impl Target { pub fn from_triple(triple: &str) -> Self { let mut target: Self = Default::default(); - if triple.contains("-none") || triple.contains("nvptx") { + if triple.contains("-none") || triple.contains("nvptx") || triple.contains("switch") { target.no_std = true; } target diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index c5d62a8810a8b..1895e2901489e 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -298,7 +298,8 @@ pub fn use_host_linker(target: TargetSelection) -> bool { || target.contains("nvptx") || target.contains("fortanix") || target.contains("fuchsia") - || target.contains("bpf")) + || target.contains("bpf") + || target.contains("switch")) } pub fn is_valid_test_suite_arg<'a, P: AsRef>( diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 87dc513853968..f6348b2bddc88 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -17,6 +17,7 @@ - [Template for Target-specific Documentation](platform-support/TEMPLATE.md) - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md) - [\*-apple-watchos\*](platform-support/apple-watchos.md) + - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md) - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index eb985803266e7..7a03238f13dff 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -209,6 +209,7 @@ target | std | host | notes `aarch64-apple-tvos` | * | | ARM64 tvOS [`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 +[`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore diff --git a/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md b/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md new file mode 100644 index 0000000000000..308e1fe2f92a0 --- /dev/null +++ b/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md @@ -0,0 +1,49 @@ +# aarch64-nintendo-switch-freestanding + +**Tier: 3** + +Nintendo Switch with pure-Rust toolchain. + +## Designated Developers + +* [@leo60228](https://github.com/leo60228) +* [@jam1garner](https://github.com/jam1garner) + +## Requirements + +This target is cross-compiled. +It has no special requirements for the host. + +## Building + +The target can be built by enabling it for a `rustc` build: + +```toml +[build] +build-stage = 1 +target = ["aarch64-nintendo-switch-freestanding"] +``` + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +Currently there is no support to run the rustc test suite for this target. + +## Building Rust programs + +If `rustc` has support for that target and the library artifacts are available, +then Rust programs can be built for that target: + +```text +rustc --target aarch64-nintendo-switch-freestanding your-code.rs +``` + +To generate binaries in the NRO format that can be easily run on-device, you +can use [cargo-nx](https://github.com/aarch64-switch-rs/cargo-nx): + +```text +cargo nx --triple=aarch64-nintendo-switch-freestanding +```