Skip to content

Fix build with Rust 1.88 #169

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

Merged
merged 2 commits into from
Jul 15, 2025
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
8 changes: 4 additions & 4 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ fn main() {
let target = env::var("TARGET").unwrap();

// For Cargo integration tests
println!("cargo:rustc-env=NIX_LD_TEST_TARGET={}", target);
println!("cargo:rustc-env=NIX_LD_TEST_TARGET={target}");

// For cross-compiling in the devShell *only*
let target_suffix = target.replace('-', "_");
if let Ok(target_default_nix_ld) = env::var(format!("DEFAULT_NIX_LD_{}", target_suffix)) {
println!("cargo:rustc-env=DEFAULT_NIX_LD={}", target_default_nix_ld);
if let Ok(target_default_nix_ld) = env::var(format!("DEFAULT_NIX_LD_{target_suffix}")) {
println!("cargo:rustc-env=DEFAULT_NIX_LD={target_default_nix_ld}");
}

if let Ok(nix_system) = env::var("NIX_SYSTEM") {
let underscored = nix_system.replace('-', "_");
println!("cargo:rustc-env=NIX_SYSTEM={}", underscored);
println!("cargo:rustc-env=NIX_SYSTEM={underscored}");
}

//let out_dir = std::env::var("OUT_DIR").unwrap();
Expand Down
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
pkgs.cargo-watch
pkgs.cargo-bloat
pkgs.cargo-nextest
pkgs.clippy
pkgs.just

];
Expand Down
92 changes: 43 additions & 49 deletions src/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,67 +145,61 @@ pub const ENTRY_TRAMPOLINE: Option<unsafe extern "C" fn() -> !> = Some(entry_tra
pub const ENTRY_TRAMPOLINE: Option<unsafe extern "C" fn() -> !> = Some(entry_trampoline);

#[cfg(target_arch = "x86_64")]
#[naked]
#[unsafe(naked)]
unsafe extern "C" fn entry_trampoline() -> ! {
unsafe {
core::arch::naked_asm!(
"lea r10, [rip + {context}]",
"mov r11, [r10 + {size} * 1]", // .env_entry
"test r11, r11",
"jz 2f",
"mov r10, [r10 + {size} * 2]", // .env_string
"mov [r11], r10",
"2:",
"jmp [rip + {context}]",
context = sym TRAMPOLINE_CONTEXT,
size = const core::mem::size_of::<*const u8>(),
)
}
core::arch::naked_asm!(
"lea r10, [rip + {context}]",
"mov r11, [r10 + {size} * 1]", // .env_entry
"test r11, r11",
"jz 2f",
"mov r10, [r10 + {size} * 2]", // .env_string
"mov [r11], r10",
"2:",
"jmp [rip + {context}]",
context = sym TRAMPOLINE_CONTEXT,
size = const core::mem::size_of::<*const u8>(),
)
}

#[cfg(target_arch = "aarch64")]
pub const ENTRY_TRAMPOLINE: Option<unsafe extern "C" fn() -> !> = Some(entry_trampoline);

#[cfg(target_arch = "aarch64")]
#[naked]
#[unsafe(naked)]
unsafe extern "C" fn entry_trampoline() -> ! {
unsafe {
core::arch::naked_asm!(
"adrp x8, {context}",
"ldr x9, [x8, {env_entry_off}]", // .env_entry
"cbz x9, 2f",
"ldr x10, [x8, {env_string_off}]", // .env_string
"str x10, [x9]",
"2:",
"ldr x8, [x8]",
"br x8",
context = sym TRAMPOLINE_CONTEXT,
env_entry_off = const TrampolineContext::ENV_ENTRY_OFFSET,
env_string_off = const TrampolineContext::ENV_STRING_OFFSET,
)
}
core::arch::naked_asm!(
"adrp x8, {context}",
"ldr x9, [x8, {env_entry_off}]", // .env_entry
"cbz x9, 2f",
"ldr x10, [x8, {env_string_off}]", // .env_string
"str x10, [x9]",
"2:",
"ldr x8, [x8]",
"br x8",
context = sym TRAMPOLINE_CONTEXT,
env_entry_off = const TrampolineContext::ENV_ENTRY_OFFSET,
env_string_off = const TrampolineContext::ENV_STRING_OFFSET,
)
}

#[cfg(target_arch = "riscv64")]
#[naked]
#[unsafe(naked)]
unsafe extern "C" fn entry_trampoline() -> ! {
unsafe {
core::arch::naked_asm!(
"1:",
"auipc t0, %pcrel_hi({context})",
"addi t0, t0, %pcrel_lo(1b)",
"ld t1, {env_entry_off}(t0)", // .env_entry
"beqz t1, 2f",
"ld t2, {env_string_off}(t0)", // .env_string
"sd t2, 0(t1)",
"2:",
"ld t0, 0(t0)",
"jr t0",
context = sym TRAMPOLINE_CONTEXT,
env_entry_off = const TrampolineContext::ENV_ENTRY_OFFSET,
env_string_off = const TrampolineContext::ENV_STRING_OFFSET,
)
}
core::arch::naked_asm!(
"1:",
"auipc t0, %pcrel_hi({context})",
"addi t0, t0, %pcrel_lo(1b)",
"ld t1, {env_entry_off}(t0)", // .env_entry
"beqz t1, 2f",
"ld t2, {env_string_off}(t0)", // .env_string
"sd t2, 0(t1)",
"2:",
"ld t0, 0(t0)",
"jr t0",
context = sym TRAMPOLINE_CONTEXT,
env_entry_off = const TrampolineContext::ENV_ENTRY_OFFSET,
env_string_off = const TrampolineContext::ENV_STRING_OFFSET,
)
}

// !!!!
Expand Down
19 changes: 9 additions & 10 deletions src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl ElfHandle {

let header = Header::from_bytes(&buf);
if &header.e_ident[..4] != b"\x7fELF".as_slice() {
log::error!("{:?} is not an ELF", path);
log::error!("{path:?} is not an ELF");
return Err(IoError::Unknown);
}

Expand All @@ -91,13 +91,13 @@ impl ElfHandle {
}

if header.e_type != ET_DYN {
log::error!("{:?} is not a dynamic library", path);
log::error!("{path:?} is not a dynamic library");
return Err(IoError::Unknown);
}

let phsize = header.e_phentsize as usize * header.e_phnum as usize;
if phsize == 0 || phsize > 65536 {
log::error!("{:?} has incorrect program header size {}", path, phsize);
log::error!("{path:?} has incorrect program header size {phsize}");
return Err(IoError::Unknown);
}

Expand Down Expand Up @@ -168,15 +168,14 @@ impl ElfHandle {
let entry_point = (load_bias + self.entry_point_v) as *const c_void;

log::debug!(" Total Size: 0x{:x}", summary.total_mapping_size);
log::debug!(" Load Addr: {:x?}", load_addr);
log::debug!(" Load Addr: {load_addr:x?}");
log::debug!(" First Vaddr: 0x{:x?}", summary.first_vaddr);
log::debug!(" Load Bias: 0x{:x?}", load_bias);
log::debug!(" Entry Point: 0x{:x?}", entry_point);
log::debug!(" Load Bias: 0x{load_bias:x?}");
log::debug!(" Entry Point: 0x{entry_point:x?}");
log::debug!(" Page Size: {}", self.page_size);

log::debug!(
"GDB: add-symbol-file /path/to/ld.so.symbols 0x{:x}",
load_bias
"GDB: add-symbol-file /path/to/ld.so.symbols 0x{load_bias:x}"
);

for ph in self.phs.iter() {
Expand Down Expand Up @@ -263,7 +262,7 @@ impl ElfHandle {
};

if mapping == MAP_FAILED {
log::error!("Failed to map anonymous portion for segment 0x{:x}", vaddr);
log::error!("Failed to map anonymous portion for segment 0x{vaddr:x}");
return Err(());
}
}
Expand Down Expand Up @@ -393,7 +392,7 @@ impl fmt::Display for DisplayPFlags<'_> {
let p_flags = &self.0.p_flags;
let mut write_prot = |mask, s| {
if p_flags & mask != 0 {
write!(f, "{}", s)
write!(f, "{s}")
} else {
write!(f, " ")
}
Expand Down
17 changes: 8 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(naked_functions)]
#![feature(lang_items)]
#![no_std]
#![no_main]
Expand Down Expand Up @@ -77,7 +76,7 @@ extern "C" fn real_main() -> ! {
if let Ok(level) = log_level.parse::<log::LevelFilter>() {
log::set_max_level(level);
} else {
log::warn!("Unknown log level {}", log_level);
log::warn!("Unknown log level {log_level}");
}
}
}
Expand Down Expand Up @@ -117,7 +116,7 @@ extern "C" fn real_main() -> ! {
}
Some(nix_ld) => {
let cstr = nix_ld.value_cstr();
log::info!("NIX_LD is set to {:?}", cstr);
log::info!("NIX_LD is set to {cstr:?}");
cstr
}
};
Expand Down Expand Up @@ -184,7 +183,7 @@ extern "C" fn real_main() -> ! {
.expect("AT_PAGESZ must exist")
.value();

log::info!("Loading {:?}", nix_ld);
log::info!("Loading {nix_ld:?}");
let loader = elf::ElfHandle::open(nix_ld, pagesz).unwrap();
let loader_map = loader.map().unwrap();

Expand All @@ -201,14 +200,14 @@ extern "C" fn real_main() -> ! {
// We were executed directly - execve the actual loader
if args.argc() <= 1 {
log::warn!("Environment honored by nix-ld:");
log::warn!("- NIX_LD, {}", NIX_LD_SYSTEM_ENV);
log::warn!("- NIX_LD_LIBRARY_PATH, {}", NIX_LD_LIBRARY_PATH_SYSTEM_ENV);
log::warn!("- NIX_LD, {NIX_LD_SYSTEM_ENV}");
log::warn!("- NIX_LD_LIBRARY_PATH, {NIX_LD_LIBRARY_PATH_SYSTEM_ENV}");
log::warn!("- NIX_LD_LOG (error, warn, info, debug, trace)");
log::warn!("Default ld.so: {:?}", DEFAULT_NIX_LD);
log::warn!("Default ld.so: {DEFAULT_NIX_LD:?}");
}

args.handoff(|start| unsafe {
log::debug!("Start context: {:#?}", start);
log::debug!("Start context: {start:#?}");
sys::execve(nix_ld.as_ptr(), start.argv, start.envp);
sys::abort();
});
Expand Down Expand Up @@ -237,7 +236,7 @@ extern "C" fn real_main() -> ! {
}

args.handoff(|start| unsafe {
log::debug!("Start context: {:#?}", start);
log::debug!("Start context: {start:#?}");

if arch::ENTRY_TRAMPOLINE.is_some() {
if let Some(extra_env) = start.extra_env {
Expand Down
2 changes: 1 addition & 1 deletion src/support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub fn explode(s: &str) -> ! {
#[panic_handler]
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
let mut stderr = sys::stderr();
writeln!(stderr, "[nix-ld] FATAL: {}", info).unwrap();
writeln!(stderr, "[nix-ld] FATAL: {info}").unwrap();

unsafe {
sys::abort();
Expand Down
1 change: 0 additions & 1 deletion src/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,4 @@ pub fn new_slice_leak(size: usize) -> Option<&'static mut [u8]> {

#[cfg(not(test))]
#[lang = "eh_personality"]
#[unsafe(no_mangle)]
pub extern "C" fn rust_eh_personality() {}
26 changes: 13 additions & 13 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use tempfile::TempDir;
#[fixture]
#[once]
fn libtest() -> &'static str {
eprintln!("Testing {} on {}", EXE, TARGET);
eprintln!("Testing {EXE} on {TARGET}");

eprintln!("Building libtest");
compile_test_lib("test");
Expand Down Expand Up @@ -60,7 +60,7 @@ fn test_dt_needed(libtest: &str, dt_needed_bin: &Path) {
#[rstest]
fn test_dlopen(libtest: &str) {
let bin = compile_test_bin("dlopen", &[]);
eprintln!("test_dlopen: {}", libtest);
eprintln!("test_dlopen: {libtest}");

// First make sure it doesn't run without the library
{
Expand Down Expand Up @@ -94,7 +94,7 @@ fn test_dlopen(libtest: &str) {
fn test_ld_path_restore(libtest: &str, _dt_needed_bin: &Path) {
let bin = compile_test_bin("ld-path-restore", &["test"]);

let nix_ld_path = format!("{}:POISON", libtest);
let nix_ld_path = format!("{libtest}:POISON");

// First try without LD_LIBRARY_PATH
{
Expand Down Expand Up @@ -132,7 +132,7 @@ fn get_tmpdir() -> &'static TempDir {

fn find_cc() -> String {
let target_suffix = TARGET.replace('-', "_");
env::var(format!("CC_{}", target_suffix))
env::var(format!("CC_{target_suffix}"))
.or_else(|_| env::var("CC"))
.unwrap_or_else(|_| "cc".to_string())
}
Expand All @@ -146,8 +146,8 @@ fn get_source_file(file: &str) -> PathBuf {

fn compile_test_lib(name: &str) {
let cc = find_cc();
let source_path = get_source_file(&format!("tests/lib{}.c", name));
let out_path = get_tmpdir().path().join(format!("lib{}.so", name));
let source_path = get_source_file(&format!("tests/lib{name}.c"));
let out_path = get_tmpdir().path().join(format!("lib{name}.so"));

let status = Command::new(cc)
.arg("-fPIC")
Expand All @@ -158,16 +158,16 @@ fn compile_test_lib(name: &str) {
.status()
.expect("Failed to spawn compiler");

assert!(status.success(), "Failed to build test library {}", name);
assert!(status.success(), "Failed to build test library {name}");
}

fn compile_test_bin(name: &str, libs: &[&str]) -> PathBuf {
let cc = find_cc();
let source_path = get_source_file(&format!("tests/{}.c", name));
let source_path = get_source_file(&format!("tests/{name}.c"));
let out_path = get_tmpdir().path().join(name);

let out_dir_arg = format!("-DOUT_DIR=\"{}\"", get_tmpdir().path().to_str().unwrap());
let dynamic_linker_arg = format!("-Wl,--dynamic-linker,{}", EXE);
let dynamic_linker_arg = format!("-Wl,--dynamic-linker,{EXE}");

let status = Command::new(cc)
.arg("-o")
Expand All @@ -176,12 +176,12 @@ fn compile_test_bin(name: &str, libs: &[&str]) -> PathBuf {
.arg(dynamic_linker_arg)
.arg("-L")
.arg(get_tmpdir().path())
.args(libs.iter().map(|l| format!("-l{}", l)))
.args(libs.iter().map(|l| format!("-l{l}")))
.arg(source_path)
.status()
.expect("Failed to spawn compiler");

assert!(status.success(), "Failed to build test binary {}", name);
assert!(status.success(), "Failed to build test binary {name}");

out_path
}
Expand All @@ -200,8 +200,8 @@ impl CommandExt for Command {
let stdout = String::from_utf8(output.stdout).expect("stdout contains non-UTF-8");
let stderr = String::from_utf8(output.stderr).expect("stderr contains non-UTF-8");

print!("{}", stdout);
eprint!("{}", stderr);
print!("{stdout}");
eprint!("{stderr}");

if want_success {
assert!(
Expand Down
Loading