Skip to content

add first HelenOS compilation targets #139310

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

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions compiler/rustc_target/src/spec/base/helenos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use crate::spec::{PanicStrategy, RelroLevel, StackProbeType, TargetOptions};

pub(crate) fn opts() -> TargetOptions {
TargetOptions {
os: "helenos".into(),

dynamic_linking: true,
// we need the linker to keep libgcc and friends
no_default_libraries: false,
has_rpath: true,
relro_level: RelroLevel::Full,
panic_strategy: PanicStrategy::Abort,
stack_probes: StackProbeType::Inline,

..Default::default()
}
}
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/base/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub(crate) mod dragonfly;
pub(crate) mod freebsd;
pub(crate) mod fuchsia;
pub(crate) mod haiku;
pub(crate) mod helenos;
pub(crate) mod hermit;
pub(crate) mod hurd;
pub(crate) mod hurd_gnu;
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,11 @@ supported_targets! {
("i686-unknown-haiku", i686_unknown_haiku),
("x86_64-unknown-haiku", x86_64_unknown_haiku),

("aarch64-unknown-helenos", aarch64_unknown_helenos),
("armv5te-unknown-helenos-eabi", armv5te_unknown_helenos_eabi),
("i686-unknown-helenos", i686_unknown_helenos),
("x86_64-unknown-helenos", x86_64_unknown_helenos),

("i686-unknown-hurd-gnu", i686_unknown_hurd_gnu),
("x86_64-unknown-hurd-gnu", x86_64_unknown_hurd_gnu),

Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_target/src/spec/targets/aarch64_unknown_helenos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::spec::{Target, base};

pub(crate) fn target() -> Target {
let mut base = base::helenos::opts();
base.max_atomic_width = Some(128);
base.features = "+v8a".into();
base.linker = Some("aarch64-helenos-gcc".into());

Target {
llvm_target: "aarch64-unknown-helenos".into(),
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 HelenOS".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(true),
},
pointer_width: 64,
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: "aarch64".into(),
options: base,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::spec::{Cc, FloatAbi, LinkerFlavor, Lld, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::helenos::opts();
base.abi = "eabi".into();
base.llvm_floatabi = Some(FloatAbi::Soft);
base.max_atomic_width = Some(32);
base.features = "+soft-float,+strict-align,+atomics-32".into();
base.has_thumb_interworking = true;
base.linker = Some("arm-helenos-gcc".into());
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-march=armv5te"]);

// FIXME: these 3 flags are a hack to avoid generating R_*_RELATIVE relocations in code segment,
// which cause the HelenOS loader to segfault. I believe the underlying issue is that HelenOS
// doesn't map the code segment as writable, so the loader can't apply the relocations.
// The same issue was with the i686-helenos target, I don't recall why the current combination
// of flags avoids the issue there.
base.crt_static_default = true;
base.crt_static_respected = false;
base.crt_static_allows_dylibs = true;

Target {
llvm_target: "armv5te-unknown-helenos-eabi".into(),
metadata: crate::spec::TargetMetadata {
description: Some("ARMv5te HelenOS".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(true),
},
pointer_width: 32,
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
arch: "arm".into(),
options: base,
}
}
25 changes: 25 additions & 0 deletions compiler/rustc_target/src/spec/targets/i686_unknown_helenos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::spec::{Cc, LinkerFlavor, Lld, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::helenos::opts();
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.linker = Some("i686-helenos-gcc".into());
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);

Target {
llvm_target: "i686-unknown-helenos".into(),
metadata: crate::spec::TargetMetadata {
description: Some("IA-32 (i686) HelenOS".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(true),
},
pointer_width: 32,
data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
i128:128-f64:32:64-f80:32-n8:16:32-S128"
.into(),
arch: "x86".into(),
options: base,
}
}
25 changes: 25 additions & 0 deletions compiler/rustc_target/src/spec/targets/x86_64_unknown_helenos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::spec::{Cc, LinkerFlavor, Lld, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::helenos::opts();
base.cpu = "x86-64".into();
base.plt_by_default = false;
base.max_atomic_width = Some(64);
base.linker = Some("amd64-helenos-gcc".into());
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);

Target {
llvm_target: "x86_64-unknown-helenos".into(),
metadata: crate::spec::TargetMetadata {
description: Some("64-bit HelenOS".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(true),
},
pointer_width: 64,
data_layout:
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: "x86_64".into(),
options: base,
}
}
4 changes: 4 additions & 0 deletions src/bootstrap/src/core/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ pub struct Finder {
//
// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
const STAGE0_MISSING_TARGETS: &[&str] = &[
"aarch64-unknown-helenos",
"armv5te-unknown-helenos-eabi",
"i686-unknown-helenos",
"x86_64-unknown-helenos",
// just a dummy comment so the list doesn't get onelined
"x86_64-lynx-lynxos178",
];
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 @@ -106,6 +106,7 @@
- [solaris](platform-support/solaris.md)
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)
- [\*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md)
- [\*-unknown-helenos](platform-support/helenos.md)
- [\*-unknown-hermit](platform-support/hermit.md)
- [\*-unknown-freebsd](platform-support/freebsd.md)
- [\*-unknown-netbsd\*](platform-support/netbsd.md)
Expand Down
4 changes: 4 additions & 0 deletions src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ target | std | host | notes
[`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-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | ARM64 FreeBSD
[`aarch64-unknown-helenos`](platform-support/helenos.md) | ? | | ARM64 HelenOS
[`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit
[`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos
`aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
Expand Down Expand Up @@ -280,6 +281,7 @@ target | std | host | notes
[`armv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Bare Armv4T
`armv4t-unknown-linux-gnueabi` | ? | | Armv4T Linux
[`armv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Bare Armv5TE
[`armv5te-unknown-helenos-eabi`](platform-support/helenos.md) | ? | | Armv5TE HelenOS
`armv5te-unknown-linux-uclibceabi` | ? | | Armv5TE Linux with uClibc
[`armv6-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | Armv6 FreeBSD
[`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv6 NetBSD w/hard-float
Expand Down Expand Up @@ -313,6 +315,7 @@ target | std | host | notes
[`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI]
[`i686-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI]
`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI]
[`i686-unknown-helenos`](platform-support/helenos.md) | ? | | 32-bit (IA-32) HelenOS
[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (Pentium 4) [^x86_32-floats-return-ABI]
[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 (Pentium 4) [^x86_32-floats-return-ABI]
[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD (Pentium 4) [^x86_32-floats-return-ABI]
Expand Down Expand Up @@ -416,6 +419,7 @@ target | std | host | notes
`x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
`x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
[`x86_64-unknown-hermit`](platform-support/hermit.md) | ✓ | | x86_64 Hermit
[`x86_64-unknown-helenos`](platform-support/helenos.md) | ? | | x86_64 (amd64) HelenOS
[`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd
`x86_64-unknown-l4re-uclibc` | ? | |
[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc
Expand Down
62 changes: 62 additions & 0 deletions src/doc/rustc/src/platform-support/helenos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# `*-unknown-helenos`

**Tier: 3**

Targets for [HelenOS](https://www.helenos.org).
These targets allow compiling user-space applications, that you can then copy into your HelenOS ISO image to run them.

Target triplets available so far:

- `x86_64-unknown-helenos`
- `i686-unknown-helenos`

## Target maintainers

- Matěj Volf ([@mvolfik](https://github.com/mvolfik))

## Requirements

These targets only support cross-compilation. The targets will[^helenos-libstd-pending] support libstd, although support of some platform features (filesystem, networking) may be limited.

You need to have a local clone of the HelenOS repository and the HelenOS toolchain set up, no HelenOS-Rust development artifacts are available.

[^helenos-libstd-pending]: libstd is not yet available, because it needs to be done in a separate PR, because compiler support needs to be merged first to allow creating libc bindings

## Building

### HelenOS toolchain setup

For compilation of standard library, you need to build the HelenOS toolchain (because Rust needs to use `*-helenos-gcc` as linker) and its libraries (libc and a few others). See [this HelenOS wiki page](https://www.helenos.org/wiki/UsersGuide/CompilingFromSource#a2.Buildasupportedcross-compiler) for instruction on setting up the build. At the end of step 4 (_Configure and build_), after `ninja image_path`, invoke `ninja export-dev` to build the shared libraries.

Copy the libraries to the path where the compiler automatically searches for them. This will be the directory where you installed the toolchain (for example `~/.local/share/HelenOS/cross/i686-helenos/lib`). In the folder where you built HelenOS, you can run these commands:

```sh
touch /tmp/test.c
HELENOS_LIB_PATH="$(realpath "$(i686-helenos-gcc -v -c /tmp/test.c 2>&1 | grep LIBRARY_PATH | cut -d= -f2 | cut -d: -f3)")"
# use amd64-helenos-gcc above for x86_64 toolchain, etc
cp export-dev/lib/* dist/lib/libc.so.0 dist/lib/libposix.so.0 "$HELENOS_LIB_PATH"
ln -s libposix.so.0 "$HELENOS_LIB_PATH/libposix.so"
ln -s libc.so.0 "$HELENOS_LIB_PATH/libc.so"
```

This automatically determines the library path, copies the libraries, and creates the necessary unversioned shared library symlinks.

### Building the target

When you have the HelenOS toolchain set up and installed in your path, you can build the Rust toolchain using the standard procedure. See [rustc dev guide](https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html).

In the most simple case, this means that you can run `./x build library --stage 1 --target x86_64-unknown-linux-gnu,i686-unknown-helenos` (the first target triple should be your host machine, adjust accordingly). Then run `rustup toolchain link mytoolchain build/host/stage1` to allow using your toolchain for building Rust programs.

### Building Rust programs

If you linked the toolchain above as `mytoolchain`, run `cargo +mytoolchain build --target <arch>-unknown-helenos`.

## Testing

After you build a Rust program for HelenOS, you can put it into the `dist` directory of the HelenOS build, build the ISO image, and then run it either in an emulator, or on real hardware. See HelenOS wiki for further instructions on running the OS.

Running the Rust testsuite has not been attempted yet due to missing host tools (thus the test suite can't be run natively) and insufficient networking support (thus we can't use the `remote-test-server` tool).

## Cross-compilation toolchains and C code

You should be able to cross-compile and link any needed C code using `<arch>-helenos-gcc` that you built above. However, note that clang support is highly lacking. Therefore, to run tools such as `bindgen`, you will need to provide flag `-nostdinc` and manually specify the include paths to HelenOS headers, which you will find in the `export-dev` folder + in the cross-compilation toolchain (e.g. `~/.local/share/HelenOS/cross/lib/gcc/i686-helenos/14.2.0/include`).
12 changes: 12 additions & 0 deletions tests/assembly/targets/targets-elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
//@ revisions: aarch64_unknown_fuchsia
//@ [aarch64_unknown_fuchsia] compile-flags: --target aarch64-unknown-fuchsia
//@ [aarch64_unknown_fuchsia] needs-llvm-components: aarch64
//@ revisions: aarch64_unknown_helenos
//@ [aarch64_unknown_helenos] compile-flags: --target aarch64-unknown-helenos
//@ [aarch64_unknown_helenos] needs-llvm-components: aarch64
//@ revisions: aarch64_unknown_hermit
//@ [aarch64_unknown_hermit] compile-flags: --target aarch64-unknown-hermit
//@ [aarch64_unknown_hermit] needs-llvm-components: aarch64
Expand Down Expand Up @@ -115,6 +118,9 @@
//@ revisions: armv5te_none_eabi
//@ [armv5te_none_eabi] compile-flags: --target armv5te-none-eabi
//@ [armv5te_none_eabi] needs-llvm-components: arm
//@ revisions: armv5te_unknown_helenos_eabi
//@ [armv5te_unknown_helenos_eabi] compile-flags: --target armv5te-unknown-helenos-eabi
//@ [armv5te_unknown_helenos_eabi] needs-llvm-components: arm
//@ revisions: armv5te_unknown_linux_gnueabi
//@ [armv5te_unknown_linux_gnueabi] compile-flags: --target armv5te-unknown-linux-gnueabi
//@ [armv5te_unknown_linux_gnueabi] needs-llvm-components: arm
Expand Down Expand Up @@ -241,6 +247,9 @@
//@ revisions: i686_unknown_haiku
//@ [i686_unknown_haiku] compile-flags: --target i686-unknown-haiku
//@ [i686_unknown_haiku] needs-llvm-components: x86
//@ revisions: i686_unknown_helenos
//@ [i686_unknown_helenos] compile-flags: --target i686-unknown-helenos
//@ [i686_unknown_helenos] needs-llvm-components: x86
//@ revisions: i686_unknown_hurd_gnu
//@ [i686_unknown_hurd_gnu] compile-flags: --target i686-unknown-hurd-gnu
//@ [i686_unknown_hurd_gnu] needs-llvm-components: x86
Expand Down Expand Up @@ -601,6 +610,9 @@
//@ revisions: x86_64_unknown_haiku
//@ [x86_64_unknown_haiku] compile-flags: --target x86_64-unknown-haiku
//@ [x86_64_unknown_haiku] needs-llvm-components: x86
//@ revisions: x86_64_unknown_helenos
//@ [x86_64_unknown_helenos] compile-flags: --target x86_64-unknown-helenos
//@ [x86_64_unknown_helenos] needs-llvm-components: x86
//@ revisions: x86_64_unknown_hurd_gnu
//@ [x86_64_unknown_hurd_gnu] compile-flags: --target x86_64-unknown-hurd-gnu
//@ [x86_64_unknown_hurd_gnu] needs-llvm-components: x86
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/check-cfg/well-known-values.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_os = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration

warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
Expand Down Expand Up @@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
| |
| help: there is a expected value with a similar name: `"linux"`
|
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration

warning: 28 warnings emitted
Expand Down
Loading