Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Nintendo Switch as tier 3 target #88991

Merged
merged 10 commits into from
Jul 15, 2022
Original file line number Diff line number Diff line change
@@ -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()
},
}
}
Original file line number Diff line number Diff line change
@@ -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
}
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),

Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Off topic - could this be turned into a no_std flag in the target config file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The linker has the same issue with a FIXME for pulling the info from the target config file. I'm guessing that bootstrap doesn't have a way to access the actual target definition.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bootstrap could invoke rustc using --print cfg or something similar to print if the target is no_std if the target config file contains this. If it is a cfg, libstd could use the same cfg for restricted-std.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this PR, though, it's just temporary until std is implemented on Switch.

target.no_std = true;
}
target
Expand Down
3 changes: 2 additions & 1 deletion src/bootstrap/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Path>>(
Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
```