From 6e23ef9adba097ea0c36f8555f0fa1088165039a Mon Sep 17 00:00:00 2001 From: Jonas Kruckenberg Date: Fri, 11 Jul 2025 10:48:21 +0200 Subject: [PATCH] update Rust to 1.90.0-nightly --- flake.lock | 12 +- kernel/src/arch/riscv64/setjmp_longjmp.rs | 222 +++++++-------- kernel/src/arch/riscv64/trap_handler.rs | 331 +++++++++++----------- kernel/src/backtrace/mod.rs | 26 +- kernel/src/backtrace/print.rs | 8 +- kernel/src/device_tree.rs | 26 +- kernel/src/main.rs | 2 - kernel/src/mem/address_space.rs | 10 +- kernel/src/mem/frame_alloc/frame_list.rs | 10 +- kernel/src/mem/vmo.rs | 2 +- kernel/src/shell.rs | 4 +- kernel/src/tracing/filter.rs | 12 +- kernel/src/tracing/registry.rs | 15 +- kernel/src/wasm/module.rs | 2 +- kernel/src/wasm/types.rs | 8 +- kernel/src/wasm/utils.rs | 3 +- kernel/src/wasm/vm/instance.rs | 2 +- kernel/src/wasm/vm/table.rs | 8 +- libs/cpu-local/src/collection.rs | 2 +- libs/kaddr2line/src/frame.rs | 8 +- libs/kaddr2line/src/function.rs | 8 +- libs/kaddr2line/src/line.rs | 28 +- libs/kaddr2line/src/unit.rs | 20 +- libs/kasync/src/executor.rs | 2 +- libs/kasync/src/executor/steal.rs | 2 +- libs/kasync/src/task.rs | 2 +- libs/kasync/src/time/sleep.rs | 4 +- libs/kasync/src/time/timeout.rs | 4 +- libs/kbacktrace/src/lib.rs | 2 +- libs/ksharded-slab/src/lib.rs | 5 +- libs/unwind2/src/arch/riscv64.rs | 43 ++- libs/unwind2/src/eh_info.rs | 6 +- libs/unwind2/src/lib.rs | 9 +- libs/unwind2/src/utils.rs | 11 +- libs/wast/src/core/binary.rs | 17 +- libs/wast/src/core/expr.rs | 17 +- libs/wast/src/core/resolve/mod.rs | 4 +- libs/wast/src/core/resolve/names.rs | 14 +- libs/wast/src/core/wast.rs | 18 +- libs/wast/src/lexer.rs | 22 +- libs/wast/src/lib.rs | 1 - libs/wast/src/names.rs | 18 +- libs/wast/src/parser.rs | 2 +- libs/wavltree/src/lib.rs | 1 - loader/src/arch/riscv64.rs | 255 ++++++++--------- loader/src/frame_alloc.rs | 4 +- loader/src/kernel.rs | 2 +- loader/src/main.rs | 2 - loader/src/mapping.rs | 10 +- loader/src/page_alloc.rs | 2 +- rust-toolchain.toml | 2 +- 51 files changed, 617 insertions(+), 633 deletions(-) diff --git a/flake.lock b/flake.lock index 82fe856c1..06d0fd1c6 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1750365781, - "narHash": "sha256-XE/lFNhz5lsriMm/yjXkvSZz5DfvKJLUjsS6pP8EC50=", + "lastModified": 1751984180, + "narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "08f22084e6085d19bcfb4be30d1ca76ecb96fe54", + "rev": "9807714d6944a957c2e036f84b0ff8caf9930bc0", "type": "github" }, "original": { @@ -48,11 +48,11 @@ ] }, "locked": { - "lastModified": 1750387093, - "narHash": "sha256-MgL1+yNVcSD6OlzSmKt5GS4RmAQnNCjckjgPC1hmMPg=", + "lastModified": 1752201818, + "narHash": "sha256-d8KczaVT8WFEZdWg//tMAbv8EDyn2YTWcJvSY8gqKBU=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "517e9871d182346b53bb7f23fed00810c14db396", + "rev": "bd8f8329780b348fedcd37b53dbbee48c08c496d", "type": "github" }, "original": { diff --git a/kernel/src/arch/riscv64/setjmp_longjmp.rs b/kernel/src/arch/riscv64/setjmp_longjmp.rs index 9fa17d8fc..dd8ef80af 100644 --- a/kernel/src/arch/riscv64/setjmp_longjmp.rs +++ b/kernel/src/arch/riscv64/setjmp_longjmp.rs @@ -80,67 +80,64 @@ pub type JmpBuf = *const JmpBufStruct; /// /// Due to the weird multi-return nature of `setjmp` it is very easy to make mistakes, this /// function be used with extreme care. -#[naked] +#[unsafe(naked)] pub unsafe extern "C" fn setjmp(env: JmpBuf) -> i32 { - // Safety: inline assembly - unsafe { - cfg_if::cfg_if! { - if #[cfg(target_feature = "d")] { - naked_asm! { - // FIXME this is a workaround for bug in rustc/llvm - // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 - ".attribute arch, \"rv64gc\"", + cfg_if::cfg_if! { + if #[cfg(target_feature = "d")] { + naked_asm! { + // FIXME this is a workaround for bug in rustc/llvm + // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 + ".attribute arch, \"rv64gc\"", - save_gp!(ra => a0[0]), - save_gp!(s0 => a0[1]), - save_gp!(s1 => a0[2]), - save_gp!(s2 => a0[3]), - save_gp!(s3 => a0[4]), - save_gp!(s4 => a0[5]), - save_gp!(s5 => a0[6]), - save_gp!(s6 => a0[7]), - save_gp!(s7 => a0[8]), - save_gp!(s8 => a0[9]), - save_gp!(s9 => a0[10]), - save_gp!(s10 => a0[11]), - save_gp!(s11 => a0[12]), - save_gp!(sp => a0[13]), + save_gp!(ra => a0[0]), + save_gp!(s0 => a0[1]), + save_gp!(s1 => a0[2]), + save_gp!(s2 => a0[3]), + save_gp!(s3 => a0[4]), + save_gp!(s4 => a0[5]), + save_gp!(s5 => a0[6]), + save_gp!(s6 => a0[7]), + save_gp!(s7 => a0[8]), + save_gp!(s8 => a0[9]), + save_gp!(s9 => a0[10]), + save_gp!(s10 => a0[11]), + save_gp!(s11 => a0[12]), + save_gp!(sp => a0[13]), - save_fp!(fs0 => a0[14]), - save_fp!(fs1 => a0[15]), - save_fp!(fs2 => a0[16]), - save_fp!(fs3 => a0[17]), - save_fp!(fs4 => a0[18]), - save_fp!(fs5 => a0[19]), - save_fp!(fs6 => a0[20]), - save_fp!(fs7 => a0[21]), - save_fp!(fs8 => a0[22]), - save_fp!(fs9 => a0[23]), - save_fp!(fs10 => a0[24]), - save_fp!(fs11 => a0[25]), + save_fp!(fs0 => a0[14]), + save_fp!(fs1 => a0[15]), + save_fp!(fs2 => a0[16]), + save_fp!(fs3 => a0[17]), + save_fp!(fs4 => a0[18]), + save_fp!(fs5 => a0[19]), + save_fp!(fs6 => a0[20]), + save_fp!(fs7 => a0[21]), + save_fp!(fs8 => a0[22]), + save_fp!(fs9 => a0[23]), + save_fp!(fs10 => a0[24]), + save_fp!(fs11 => a0[25]), - "mv a0, zero", - "ret", - } - } else { - naked_asm! { - save_gp!(ra => a0[0]), - save_gp!(s0 => a0[1]), - save_gp!(s1 => a0[2]), - save_gp!(s2 => a0[3]), - save_gp!(s3 => a0[4]), - save_gp!(s4 => a0[5]), - save_gp!(s5 => a0[6]), - save_gp!(s6 => a0[7]), - save_gp!(s7 => a0[8]), - save_gp!(s8 => a0[9]), - save_gp!(s9 => a0[10]), - save_gp!(s10 => a0[11]), - save_gp!(s11 => a0[12]), - save_gp!(sp => a0[13]), - "mv a0, zero", - "ret", - } + "mv a0, zero", + "ret", + } + } else { + naked_asm! { + save_gp!(ra => a0[0]), + save_gp!(s0 => a0[1]), + save_gp!(s1 => a0[2]), + save_gp!(s2 => a0[3]), + save_gp!(s3 => a0[4]), + save_gp!(s4 => a0[5]), + save_gp!(s5 => a0[6]), + save_gp!(s6 => a0[7]), + save_gp!(s7 => a0[8]), + save_gp!(s8 => a0[9]), + save_gp!(s9 => a0[10]), + save_gp!(s10 => a0[11]), + save_gp!(s11 => a0[12]), + save_gp!(sp => a0[13]), + "mv a0, zero", + "ret", } } } @@ -156,68 +153,65 @@ pub unsafe extern "C" fn setjmp(env: JmpBuf) -> i32 { /// so extreme care must be taken to ensure that the `JumpBuf` is valid and has been initialized. /// Additionally, the whole point of this function is to continue execution at a wildly different /// address, so this might cause confusing and hard-to-debug behavior. -#[naked] +#[unsafe(naked)] pub unsafe extern "C" fn longjmp(env: JmpBuf, val: i32) -> ! { - // Safety: inline assembly - unsafe { - cfg_if::cfg_if! { - if #[cfg(target_feature = "d")] { - naked_asm! { - // FIXME this is a workaround for bug in rustc/llvm - // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 - ".attribute arch, \"rv64gc\"", + cfg_if::cfg_if! { + if #[cfg(target_feature = "d")] { + naked_asm! { + // FIXME this is a workaround for bug in rustc/llvm + // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 + ".attribute arch, \"rv64gc\"", - load_gp!(a0[0] => ra), - load_gp!(a0[1] => s0), - load_gp!(a0[2] => s1), - load_gp!(a0[3] => s2), - load_gp!(a0[4] => s3), - load_gp!(a0[5] => s4), - load_gp!(a0[6] => s5), - load_gp!(a0[7] => s6), - load_gp!(a0[8] => s7), - load_gp!(a0[9] => s8), - load_gp!(a0[10] => s9), - load_gp!(a0[11] => s10), - load_gp!(a0[12] => s11), - load_gp!(a0[13] => sp), + load_gp!(a0[0] => ra), + load_gp!(a0[1] => s0), + load_gp!(a0[2] => s1), + load_gp!(a0[3] => s2), + load_gp!(a0[4] => s3), + load_gp!(a0[5] => s4), + load_gp!(a0[6] => s5), + load_gp!(a0[7] => s6), + load_gp!(a0[8] => s7), + load_gp!(a0[9] => s8), + load_gp!(a0[10] => s9), + load_gp!(a0[11] => s10), + load_gp!(a0[12] => s11), + load_gp!(a0[13] => sp), - load_fp!(a0[14] => fs0), - load_fp!(a0[15] => fs1), - load_fp!(a0[16] => fs2), - load_fp!(a0[17] => fs3), - load_fp!(a0[18] => fs4), - load_fp!(a0[19] => fs5), - load_fp!(a0[20] => fs6), - load_fp!(a0[21] => fs7), - load_fp!(a0[22] => fs8), - load_fp!(a0[23] => fs9), - load_fp!(a0[24] => fs10), - load_fp!(a0[25] => fs11), + load_fp!(a0[14] => fs0), + load_fp!(a0[15] => fs1), + load_fp!(a0[16] => fs2), + load_fp!(a0[17] => fs3), + load_fp!(a0[18] => fs4), + load_fp!(a0[19] => fs5), + load_fp!(a0[20] => fs6), + load_fp!(a0[21] => fs7), + load_fp!(a0[22] => fs8), + load_fp!(a0[23] => fs9), + load_fp!(a0[24] => fs10), + load_fp!(a0[25] => fs11), - "add a0, a1, zero", - "ret", - } - } else { - naked_asm! { - load_gp!(a0[0] => ra), - load_gp!(a0[1] => s0), - load_gp!(a0[2] => s1), - load_gp!(a0[3] => s2), - load_gp!(a0[4] => s3), - load_gp!(a0[5] => s4), - load_gp!(a0[6] => s5), - load_gp!(a0[7] => s6), - load_gp!(a0[8] => s7), - load_gp!(a0[9] => s8), - load_gp!(a0[10] => s9), - load_gp!(a0[11] => s10), - load_gp!(a0[12] => s11), - load_gp!(a0[13] => sp), + "add a0, a1, zero", + "ret", + } + } else { + naked_asm! { + load_gp!(a0[0] => ra), + load_gp!(a0[1] => s0), + load_gp!(a0[2] => s1), + load_gp!(a0[3] => s2), + load_gp!(a0[4] => s3), + load_gp!(a0[5] => s4), + load_gp!(a0[6] => s5), + load_gp!(a0[7] => s6), + load_gp!(a0[8] => s7), + load_gp!(a0[9] => s8), + load_gp!(a0[10] => s9), + load_gp!(a0[11] => s10), + load_gp!(a0[12] => s11), + load_gp!(a0[13] => sp), - "add a0, a1, zero", - "ret", - } + "add a0, a1, zero", + "ret", } } } diff --git a/kernel/src/arch/riscv64/trap_handler.rs b/kernel/src/arch/riscv64/trap_handler.rs index c35d252f3..7832e783f 100644 --- a/kernel/src/arch/riscv64/trap_handler.rs +++ b/kernel/src/arch/riscv64/trap_handler.rs @@ -85,174 +85,171 @@ pub struct TrapFrame { // } // } -#[naked] +#[unsafe(naked)] unsafe extern "C" fn default_trap_entry() { - // Safety: inline assembly - unsafe { - naked_asm! { - // FIXME this is a workaround for bug in rustc/llvm - // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 - ".attribute arch, \"rv64gc\"", - ".align 4", - ".cfi_startproc", - - // Set the CFI rule for the return address to always return zero - // This is always the first frame on stack, there is nowhere to return to - ".cfi_register ra, zero", - - "csrrw sp, sscratch, sp", // sp points to the TrapFrame - - "add sp, sp, -0x210", - ".cfi_def_cfa_offset 0x210", - - // save gp regs - save_gp!(x0 => sp[0]), - save_gp!(x1 => sp[1]), - // skip sp since it is saved in sscratch - save_gp!(x3 => sp[3]), - save_gp!(x4 => sp[4]), - save_gp!(x5 => sp[5]), - save_gp!(x6 => sp[6]), - save_gp!(x7 => sp[7]), - save_gp!(x8 => sp[8]), - save_gp!(x9 => sp[9]), - save_gp!(x10 => sp[10]), - save_gp!(x11 => sp[11]), - save_gp!(x12 => sp[12]), - save_gp!(x13 => sp[13]), - save_gp!(x14 => sp[14]), - save_gp!(x15 => sp[15]), - save_gp!(x16 => sp[16]), - save_gp!(x17 => sp[17]), - save_gp!(x18 => sp[18]), - save_gp!(x19 => sp[19]), - save_gp!(x20 => sp[20]), - save_gp!(x21 => sp[21]), - save_gp!(x22 => sp[22]), - save_gp!(x23 => sp[23]), - save_gp!(x24 => sp[24]), - save_gp!(x25 => sp[25]), - save_gp!(x26 => sp[26]), - save_gp!(x27 => sp[27]), - save_gp!(x28 => sp[28]), - save_gp!(x29 => sp[29]), - save_gp!(x30 => sp[30]), - save_gp!(x31 => sp[31]), - - // save fp regs - save_fp!(f0 => sp[32]), - save_fp!(f1 => sp[33]), - save_fp!(f2 => sp[34]), - save_fp!(f3 => sp[35]), - save_fp!(f4 => sp[36]), - save_fp!(f5 => sp[37]), - save_fp!(f6 => sp[38]), - save_fp!(f7 => sp[39]), - save_fp!(f8 => sp[40]), - save_fp!(f9 => sp[41]), - save_fp!(f10 => sp[42]), - save_fp!(f11 => sp[43]), - save_fp!(f12 => sp[44]), - save_fp!(f13 => sp[45]), - save_fp!(f14 => sp[46]), - save_fp!(f15 => sp[47]), - save_fp!(f16 => sp[48]), - save_fp!(f17 => sp[49]), - save_fp!(f18 => sp[50]), - save_fp!(f19 => sp[51]), - save_fp!(f20 => sp[52]), - save_fp!(f21 => sp[53]), - save_fp!(f22 => sp[54]), - save_fp!(f23 => sp[55]), - save_fp!(f24 => sp[56]), - save_fp!(f25 => sp[57]), - save_fp!(f26 => sp[58]), - save_fp!(f27 => sp[59]), - save_fp!(f28 => sp[60]), - save_fp!(f29 => sp[61]), - save_fp!(f30 => sp[62]), - save_fp!(f31 => sp[63]), - - "mv a0, sp", - "call {trap_handler}", - - // restore gp regs - // skip x0 since its always zero - load_gp!(sp[1] => x1), - // skip sp since it is saved in sscratch - load_gp!(sp[3] => x3), - load_gp!(sp[4] => x4), - load_gp!(sp[5] => x5), - load_gp!(sp[6] => x6), - load_gp!(sp[7] => x7), - load_gp!(sp[8] => x8), - load_gp!(sp[9] => x9), - load_gp!(sp[10] => x10), - load_gp!(sp[11] => x11), - load_gp!(sp[12] => x12), - load_gp!(sp[13] => x13), - load_gp!(sp[14] => x14), - load_gp!(sp[15] => x15), - load_gp!(sp[16] => x16), - load_gp!(sp[17] => x17), - load_gp!(sp[18] => x18), - load_gp!(sp[19] => x19), - load_gp!(sp[20] => x20), - load_gp!(sp[21] => x21), - load_gp!(sp[22] => x22), - load_gp!(sp[23] => x23), - load_gp!(sp[24] => x24), - load_gp!(sp[25] => x25), - load_gp!(sp[26] => x26), - load_gp!(sp[27] => x27), - load_gp!(sp[28] => x28), - load_gp!(sp[29] => x29), - load_gp!(sp[30] => x30), - load_gp!(sp[31] => x31), - - // restore fp regs - load_fp!(sp[32] => f0), - load_fp!(sp[33] => f1), - load_fp!(sp[34] => f2), - load_fp!(sp[35] => f3), - load_fp!(sp[36] => f4), - load_fp!(sp[37] => f5), - load_fp!(sp[38] => f6), - load_fp!(sp[39] => f7), - load_fp!(sp[40] => f8), - load_fp!(sp[41] => f9), - load_fp!(sp[42] => f10), - load_fp!(sp[43] => f11), - load_fp!(sp[44] => f12), - load_fp!(sp[45] => f13), - load_fp!(sp[46] => f14), - load_fp!(sp[47] => f15), - load_fp!(sp[48] => f16), - load_fp!(sp[49] => f17), - load_fp!(sp[50] => f18), - load_fp!(sp[51] => f19), - load_fp!(sp[52] => f20), - load_fp!(sp[53] => f21), - load_fp!(sp[54] => f22), - load_fp!(sp[55] => f23), - load_fp!(sp[56] => f24), - load_fp!(sp[57] => f25), - load_fp!(sp[58] => f26), - load_fp!(sp[59] => f27), - load_fp!(sp[60] => f28), - load_fp!(sp[61] => f29), - load_fp!(sp[62] => f30), - load_fp!(sp[63] => f31), - - "add sp, sp, 0x210", - ".cfi_def_cfa_offset 0", - - "csrrw sp, sscratch, sp", - "sret", - ".cfi_endproc", - - trap_handler = sym default_trap_handler, - } + naked_asm! { + // FIXME this is a workaround for bug in rustc/llvm + // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 + ".attribute arch, \"rv64gc\"", + ".align 4", + ".cfi_startproc", + + // Set the CFI rule for the return address to always return zero + // This is always the first frame on stack, there is nowhere to return to + ".cfi_register ra, zero", + + "csrrw sp, sscratch, sp", // sp points to the TrapFrame + + "add sp, sp, -0x210", + ".cfi_def_cfa_offset 0x210", + + // save gp regs + save_gp!(x0 => sp[0]), + save_gp!(x1 => sp[1]), + // skip sp since it is saved in sscratch + save_gp!(x3 => sp[3]), + save_gp!(x4 => sp[4]), + save_gp!(x5 => sp[5]), + save_gp!(x6 => sp[6]), + save_gp!(x7 => sp[7]), + save_gp!(x8 => sp[8]), + save_gp!(x9 => sp[9]), + save_gp!(x10 => sp[10]), + save_gp!(x11 => sp[11]), + save_gp!(x12 => sp[12]), + save_gp!(x13 => sp[13]), + save_gp!(x14 => sp[14]), + save_gp!(x15 => sp[15]), + save_gp!(x16 => sp[16]), + save_gp!(x17 => sp[17]), + save_gp!(x18 => sp[18]), + save_gp!(x19 => sp[19]), + save_gp!(x20 => sp[20]), + save_gp!(x21 => sp[21]), + save_gp!(x22 => sp[22]), + save_gp!(x23 => sp[23]), + save_gp!(x24 => sp[24]), + save_gp!(x25 => sp[25]), + save_gp!(x26 => sp[26]), + save_gp!(x27 => sp[27]), + save_gp!(x28 => sp[28]), + save_gp!(x29 => sp[29]), + save_gp!(x30 => sp[30]), + save_gp!(x31 => sp[31]), + + // save fp regs + save_fp!(f0 => sp[32]), + save_fp!(f1 => sp[33]), + save_fp!(f2 => sp[34]), + save_fp!(f3 => sp[35]), + save_fp!(f4 => sp[36]), + save_fp!(f5 => sp[37]), + save_fp!(f6 => sp[38]), + save_fp!(f7 => sp[39]), + save_fp!(f8 => sp[40]), + save_fp!(f9 => sp[41]), + save_fp!(f10 => sp[42]), + save_fp!(f11 => sp[43]), + save_fp!(f12 => sp[44]), + save_fp!(f13 => sp[45]), + save_fp!(f14 => sp[46]), + save_fp!(f15 => sp[47]), + save_fp!(f16 => sp[48]), + save_fp!(f17 => sp[49]), + save_fp!(f18 => sp[50]), + save_fp!(f19 => sp[51]), + save_fp!(f20 => sp[52]), + save_fp!(f21 => sp[53]), + save_fp!(f22 => sp[54]), + save_fp!(f23 => sp[55]), + save_fp!(f24 => sp[56]), + save_fp!(f25 => sp[57]), + save_fp!(f26 => sp[58]), + save_fp!(f27 => sp[59]), + save_fp!(f28 => sp[60]), + save_fp!(f29 => sp[61]), + save_fp!(f30 => sp[62]), + save_fp!(f31 => sp[63]), + + "mv a0, sp", + "call {trap_handler}", + + // restore gp regs + // skip x0 since its always zero + load_gp!(sp[1] => x1), + // skip sp since it is saved in sscratch + load_gp!(sp[3] => x3), + load_gp!(sp[4] => x4), + load_gp!(sp[5] => x5), + load_gp!(sp[6] => x6), + load_gp!(sp[7] => x7), + load_gp!(sp[8] => x8), + load_gp!(sp[9] => x9), + load_gp!(sp[10] => x10), + load_gp!(sp[11] => x11), + load_gp!(sp[12] => x12), + load_gp!(sp[13] => x13), + load_gp!(sp[14] => x14), + load_gp!(sp[15] => x15), + load_gp!(sp[16] => x16), + load_gp!(sp[17] => x17), + load_gp!(sp[18] => x18), + load_gp!(sp[19] => x19), + load_gp!(sp[20] => x20), + load_gp!(sp[21] => x21), + load_gp!(sp[22] => x22), + load_gp!(sp[23] => x23), + load_gp!(sp[24] => x24), + load_gp!(sp[25] => x25), + load_gp!(sp[26] => x26), + load_gp!(sp[27] => x27), + load_gp!(sp[28] => x28), + load_gp!(sp[29] => x29), + load_gp!(sp[30] => x30), + load_gp!(sp[31] => x31), + + // restore fp regs + load_fp!(sp[32] => f0), + load_fp!(sp[33] => f1), + load_fp!(sp[34] => f2), + load_fp!(sp[35] => f3), + load_fp!(sp[36] => f4), + load_fp!(sp[37] => f5), + load_fp!(sp[38] => f6), + load_fp!(sp[39] => f7), + load_fp!(sp[40] => f8), + load_fp!(sp[41] => f9), + load_fp!(sp[42] => f10), + load_fp!(sp[43] => f11), + load_fp!(sp[44] => f12), + load_fp!(sp[45] => f13), + load_fp!(sp[46] => f14), + load_fp!(sp[47] => f15), + load_fp!(sp[48] => f16), + load_fp!(sp[49] => f17), + load_fp!(sp[50] => f18), + load_fp!(sp[51] => f19), + load_fp!(sp[52] => f20), + load_fp!(sp[53] => f21), + load_fp!(sp[54] => f22), + load_fp!(sp[55] => f23), + load_fp!(sp[56] => f24), + load_fp!(sp[57] => f25), + load_fp!(sp[58] => f26), + load_fp!(sp[59] => f27), + load_fp!(sp[60] => f28), + load_fp!(sp[61] => f29), + load_fp!(sp[62] => f30), + load_fp!(sp[63] => f31), + + "add sp, sp, 0x210", + ".cfi_def_cfa_offset 0", + + "csrrw sp, sscratch, sp", + "sret", + ".cfi_endproc", + + trap_handler = sym default_trap_handler, } } diff --git a/kernel/src/backtrace/mod.rs b/kernel/src/backtrace/mod.rs index 05316d796..98674c076 100644 --- a/kernel/src/backtrace/mod.rs +++ b/kernel/src/backtrace/mod.rs @@ -185,19 +185,19 @@ impl fmt::Display for Backtrace<'_, MAX_FRAMES> { any = true; // `__rust_end_short_backtrace` means we are done hiding symbols // for now. Print until we see `__rust_begin_short_backtrace`. - if style == BacktraceStyle::Short { - if let Some(sym) = sym.name().map(|s| s.as_raw_str()) { - if sym.contains("__rust_end_short_backtrace") { - print = true; - break; - } - if print && sym.contains("__rust_begin_short_backtrace") { - print = false; - break; - } - if !print { - omitted_count += 1; - } + if style == BacktraceStyle::Short + && let Some(sym) = sym.name().map(|s| s.as_raw_str()) + { + if sym.contains("__rust_end_short_backtrace") { + print = true; + break; + } + if print && sym.contains("__rust_begin_short_backtrace") { + print = false; + break; + } + if !print { + omitted_count += 1; } } diff --git a/kernel/src/backtrace/print.rs b/kernel/src/backtrace/print.rs index 0ef152e5a..083933003 100644 --- a/kernel/src/backtrace/print.rs +++ b/kernel/src/backtrace/print.rs @@ -111,10 +111,10 @@ impl BacktraceFrameFmt<'_, '_, '_> { ) -> fmt::Result { // No need to print "null" frames, it basically just means that the // system backtrace was a bit eager to trace back super far. - if let BacktraceStyle::Short = self.fmt.format { - if frame_ip == 0 { - return Ok(()); - } + if let BacktraceStyle::Short = self.fmt.format + && frame_ip == 0 + { + return Ok(()); } // Print the index of the frame as well as the optional instruction diff --git a/kernel/src/device_tree.rs b/kernel/src/device_tree.rs index b269300f7..daef1a7bf 100644 --- a/kernel/src/device_tree.rs +++ b/kernel/src/device_tree.rs @@ -119,41 +119,41 @@ impl DeviceTree { /// Returns an iterator over all top-level devices in the tree. #[inline] - pub fn children(&self) -> Children { + pub fn children(&self) -> Children<'_> { self.root().children() } /// Returns an iterator over all nodes in the tree in depth-first order. #[inline] - pub fn descendants(&self) -> Descendants { + pub fn descendants(&self) -> Descendants<'_> { self.root().descendants() } /// Returns an iterator over all top-level properties in the tree. #[inline] - pub fn properties(&self) -> Properties { + pub fn properties(&self) -> Properties<'_> { self.root().properties() } /// Returns the top-level property with the given name. #[inline] - pub fn property(&self, name: &str) -> Option<&Property> { + pub fn property(&self, name: &str) -> Option<&Property<'_>> { self.root().property(name) } /// Returns the device with the given path. #[inline] - pub fn find_by_path(&self, path: &str) -> Option<&Device> { + pub fn find_by_path(&self, path: &str) -> Option<&Device<'_>> { self.root().find_by_path(path) } - pub fn find_by_phandle(&self, phandle: u32) -> Option<&Device> { + pub fn find_by_phandle(&self, phandle: u32) -> Option<&Device<'_>> { // Safety: we only inserted valid pointers into the map, so we should only get valid pointers out... self.with_inner(|inner| unsafe { Some(inner.phandle2ptr.get(&phandle)?.as_ref()) }) } #[inline] - fn root(&self) -> &Device { + fn root(&self) -> &Device<'_> { // Safety: `init` guarantees the root node always exists and is correctly initialized unsafe { self.borrow_inner().root.as_ref() } } @@ -209,14 +209,14 @@ impl<'a> Device<'a> { } /// Returns an iterator over all immediate children of this device. - pub fn children(&self) -> Children { + pub fn children(&self) -> Children<'_> { Children { current: self.first_child, } } /// Returns an iterator over all descendants of this device in depth-first order. - pub fn descendants(&self) -> Descendants { + pub fn descendants(&self) -> Descendants<'_> { Descendants { stack: smallvec![], current: self.children(), @@ -224,19 +224,19 @@ impl<'a> Device<'a> { } /// Returns an iterator over all properties of this device. - pub fn properties(&self) -> Properties { + pub fn properties(&self) -> Properties<'_> { Properties { current: self.properties, } } /// Returns the property with the given name. - pub fn property(&self, name: &str) -> Option<&Property> { + pub fn property(&self, name: &str) -> Option<&Property<'_>> { self.properties().find(|prop| prop.inner.name == name) } /// Returns the device with the given path starting from this device. - pub fn find_by_path(&self, path: &str) -> Option<&Device> { + pub fn find_by_path(&self, path: &str) -> Option<&Device<'_>> { let mut node = self; for component in path.trim_start_matches('/').split('/') { node = node.children().find(|child| child.name.name == component)?; @@ -265,7 +265,7 @@ impl<'a> Device<'a> { } } - pub fn regs(&self) -> Option { + pub fn regs(&self) -> Option> { self.properties() .find(|p| p.name() == "reg") .map(|prop| prop.inner.as_regs(self.cell_sizes())) diff --git a/kernel/src/main.rs b/kernel/src/main.rs index b78aab798..53e8bad72 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -8,7 +8,6 @@ #![no_std] #![no_main] #![feature(used_with_arg)] -#![feature(naked_functions)] #![feature(thread_local, never_type)] #![feature(new_range_api)] #![feature(debug_closure_helpers)] @@ -16,7 +15,6 @@ #![feature(std_internals, panic_can_unwind, formatting_options)] #![feature(step_trait)] #![feature(box_into_inner)] -#![feature(let_chains)] #![feature(array_chunks)] #![feature(iter_array_chunks)] #![feature(iter_next_chunk)] diff --git a/kernel/src/mem/address_space.rs b/kernel/src/mem/address_space.rs index 723efc95b..5a23c16dc 100644 --- a/kernel/src/mem/address_space.rs +++ b/kernel/src/mem/address_space.rs @@ -506,10 +506,10 @@ impl AddressSpace { let mut prev_end = None; for region in self.regions.range(range) { // ensure there is no gap between this region and the previous one - if let Some(prev_end) = prev_end.replace(region.range.end) { - if prev_end != region.range.start { - bail!("not mapped"); - } + if let Some(prev_end) = prev_end.replace(region.range.end) + && prev_end != region.range.start + { + bail!("not mapped"); } // call the callback @@ -768,7 +768,7 @@ impl<'a> Batch<'a> { flags: ::Flags, ) -> crate::Result<()> { debug_assert!( - len.get() % arch::PAGE_SIZE == 0, + len.get().is_multiple_of(arch::PAGE_SIZE), "physical address range must be multiple of page size" ); diff --git a/kernel/src/mem/frame_alloc/frame_list.rs b/kernel/src/mem/frame_alloc/frame_list.rs index 3ad016221..c8640ce85 100644 --- a/kernel/src/mem/frame_alloc/frame_list.rs +++ b/kernel/src/mem/frame_alloc/frame_list.rs @@ -13,7 +13,7 @@ use core::iter::{FlatMap, Flatten, FusedIterator}; use core::mem::offset_of; use core::pin::Pin; use core::ptr::NonNull; -use core::{array, fmt, mem}; +use core::{array, fmt}; use pin_project::pin_project; use wavltree::WAVLTree; @@ -162,7 +162,7 @@ impl FrameList { node.frames.iter().rfind(|f| f.is_some())?.as_ref() } - pub fn cursor(&self, offset: usize) -> Cursor { + pub fn cursor(&self, offset: usize) -> Cursor<'_> { let node_offset = offset_to_node_offset(offset); let cursor = self.nodes.find(&node_offset); @@ -173,7 +173,7 @@ impl FrameList { } } - pub fn cursor_mut(&mut self, offset: usize) -> CursorMut { + pub fn cursor_mut(&mut self, offset: usize) -> CursorMut<'_> { let node_offset = offset_to_node_offset(offset); let cursor = self.nodes.find_mut(&node_offset); @@ -184,7 +184,7 @@ impl FrameList { } } - pub(crate) fn entry(&mut self, offset: usize) -> Entry { + pub(crate) fn entry(&mut self, offset: usize) -> Entry<'_> { let node_offset = offset_to_node_offset(offset); let index_in_node = offset_to_node_index(offset); let entry = self.nodes.entry(&node_offset); @@ -513,7 +513,7 @@ impl<'a> VacantEntry<'a> { frames: [const { None }; FRAME_LIST_NODE_FANOUT], }) }); - let old = mem::replace(&mut node.frames[self.index_in_node], Some(value)); + let old = node.frames[self.index_in_node].replace(value); debug_assert!(old.is_none()); // Safety: guaranteed by `FrameList::entry` diff --git a/kernel/src/mem/vmo.rs b/kernel/src/mem/vmo.rs index 609f364a1..f6d2b04ca 100644 --- a/kernel/src/mem/vmo.rs +++ b/kernel/src/mem/vmo.rs @@ -65,7 +65,7 @@ impl PhysVmo { pub fn lookup_contiguous(&self, range: Range) -> crate::Result> { ensure!( - range.start % arch::PAGE_SIZE == 0, + range.start.is_multiple_of(arch::PAGE_SIZE), "range is not arch::PAGE_SIZE aligned" ); let start = self.range.start.checked_add(range.start).unwrap(); diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index f856a5d50..124744894 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -142,6 +142,8 @@ const PANIC: Command = Command::new("panic") const FAULT: Command = Command::new("fault") .with_help("cause a CPU fault (null pointer dereference). use with caution.") .with_fn(|_| { + // Safety: This actually *is* unsafe and *is* causing problematic behaviour, but that is exactly what + // we want here! unsafe { #[expect(clippy::zero_ptr, reason = "we actually want to cause a fault here")] (0x0 as *const u8).read_volatile(); @@ -252,7 +254,7 @@ impl<'cmd> Command<'cmd> { #[must_use] pub const fn new(name: &'cmd str) -> Self { #[cold] - fn invalid_command(_ctx: Context<'_>) -> CmdResult { + fn invalid_command(_ctx: Context<'_>) -> CmdResult<'_> { panic!("command is missing run function, this is a bug"); } diff --git a/kernel/src/tracing/filter.rs b/kernel/src/tracing/filter.rs index 1614e7432..47eae212a 100644 --- a/kernel/src/tracing/filter.rs +++ b/kernel/src/tracing/filter.rs @@ -114,7 +114,7 @@ impl Filter { ); for directive in disabled { let target = if let Some(target) = &directive.target { - format!("the `{}` target", target) + format!("the `{target}` target") } else { "all targets".into() }; @@ -139,7 +139,7 @@ impl Filter { Some(Level::ERROR) => ("max_level_error", Level::WARN), None => return ("max_level_off", String::new()), }; - (feature, format!("{} ", filter)) + (feature, format!("{filter} ")) }; let (feature, earlier_level) = help_msg(); tracing::warn!( @@ -189,10 +189,10 @@ impl Directive { fn cares_about(&self, meta: &Metadata<'_>) -> bool { // Does this directive have a target filter, and does it match the // metadata's target? - if let Some(ref target) = self.target { - if !meta.target().starts_with(&target[..]) { - return false; - } + if let Some(ref target) = self.target + && !meta.target().starts_with(&target[..]) + { + return false; } true diff --git a/kernel/src/tracing/registry.rs b/kernel/src/tracing/registry.rs index f093d383d..2d1a175bf 100644 --- a/kernel/src/tracing/registry.rs +++ b/kernel/src/tracing/registry.rs @@ -144,12 +144,12 @@ impl Registry { self.spans.get(id_to_idx(id)) } - fn span_data(&self, id: &Id) -> Option { + fn span_data(&self, id: &Id) -> Option> { let inner = self.get(id)?; Some(Data { inner }) } - fn span(&self, id: &Id) -> Option + fn span(&self, id: &Id) -> Option> where Self: Sized, { @@ -215,10 +215,10 @@ impl Collect for Registry { } fn exit(&self, id: &Id) { - if let Some(spans) = self.current_spans.get() { - if spans.borrow_mut().pop(id) { - dispatch::get_default(|dispatch| dispatch.try_close(id.clone())); - } + if let Some(spans) = self.current_spans.get() + && spans.borrow_mut().pop(id) + { + dispatch::get_default(|dispatch| dispatch.try_close(id.clone())); } } @@ -234,8 +234,7 @@ impl Collect for Registry { let refs = span.ref_count.fetch_add(1, Ordering::Relaxed); assert_ne!( refs, 0, - "tried to clone a span ({:?}) that already closed", - id + "tried to clone a span ({id:?}) that already closed", ); id.clone() } diff --git a/kernel/src/wasm/module.rs b/kernel/src/wasm/module.rs index ece66da88..0d998050c 100644 --- a/kernel/src/wasm/module.rs +++ b/kernel/src/wasm/module.rs @@ -136,7 +136,7 @@ impl Module { } pub(crate) fn functions( &self, - ) -> cranelift_entity::Iter { + ) -> cranelift_entity::Iter<'_, DefinedFuncIndex, CompiledFunctionInfo> { self.0.code.function_info().iter() } diff --git a/kernel/src/wasm/types.rs b/kernel/src/wasm/types.rs index 910814cd1..50268138c 100644 --- a/kernel/src/wasm/types.rs +++ b/kernel/src/wasm/types.rs @@ -1507,10 +1507,10 @@ impl FuncType { vec.push(ty.clone()); } - if let Some(r) = ty.as_ref() { - if let Some(r) = r.heap_type().as_registered_type() { - registrations.push(r.clone()); - } + if let Some(r) = ty.as_ref() + && let Some(r) = r.heap_type().as_registered_type() + { + registrations.push(r.clone()); } ty.to_wasm_type() diff --git a/kernel/src/wasm/utils.rs b/kernel/src/wasm/utils.rs index b02c3a690..f9cf922c4 100644 --- a/kernel/src/wasm/utils.rs +++ b/kernel/src/wasm/utils.rs @@ -142,8 +142,9 @@ pub fn array_call_signature(isa: &dyn TargetIsa) -> ir::Signature { } /// Is `bytes` a multiple of the host page size? +#[inline] pub fn usize_is_multiple_of_host_page_size(bytes: usize) -> bool { - bytes % PAGE_SIZE == 0 + bytes.is_multiple_of(PAGE_SIZE) } pub fn round_u64_up_to_host_pages(bytes: u64) -> u64 { diff --git a/kernel/src/wasm/vm/instance.rs b/kernel/src/wasm/vm/instance.rs index bfe151045..56a4b0ee1 100644 --- a/kernel/src/wasm/vm/instance.rs +++ b/kernel/src/wasm/vm/instance.rs @@ -344,7 +344,7 @@ impl InstanceHandle { /// Specifically, it provides access to the key-value pairs, where the keys /// are export names, and the values are export declarations which can be /// resolved `lookup_by_declaration`. - pub fn exports(&self) -> wasmparser::collections::index_map::Iter { + pub fn exports(&self) -> wasmparser::collections::index_map::Iter<'_, String, EntityIndex> { self.instance().translated_module().exports.iter() } diff --git a/kernel/src/wasm/vm/table.rs b/kernel/src/wasm/vm/table.rs index 3e5065291..fc3cc447b 100644 --- a/kernel/src/wasm/vm/table.rs +++ b/kernel/src/wasm/vm/table.rs @@ -121,10 +121,10 @@ impl Table { // The WebAssembly spec requires failing a `table.grow` request if // it exceeds the declared limits of the table. We may have set lower // limits in the instance allocator as well. - if let Some(max) = self.maximum { - if new_size > max { - return Ok(None); - } + if let Some(max) = self.maximum + && new_size > max + { + return Ok(None); } // we only support static tables that have all their memory reserved (not allocated) upfront diff --git a/libs/cpu-local/src/collection.rs b/libs/cpu-local/src/collection.rs index ba8d3e674..a15759f19 100644 --- a/libs/cpu-local/src/collection.rs +++ b/libs/cpu-local/src/collection.rs @@ -229,7 +229,7 @@ impl CpuLocal { /// Since this call borrows the `CpuLocal` mutably, this operation can /// be done safely---the mutable borrow statically guarantees no other /// cpus are currently accessing their associated values. - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_, T> { IterMut { cpu_local: self, raw: RawIter::new(), diff --git a/libs/kaddr2line/src/frame.rs b/libs/kaddr2line/src/frame.rs index e9672f868..4defb6094 100644 --- a/libs/kaddr2line/src/frame.rs +++ b/libs/kaddr2line/src/frame.rs @@ -139,10 +139,10 @@ where None }, }; - if let Some(call_file) = func.call_file { - if let Some(lines) = frames.unit.parse_lines(frames.sections)? { - next.file = lines.file(call_file); - } + if let Some(call_file) = func.call_file + && let Some(lines) = frames.unit.parse_lines(frames.sections)? + { + next.file = lines.file(call_file); } frames.next = Some(next); diff --git a/libs/kaddr2line/src/function.rs b/libs/kaddr2line/src/function.rs index 0c1f0ebc1..c4cdeabcb 100644 --- a/libs/kaddr2line/src/function.rs +++ b/libs/kaddr2line/src/function.rs @@ -417,10 +417,10 @@ impl InlinedFunction { // // Thus, if we see a version of 5 or later, treat a file index of 0 as such. // [1]: http://wiki.dwarfstd.org/index.php?title=DWARF5_Line_Table_File_Numbers - if let gimli::AttributeValue::FileIndex(fi) = attr.value() { - if fi > 0 || unit.header.version() >= 5 { - call_file = Some(fi); - } + if let gimli::AttributeValue::FileIndex(fi) = attr.value() + && (fi > 0 || unit.header.version() >= 5) + { + call_file = Some(fi); } } gimli::DW_AT_call_line => { diff --git a/libs/kaddr2line/src/line.rs b/libs/kaddr2line/src/line.rs index 7520f8d34..310017ec2 100644 --- a/libs/kaddr2line/src/line.rs +++ b/libs/kaddr2line/src/line.rs @@ -85,13 +85,13 @@ impl Lines { gimli::ColumnType::Column(x) => x.get() as u32, }; - if let Some(last_row) = sequence_rows.last_mut() { - if last_row.address == address { - last_row.file_index = file_index; - last_row.line = line; - last_row.column = column; - continue; - } + if let Some(last_row) = sequence_rows.last_mut() + && last_row.address == address + { + last_row.file_index = file_index; + last_row.line = line; + last_row.column = column; + continue; } sequence_rows.push(LineRow { @@ -272,13 +272,13 @@ fn render_file( }; // The directory index 0 is defined to correspond to the compilation unit directory. - if file.directory_index() != 0 { - if let Some(directory) = file.directory(header) { - path_push( - &mut path, - dw_unit.attr_string(directory)?.to_string_lossy()?.as_ref(), - ); - } + if file.directory_index() != 0 + && let Some(directory) = file.directory(header) + { + path_push( + &mut path, + dw_unit.attr_string(directory)?.to_string_lossy()?.as_ref(), + ); } path_push( diff --git a/libs/kaddr2line/src/unit.rs b/libs/kaddr2line/src/unit.rs index ab8c249b5..2390b5f94 100644 --- a/libs/kaddr2line/src/unit.rs +++ b/libs/kaddr2line/src/unit.rs @@ -314,15 +314,15 @@ impl ResUnits { if need_unit_range { // The unit did not declare any ranges. // Try to get some ranges from the line program sequences. - if let Some(ref ilnp) = dw_unit_ref.line_program { - if let Ok(lines) = lines.borrow(dw_unit_ref, ilnp) { - for range in lines.ranges() { - unit_ranges.push(UnitRange { - range, - unit_id, - min_begin: 0, - }) - } + if let Some(ref ilnp) = dw_unit_ref.line_program + && let Ok(lines) = lines.borrow(dw_unit_ref, ilnp) + { + for range in lines.ranges() { + unit_ranges.push(UnitRange { + range, + unit_id, + min_begin: 0, + }) } } } @@ -450,7 +450,7 @@ struct DwoUnit { } impl DwoUnit { - fn unit_ref(&self) -> gimli::UnitRef { + fn unit_ref(&self) -> gimli::UnitRef<'_, R> { gimli::UnitRef::new(&self.sections, &self.dw_unit) } } diff --git a/libs/kasync/src/executor.rs b/libs/kasync/src/executor.rs index 4062b603e..49ae66f17 100644 --- a/libs/kasync/src/executor.rs +++ b/libs/kasync/src/executor.rs @@ -484,7 +484,7 @@ impl Scheduler { tick } - fn try_steal(&self) -> Result { + fn try_steal(&self) -> Result, TryStealError> { Stealer::new(&self.run_queue, &self.queued) } } diff --git a/libs/kasync/src/executor/steal.rs b/libs/kasync/src/executor/steal.rs index 13aee6c9e..2591d8161 100644 --- a/libs/kasync/src/executor/steal.rs +++ b/libs/kasync/src/executor/steal.rs @@ -53,7 +53,7 @@ impl Injector { /// /// When stealing from the target is not possible, either because its queue is *empty* /// or because there is *already an active stealer*, an error is returned. - pub fn try_steal(&self) -> Result { + pub fn try_steal(&self) -> Result, TryStealError> { Stealer::new(&self.run_queue, &self.queued) } diff --git a/libs/kasync/src/task.rs b/libs/kasync/src/task.rs index 751ab6664..61d6fbc06 100644 --- a/libs/kasync/src/task.rs +++ b/libs/kasync/src/task.rs @@ -219,7 +219,7 @@ impl TaskRef { A: Allocator, { assert_eq!(task.state().refcount(), 1); - let ptr = Box::into_raw(task); + let (ptr, _) = Box::into_raw_with_allocator(task); // Safety: we just allocated the ptr so it is never null let task = Self(unsafe { NonNull::new_unchecked(ptr).cast() }); diff --git a/libs/kasync/src/time/sleep.rs b/libs/kasync/src/time/sleep.rs index f15157768..856a1c865 100644 --- a/libs/kasync/src/time/sleep.rs +++ b/libs/kasync/src/time/sleep.rs @@ -23,7 +23,7 @@ use pin_project::{pin_project, pinned_drop}; /// This function fails for two reasons: /// 1. [`TimeError::NoGlobalTimer`] No global timer has been set up yet. Call [`crate::time::set_global_timer`] first. /// 2. [`TimeError::DurationTooLong`] The requested duration is too big -pub fn sleep(timer: &Timer, duration: Duration) -> Result { +pub fn sleep(timer: &Timer, duration: Duration) -> Result, TimeError> { let ticks = timer.duration_to_ticks(duration)?; let now = timer.now(); let deadline = Ticks(ticks.0 + now.0); @@ -38,7 +38,7 @@ pub fn sleep(timer: &Timer, duration: Duration) -> Result { /// This function fails for two reasons: /// 1. [`TimeError::NoGlobalTimer`] No global timer has been set up yet. Call [`crate::time::set_global_timer`] first. /// 2. [`TimeError::DurationTooLong`] The requested deadline lies too far into the future -pub fn sleep_until(timer: &Timer, deadline: Instant) -> Result { +pub fn sleep_until(timer: &Timer, deadline: Instant) -> Result, TimeError> { let deadline = deadline.as_ticks(timer)?; Ok(Sleep::new(timer, deadline)) diff --git a/libs/kasync/src/time/timeout.rs b/libs/kasync/src/time/timeout.rs index 1a07128b2..d1838449e 100644 --- a/libs/kasync/src/time/timeout.rs +++ b/libs/kasync/src/time/timeout.rs @@ -29,7 +29,7 @@ pub fn timeout( timer: &Timer, duration: Duration, future: F, -) -> Result, TimeError> +) -> Result, TimeError> where F: IntoFuture, { @@ -50,7 +50,7 @@ pub fn timeout_at( timer: &Timer, deadline: Instant, future: F, -) -> Result, TimeError> +) -> Result, TimeError> where F: IntoFuture, { diff --git a/libs/kbacktrace/src/lib.rs b/libs/kbacktrace/src/lib.rs index c5ee59aee..89b80326f 100644 --- a/libs/kbacktrace/src/lib.rs +++ b/libs/kbacktrace/src/lib.rs @@ -96,7 +96,7 @@ impl fmt::Display for Backtrace<'_, '_, MAX_FRAMES> { .unwrap(); while let Some(sym) = syms.next().unwrap() { - write!(f, "{frame_idx}: {address:#x} -", address = ip)?; + write!(f, "{frame_idx}: {ip:#x} -")?; if let Some(name) = sym.name() { writeln!(f, " {name}")?; } else { diff --git a/libs/ksharded-slab/src/lib.rs b/libs/ksharded-slab/src/lib.rs index 55bb670ef..b97b994e3 100644 --- a/libs/ksharded-slab/src/lib.rs +++ b/libs/ksharded-slab/src/lib.rs @@ -205,6 +205,7 @@ #![feature(thread_local)] #![feature(used_with_arg)] #![feature(never_type)] +#![expect(clippy::uninlined_format_args, reason = "not worth the effort")] extern crate alloc; @@ -616,7 +617,7 @@ impl Slab { /// ``` /// /// # Panics - /// + /// /// TODO pub fn get(&self, key: usize) -> Option> { let tid = C::unpack_tid(key); @@ -699,7 +700,7 @@ impl Slab { /// ``` /// /// # Panics - /// + /// /// TODO /// /// [`get`]: Slab::get diff --git a/libs/unwind2/src/arch/riscv64.rs b/libs/unwind2/src/arch/riscv64.rs index f425ee4bd..c8011eac8 100644 --- a/libs/unwind2/src/arch/riscv64.rs +++ b/libs/unwind2/src/arch/riscv64.rs @@ -201,18 +201,16 @@ macro_rules! code { }; } -#[naked] +#[unsafe(naked)] pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Registers, *mut ()), ptr: *mut ()) { - // Safety: inline assembly - unsafe { - cfg_if! { - if #[cfg(target_feature = "d")] { - // No need to save caller-saved registers here. - naked_asm! { - // FIXME this is a workaround for bug in rustc/llvm - // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 - ".attribute arch, \"rv64gc\"", - " + cfg_if! { + if #[cfg(target_feature = "d")] { + // No need to save caller-saved registers here. + naked_asm! { + // FIXME this is a workaround for bug in rustc/llvm + // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 + ".attribute arch, \"rv64gc\"", + " .cfi_startproc mv t0, sp add sp, sp, -0x210 @@ -220,9 +218,9 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Registers, *mut ()), sd ra, 0x200(sp) .cfi_offset ra, -16 ", - code!(save_gp), - code!(save_fp), - " + code!(save_gp), + code!(save_fp), + " mv t0, a0 mv a0, sp jalr t0 @@ -233,19 +231,19 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Registers, *mut ()), ret .cfi_endproc " - }; - } else { - // No need to save caller-saved registers here. - naked_asm! { - " + }; + } else { + // No need to save caller-saved registers here. + naked_asm! { + " mv t0, sp add sp, sp, -0x110 .cfi_def_cfa_offset 0x110 sd ra, 0x100(sp) .cfi_offset ra, -16 ", - code!(save_gp), - " + code!(save_gp), + " mv t0, a0 mv a0, sp jalr t0 @@ -255,8 +253,7 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Registers, *mut ()), .cfi_restore ra ret ", - }; - } + }; } } } diff --git a/libs/unwind2/src/eh_info.rs b/libs/unwind2/src/eh_info.rs index d8848bfe3..2a6af4ff3 100644 --- a/libs/unwind2/src/eh_info.rs +++ b/libs/unwind2/src/eh_info.rs @@ -32,19 +32,23 @@ pub struct EhInfo { } pub static EH_INFO: LazyLock = LazyLock::new(|| { + // Safety: The start is valid by construction (ensured by the linker) and gimli + // takes care to never read more than the required bytes from the slice #[allow(static_mut_refs, reason = "TODO remove")] let eh_frame_hdr = unsafe { get_unlimited_slice(EH_FRAME_HDR.as_ptr()) }; let mut bases = BaseAddresses::default().set_eh_frame_hdr(eh_frame_hdr.as_ptr() as u64); - // .set_text(0xffff_ffff_8000_0000); // TODO support dynamic offsets let hdr = EhFrameHdr::new(eh_frame_hdr, NativeEndian) .parse(&bases, 8) .unwrap(); + // Safety: we have to trust the pointer returned by gimli is valid let eh_frame = unsafe { deref_pointer(hdr.eh_frame_ptr()) as *const u8 }; bases = bases.set_eh_frame(eh_frame as u64); + // Safety: The start is valid by construction (ensured by the linker) and gimli + // takes care to never read more than the required bytes from the slice let eh_frame = EhFrame::new(unsafe { get_unlimited_slice(eh_frame) }, NativeEndian); EhInfo { diff --git a/libs/unwind2/src/lib.rs b/libs/unwind2/src/lib.rs index 3692b536d..c567e19b7 100644 --- a/libs/unwind2/src/lib.rs +++ b/libs/unwind2/src/lib.rs @@ -8,14 +8,7 @@ #![no_std] // this is crate is fully incompatible with `std` due to clashing lang item definitions #![cfg(target_os = "none")] #![expect(internal_features, reason = "lang items")] -#![feature( - core_intrinsics, - rustc_attrs, - used_with_arg, - lang_items, - naked_functions, - never_type -)] +#![feature(core_intrinsics, rustc_attrs, used_with_arg, lang_items, never_type)] extern crate alloc; diff --git a/libs/unwind2/src/utils.rs b/libs/unwind2/src/utils.rs index 8dd7da692..b963182aa 100644 --- a/libs/unwind2/src/utils.rs +++ b/libs/unwind2/src/utils.rs @@ -29,19 +29,26 @@ impl gimli::UnwindContextStorage for StoreOnStack { type Stack = [UnwindTableRow; 2]; } +/// # Safety +/// +/// The caller has to ensure the start is valid and to never read more values from the slice +/// than can actually be read pub unsafe fn get_unlimited_slice<'a>(start: *const u8) -> &'a [u8] { // Create the largest possible slice for this address. let start = start as usize; let end = start.saturating_add(isize::MAX as usize); let len = end - start; - // Safety: caller has to ensure start is valid + // Safety: caller ensures start is valid unsafe { core::slice::from_raw_parts(start as *const u8, len) } } +/// # Safety +/// +/// The caller has to ensure the `ptr` (if `Pointer::Indirect`) is valid. pub unsafe fn deref_pointer(ptr: Pointer) -> u64 { match ptr { Pointer::Direct(x) => x, - // Safety: caller has to ensure `ptr` is valid + // Safety: caller ensures `ptr` is valid Pointer::Indirect(x) => unsafe { *(x as *const u64) }, } } diff --git a/libs/wast/src/core/binary.rs b/libs/wast/src/core/binary.rs index 2f409404a..9b9438c07 100644 --- a/libs/wast/src/core/binary.rs +++ b/libs/wast/src/core/binary.rs @@ -1,10 +1,10 @@ -use alloc::borrow::Cow; +use crate::Wat; #[cfg(feature = "component-model")] use crate::component::Component; use crate::core::*; use crate::encode::Encode; use crate::token::*; -use crate::Wat; +use alloc::borrow::Cow; use alloc::vec; use alloc::vec::Vec; use core::marker; @@ -785,10 +785,10 @@ impl Expression<'_> { // If DWARF is enabled then track this instruction's binary offset // and source location. - if let Some(dwarf) = &mut dwarf { - if let Some(span) = self.instr_spans.as_ref().map(|s| s[i]) { - dwarf.instr(func.byte_len() + tmp.len(), span); - } + if let Some(dwarf) = &mut dwarf + && let Some(span) = self.instr_spans.as_ref().map(|s| s[i]) + { + dwarf.instr(func.byte_len() + tmp.len(), span); } // Finally emit the instruction and move to the next. @@ -995,7 +995,10 @@ fn find_names<'a>( Data, } - let mut ret = Names { module: get_name(module_id, module_name), ..Default::default() }; + let mut ret = Names { + module: get_name(module_id, module_name), + ..Default::default() + }; let mut names = Vec::new(); for field in fields { // Extract the kind/id/name from whatever kind of field this is... diff --git a/libs/wast/src/core/expr.rs b/libs/wast/src/core/expr.rs index 4385fd9ab..3e0ea7267 100644 --- a/libs/wast/src/core/expr.rs +++ b/libs/wast/src/core/expr.rs @@ -192,10 +192,11 @@ impl<'a> ExpressionParser<'a> { // As a small ease-of-life adjustment here, if we're parsing inside // of an `if block then we require that all sub-components are // s-expressions surrounded by `(` and `)`, so verify that here. - if let Some(Level::If(_)) = self.stack.last() { - if !parser.is_empty() && !parser.peek::()? { - return Err(parser.error("expected `(`")); - } + if let Some(Level::If(_)) = self.stack.last() + && !parser.is_empty() + && !parser.peek::()? + { + return Err(parser.error("expected `(`")); } match self.paren(parser)? { @@ -1578,10 +1579,10 @@ impl<'a> LoadOrStoreLane<'a> { // If the first integer is trailed by `offset=...` or // `align=...` then this is definitely a memarg. - if let Some((kw, _)) = after_int.keyword()? { - if kw.starts_with("offset=") || kw.starts_with("align=") { - return Ok((true, c)); - } + if let Some((kw, _)) = after_int.keyword()? + && (kw.starts_with("offset=") || kw.starts_with("align=")) + { + return Ok((true, c)); } // Otherwise the first integer was trailed by something that diff --git a/libs/wast/src/core/resolve/mod.rs b/libs/wast/src/core/resolve/mod.rs index 986c47178..eb1e363ac 100644 --- a/libs/wast/src/core/resolve/mod.rs +++ b/libs/wast/src/core/resolve/mod.rs @@ -1,6 +1,6 @@ use crate::core::*; use crate::token::Index; -use crate::{gensym, Error}; +use crate::{Error, gensym}; use alloc::format; use alloc::vec::Vec; @@ -40,7 +40,7 @@ pub fn resolve<'a>(fields: &mut Vec>) -> Result, Error match field { ModuleField::Import(i) => { if let Some(name) = last { - return Err(Error::new(i.span, format!("import after {}", name))); + return Err(Error::new(i.span, format!("import after {name}"))); } } ModuleField::Memory(_) => last = Some("memory"), diff --git a/libs/wast/src/core/resolve/names.rs b/libs/wast/src/core/resolve/names.rs index 31a01d0c9..d2b5d38bc 100644 --- a/libs/wast/src/core/resolve/names.rs +++ b/libs/wast/src/core/resolve/names.rs @@ -1,8 +1,8 @@ +use crate::Error; use crate::core::resolve::Ns; use crate::core::*; -use crate::names::{resolve_error, Namespace}; +use crate::names::{Namespace, resolve_error}; use crate::token::{Id, Index}; -use crate::Error; use alloc::boxed::Box; use alloc::string::ToString; use alloc::vec::Vec; @@ -116,7 +116,7 @@ impl<'a> Resolver<'a> { // These fields don't define any items in any index space. ModuleField::Export(_) | ModuleField::Start(_) | ModuleField::Custom(_) => { - return Ok(()) + return Ok(()); } }; @@ -517,10 +517,10 @@ impl<'a, 'b> ExprResolver<'a, 'b> { }; // Reset the local scopes to before this block was entered - if matching_block.pushed_scope { - if let End(_) = instr { - self.scopes.pop(); - } + if matching_block.pushed_scope + && let End(_) = instr + { + self.scopes.pop(); } let label = match label { diff --git a/libs/wast/src/core/wast.rs b/libs/wast/src/core/wast.rs index 1dd5e19ba..a70e8d9a3 100644 --- a/libs/wast/src/core/wast.rs +++ b/libs/wast/src/core/wast.rs @@ -1,7 +1,7 @@ use crate::core::{HeapType, V128Const}; use crate::kw; use crate::parser::{Cursor, Parse, Parser, Peek, Result}; -use crate::token::{Index, F32, F64}; +use crate::token::{F32, F64, Index}; use alloc::vec::Vec; /// Expression that can be used inside of `invoke` expressions for core wasm @@ -37,10 +37,10 @@ static ARGS: &[(&str, fn(Parser<'_>) -> Result>)] = { impl<'a> Parse<'a> for WastArgCore<'a> { fn parse(parser: Parser<'a>) -> Result { let parse = parser.step(|c| { - if let Some((kw, rest)) = c.keyword()? { - if let Some(i) = ARGS.iter().position(|(name, _)| *name == kw) { - return Ok((ARGS[i].1, rest)); - } + if let Some((kw, rest)) = c.keyword()? + && let Some(i) = ARGS.iter().position(|(name, _)| *name == kw) + { + return Ok((ARGS[i].1, rest)); } Err(c.error("expected a [type].const expression")) })?; @@ -131,10 +131,10 @@ static RETS: &[(&str, fn(Parser<'_>) -> Result>)] = { impl<'a> Parse<'a> for WastRetCore<'a> { fn parse(parser: Parser<'a>) -> Result { let parse = parser.step(|c| { - if let Some((kw, rest)) = c.keyword()? { - if let Some(i) = RETS.iter().position(|(name, _)| *name == kw) { - return Ok((RETS[i].1, rest)); - } + if let Some((kw, rest)) = c.keyword()? + && let Some(i) = RETS.iter().position(|(name, _)| *name == kw) + { + return Ok((RETS[i].1, rest)); } Err(c.error("expected a [type].const expression")) })?; diff --git a/libs/wast/src/lexer.rs b/libs/wast/src/lexer.rs index 99c87816a..6171b5048 100644 --- a/libs/wast/src/lexer.rs +++ b/libs/wast/src/lexer.rs @@ -764,15 +764,15 @@ impl<'a> Lexer<'a> { // characters show up they're guaranteed to start with 0xe2 bytes. let bytes = comment.as_bytes(); for pos in memchr::Memchr::new(0xe2, bytes) { - if let Some(c) = comment[pos..].chars().next() { - if is_confusing_unicode(c) { - // Note that `self.cur()` accounts for already having - // parsed `comment`, so we move backwards to where - // `comment` started and then add the index within - // `comment`. - let pos = end - comment.len() + pos; - return Err(self.error(pos, LexError::ConfusingUnicode(c))); - } + if let Some(c) = comment[pos..].chars().next() + && is_confusing_unicode(c) + { + // Note that `self.cur()` accounts for already having + // parsed `comment`, so we move backwards to where + // `comment` started and then add the index within + // `comment`. + let pos = end - comment.len() + pos; + return Err(self.error(pos, LexError::ConfusingUnicode(c))); } } @@ -1212,9 +1212,9 @@ impl fmt::Display for LexError { )?, UnexpectedEof => write!(f, "unexpected end-of-file")?, NumberTooBig => f.write_str("number is too big to parse")?, - InvalidUnicodeValue(c) => write!(f, "invalid unicode scalar value 0x{:x}", c)?, + InvalidUnicodeValue(c) => write!(f, "invalid unicode scalar value 0x{c:x}")?, LoneUnderscore => write!(f, "bare underscore in numeric literal")?, - ConfusingUnicode(c) => write!(f, "likely-confusing unicode character found {:?}", c)?, + ConfusingUnicode(c) => write!(f, "likely-confusing unicode character found {c:?}")?, InvalidUtf8Id(_) => write!(f, "malformed UTF-8 encoding of string-based id")?, EmptyId => write!(f, "empty identifier")?, EmptyAnnotation => write!(f, "empty annotation id")?, diff --git a/libs/wast/src/lib.rs b/libs/wast/src/lib.rs index 97bfe43c4..a71a6f041 100644 --- a/libs/wast/src/lib.rs +++ b/libs/wast/src/lib.rs @@ -68,7 +68,6 @@ clippy::cast_sign_loss, clippy::cloned_instead_of_copied, clippy::cast_lossless, - clippy::needless_lifetimes, clippy::cast_possible_wrap, clippy::unnested_or_patterns, clippy::allow_attributes_without_reason, diff --git a/libs/wast/src/names.rs b/libs/wast/src/names.rs index 944341192..d473f0eeb 100644 --- a/libs/wast/src/names.rs +++ b/libs/wast/src/names.rs @@ -12,14 +12,15 @@ pub struct Namespace<'a> { impl<'a> Namespace<'a> { pub fn register(&mut self, name: Option>, desc: &str) -> Result { let index = self.alloc(); - if let Some(name) = name { - if let Some(_prev) = self.names.insert(name, index) { - return Err(Error::new( - name.span(), - format!("duplicate {} identifier", desc), - )); - } + if let Some(name) = name + && let Some(_prev) = self.names.insert(name, index) + { + return Err(Error::new( + name.span(), + format!("duplicate {desc} identifier"), + )); } + Ok(index) } @@ -58,8 +59,7 @@ impl<'a> Namespace<'a> { pub fn resolve_error(id: Id<'_>, ns: &str) -> Error { assert!( !id.is_gensym(), - "symbol generated by `wast` itself cannot be resolved {:?}", - id + "symbol generated by `wast` itself cannot be resolved {id:?}", ); Error::new( id.span(), diff --git a/libs/wast/src/parser.rs b/libs/wast/src/parser.rs index bb8eb248b..5bebc2d06 100644 --- a/libs/wast/src/parser.rs +++ b/libs/wast/src/parser.rs @@ -1442,7 +1442,7 @@ impl<'a> Lookahead1<'a> { } _ => { let join = self.attempts.join(", "); - let message = format!("unexpected token, expected one of: {}", join); + let message = format!("unexpected token, expected one of: {join}"); self.parser.error(&message) } } diff --git a/libs/wavltree/src/lib.rs b/libs/wavltree/src/lib.rs index 0db636014..f6a0dbcdc 100644 --- a/libs/wavltree/src/lib.rs +++ b/libs/wavltree/src/lib.rs @@ -127,7 +127,6 @@ //! [graphviz format]: https://graphviz.org #![cfg_attr(not(test), no_std)] -#![feature(let_chains)] #![allow( clippy::undocumented_unsafe_blocks, reason = "too many trivial unsafe blocks" diff --git a/loader/src/arch/riscv64.rs b/loader/src/arch/riscv64.rs index 0cfe6bb3c..cff56012c 100644 --- a/loader/src/arch/riscv64.rs +++ b/loader/src/arch/riscv64.rs @@ -37,70 +37,67 @@ const PTE_PPN_SHIFT: usize = 2; /// For the entry point of all secondary harts see [`_start_secondary`]. #[unsafe(link_section = ".text.start")] #[unsafe(no_mangle)] -#[naked] +#[unsafe(naked)] unsafe extern "C" fn _start() -> ! { - // Safety: inline assembly - unsafe { - naked_asm! { - // FIXME this is a workaround for bug in rustc/llvm - // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 - ".attribute arch, \"rv64gc\"", - - // read boot time stamp as early as possible - "rdtime a2", - - // Clear return address and frame pointer - "mv ra, zero", - "mv s0, zero", - - // Clear the gp register in case anything tries to use it. - "mv gp, zero", - - // Mask all interrupts in case the previous stage left them on. - "csrc sstatus, 1 << 1", - "csrw sie, zero", - - // Reset the trap vector in case the previous stage left one installed. - "csrw stvec, zero", - - // Disable the MMU in case it was left on. - "csrw satp, zero", - - // Setup the stack pointer - "la t0, __stack_start", // set the stack pointer to the bottom of the stack - "li t1, {stack_size}", // load the stack size - "mul sp, a0, t1", // multiply the stack size by the hart id to get the relative stack bottom offset - "add t0, t0, sp", // add the relative stack bottom offset to the absolute stack region offset to get - // the absolute stack bottom - "add sp, t0, t1", // add one stack size again to get to the top of the stack. This is our final stack pointer. - - // fill stack with canary pattern - // $sp is set to stack top above, $t0 as well - "call {fill_stack}", - - // Clear .bss. The linker script ensures these are aligned to 16 bytes. - "lla a3, __bss_zero_start", - "lla a4, __bss_end", - "0:", - " sd zero, (a3)", - " sd zero, 8(a3)", - " add a3, a3, 16", - " blt a3, a4, 0b", - - // Call the rust entry point - "call {start_rust}", - - // Loop forever. - // `start_rust` should never return, but in case it does prevent the hart from executing - // random code - "2:", - " wfi", - " j 2b", - - stack_size = const crate::STACK_SIZE, - start_rust = sym crate::main, - fill_stack = sym fill_stack - } + naked_asm! { + // FIXME this is a workaround for bug in rustc/llvm + // https://github.com/rust-lang/rust/issues/80608#issuecomment-1094267279 + ".attribute arch, \"rv64gc\"", + + // read boot time stamp as early as possible + "rdtime a2", + + // Clear return address and frame pointer + "mv ra, zero", + "mv s0, zero", + + // Clear the gp register in case anything tries to use it. + "mv gp, zero", + + // Mask all interrupts in case the previous stage left them on. + "csrc sstatus, 1 << 1", + "csrw sie, zero", + + // Reset the trap vector in case the previous stage left one installed. + "csrw stvec, zero", + + // Disable the MMU in case it was left on. + "csrw satp, zero", + + // Setup the stack pointer + "la t0, __stack_start", // set the stack pointer to the bottom of the stack + "li t1, {stack_size}", // load the stack size + "mul sp, a0, t1", // multiply the stack size by the hart id to get the relative stack bottom offset + "add t0, t0, sp", // add the relative stack bottom offset to the absolute stack region offset to get + // the absolute stack bottom + "add sp, t0, t1", // add one stack size again to get to the top of the stack. This is our final stack pointer. + + // fill stack with canary pattern + // $sp is set to stack top above, $t0 as well + "call {fill_stack}", + + // Clear .bss. The linker script ensures these are aligned to 16 bytes. + "lla a3, __bss_zero_start", + "lla a4, __bss_end", + "0:", + " sd zero, (a3)", + " sd zero, 8(a3)", + " add a3, a3, 16", + " blt a3, a4, 0b", + + // Call the rust entry point + "call {start_rust}", + + // Loop forever. + // `start_rust` should never return, but in case it does prevent the hart from executing + // random code + "2:", + " wfi", + " j 2b", + + stack_size = const crate::STACK_SIZE, + start_rust = sym crate::main, + fill_stack = sym fill_stack } } @@ -108,57 +105,54 @@ unsafe extern "C" fn _start() -> ! { /// attempt to zero out the BSS. /// /// It will however transfer control to the common [`crate::main`] routine. -#[naked] +#[unsafe(naked)] unsafe extern "C" fn _start_secondary() -> ! { - // Safety: inline assembly - unsafe { - naked_asm! { - // read boot time stamp as early as possible - "rdtime a2", - - // Clear return address and frame pointer - "mv ra, zero", - "mv s0, zero", - - // Clear the gp register in case anything tries to use it. - "mv gp, zero", - - // Mask all interrupts in case the previous stage left them on. - "csrc sstatus, 1 << 1", - "csrw sie, zero", - - // Reset the trap vector in case the previous stage left one installed. - "csrw stvec, zero", - - // Disable the MMU in case it was left on. - "csrw satp, zero", - - // Setup the stack pointer - "la t0, __stack_start", // set the stack pointer to the bottom of the stack - "li t1, {stack_size}", // load the stack size - "mul sp, a0, t1", // multiply the stack size by the hart id to get the relative stack bottom offset - "add t0, t0, sp", // add the relative stack bottom offset to the absolute stack region offset to get - // the absolute stack bottom - "add sp, t0, t1", // add one stack size again to get to the top of the stack. This is our final stack pointer. - - // fill stack with canary pattern - // $sp is set to stack top above, $t0 as well - "call {fill_stack}", - - // Call the rust entry point - "call {start_rust}", - - // Loop forever. - // `start_rust` should never return, but in case it does prevent the hart from executing - // random code - "2:", - " wfi", - " j 2b", - - stack_size = const crate::STACK_SIZE, - start_rust = sym crate::main, - fill_stack = sym fill_stack - } + naked_asm! { + // read boot time stamp as early as possible + "rdtime a2", + + // Clear return address and frame pointer + "mv ra, zero", + "mv s0, zero", + + // Clear the gp register in case anything tries to use it. + "mv gp, zero", + + // Mask all interrupts in case the previous stage left them on. + "csrc sstatus, 1 << 1", + "csrw sie, zero", + + // Reset the trap vector in case the previous stage left one installed. + "csrw stvec, zero", + + // Disable the MMU in case it was left on. + "csrw satp, zero", + + // Setup the stack pointer + "la t0, __stack_start", // set the stack pointer to the bottom of the stack + "li t1, {stack_size}", // load the stack size + "mul sp, a0, t1", // multiply the stack size by the hart id to get the relative stack bottom offset + "add t0, t0, sp", // add the relative stack bottom offset to the absolute stack region offset to get + // the absolute stack bottom + "add sp, t0, t1", // add one stack size again to get to the top of the stack. This is our final stack pointer. + + // fill stack with canary pattern + // $sp is set to stack top above, $t0 as well + "call {fill_stack}", + + // Call the rust entry point + "call {start_rust}", + + // Loop forever. + // `start_rust` should never return, but in case it does prevent the hart from executing + // random code + "2:", + " wfi", + " j 2b", + + stack_size = const crate::STACK_SIZE, + start_rust = sym crate::main, + fill_stack = sym fill_stack } } @@ -169,21 +163,18 @@ unsafe extern "C" fn _start_secondary() -> ! { /// # Safety /// /// expects the bottom of the stack in `t0` and the top of stack in `sp` -#[naked] +#[unsafe(naked)] unsafe extern "C" fn fill_stack() { - // Safety: inline assembly - unsafe { - naked_asm! { - // Fill the stack with a canary pattern (0xACE0BACE) so that we can identify unused stack memory - // in dumps & calculate stack usage. This is also really great (don't ask my why I know this) to identify - // when we tried executing stack memory. - "li t1, 0xACE0BACE", - "1:", - " sw t1, 0(t0)", // write the canary as u64 - " addi t0, t0, 8", // move to the next u64 - " bltu t0, sp, 1b", // loop until we reach the top of the stack - "ret" - } + naked_asm! { + // Fill the stack with a canary pattern (0xACE0BACE) so that we can identify unused stack memory + // in dumps & calculate stack usage. This is also really great (don't ask my why I know this) to identify + // when we tried executing stack memory. + "li t1, 0xACE0BACE", + "1:", + " sw t1, 0(t0)", // write the canary as u64 + " addi t0, t0, 8", // move to the next u64 + " bltu t0, sp, 1b", // loop until we reach the top of the stack + "ret" } } @@ -283,11 +274,11 @@ pub unsafe fn map_contiguous( "address range span be at least one page" ); debug_assert!( - virt % PAGE_SIZE == 0, + virt.is_multiple_of(PAGE_SIZE), "virtual address must be aligned to at least 4KiB page size ({virt:#x})" ); debug_assert!( - phys % PAGE_SIZE == 0, + phys.is_multiple_of(PAGE_SIZE), "physical address must be aligned to at least 4KiB page size ({phys:#x})" ); @@ -373,11 +364,11 @@ pub unsafe fn remap_contiguous( "virtual address range must span be at least one page" ); debug_assert!( - virt % PAGE_SIZE == 0, + virt.is_multiple_of(PAGE_SIZE), "virtual address must be aligned to at least 4KiB page size" ); debug_assert!( - phys % PAGE_SIZE == 0, + phys.is_multiple_of(PAGE_SIZE), "physical address must be aligned to at least 4KiB page size" ); @@ -464,7 +455,7 @@ pub fn pte_index_for_level(virt: usize, lvl: usize) -> usize { /// AND the remaining size is at least the page size. pub fn can_map_at_level(virt: usize, phys: usize, remaining_bytes: usize, lvl: usize) -> bool { let page_size = page_size_for_level(lvl); - virt % page_size == 0 && phys % page_size == 0 && remaining_bytes >= page_size + virt.is_multiple_of(page_size) && phys.is_multiple_of(page_size) && remaining_bytes >= page_size } fn pgtable_ptr_from_phys(phys: usize, phys_off: usize) -> NonNull { diff --git a/loader/src/frame_alloc.rs b/loader/src/frame_alloc.rs index b2c4e37c7..35440e1a2 100644 --- a/loader/src/frame_alloc.rs +++ b/loader/src/frame_alloc.rs @@ -63,7 +63,7 @@ impl<'a> FrameAllocator<'a> { let remaining = layout.pad_to_align().size(); - debug_assert!(remaining % arch::PAGE_SIZE == 0); + debug_assert!(remaining.is_multiple_of(arch::PAGE_SIZE)); FrameIter { alloc: self, remaining, @@ -167,7 +167,7 @@ impl FallibleIterator for FrameIter<'_, '_> { { let allocation_size = cmp::min(self.remaining, allocatable_size) & 0usize.wrapping_sub(arch::PAGE_SIZE); - debug_assert!(allocation_size % arch::PAGE_SIZE == 0); + debug_assert!(allocation_size.is_multiple_of(arch::PAGE_SIZE)); let frame = region.end.checked_sub(offset + allocation_size).unwrap(); self.alloc.offset += allocation_size; diff --git a/loader/src/kernel.rs b/loader/src/kernel.rs index 1e4d195a2..7aade9083 100644 --- a/loader/src/kernel.rs +++ b/loader/src/kernel.rs @@ -89,7 +89,7 @@ impl Kernel<'_> { load_program_headers.map(|ph| ph.align()).max().unwrap_or(1) } - fn loadable_program_headers(&self) -> impl Iterator + '_ { + fn loadable_program_headers(&self) -> impl Iterator> + '_ { self.elf_file .program_iter() .filter(|ph| ph.get_type().unwrap() == Type::Load) diff --git a/loader/src/main.rs b/loader/src/main.rs index 926944dd5..f771b9928 100644 --- a/loader/src/main.rs +++ b/loader/src/main.rs @@ -7,11 +7,9 @@ #![no_std] #![no_main] -#![feature(naked_functions)] #![feature(new_range_api)] #![feature(maybe_uninit_slice)] #![feature(alloc_layout_extra)] -#![feature(let_chains)] use crate::boot_info::prepare_boot_info; use crate::error::Error; diff --git a/loader/src/mapping.rs b/loader/src/mapping.rs index b2e3a6bc6..5cf2fc965 100644 --- a/loader/src/mapping.rs +++ b/loader/src/mapping.rs @@ -114,8 +114,8 @@ pub fn map_physical_memory( ); let size = NonZeroUsize::new(phys.end.checked_sub(phys.start).unwrap()).unwrap(); - debug_assert!(phys.start % alignment == 0 && phys.end % alignment == 0); - debug_assert!(virt.start % alignment == 0 && virt.end % alignment == 0); + debug_assert!(phys.start.is_multiple_of(alignment) && phys.end.is_multiple_of(alignment)); + debug_assert!(virt.start.is_multiple_of(alignment) && virt.end.is_multiple_of(alignment)); log::trace!("Mapping physical memory {phys:#x?} => {virt:#x?}..."); // Safety: Leaving the address space in an invalid state here is fine since on panic we'll @@ -156,7 +156,7 @@ pub fn map_kernel( let phys_base = kernel.elf_file.input.as_ptr() as usize - arch::KERNEL_ASPACE_BASE; assert!( - phys_base % arch::PAGE_SIZE == 0, + phys_base.is_multiple_of(arch::PAGE_SIZE), "Loaded ELF file is not sufficiently aligned" ); @@ -785,7 +785,7 @@ pub const fn checked_align_up(this: usize, align: usize) -> Option { // addr.wrapping_add(align_minus_one) & 0usize.wrapping_sub(align) if let Some(addr_plus_align) = this.checked_add(align_minus_one) { let aligned = addr_plus_align & 0usize.wrapping_sub(align); - debug_assert!(aligned % align == 0); + debug_assert!(aligned.is_multiple_of(align)); debug_assert!(aligned >= this); Some(aligned) } else { @@ -802,7 +802,7 @@ pub const fn align_down(this: usize, align: usize) -> usize { ); let aligned = this & 0usize.wrapping_sub(align); - debug_assert!(aligned % align == 0); + debug_assert!(aligned.is_multiple_of(align)); debug_assert!(aligned <= this); aligned } diff --git a/loader/src/page_alloc.rs b/loader/src/page_alloc.rs index 6efc26eb2..fe9fd3efa 100644 --- a/loader/src/page_alloc.rs +++ b/loader/src/page_alloc.rs @@ -70,7 +70,7 @@ impl PageAllocator { ); let top_level_page_size = arch::page_size_for_level(arch::PAGE_TABLE_LEVELS - 1); - debug_assert!(virt_base % top_level_page_size == 0); + debug_assert!(virt_base.is_multiple_of(top_level_page_size)); while remaining_bytes > 0 { let page_idx = (virt_base - (usize::MAX << arch::VIRT_ADDR_BITS)) / top_level_page_size; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 68af685ef..938d077bd 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "nightly-2025-02-21" +channel = "nightly-2025-07-11" components = ["rustfmt", "miri", "clippy", "rust-src", "llvm-tools"] targets = ["wasm32-unknown-unknown", "riscv64gc-unknown-none-elf"] profile = "minimal"