Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
matrix:
build: [ubuntu, i686-linux, aarch64-linux, riscv64-linux]
rust: [1.78, nightly-2025-01-02]
rust: [1.78, nightly-2025-03-05]
include:
- build: ubuntu
os: ubuntu-latest
Expand Down Expand Up @@ -51,7 +51,7 @@ jobs:
qemu: qemu-riscv64 -L /usr/riscv64-linux-gnu
qemu_target: riscv64-linux-user
host_target: riscv64gc-unknown-linux-gnu
- rust: nightly-2025-01-02
- rust: nightly-2025-03-05
features: nightly
steps:
- uses: actions/checkout@v4
Expand Down
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ include = ["src", "Cargo.toml", "COPYRIGHT", "LICENSE*", "/*.md"]
rust-version = "1.78"

[dependencies]
linux-raw-sys = { version = "0.4.9", default-features = false, features = ["general", "no_std", "elf"] }
rustix = { version = "0.38.35", default-features = false }
linux-raw-sys = { version = "0.9.2", default-features = false, features = ["general", "no_std", "elf"] }
rustix = { version = "1.0.0", default-features = false }
bitflags = { version = "2.4.0", default-features = false }
log = { version = "0.4.14", default-features = false, optional = true }
rustix-futex-sync = { version = "0.2.1", optional = true }
rustix-futex-sync = { version = "0.3.0", optional = true }
smallvec = { version = "1.11.1", optional = true, features = ["const_new"] }

# Optional logging backends for use with "take-charge". You can use any
Expand All @@ -31,7 +31,7 @@ smallvec = { version = "1.11.1", optional = true, features = ["const_new"] }
env_logger = { version = "0.11.0", default-features = false, optional = true }

# Enable `atomic-dbg`'s simple logger. This doesn't require `std`.
atomic-dbg = { version = "0.1", default-features = false, optional = true }
atomic-dbg = { version = "0.1.11", default-features = false, optional = true }

# Enable this when disabling origin's implementations.
libc = { version = "0.2.149", default-features = false, optional = true }
Expand All @@ -52,7 +52,7 @@ optional = true
# On aarch64, compiler_builtins depends on `getauxval`, so we need rustix with
# the "param" feature.
[target.'cfg(target_arch = "aarch64")'.dependencies.rustix]
version = "0.38.35"
version = "1.0.0"
default-features = false
features = ["param"]

Expand Down
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ 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 [no-std example] uses `#![no_std]` and starts the program using Rust's
`#[start]` feature, and then hands control to Origin. libc is still
doing most of the work here.

