sunfishcode / origin
Program startup and thread support written in Rust
README
Origin implements program startup and shutdown, as well as thread startup and
shutdown, for Linux, implemented in Rust.
Program startup and shutdown for Linux is traditionally implemented in crt1.o,
and the libc functions exit, atexit, and _exit. And thread startup and
shutdown are traditionally implemented in libpthread functions
pthread_create, pthread_join, pthread_detach, and so on. Origin provides
its own implementations of this functionality, written in Rust.
For a C-ABI-compatible interface to this functionality, see c-scape.
This is used by Mustang and Eyra in their libc implementations, and in the
Origin Studio project in its std implementation, which are three different
ways to support building Rust programs written entirely in Rust.
It works with both stable (currently Rust >= 1.85) and nightly Rust. If you're
using nightly Rust, enable the feature "nightly" to let origin use nightly-only
features, which include proper support for unwinding, better safety checks, and
better optimizations.
Origin supports multiple architectures: x86-64, x86, aarch64, arm (32-bit),
riscv64, powerpc64, and mips32. The arm, powerpc64, and mips32 ports are not
tested in CI, for reasons that range from "Rust doesn't ship binaries for that"
to "that one crate doesn't support this arch yet":
-
mips32: rust-std isn't available for download. CI would need
-Zbuild-std
to build the standard library from source, which is nightly-only. -
powerpc64: On stable, rustix uses the libc backend which is missing the
runtime module for signal handling. On nightly, theunwindingcrate hasn't
caught up with ppc64 yet. -
arm (32-bit): CI setup exists on a branch somewhere, waiting to be merged.
Example crates
Origin can also be used on its own, in several different configurations:
-
The basic example shows a simple example of using Origin as a simple
library. In this configuration, libc is doing most of the work. -
The external-start example uses
#![no_std]and#![no_main], and starts
the program by taking over control from libc as soon as possible, and then
hands control to Origin. Origin handles program and thread startup and
shutdown once it takes control. -
The origin-start example uses
#![no_std]and#![no_main], and lets
Origin start the program using its own program entrypoint. Origin handles
program and thread startup and shutdown and no part of libc is used. This is
the approach that Origin Studio uses. -
The origin-start-no-alloc example is like origin-start, but disables the
"alloc" and "thread" features, since Origin's "thread" feature currently
depends on "alloc". Without "alloc", functions that return owned strings or
Vecs are not available. In this mode, Origin avoids using a global
allocator entirely. -
The origin-start-lto example is like origin-start, but builds with LTO.
-
The tiny example is like origin-start, but builds with optimization flags,
disables features, and adds an objcopy trick to produce a very small
binary—408 bytes on x86-64!
Fully static linking
The resulting executables in the origin-start, origin-start-no-alloc, and
origin-start-lto examples don't depend on any dynamic libraries, however by
default they do still depend on a dynamic linker.
For fully static linking, there are two options:
-
Build with
RUSTFLAGS=-C target-feature=+crt-static -C relocation-model=static. This
disables PIE mode, which is safer in terms of Origin's code, but loses the
security benefits of Address-Space Layout Randomization (ASLR). -
Build with
RUSTFLAGS=-C target-feature=+crt-staticand enable Origin's
experimental-relocatefeature. This allows PIE mode to work, however it
does so by enabling some experimental code in Origin for performing
relocations.
KiloClaw - Managed 🦀 