- 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
Expand Down
4 changes: 2 additions & 2 deletions example-crates/external-start/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ origin = { path = "../..", default-features = false, features = ["external-start
libc = { version = "0.2", default-features = false }

# Crates to help writing no_std code.
atomic-dbg = { version = "0.1.8", default-features = false }
rustix-dlmalloc = { version = "0.1.0", features = ["global"] }
atomic-dbg = { version = "0.1.11", default-features = false }
rustix-dlmalloc = { version = "0.2.1", features = ["global"] }

# This is just an example crate, and not part of the origin workspace.
[workspace]
17 changes: 0 additions & 17 deletions example-crates/no-std/Cargo.toml

This file was deleted.

2 changes: 0 additions & 2 deletions example-crates/no-std/README.md

This file was deleted.

48 changes: 0 additions & 48 deletions example-crates/no-std/src/main.rs

This file was deleted.

4 changes: 2 additions & 2 deletions example-crates/origin-start-dynamic-linker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ crate-type = ["cdylib"]
origin = { path = "../..", default-features = false, features = ["origin-start", "program-at-exit", "thread-at-exit", "experimental-relocate", "eh-personality-continue", "panic-handler-trap", "nightly"] }

# Crates to help writing no_std code.
atomic-dbg = { version = "0.1.8", default-features = false }
rustix-dlmalloc = { version = "0.1.0", features = ["global"] }
atomic-dbg = { version = "0.1.11", default-features = false }
rustix-dlmalloc = { version = "0.2.1", features = ["global"] }

# This is just an example crate, and not part of the origin workspace.
[workspace]
4 changes: 2 additions & 2 deletions example-crates/origin-start-lto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ publish = false
origin = { path = "../..", default-features = false, features = ["origin-start", "program-at-exit", "thread-at-exit", "eh-personality-continue", "panic-handler-trap", "nightly"] }

# Crates to help writing no_std code.
atomic-dbg = { version = "0.1.8", default-features = false }
rustix-dlmalloc = { version = "0.1.0", features = ["global"] }
atomic-dbg = { version = "0.1.11", default-features = false }
rustix-dlmalloc = { version = "0.2.1", features = ["global"] }

# This is just an example crate, and not part of the origin workspace.
[workspace]
Expand Down
2 changes: 1 addition & 1 deletion example-crates/origin-start-no-alloc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ publish = false
origin = { path = "../..", default-features = false, features = ["origin-start", "eh-personality-continue", "panic-handler-trap", "nightly"] }

# Crates to help writing no_std code.
atomic-dbg = { version = "0.1.8", default-features = false }
atomic-dbg = { version = "0.1.11", default-features = false }

# This is just an example crate, and not part of the origin workspace.
[workspace]
4 changes: 2 additions & 2 deletions example-crates/origin-start-panic-abort/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ publish = false
origin = { path = "../..", default-features = false, features = ["origin-start", "program-at-exit", "thread-at-exit", "eh-personality-continue", "panic-handler-trap", "nightly"] }

# Crates to help writing no_std code.
atomic-dbg = { version = "0.1.8", default-features = false }
rustix-dlmalloc = { version = "0.1.0", features = ["global"] }
atomic-dbg = { version = "0.1.11", default-features = false }
rustix-dlmalloc = { version = "0.2.1", features = ["global"] }

[profile.dev]
panic = "abort"
Expand Down
4 changes: 2 additions & 2 deletions example-crates/origin-start-stable/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ publish = false
origin = { path = "../..", default-features = false, features = ["origin-start", "program-at-exit", "thread-at-exit", "eh-personality-continue", "panic-handler-trap"] }

# Crates to help writing no_std code.
atomic-dbg = { version = "0.1.8", default-features = false }
rustix-dlmalloc = { version = "0.1.0", features = ["global"] }
atomic-dbg = { version = "0.1.11", default-features = false }
rustix-dlmalloc = { version = "0.2.1", features = ["global"] }

[profile.dev]
panic = "abort"
Expand Down
4 changes: 2 additions & 2 deletions example-crates/origin-start/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ publish = false
origin = { path = "../..", default-features = false, features = ["origin-start", "program-at-exit", "thread-at-exit", "eh-personality-continue", "panic-handler-trap", "nightly"] }

# Crates to help writing no_std code.
atomic-dbg = { version = "0.1.8", default-features = false }
rustix-dlmalloc = { version = "0.1.0", features = ["global"] }
atomic-dbg = { version = "0.1.11", default-features = false }
rustix-dlmalloc = { version = "0.2.1", features = ["global"] }

# This is just an example crate, and not part of the origin workspace.
[workspace]
2 changes: 1 addition & 1 deletion example-crates/tiny-hello/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ publish = false
[dependencies]
# Origin can be depended on just like any other crate. For no_std, disable
# the default features, and add the desired features.
rustix = { version = "0.38.35", default-features = false, features = ["stdio"] }
rustix = { version = "1.0.0", default-features = false, features = ["stdio"] }
origin = { path = "../..", default-features = false, features = ["origin-start", "eh-personality-continue", "panic-handler-trap", "nightly", "optimize_for_size"] }

# This is just an example crate, and not part of the origin workspace.
Expand Down
11 changes: 7 additions & 4 deletions src/arch/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use core::arch::asm;
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
use linux_raw_sys::elf::{Elf_Dyn, Elf_Ehdr};
use linux_raw_sys::elf::Elf_Ehdr;
#[cfg(feature = "take-charge")]
#[cfg(feature = "signal")]
#[cfg(test)]
Expand Down Expand Up @@ -60,9 +60,12 @@ pub(super) fn trap() -> ! {
}

/// Compute the dynamic address of `_DYNAMIC`.
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
pub(super) fn dynamic_table_addr() -> *const Elf_Dyn {
#[cfg(any(
all(feature = "thread", feature = "take-charge"),
all(feature = "experimental-relocate", feature = "origin-start")
))]
#[allow(dead_code)]
pub(super) fn dynamic_table_addr() -> *const linux_raw_sys::elf::Elf_Dyn {
let addr;
unsafe {
asm!(
Expand Down
11 changes: 7 additions & 4 deletions src/arch/arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use core::arch::asm;
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
use linux_raw_sys::elf::{Elf_Dyn, Elf_Ehdr};
use linux_raw_sys::elf::Elf_Ehdr;
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
use linux_raw_sys::general::{__NR_mprotect, PROT_READ};
Expand Down Expand Up @@ -60,9 +60,12 @@ pub(super) fn trap() -> ! {
}

/// Compute the dynamic address of `_DYNAMIC`.
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
pub(super) fn dynamic_table_addr() -> *const Elf_Dyn {
#[cfg(any(
all(feature = "thread", feature = "take-charge"),
all(feature = "experimental-relocate", feature = "origin-start")
))]
#[allow(dead_code)]
pub(super) fn dynamic_table_addr() -> *const linux_raw_sys::elf::Elf_Dyn {
let addr;
unsafe {
asm!(
Expand Down
11 changes: 7 additions & 4 deletions src/arch/riscv64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use core::arch::asm;
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
use linux_raw_sys::elf::{Elf_Dyn, Elf_Ehdr};
use linux_raw_sys::elf::Elf_Ehdr;
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
use linux_raw_sys::general::{__NR_mprotect, PROT_READ};
Expand Down Expand Up @@ -57,9 +57,12 @@ pub(super) fn trap() -> ! {
}

/// Compute the dynamic address of `_DYNAMIC`.
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
pub(super) fn dynamic_table_addr() -> *const Elf_Dyn {
#[cfg(any(
all(feature = "thread", feature = "take-charge"),
all(feature = "experimental-relocate", feature = "origin-start")
))]
#[allow(dead_code)]
pub(super) fn dynamic_table_addr() -> *const linux_raw_sys::elf::Elf_Dyn {
let addr;
unsafe {
asm!(
Expand Down
22 changes: 8 additions & 14 deletions src/arch/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use core::arch::asm;
use core::ptr::without_provenance_mut;
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
use linux_raw_sys::elf::{Elf_Dyn, Elf_Ehdr};
use linux_raw_sys::elf::Elf_Ehdr;
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
use linux_raw_sys::general::{__NR_mprotect, PROT_READ};
Expand Down Expand Up @@ -72,9 +72,12 @@ pub(super) fn trap() -> ! {
}

/// Compute the dynamic address of `_DYNAMIC`.
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
pub(super) fn dynamic_table_addr() -> *const Elf_Dyn {
#[cfg(any(
all(feature = "thread", feature = "take-charge"),
all(feature = "experimental-relocate", feature = "origin-start")
))]
#[allow(dead_code)]
pub(super) fn dynamic_table_addr() -> *const linux_raw_sys::elf::Elf_Dyn {
let addr;
unsafe {
asm!(
Expand All @@ -83,17 +86,8 @@ pub(super) fn dynamic_table_addr() -> *const Elf_Dyn {
"call 2f",
".cfi_adjust_cfa_offset 4",
"2:",
"pop {0}",
"pop {0}", // We depend on this being exactly one byte long.
".cfi_adjust_cfa_offset -4",
"3:",
// Use "2" and "3" instead of "0" and "1" because "0b" and "1b" are
// parsed as binary literals rather than as label references. And,
// hard-code the value `1` here because the assembler doesn't support
// the symbol difference expression in an instruction operand
// context. Then, check that the hard-coded value is what we expect.
".ifne (3b-2b)-1",
".error \"The pop opcode is expected to be 1 byte long.\"",
".endif",
"add {0}, offset _GLOBAL_OFFSET_TABLE_+1",
"lea {0}, [{0} + _DYNAMIC@GOTOFF]",
out(reg) addr
Expand Down
11 changes: 7 additions & 4 deletions src/arch/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use core::arch::asm;
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
use linux_raw_sys::elf::{Elf_Dyn, Elf_Ehdr};
use linux_raw_sys::elf::Elf_Ehdr;
#[cfg(feature = "take-charge")]
#[cfg(feature = "signal")]
#[cfg(test)]
Expand Down Expand Up @@ -60,9 +60,12 @@ pub(super) fn trap() -> ! {
}

/// Compute the dynamic address of `_DYNAMIC`.
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
#[cfg(relocation_model = "pic")]
pub(super) fn dynamic_table_addr() -> *const Elf_Dyn {
#[cfg(any(
all(feature = "thread", feature = "take-charge"),
all(feature = "experimental-relocate", feature = "origin-start")
))]
#[allow(dead_code)]
pub(super) fn dynamic_table_addr() -> *const linux_raw_sys::elf::Elf_Dyn {
let addr;
unsafe {
asm!(
Expand Down
14 changes: 6 additions & 8 deletions src/relocate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,12 @@ pub(super) unsafe fn relocate(envp: *mut *mut u8) {
return;
}

let the_ehdr = &*ehdr_addr();

let base = if auxv_base == null_mut() {
// Obtain the static address of `_start`, which is recorded in the
// entry field of the ELF header.
let static_start = (*ehdr_addr()).e_entry;
let static_start = the_ehdr.e_entry;

// This is case 2) as without dynamic linker `AT_BASE` doesn't exist
// and we have already excluded case 1) above.
Expand Down Expand Up @@ -330,18 +332,14 @@ pub(super) unsafe fn relocate(envp: *mut *mut u8) {
// Finally, look through the static segment headers (phdrs) to find the
// the relro description if present. Also do a debug assertion that
// the dynv argument matches the PT_DYNAMIC segment.
extern "C" {
#[link_name = "__ehdr_start"]
static EHDR: Elf_Ehdr;
}

// The location and size of the `relro` region.
let mut relro = 0;
let mut relro_size = 0;

let phentsize = EHDR.e_phentsize as usize;
let mut current_phdr = base.byte_add(EHDR.e_phoff).cast::<Elf_Phdr>();
let phdrs_end = current_phdr.byte_add(EHDR.e_phnum as usize * phentsize);
let phentsize = the_ehdr.e_phentsize as usize;
let mut current_phdr = base.byte_add(the_ehdr.e_phoff).cast::<Elf_Phdr>();
let phdrs_end = current_phdr.byte_add(the_ehdr.e_phnum as usize * phentsize);
while current_phdr != phdrs_end {
let phdr = &*current_phdr;
current_phdr = current_phdr.byte_add(phentsize);
Expand Down
Loading