ADR-0039 + T-027 — userland build pipeline (userland/hello + tyrne-user, B6 step 5)#41
Conversation
Settles the build orchestration ADR-0029 deferred: a tools/build-userland.sh step + rust-objcopy from the pinned llvm-tools-preview (no Cargo dep) + include_bytes! of a git-ignored .bin; userland/hello + tyrne-user as default-members-excluded workspace members; a Rust-side base-VA source-of-truth. Opens T-027 (build pipeline) + T-028 (EL0 wire-up) at Draft per ADR-0025 Rule 1. cargo-xtask named as the B7+ multi-binary upgrade path. Refs: ADR-0039 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ixes Relayed review against the still-Proposed ADR-0039 + its two Draft task slots; verified each finding against source, all valid (1 non-defect observation skipped): - ADR §Context: 'three gates' miscount — listed 4 (T-022 is the high-half prerequisite, not a T-021 gate); reworded to gate #1/#2/#3 + the high-half prerequisite. - ADR + T-027: pinned tyrne-user to userland/tyrne-user/ (was ambiguous 'or workspace root'). - T-027 (HIGH): added the userland-unsafe-audit AC — the svc shims are unsafe; unsafe-policy applies to userspace (SAFETY + audit-log entry). - T-027: added the HELLO_CONSOLE_CAP handle-contract AC (T-027<->T-028 interface) + the explicit userland clippy gate (kernel/host clippy miss the new crates). - T-028 (HIGH): added the AS-lifetime-coupling AC (T-024 SEC-T024-01 carry-forward). - T-028: clarified the smoke is debug-profile (console_write is debug-gated) + documented release behaviour; added the tools/smoke.sh greeting-marker gate AC; pinned the kernel-stack floor at >=1 page. Skipped: the ADR build.rs-panic §Negative item (an implementation detail the reviewer agreed is non-defect). Refs: ADR-0039 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nd ordering) Adversarial 5-lens pre-Accept review (81 agents, per-finding 2-skeptic verification): 38 findings, 37 refuted, 1 confirmed (governance lens fully clean). The confirmed finding: CI's kernel-build/kernel-clippy jobs run 'cargo kernel-build' directly on a clean checkout, so once USERSPACE_IMAGE becomes include_bytes! of a git-ignored .bin, the BSP build.rs missing-.bin panic would break CI. Fix: T-027 gains a CI-workflow-update AC (run tools/build-userland.sh before kernel-build); ADR-0039's stale 'what CI runs' claim corrected (CI runs kernel-build, not the smoke). The 37 refutations confirmed the prior review-round's fixes are present and the option analysis / governance / feasibility are sound. Refs: ADR-0039 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Careful re-read complete (two review rounds: relayed + adversarial 5-lens/81-agent, 37/38 refuted). Flips Proposed -> Accepted in a separate commit per write-adr §10. T-027 (build pipeline + crates) implementation follows. Refs: ADR-0039 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…pipeline (B6 step 5) Implements ADR-0039: Tyrne's first real userspace program, built from Rust source and embedded into the kernel image, replacing the hand-coded mov-w0-#42 placeholder. - userland/tyrne-user (no_std lib): safe console_write / task_exit wrappers over the svc #0 ABI (x8=number, x0..x5=args; ConsoleWrite=5, TaskExit=4); HELLO_CONSOLE_CAP const (the T-027<->T-028 cap-handle interface = root cap, index 0/gen 0 = 0). The two svc shims are the first userspace unsafe (UNSAFE-2026-0033). - userland/hello (no_std no_main bin): _start at .text._start (offset 0) -> console_write(greeting) -> task_exit(0); panic_handler -> task_exit. hello.ld fixes the entry at USERSPACE_IMAGE_BASE_VA (0x0080_0000), ASSERTs no .data/.bss (image maps USER|EXECUTE, no WRITE). - tools/build-userland.sh: cargo build -> rust-objcopy -O binary (from the pinned llvm-tools-preview, NO Cargo dep) -> git-ignored userland/hello/hello.bin. - Workspace: both crates added to members, excluded from default-members (host commands skip them). - BSP: USERSPACE_IMAGE -> include_bytes!(hello.bin); build.rs assert!s the .bin exists (run build-userland.sh first). - tools/smoke.sh now builds userland + kernel (one-command); .github/workflows/ci.yml installs llvm-tools-preview + builds userland before kernel-build (else the clean-checkout kernel-build job hits the missing-.bin assert). Verification: the 117-byte .bin disassembles at offset 0 to _start prologue -> x0=0 (HELLO_CONSOLE_CAP) -> adr x1 greeting -> w2=0x15 (21=len) -> bl console_write -> x0=0 -> bl task_exit. The image loads DORMANT under the smoke (entry=0x800000, image bytes 117, stack bytes 4096); running it in EL0 is T-028. Gates: fmt; host + kernel + userland clippy -D warnings; host tests 46 hal / 258 kernel / 58 test-hal / 3 doc (unchanged — userland is bare-metal); kernel build; tools/smoke.sh --int PASS (image loads, all tasks complete, 2 stub SVCs, zero new fault class); Miri unaffected (no kernel/host logic change). UNSAFE-2026-0033. Refs: T-027, ADR-0039 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reviewer's GuideImplements ADR-0039 / T-027 by introducing a no_std userspace syscall wrapper library and a hello-world userland binary, adding a shell-based userland build pipeline that produces a raw-flat hello image embedded into the BSP via include_bytes!, and wiring smoke/CI and documentation to require the userland image to be built before kernel builds. Flow diagram for the new userland build pipeline and BSP embedflowchart TD
Dev["Developer / CI"] --> SmokeOrCI
SmokeOrCI["tools/smoke.sh or CI 'build userland image' step"] --> BuildScript
BuildScript["tools/build-userland.sh"] --> CargoBuild
CargoBuild["cargo build -p tyrne-userland-hello --target aarch64-unknown-none"] --> HelloElf
HelloElf["target/.../hello (ELF)"] --> Objcopy
Objcopy["rust-objcopy -O binary"] --> HelloBin
HelloBin["userland/hello/hello.bin"] --> BSPBuildRs
BSPBuildRs["bsp-qemu-virt/build.rs assert!(hello.bin exists)"] --> BSPMain
BSPMain["bsp-qemu-virt/src/main.rs USERSPACE_IMAGE = include_bytes!(hello.bin)"]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis PR implements the complete Phase B Milestone B6 Step 5 userland build pipeline: a no_std Rust syscall wrapper crate ( ChangesUserland Build Pipeline and EL0 Integration
Sequence DiagramsequenceDiagram
participant Dev as Developer
participant CI as CI (GitHub Actions)
participant BuildSH as tools/build-userland.sh
participant Cargo as cargo build (hello)
participant ObjCopy as rust-objcopy -O binary
participant BSPBuild as bsp build.rs / include_bytes!
participant KernelBuild as cargo kernel-build
participant QEMU as QEMU Loader
participant StartEL0 as hello _start (EL0)
alt Local smoke.sh (no ELF arg)
Dev->>BuildSH: ./tools/smoke.sh
BuildSH->>Cargo: build hello (aarch64)
Cargo->>ObjCopy: rust-objcopy -> hello.bin
end
CI->>CI: Install llvm-tools-preview
CI->>BuildSH: Run build-userland.sh
BuildSH->>Cargo: Build hello
Cargo->>ObjCopy: Produce ELF -> objcopy
ObjCopy->>BSPBuild: Write hello.bin
CI->>KernelBuild: cargo kernel-build
KernelBuild->>BSPBuild: Compile BSP (include_bytes! + assert)
KernelBuild->>KernelBuild: link kernel
alt Smoke Test
CI->>QEMU: Run kernel in QEMU
QEMU->>QEMU: Load hello.bin at 0x00800000
QEMU->>StartEL0: Jump to _start (offset 0)
StartEL0->>StartEL0: console_write (greeting)
StartEL0->>StartEL0: task_exit(0)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- In
tools/build-userland.sh, resolvingrust-objcopybyfind-ing the entire sysroot can be brittle and slow; consider deriving the path via$(rustc --print target-libdir)/../bin/rust-objcopy(or similar) to avoid unexpected matches and make the lookup more deterministic. - The BSP
build.rshardcodes the hello image path as../userland/hello/hello.bin; you could derive this from the workspace root (e.g., viaCARGO_MANIFEST_DIRplus a known relative) or a shared constant to make future workspace layout changes less fragile.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `tools/build-userland.sh`, resolving `rust-objcopy` by `find`-ing the entire sysroot can be brittle and slow; consider deriving the path via `$(rustc --print target-libdir)/../bin/rust-objcopy` (or similar) to avoid unexpected matches and make the lookup more deterministic.
- The BSP `build.rs` hardcodes the hello image path as `../userland/hello/hello.bin`; you could derive this from the workspace root (e.g., via `CARGO_MANIFEST_DIR` plus a known relative) or a shared constant to make future workspace layout changes less fragile.
## Individual Comments
### Comment 1
<location path="docs/analysis/tasks/phase-b/T-027-userland-build-pipeline.md" line_range="25" />
<code_context>
+- [x] **Userland `unsafe` audit** (security policy applies to userspace too): the `tyrne-user` `svc #0` shims are `unsafe` (inline asm); per [unsafe-policy §Scope](../../../standards/unsafe-policy.md) ("the rules apply equally in kernel, HAL, and userspace code") **and** [CLAUDE.md non-negotiable #2](../../../../CLAUDE.md), each `unsafe` block carries a `// SAFETY:` comment (why the asm upholds the ABI contract — args in `x0..x5`/`x8`, the clobber list, no UB) **and** a dated [`docs/audits/unsafe-log.md`](../../../audits/unsafe-log.md) entry (`UNSAFE-2026-NNNN`). The workspace `clippy::undocumented_unsafe_blocks` / `missing_safety_doc` denies enforce the comment; the audit entry is the policy obligation.
</code_context>
<issue_to_address>
**issue (typo):** Clarify the phrase "denies enforce" in the Clippy sentence.
The clause "the workspace `clippy::undocumented_unsafe_blocks` / `missing_safety_doc` denies enforce the comment" is ungrammatical. Consider something like: "the workspace `clippy::undocumented_unsafe_blocks` / `missing_safety_doc` lints (set to `deny`) require this comment" or similar.
```suggestion
- [x] **Userland `unsafe` audit** (security policy applies to userspace too): the `tyrne-user` `svc #0` shims are `unsafe` (inline asm); per [unsafe-policy §Scope](../../../standards/unsafe-policy.md) ("the rules apply equally in kernel, HAL, and userspace code") **and** [CLAUDE.md non-negotiable #2](../../../../CLAUDE.md), each `unsafe` block carries a `// SAFETY:` comment (why the asm upholds the ABI contract — args in `x0..x5`/`x8`, the clobber list, no UB) **and** a dated [`docs/audits/unsafe-log.md`](../../../audits/unsafe-log.md) entry (`UNSAFE-2026-NNNN`). The workspace `clippy::undocumented_unsafe_blocks` and `clippy::missing_safety_doc` lints (set to `deny`) require this comment; the audit entry is the policy obligation.
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Code Review
This pull request implements the first real userspace program and its build pipeline (ADR-0039) by introducing the tyrne-user and tyrne-userland-hello crates, along with a tools/build-userland.sh script to generate a raw-flat binary. Feedback focuses on improving build robustness and platform independence, such as supporting CARGO_TARGET_DIR in the build script, using std::path::Path for platform-independent path construction in build scripts, and asserting that .got sections are empty in the linker script. Additionally, reviewers suggested enhancing userspace debuggability by printing a diagnostic message in the panic handler and implementing Display for SyscallError.
| exit 1 | ||
| fi | ||
|
|
||
| ELF="target/aarch64-unknown-none/${PROFILE}/hello" |
There was a problem hiding this comment.
The script hardcodes the target/ directory, which will fail if a custom target directory is configured via the CARGO_TARGET_DIR environment variable. Supporting CARGO_TARGET_DIR improves build robustness in nested or CI environments.
| ELF="target/aarch64-unknown-none/${PROFILE}/hello" | |
| TARGET_DIR="${CARGO_TARGET_DIR:-target}" | |
| ELF="${TARGET_DIR}/aarch64-unknown-none/${PROFILE}/hello" |
There was a problem hiding this comment.
Fixed in ce25727 — rust-objcopy is now resolved deterministically via $(rustc --print target-libdir)/../bin/rust-objcopy (with a sysroot find fallback), and the ELF path respects CARGO_TARGET_DIR.
| let hello_bin = format!("{manifest_dir}/../userland/hello/hello.bin"); | ||
| println!("cargo:rerun-if-changed={hello_bin}"); | ||
| assert!( | ||
| std::path::Path::new(&hello_bin).exists(), | ||
| "userland image not built: {hello_bin} is missing.\n \ | ||
| Run `tools/build-userland.sh` before `cargo kernel-build` \ | ||
| (ADR-0039); `tools/smoke.sh` and CI do this automatically." | ||
| ); |
There was a problem hiding this comment.
Path concatenation using format! with hardcoded / separators is not platform-independent. Using std::path::Path and PathBuf is more idiomatic and robust across different host platforms.
let hello_bin = std::path::Path::new(&manifest_dir)
.parent()
.unwrap()
.join("userland")
.join("hello")
.join("hello.bin");
let hello_bin_str = hello_bin.to_str().unwrap();
println!("cargo:rerun-if-changed={}", hello_bin_str);
assert!(
hello_bin.exists(),
"userland image not built: {} is missing.\n \
Run tools/build-userland.sh before cargo kernel-build \
(ADR-0039); tools/smoke.sh and CI do this automatically.",
hello_bin_str
);There was a problem hiding this comment.
Skipped — the format! path with / works on Tyrne's Unix-only dev/CI (macOS + ubuntu, per .github/workflows + the platform); it is not a bug. Path::join is an idiomatic nicety; deferred to keep the change minimal (no Windows target exists).
| let manifest_dir = std::env::var("CARGO_MANIFEST_DIR") | ||
| .expect("CARGO_MANIFEST_DIR must be set by Cargo when running build scripts"); | ||
|
|
||
| println!("cargo:rustc-link-arg=-T{manifest_dir}/hello.ld"); | ||
| println!("cargo:rerun-if-changed=hello.ld"); | ||
| println!("cargo:rerun-if-changed=build.rs"); |
There was a problem hiding this comment.
Path concatenation using / is not platform-independent. Using std::path::Path to construct the path to the linker script is more robust and idiomatic.
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")
.expect("CARGO_MANIFEST_DIR must be set by Cargo when running build scripts");
let linker_script = std::path::Path::new(&manifest_dir).join("hello.ld");
println!("cargo:rustc-link-arg=-T{}", linker_script.display());
println!("cargo:rerun-if-changed=hello.ld");
println!("cargo:rerun-if-changed=build.rs");There was a problem hiding this comment.
Skipped — same as the BSP build.rs thread (Unix-only paths; minimal-change; no Windows target).
| #[panic_handler] | ||
| fn panic(_info: &core::panic::PanicInfo) -> ! { | ||
| task_exit(101) | ||
| } |
There was a problem hiding this comment.
The panic handler currently exits silently with code 101. Writing a static diagnostic message to the console before exiting will greatly aid debugging when a userspace panic occurs.
| #[panic_handler] | |
| fn panic(_info: &core::panic::PanicInfo) -> ! { | |
| task_exit(101) | |
| } | |
| #[panic_handler] | |
| fn panic(_info: &core::panic::PanicInfo) -> ! { | |
| let _ = console_write(HELLO_CONSOLE_CAP, b"userspace panic\n"); | |
| task_exit(101) | |
| } |
There was a problem hiding this comment.
Skipped — for the trivial v1 hello the panic path is effectively unreachable (the only fallible call, console_write, is intentionally ignored); the distinct exit code (101) + the kernel's task-termination report are the signal. A console write inside the panic handler (needing the cap + a possibly-bad state) is over-engineering for v1.
| /* v1 forbids writable data (image is USER|EXECUTE, no WRITE). Collect any | ||
| * stray .data/.bss so the ASSERTs can prove they are empty. */ | ||
| .data : { *(.data .data.*) } | ||
| .bss : { *(.bss .bss.* COMMON) } | ||
|
|
||
| ASSERT(SIZEOF(.data) == 0, | ||
| "userland hello: .data must be empty (image maps USER|EXECUTE, no WRITE)") | ||
| ASSERT(SIZEOF(.bss) == 0, | ||
| "userland hello: .bss must be empty (image maps USER|EXECUTE, no WRITE)") |
There was a problem hiding this comment.
The linker script asserts that .data and .bss are empty, but does not check for .got or .got.plt sections. If position-independent code or dynamic linking artifacts are accidentally generated, they could silently slip into the raw-flat binary. Adding an assertion for .got ensures full robustness.
/* v1 forbids writable data (image is USER|EXECUTE, no WRITE). Collect any
* stray .data/.bss/.got so the ASSERTs can prove they are empty. */
.data : { *(.data .data.*) }
.bss : { *(.bss .bss.* COMMON) }
.got : { *(.got .got.plt) }
ASSERT(SIZEOF(.data) == 0,
"userland hello: .data must be empty (image maps USER|EXECUTE, no WRITE)")
ASSERT(SIZEOF(.bss) == 0,
"userland hello: .bss must be empty (image maps USER|EXECUTE, no WRITE)")
ASSERT(SIZEOF(.got) == 0,
"userland hello: .got must be empty (image maps USER|EXECUTE, no WRITE)")
There was a problem hiding this comment.
Fixed in ce25727 — added a .got : { *(.got .got.plt) } collection + ASSERT(SIZEOF(.got) == 0, …) (v1 is non-PIC / fixed-VA). Good belt-and-suspenders against a stray PIC artifact.
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||
| pub struct SyscallError( | ||
| /// The raw kernel status word (`x0`); the low/high blocks encode the | ||
| /// kernel's `SyscallError` taxonomy ([ADR-0030][adr-0030]). | ||
| /// | ||
| /// [adr-0030]: https://github.com/HodeTech/Tyrne/blob/main/docs/decisions/0030-syscall-abi.md | ||
| pub u64, | ||
| ); |
There was a problem hiding this comment.
SyscallError does not implement core::fmt::Display. Implementing Display is a standard Rust idiom for custom error types, allowing them to be formatted cleanly in userspace programs.
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] | |
| pub struct SyscallError( | |
| /// The raw kernel status word (`x0`); the low/high blocks encode the | |
| /// kernel's `SyscallError` taxonomy ([ADR-0030][adr-0030]). | |
| /// | |
| /// [adr-0030]: https://github.com/HodeTech/Tyrne/blob/main/docs/decisions/0030-syscall-abi.md | |
| pub u64, | |
| ); | |
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] | |
| pub struct SyscallError( | |
| /// The raw kernel status word (x0); the low/high blocks encode the | |
| /// kernel's SyscallError taxonomy ([ADR-0030][adr-0030]). | |
| /// | |
| /// [adr-0030]: https://github.com/HodeTech/Tyrne/blob/main/docs/decisions/0030-syscall-abi.md | |
| pub u64, | |
| ); | |
| impl core::fmt::Display for SyscallError { | |
| fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | |
| write!(f, "SyscallError({:#x})", self.0) | |
| } | |
| } |
There was a problem hiding this comment.
Skipped — SyscallError is never formatted in v1 (hello ignores the result via let _ =). Adding an unused Display impl runs against the 'smallest shape that works' ethos; trivial to add when a userspace program actually needs to format it.
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/analysis/tasks/phase-b/T-027-userland-build-pipeline.md`:
- Line 58: Update the future-dated history entry "2026-06-01 — implemented (→ In
Review)" to a correct past/neutral value: either replace the date with the
actual implementation date or change the phrasing to "planned", "forthcoming",
or "implemented (date TBD)"; edit the line containing the phrase `2026-06-01 —
implemented (→ In Review)` (and any identical timestamped entries) so the
timeline is accurate and not future-dated.
In `@docs/audits/unsafe-log.md`:
- Line 745: The audit entry currently lists "Introduced: 2026-06-01" which is a
future date; locate the "Introduced: 2026-06-01" string in
docs/audits/unsafe-log.md (the audit entry describing the userspace inline-asm
wrappers / T-027 and ADR-0039) and change that date to a non-future date (for
example the PR date or any prior date such as 2026-05-31) so the audit
chronology remains valid.
In `@docs/roadmap/current.md`:
- Around line 7-8: The banner header date "2026-06-01 update" is future-dated;
update it to the actual posting date (e.g., "2026-05-31 update") or explicitly
label it as a planned/future update (e.g., "Planned — 2026-06-01 update") in the
banner text; locate and edit the banner line that references ADR-0039 / T-027
(and surrounding mentions of tools/build-userland.sh, build.rs, tools/smoke.sh)
to replace the date accordingly.
In `@docs/roadmap/phases/phase-b.md`:
- Line 254: The milestone text incorrectly marks the `tyrne-user` /
`userland/hello/` step as "landed (2026-06-01)" which is a future date; update
the sentence in the Phase B doc to either replace the future date with the
actual landing date or change the phrasing to indicate it is scheduled (e.g.,
"scheduled for 2026-06-01" or "targeted 2026-06-01") so the status and date for
the `tools/build-userland.sh`, `build.rs`/`include_bytes!` pipeline and
UNSAFE-2026-0033 reference are consistent.
In `@userland/tyrne-user/src/lib.rs`:
- Line 23: The file unconditionally imports and uses core::arch::asm and
contains inline-asm blocks that reference aarch64 registers (causing CI failures
on non-aarch64 hosts); wrap the asm import and every inline asm block with
#[cfg(target_arch = "aarch64")] and provide host-safe fallbacks (e.g.,
pure-Rust/no-op or Result::Err stubs) for the functions that currently use asm
so non-aarch64 builds (coverage/miri) compile; specifically gate the `use
core::arch::asm;` line and the inline-asm sections mentioned (around the asm
usages and the blocks at the cited ranges) and add #[cfg(not(target_arch =
"aarch64"))] implementations for the same function names to preserve API
surface.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 28abfa35-dd5a-46bb-9879-2f9180f97cc8
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (19)
.github/workflows/ci.ymlCargo.tomlbsp-qemu-virt/build.rsbsp-qemu-virt/src/main.rsdocs/analysis/tasks/phase-b/T-027-userland-build-pipeline.mddocs/analysis/tasks/phase-b/T-028-el0-userspace-wireup.mddocs/audits/unsafe-log.mddocs/decisions/0039-userland-build-pipeline.mddocs/decisions/README.mddocs/roadmap/current.mddocs/roadmap/phases/phase-b.mdtools/build-userland.shtools/smoke.shuserland/hello/Cargo.tomluserland/hello/build.rsuserland/hello/hello.lduserland/hello/src/main.rsuserland/tyrne-user/Cargo.tomluserland/tyrne-user/src/lib.rs
|
|
||
| ### UNSAFE-2026-0033 — `tyrne-user` EL0 syscall `svc #0` shims | ||
|
|
||
| - **Introduced:** 2026-06-01, [T-027 — userland build pipeline](../analysis/tasks/phase-b/T-027-userland-build-pipeline.md) / [ADR-0039](../decisions/0039-userland-build-pipeline.md). The **userspace-side** inline-asm wrappers a userspace program calls to invoke a syscall — the first `unsafe` in userspace code (per [unsafe-policy §Scope](../standards/unsafe-policy.md), "the rules apply equally in kernel, HAL, and userspace code"). |
There was a problem hiding this comment.
Use an introduction date that is not in the future for this audit entry.
Line 745 records Introduced: 2026-06-01, which is future-dated relative to this PR context and weakens audit chronology integrity.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/audits/unsafe-log.md` at line 745, The audit entry currently lists
"Introduced: 2026-06-01" which is a future date; locate the "Introduced:
2026-06-01" string in docs/audits/unsafe-log.md (the audit entry describing the
userspace inline-asm wrappers / T-027 and ADR-0039) and change that date to a
non-future date (for example the PR date or any prior date such as 2026-05-31)
so the audit chronology remains valid.
There was a problem hiding this comment.
Same as the T-027 thread — 2026-06-01 is today's date (verified via date), not future-dated. No change.
There was a problem hiding this comment.
@cemililik — Understood, my apologies for the noise. My system context was slightly behind (May 2026), so I incorrectly flagged 2026-06-01 as future-dated. Since you've confirmed via date that it is today's date, the entry's chronology is accurate. No change needed.
🐇
| > **2026-06-01 update — B6 step 5 landed: ADR-0039 Accepted + T-027 (`userland/hello` + `tyrne-user` + the raw-flat build pipeline) implemented, In Review.** [ADR-0039](../decisions/0039-userland-build-pipeline.md) **Accepted** (the build orchestration ADR-0029 deferred — settled via two review rounds: a relayed 8-fix round + an adversarial 5-lens/81-agent pass, 37/38 refuted). **[T-027](../analysis/tasks/phase-b/T-027-userland-build-pipeline.md)** builds Tyrne's first **real** userspace program from Rust source: a `userland/tyrne-user` crate (safe `console_write`/`task_exit` shims over the `svc #0` ABI — UNSAFE-2026-0033, the first userspace `unsafe`) + a `userland/hello` `#![no_std] #![no_main]` crate (`_start` at offset 0 → greet → `task_exit`; an `hello.ld` linker script fixing the entry at `0x0080_0000`, ASSERT-no-`.data`/`.bss`). The pipeline (per ADR-0039): `tools/build-userland.sh` → `cargo build` → **`rust-objcopy -O binary`** (from the pinned `llvm-tools-preview` — **no Cargo dep**, K3-8 unfired) → a git-ignored `hello.bin`, embedded into the BSP via `include_bytes!` (replacing the hand-coded `mov w0,#42` placeholder; `build.rs` `assert!`s the `.bin` exists). Both crates are `default-members`-excluded workspace members (host commands skip them). `tools/smoke.sh` + CI build userland first (CI gains `llvm-tools-preview` + a build step — the one adversarial-confirmed finding: else the clean-checkout `kernel-build` job would hit the missing-`.bin` panic). **The 117-byte image disassembles at offset 0 to `_start` → `x0=0` (`HELLO_CONSOLE_CAP`) → greeting → `bl console_write` → `bl task_exit`**, and **loads dormant** under the smoke (`entry=0x800000`, `image bytes 117`, `stack bytes 4096`) — **running it in EL0 is [T-028](../analysis/tasks/phase-b/T-028-el0-userspace-wireup.md)** (the `+0x400` round-trip + the explicit EL0-boundary security review). Gates: **host tests 258 kernel / 46 hal / 58 test-hal / 3 doc** (unchanged — userland is bare-metal), fmt, host + kernel + **userland** clippy `-D warnings`, kernel build, `tools/smoke.sh --int` PASS (image loads, `all tasks complete`, 2 stub SVCs, **zero new fault class**), Miri unaffected. **Next:** [T-028](../analysis/tasks/phase-b/T-028-el0-userspace-wireup.md) — wire the EL0 task (load → `task_create_from_image` → seed a `DebugConsole` cap at `HELLO_CONSOLE_CAP` → `add_user_task` → run) + the `+0x400` smoke + the security review; then B6 closure (Phase B retrospective trio). This banner supersedes the gate-#3 banner below. | ||
| > |
There was a problem hiding this comment.
Correct the banner date to avoid future-dated status reporting.
The banner is labeled “2026-06-01 update,” which is in the future relative to today (May 31, 2026). Please use the actual posting date or explicitly mark this as a planned update.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/roadmap/current.md` around lines 7 - 8, The banner header date
"2026-06-01 update" is future-dated; update it to the actual posting date (e.g.,
"2026-05-31 update") or explicitly label it as a planned/future update (e.g.,
"Planned — 2026-06-01 update") in the banner text; locate and edit the banner
line that references ADR-0039 / T-027 (and surrounding mentions of
tools/build-userland.sh, build.rs, tools/smoke.sh) to replace the date
accordingly.
There was a problem hiding this comment.
Same as the T-027 thread — 2026-06-01 is today's date, not future-dated. No change.
There was a problem hiding this comment.
@cemililik — Understood, thanks for the clarification. 2026-06-01 is the correct current date; my concern doesn't apply here. No change needed.
| 3. **`task_create_from_image`** — `LoadedImage` → runnable `CapHandle{CapObject::Task(...)}` (composes steps 1 + 2; the deferred [§B4 §3](#milestone-b4--task-loader) bridge). | ||
| 4. **Close the remaining T-021 carry-forward gates:** the per-task `console_write` window + per-page user-VA → kernel-VA translation returning `FaultAddress` (**gate #1 — security-critical**; without it an EL0 debug-console-cap holder reads arbitrary kernel memory), and `SYSCALL_STUB_TABLE` → the scheduler's current-task table (**gate #3**). | ||
| 5. **`tyrne-user` crate** (safe wrappers) + **`userland/hello/` crate** + the `cargo build → objcopy -O binary → include_bytes!` pipeline + the shared `userland-layout` source-of-truth ([ADR-0029 §"Build pipeline (B6)"](../../decisions/0029-initial-userspace-image-format.md)). *(§Sub-breakdown items 1 + 3.)* | ||
| 5. ✅ **`tyrne-user` crate** (safe wrappers) + **`userland/hello/` crate** + the `cargo build → rust-objcopy -O binary → include_bytes!` pipeline — **landed (2026-06-01, [T-027](../../analysis/tasks/phase-b/T-027-userland-build-pipeline.md) / [ADR-0039](../../decisions/0039-userland-build-pipeline.md), In Review).** `tools/build-userland.sh` (rust-objcopy from the pinned `llvm-tools-preview`, no Cargo dep) produces the git-ignored `hello.bin`; the BSP embeds it via `include_bytes!` (`build.rs` asserts it exists); `smoke.sh` + CI build userland first; UNSAFE-2026-0033 for the userspace `svc` shims. The real 117-byte image **loads dormant** (entry `0x800000`); **running** it is step 6. *(§Sub-breakdown items 1 + 3.)* |
There was a problem hiding this comment.
Avoid future-dated “landed” status in the milestone sequence.
Line 254 says step 5 “landed (2026-06-01)”, which is a future date relative to May 31, 2026. Please update to the actual landing date or change wording to indicate it is scheduled.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/roadmap/phases/phase-b.md` at line 254, The milestone text incorrectly
marks the `tyrne-user` / `userland/hello/` step as "landed (2026-06-01)" which
is a future date; update the sentence in the Phase B doc to either replace the
future date with the actual landing date or change the phrasing to indicate it
is scheduled (e.g., "scheduled for 2026-06-01" or "targeted 2026-06-01") so the
status and date for the `tools/build-userland.sh`, `build.rs`/`include_bytes!`
pipeline and UNSAFE-2026-0033 reference are consistent.
There was a problem hiding this comment.
Same as the T-027 thread — 2026-06-01 is today's date, not future-dated. No change.
There was a problem hiding this comment.
@cemililik, understood — if 2026-06-01 is today's date, the "landed" status and date are accurate and my flag was a false positive. No change needed.
…iri + linker/script hardening Relayed PR #41 bot review; verified each finding against source. HIGH (fixed) — the userland crates broke --workspace host builds: cargo check --workspace --exclude tyrne-bsp-qemu-virt (the Miri-equivalent) failed on tyrne-user's aarch64 inline asm (a regression my original 'Miri unaffected' claim missed). Cfg-gated the svc asm + no_std/no_main to target_arch=aarch64 with degenerate host stubs (never run), keeping ADR-0039's root-members structure. Verified: cargo check --workspace --exclude tyrne-bsp-qemu-virt clean and cargo +nightly miri test --workspace --exclude tyrne-bsp-qemu-virt now compiles the userland crates + passes (kernel 258 / hal 46 / test-hal 58, 0 UB). LOW (fixed): hello.ld also ASSERTs .got empty (non-PIC, catches stray PIC artifacts); tools/build-userland.sh resolves rust-objcopy deterministically via /Users/dev/.rustup/toolchains/nightly-2026-01-15-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib (was a brittle/slow sysroot find) + respects CARGO_TARGET_DIR; the T-027 'denies enforce' typo fixed; UNSAFE-2026-0033 notes the asm is aarch64-gated (host stubs carry no unsafe). Skipped (with reason): the 'future-dated 2026-06-01' findings — today IS 2026-06-01 (date confirmed), the entries are accurate; build.rs format!-> Path::join — the / paths work on Tyrne's Unix-only dev/CI (macOS + ubuntu), not a bug; a console message in the panic_handler — over-engineering for the trivial v1 hello; SyscallError: Display — unused in v1 (YAGNI). Gates re-run green: fmt; host + kernel + userland clippy -D warnings; host tests 46/258/58/3; kernel build; tools/smoke.sh --int PASS (image loads, all tasks complete, 2 stub SVCs, zero new fault); Miri --workspace --exclude 0 UB. Refs: T-027, ADR-0039 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review-round resolution (ce25727)Verified each finding against source; 3 fixed, 1 the headline catch, the rest skipped with reason. Fixed
Skipped (with reason)
Gates re-run green: fmt; host + kernel + userland clippy |
…vm-cov) host link The CI coverage job (cargo llvm-cov --workspace --exclude tyrne-bsp-qemu-virt) failed: it does a real instrumented running 46 tests test mmu::vmsav8::tests::block_descriptor_drops_low_bits_for_unaligned_pa ... ok test mmu::vmsav8::tests::block_descriptor_v1_device_block_encoding ... ok test mmu::vmsav8::tests::descriptor_bits_to_flags_is_lock_shut ... ok test mmu::vmsav8::tests::block_descriptor_v1_kernel_ram_block_encoding ... ok test mmu::vmsav8::tests::device_flag_picks_device_attr_index ... ok test mmu::vmsav8::tests::empty_flags_kernel_ro_normal_no_execute_global_inverted ... ok test mmu::vmsav8::tests::descriptor_bits_to_flags_round_trips_valid_flags ... ok test mmu::vmsav8::tests::flags_to_descriptor_bits_ignores_bits_above_four ... ok test mmu::vmsav8::tests::global_flag_clears_ng_bit ... ok test mmu::vmsav8::tests::mair_value_attr0_device_attr1_normal_others_zero ... ok test mmu::vmsav8::tests::page_descriptor_drops_low_bits_for_unaligned_pa ... ok test mmu::vmsav8::tests::page_descriptor_v1_kernel_rw_page_encoding ... ok test mmu::vmsav8::tests::sctlr_mmu_enable_mask_sets_m_c_i_only ... ok test mmu::vmsav8::tests::table_descriptor_carries_valid_and_table_bits_and_address ... ok test mmu::vmsav8::tests::table_descriptor_drops_low_bits_for_unaligned_address ... ok test mmu::vmsav8::tests::tcr_high_half_clears_only_epd1 ... ok test mmu::vmsav8::tests::tcr_value_carries_t0sz_16_and_ips_2_and_epd1_set ... ok test mmu::vmsav8::tests::user_execute_yields_user_ro_pxn_one_uxn_zero ... ok test mmu::vmsav8::tests::user_write_yields_user_rw_no_execute ... ok test mmu::vmsav8::tests::write_alone_yields_kernel_rw_no_execute ... ok test mmu::vmsav8::tests::write_plus_execute_yields_kernel_rwx_uxn_pxn_zero ... ok test timer::tests::ns_to_ticks_one_second_yields_frequency_at_any_freq ... ok test timer::tests::ns_to_ticks_round_trips_against_ticks_to_ns_at_qemu_frequency ... ok test timer::tests::ns_to_ticks_rounds_up_on_subtick ... ok test timer::tests::ns_to_ticks_saturates_at_u64_max ... ok test timer::tests::ns_to_ticks_zero_ns_is_zero ... ok test timer::tests::ns_to_ticks_panics_on_zero_frequency - should panic ... ok test timer::tests::resolution_clamps_to_one_above_2ghz ... ok test timer::tests::resolution_const_fn_works_in_const_context ... ok test timer::tests::resolution_floor_vs_round_difference_documented ... ok test timer::tests::resolution_one_gigahertz_is_one_ns ... ok test timer::tests::resolution_ns_for_freq_panics_on_zero_frequency - should panic ... ok test timer::tests::resolution_qemu_virt_is_16_ns ... ok test timer::tests::resolution_round_to_nearest_for_non_divisor ... ok test timer::tests::resolution_two_ghz_is_one_ns_exactly ... ok test timer::tests::ticks_to_ns_const_fn_works_in_const_context ... ok test timer::tests::ticks_to_ns_high_frequency_one_gigahertz ... ok test timer::tests::ticks_to_ns_is_monotonic_across_frequencies ... ok test timer::tests::ticks_to_ns_no_silent_wrap_at_64bit_boundary ... ok test timer::tests::ticks_to_ns_pi3_class_non_divisor ... ok test timer::tests::ticks_to_ns_plateaus_at_u64_max_after_saturation ... ok test timer::tests::ticks_to_ns_panics_on_zero_frequency - should panic ... ok test timer::tests::ticks_to_ns_qemu_virt_one_second ... ok test timer::tests::ticks_to_ns_qemu_virt_single_tick ... ok test timer::tests::ticks_to_ns_saturates_at_u64_max ... ok test timer::tests::ticks_to_ns_zero_count_is_zero ... ok test result: ok. 46 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s running 258 tests test cap::rights::tests::difference_clears_bits ... ok test cap::rights::tests::empty_contains_empty_but_nothing_else ... ok test cap::rights::tests::bitor_assign_adds_bits ... ok test cap::rights::tests::from_raw_masks_unknown_bits ... ok test cap::rights::tests::from_raw_and_raw_round_trip ... ok test cap::rights::tests::intersection_narrows ... ok test cap::rights::tests::union_and_contains ... ok test cap::table::tests::cap_copy_narrows_rights ... ok test cap::table::tests::cap_copy_of_root_then_revoke_root_leaves_peer_alive ... ok test cap::table::tests::cap_copy_on_stale_handle_returns_invalid_handle ... ok test cap::table::tests::cap_copy_rejects_widened_rights ... ok test cap::table::tests::cap_copy_with_same_rights_succeeds ... ok test cap::table::tests::cap_copy_without_duplicate_right_fails ... ok test cap::table::tests::cap_derive_creates_child_with_narrower_rights ... ok test cap::table::tests::cap_derive_enforces_depth_cap ... ok test cap::table::tests::cap_derive_on_full_table_returns_caps_exhausted ... ok test cap::table::tests::cap_derive_rejects_widened_rights ... ok test cap::table::tests::cap_derive_without_derive_right_fails ... ok test cap::table::tests::cap_drop_on_interior_node_returns_has_children ... ok test cap::table::tests::cap_revoke_cascades_depth_three ... ok test cap::table::tests::cap_revoke_clears_references_object ... ok test cap::table::tests::cap_revoke_on_leaf_is_a_noop ... ok test cap::table::tests::cap_revoke_on_stale_handle_fails ... ok test cap::table::tests::cap_revoke_removes_only_descendants ... ok test cap::table::tests::cap_revoke_without_revoke_right_fails ... ok test cap::table::tests::cap_take_middle_sibling_preserves_list_integrity ... ok test cap::table::tests::cap_take_on_node_with_children_fails ... ok test cap::table::tests::cap_take_returns_capability_and_invalidates_handle ... ok test cap::table::tests::cap_take_slot_reusable_with_bumped_generation ... ok test cap::table::tests::cap_take_stale_handle_fails ... ok test cap::table::tests::copy_of_a_child_shares_parent ... ok test cap::table::tests::drop_first_child_updates_parent_first_child_pointer ... ok test cap::table::tests::drop_invalidates_handle ... ok test cap::table::tests::drop_middle_sibling_preserves_list_integrity ... ok test cap::table::tests::drop_peer_does_not_affect_other_peer ... ok test cap::table::tests::drop_twice_returns_invalid_handle ... ok test cap::table::tests::freed_slot_is_reused_with_bumped_generation ... ok test cap::table::tests::is_full_transitions ... ok test cap::table::tests::lookup_on_stale_handle_returns_invalid_handle ... ok test cap::table::tests::new_table_can_accept_one_root ... ok test cap::table::tests::references_object_sees_live_caps_only ... ok test cap::table::tests::slot_entry_size_matches_adr_0023 ... ok test cap::table::tests::table_exhaustion_returns_caps_exhausted ... ok test cap::tests::capobject_debug_redacts_handle_but_shows_kind ... ok test cap::tests::debug_redacts_named_object_but_keeps_rights ... ok test ipc::tests::cancel_recv_clears_recv_waiting_back_to_idle ... ok test ipc::tests::blocked_sender_delivered_on_subsequent_recv ... ok test ipc::tests::cancel_recv_is_idempotent ... ok test ipc::tests::cancel_recv_on_idle_is_noop ... ok test ipc::tests::cancel_recv_on_recv_complete_does_not_drop_message_or_cap ... ok test ipc::tests::cancel_recv_on_send_pending_does_not_drop_message ... ok test ipc::tests::cancel_recv_to_destroyed_endpoint_returns_stale_handle ... ok test ipc::tests::cancel_recv_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::cancel_recv_without_recv_right_fails ... ok test ipc::tests::notify_sets_bits ... ok test ipc::tests::notify_with_stale_handle_after_slot_reuse_fails ... ok test ipc::tests::notify_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::notify_without_notify_right_fails ... ok test ipc::tests::receiver_first_delivers_on_send ... ok test ipc::tests::receiver_first_then_send_with_cap ... ok test ipc::tests::recv_with_full_table_preserves_pending_cap ... ok test ipc::tests::recv_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::recv_without_recv_right_fails ... ok test ipc::tests::second_recv_when_waiting_fails ... ok test ipc::tests::second_send_when_pending_fails ... ok test ipc::tests::send_to_destroyed_endpoint_returns_stale_handle ... ok test ipc::tests::send_transfers_cap_atomically ... ok test ipc::tests::send_with_bad_transfer_cap_preserves_recv_waiting ... ok test ipc::tests::send_with_dropped_cap_handle_returns_stale_handle ... ok test ipc::tests::send_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::send_without_send_right_fails ... ok test ipc::tests::send_without_transfer_right_on_xfer_cap_fails ... ok test ipc::tests::sender_first_delivers_on_recv ... ok test ipc::tests::stale_queue_state_reset_on_slot_reuse ... ok test ipc::tests::stale_recv_waiting_resets_silently ... ok test ipc::tests::stale_send_pending_without_cap_resets_silently ... ok test mm::address_space::tests::arena_alloc_returns_distinct_handles ... ok test ipc::tests::stale_send_pending_with_some_cap_panics_in_debug - should panic ... ok test mm::address_space::tests::arena_full_returns_arena_full_error ... ok test mm::address_space::tests::arena_get_with_stale_handle_returns_none ... ok test mm::address_space::tests::cap_create_address_space_consumes_one_pmm_frame_and_mints_cap ... ok test mm::address_space::tests::cap_create_address_space_rejects_missing_derive ... ok test mm::address_space::tests::cap_create_address_space_rejects_widened_rights ... ok test mm::address_space::tests::cap_create_address_space_rejects_wrong_parent_kind ... ok test mm::address_space::tests::cap_create_address_space_returns_out_of_frames_on_pmm_exhaustion ... ok test mm::address_space::tests::cap_create_rejects_too_deep_parent_without_consuming_pmm ... ok test mm::address_space::tests::cap_create_uses_cap_derive_so_revoke_parent_invalidates_child ... ok test mm::address_space::tests::cap_map_installs_mapping_and_flushes_tlb ... ok test mm::address_space::tests::cap_map_propagates_block_mapped_and_leaves_no_mapping ... ok test mm::address_space::tests::cap_map_propagates_intermediate_out_of_frames_and_does_not_consume_pa ... ok test mm::address_space::tests::cap_map_rejects_wrong_kind ... ok test mm::address_space::tests::cap_map_wraps_mmu_error_passthrough ... ok test mm::address_space::tests::cap_unmap_returns_unmapped_frame ... ok test mm::address_space::tests::cap_unmap_wraps_mmu_error_passthrough ... ok test mm::address_space::tests::destroy_with_stale_handle_returns_stale_handle_error ... ok test mm::address_space::tests::inner_accessors_provide_borrow_and_borrow_mut ... ok test mm::address_space::tests::resolve_address_space_cap_returns_handle_on_correct_kind ... ok test mm::address_space::tests::resolve_address_space_cap_returns_wrong_kind_on_endpoint_cap ... ok test mm::address_space::tests::wrap_bootstrap_returns_address_space_with_root ... ok test mm::pmm::tests::alloc_frame_implements_frame_provider ... ok test mm::pmm::tests::alloc_frame_recovers_after_free_under_exhaustion ... ok test mm::pmm::tests::alloc_frame_returns_none_when_exhausted ... ok test mm::pmm::tests::alloc_frame_returns_first_free_and_zeroes_payload ... ok test mm::pmm::tests::could_yield_pa_overlapping_interval_equals_perframe ... ok test mm::pmm::tests::could_yield_pa_overlapping_treats_allocated_frame_as_yieldable ... ok test mm::pmm::tests::extent_4f_fixture_sanity ... ok test mm::pmm::tests::free_frame_clears_bit_and_rewinds_hint ... ok test mm::pmm::tests::free_frame_rejects_double_free_and_reserved ... ok test mm::pmm::tests::free_frame_rejects_pa_outside_extent ... ok test mm::pmm::tests::free_frame_reserved_check_iterates_only_populated_slots ... ok test mm::pmm::tests::new_marks_reserved_ranges_and_initialises_counters ... ok test mm::pmm::tests::new_rejects_extent_larger_than_bitmap ... ok test mm::pmm::tests::new_rejects_overlapping_reserved_ranges ... ok test mm::pmm::tests::new_rejects_reserved_range_outside_extent ... ok test mm::pmm::tests::new_rejects_too_many_reserved_ranges ... ok test mm::pmm::tests::new_rejects_unaligned_extent ... ok test mm::pmm::tests::stats_parity_with_bitmap_bit_count ... ok test obj::arena::tests::allocate_and_get_round_trip ... ok test obj::arena::tests::empty_capacity_arena_has_no_free_slot ... ok test obj::arena::tests::exhaustion_returns_none ... ok test obj::arena::tests::free_invalidates_id ... ok test obj::arena::tests::free_middle_then_allocate_reuses_that_slot ... ok test obj::arena::tests::free_then_allocate_bumps_generation ... ok test obj::arena::tests::get_mut_permits_mutation ... ok test obj::endpoint::tests::create_destroy_round_trip ... ok test obj::notification::tests::destroy_invalidates_handle ... ok test obj::notification::tests::set_and_consume_round_trip ... ok test obj::task::tests::address_space_handle_round_trips ... ok test obj::task::tests::arena_exhaustion_returns_arena_full ... ok test obj::task::tests::create_then_get_round_trip ... ok test obj::task::tests::destroy_invalidates_handle ... ok test obj::task_loader::tests::accepts_image_disjoint_from_pmm_extent ... ok test obj::task_loader::tests::accepts_image_base_va_exactly_at_userspace_va_limit_minus_span ... ok test obj::task_loader::tests::intermediate_frame_count_8mib_image_one_stack_page_crosses_five_l2 ... ok test obj::task_loader::tests::frame_budget_includes_root_plus_intermediates ... ok test obj::task_loader::tests::intermediate_frame_count_l1_boundary_crossing ... ok test obj::task_loader::tests::intermediate_frame_count_minimal_single_l2_slot ... ok test obj::task_loader::tests::intermediate_frame_count_saturated_total_pages ... ok test obj::task_loader::tests::intermediate_frame_count_zero_span_defensive ... ok test obj::task_loader::tests::load_error_frame_budget_exceeded_fields_round_trip ... ok test obj::task_loader::tests::load_error_variants_are_distinct ... ok test obj::task_loader::tests::load_error_variants_pattern_match_exhaustively ... ok test obj::task_loader::tests::loaded_image_distinguishes_different_field_values ... ok test obj::task_loader::tests::loaded_image_struct_literal_round_trips_through_copy_and_eq ... ok test obj::task_loader::tests::maps_stack_with_user_write_flags ... ok test obj::task_loader::tests::maps_image_pages_with_user_execute_flags ... ok test obj::task_loader::tests::missing_derive_surfaces_via_address_space_creation_failed ... ok test obj::task_loader::tests::rejects_empty_image ... ok test obj::task_loader::tests::rejects_image_base_va_past_userspace_va_limit ... ok test obj::task_loader::tests::mints_address_space_cap_with_requested_non_empty_rights ... ok test obj::task_loader::tests::rejects_image_base_va_saturating_overflow ... ok test obj::task_loader::tests::rejects_invalid_parent_cap_lookup ... ok test obj::task_loader::tests::rejects_invalid_parent_cap_wrong_kind ... ok test obj::task_loader::tests::rejects_misaligned_image_base_va_with_pmm_byte_stable ... ok test obj::task_loader::tests::rejects_when_image_overlaps_allocatable_memory ... ok test obj::task_loader::tests::rejects_when_pmm_budget_exceeded ... ok test obj::task_loader::tests::rejects_zero_stack ... ok test obj::task_loader::tests::returns_loaded_image_with_correct_metadata ... ok test obj::task_loader::tests::rolls_back_on_block_mapped_mid_image_loop ... ok test obj::task_loader::tests::rollback_helper_zero_pages_only_drops_cap ... ok test obj::task_loader::tests::rolls_back_on_cap_map_failure_mid_image_loop ... ok test obj::task_loader::tests::rolls_back_on_cap_map_failure_mid_stack_loop ... ok test obj::task_loader::tests::rolls_back_on_intermediate_out_of_frames_mid_image_loop ... ok test obj::task_loader::tests::rolls_back_on_pmm_exhausted_mid_image_loop ... ok test obj::task_loader::tests::stack_top_va_is_one_past_highest_mapped ... ok test obj::task_loader::tests::tail_zeroing_on_partial_last_page ... ok test obj::task_loader::tests::task_create_from_image_mints_task_cap_bound_to_the_loaded_as ... ok test obj::task_loader::tests::task_create_from_image_rejects_stale_as_cap ... ok test obj::task_loader::tests::task_create_from_image_rejects_when_task_arena_full ... ok test obj::task_loader::tests::task_create_from_image_rejects_wrong_kind_as_cap ... ok test obj::task_loader::tests::task_create_from_image_rolls_back_task_on_cap_table_exhausted ... ok test obj::task_loader::tests::va_range_preflight_runs_before_frame_budget ... ok test obj::task_loader::tests::widened_rights_surfaces_via_address_space_creation_failed ... ok test sched::tests::add_task_sets_ready_state_and_stores_handle ... ok test sched::tests::add_user_task_seeds_el0_context_and_enqueues_ready ... ok test sched::tests::address_space_activation_target_pure_function ... ok test sched::tests::current_accessors_resolve_running_task_bindings_or_none ... ok test sched::tests::dispatcher_picks_idle_only_when_ready_queue_empty ... ok test sched::tests::ipc_recv_and_yield_deadlock_rolls_back_endpoint_state ... ok test sched::tests::ipc_recv_and_yield_resume_pending_returns_typed_err ... ok test sched::tests::ipc_recv_and_yield_returns_deadlock_when_ready_queue_empty ... ok test sched::tests::ipc_recv_and_yield_with_idle_as_current_returns_deadlock ... ok test sched::tests::ipc_recv_and_yield_with_no_current_task_leaves_endpoint_idle ... ok test sched::tests::ipc_send_and_yield_delivered_unblocks_receiver_and_yields ... ok test sched::tests::ipc_send_and_yield_enqueued_does_not_yield ... ok test sched::tests::ipc_send_and_yield_send_error_preserves_scheduler_state ... ok test sched::tests::queue_empty_dequeue_is_none ... ok test sched::tests::queue_enqueue_dequeue_fifo_order ... ok test sched::tests::queue_full_returns_error ... ok test sched::tests::queue_len_and_is_empty ... ok test sched::tests::queue_wraps_around ... ok test sched::tests::register_idle_stores_handle_in_idle_slot_and_not_in_ready_queue ... ok test sched::tests::start_prelude_dispatches_head_and_marks_ready ... ok test sched::tests::task_state_variants_are_distinct ... ok test sched::tests::start_prelude_panics_on_empty_ready_queue - should panic ... ok test sched::tests::unblock_after_yield_dispatches_unblocked_receiver_not_idle ... ok test sched::tests::unblock_receiver_on_moves_task_to_ready ... ok test sched::tests::unblock_receiver_on_wrong_ep_is_noop ... ok test sched::tests::yield_now_activates_when_tasks_differ_in_address_space ... ok test sched::tests::yield_now_masks_irqs_across_switch_and_restores_on_return ... ok test sched::tests::yield_now_skips_activation_when_tasks_share_address_space ... ok test sched::tests::yield_now_switches_context_and_updates_current ... ok test sched::tests::yield_now_with_no_current_returns_error ... ok test syscall::abi::tests::as_u64_round_trips_recognised_numbers ... ok test syscall::abi::tests::console_write_is_a_syscall_in_debug_builds ... ok test syscall::abi::tests::decode_maps_v1_numbers ... ok test syscall::abi::tests::decode_out_of_range_is_none ... ok test syscall::abi::tests::decode_send_message_reads_label_and_params ... ok test syscall::abi::tests::decode_zero_is_reserved_invalid ... ok test syscall::abi::tests::none_round_trips_through_null_sentinel ... ok test syscall::abi::tests::recv_pending_packs_pending_code_and_zeroes_rest ... ok test syscall::abi::tests::recv_received_packs_message_and_cap ... ok test syscall::abi::tests::recv_received_without_cap_packs_null_sentinel ... ok test syscall::abi::tests::required_handle_decode_ignores_sentinel_semantics ... ok test syscall::abi::tests::send_outcome_codes ... ok test syscall::abi::tests::some_handle_round_trips ... ok test syscall::abi::tests::syscall_return_with_payload_sets_indexed_word ... ok test syscall::dispatch::tests::bad_number_zero_returns_bad_syscall_number_touching_nothing ... ok test syscall::dispatch::tests::console_write_cap_ok_but_non_user_page_emits_nothing ... ok test syscall::dispatch::tests::console_write_emits_buffer_and_returns_byte_count ... ok test syscall::dispatch::tests::console_write_exactly_one_chunk_emits_all_bytes ... ok test syscall::dispatch::tests::console_write_multipage_second_page_unmapped_emits_nothing ... ok test syscall::dispatch::tests::console_write_out_of_range_buffer_faults_without_output ... ok test syscall::dispatch::tests::console_write_spanning_multiple_chunks_emits_all_bytes ... ok test syscall::dispatch::tests::console_write_with_no_cap_returns_cap_invalid_handle_no_output ... ok test syscall::dispatch::tests::console_write_with_wrong_kind_cap_returns_cap_wrong_kind ... ok test syscall::dispatch::tests::console_write_without_write_right_returns_insufficient_rights ... ok test syscall::dispatch::tests::incomplete_binding_context_fails_closed_on_both_planes ... ok test syscall::dispatch::tests::out_of_range_number_returns_bad_syscall_number ... ok test syscall::dispatch::tests::recv_of_enqueued_message_unpacks_into_registers ... ok test syscall::dispatch::tests::recv_with_no_sender_returns_pending_packing ... ok test syscall::dispatch::tests::send_with_no_receiver_enqueues_and_returns_ok ... ok test syscall::dispatch::tests::send_with_stale_transfer_handle_returns_invalid_transfer_cap ... ok test syscall::dispatch::tests::send_with_transfer_cap_then_recv_returns_cap_in_x6 ... ok test syscall::dispatch::tests::send_without_send_right_returns_typed_ipc_missing_right ... ok test syscall::dispatch::tests::task_exit_routes_to_terminate_with_code ... ok test syscall::dispatch::tests::task_exit_with_no_current_task_fails_closed ... ok test syscall::dispatch::tests::task_yield_routes_to_reschedule ... ok test syscall::dispatch::tests::task_yield_with_no_current_task_fails_closed ... ok test syscall::error::tests::cap_and_ipc_status_blocks_do_not_collide ... ok test syscall::error::tests::cap_error_from_round_trips_and_encodes_in_cap_block ... ok test syscall::error::tests::ipc_error_from_round_trips_and_encodes_in_ipc_block ... ok test syscall::error::tests::ok_status_is_zero_and_no_error_encodes_to_it ... ok test syscall::error::tests::top_level_status_codes_are_stable ... ok test syscall::user_access::tests::copy_from_user_block_mapped_page_faults ... ok test syscall::user_access::tests::copy_from_user_faults_on_unmapped_page ... ok test syscall::user_access::tests::copy_from_user_multipage_second_page_unmapped_copies_nothing ... ok test syscall::user_access::tests::copy_from_user_out_of_window_faults_before_translate ... ok test syscall::user_access::tests::copy_from_user_overrun_past_window_end_faults ... ok test syscall::user_access::tests::copy_from_user_range_ending_in_top_page_does_not_spuriously_fault ... ok test syscall::user_access::tests::copy_from_user_rejects_in_window_non_user_page ... ok test syscall::user_access::tests::copy_from_user_spanning_two_pages_copies_all ... ok test syscall::user_access::tests::copy_from_user_translates_and_copies_a_user_page ... ok test syscall::user_access::tests::copy_to_user_in_range_moves_bytes ... ok test syscall::user_access::tests::copy_to_user_rejects_read_only_user_page ... ok test syscall::user_access::tests::validate_exact_window_fit_is_ok ... ok test syscall::user_access::tests::wrapping_range_faults ... ok test syscall::user_access::tests::zero_length_copy_is_ok_even_for_unmapped_pointer ... ok test result: ok. 258 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s running 58 tests test context_switch::tests::context_switch_marks_current_and_counts ... ok test console::tests::fmt_writer_produces_formatted_output ... ok test console::tests::captures_successive_byte_writes ... ok test context_switch::tests::default_context_is_uninitialized_and_unswitched ... ok test console::tests::default_fake_console_is_empty ... ok test context_switch::tests::init_context_records_entry_stack_and_marks_initialized ... ok test context_switch::tests::init_context_clears_prior_user_markers_on_reuse ... ok test context_switch::tests::init_user_context_records_user_entry_sp_kernel_stack_and_marks_is_user ... ok test cpu::tests::default_cpu_reports_core_zero_with_irqs_enabled ... ok test cpu::tests::disable_irqs_masks_and_returns_previous_state ... ok test cpu::tests::instruction_barrier_increments_count ... ok test cpu::tests::irq_guard_enters_and_exits_critical_section ... ok test cpu::tests::irq_state_uses_daif_polarity_zero_means_enabled ... ok test cpu::tests::nested_irq_guards_restore_outer_state ... ok test cpu::tests::wait_for_interrupt_increments_count ... ok test cpu::tests::with_core_id_sets_reported_id ... ok test irq_controller::tests::ack_eoi_cycle_leaves_clean_state ... ok test irq_controller::tests::acknowledge_returns_none_when_queue_empty ... ok test irq_controller::tests::acknowledge_returns_pending_fifo ... ok test irq_controller::tests::disable_removes_enabled_state ... ok test irq_controller::tests::disabled_irq_can_still_be_injected_for_test_purposes ... ok test irq_controller::tests::enable_is_idempotent ... ok test irq_controller::tests::disable_panics_on_out_of_range_irq - should panic ... ok test irq_controller::tests::enable_marks_line_as_enabled ... ok test irq_controller::tests::end_of_interrupt_records_irq_in_order ... ok test mmu::tests::activate_records_root ... ok test irq_controller::tests::enable_panics_on_out_of_range_irq - should panic ... ok test mmu::tests::block_mapped_mmu_delegates_unblocked_addresses ... ok test mmu::tests::block_mapped_mmu_injects_block_mapped_on_map_and_unmap ... ok test mmu::tests::block_mapped_mmu_translate_injects_block_mapped ... ok test mmu::tests::bulk_map_with_ignore_then_invalidate_tlb_all ... ok test mmu::tests::create_address_space_stores_root ... ok test mmu::tests::double_map_returns_already_mapped ... ok test mmu::tests::fake_translate_returns_mapping_and_aligns_interior_offset ... ok test mmu::tests::fake_translate_unmapped_is_not_mapped ... ok test mmu::tests::map_rejects_device_plus_execute ... ok test mmu::tests::map_rejects_unaligned_va ... ok test mmu::tests::map_returns_token_with_mapped_va ... ok test mmu::tests::map_unmap_round_trip ... ok test mmu::tests::mapper_flush_carries_virt_addr ... ok test mmu::tests::mapper_flush_flush_invokes_invalidate_tlb_address ... ok test mmu::tests::mapper_flush_ignore_is_documented_noop ... ok test mmu::tests::mapping_flags_difference_clears_bits ... ok test mmu::tests::mapping_flags_union_and_contains ... ok test mmu::tests::out_of_frames_mmu_maps_while_frames_available ... ok test mmu::tests::out_of_frames_mmu_returns_out_of_frames_when_provider_empty ... ok test mmu::tests::phys_frame_rejects_unaligned ... ok test mmu::tests::tlb_invalidations_recorded_in_order ... ok test mmu::tests::unmap_missing_returns_not_mapped ... ok test mmu::tests::unmap_rejects_unaligned_va ... ok test mmu::tests::unmap_returns_token_with_unmapped_va_and_frame ... ok test timer::tests::advance_moves_clock_forward ... ok test timer::tests::arm_deadline_records_value ... ok test timer::tests::arm_deadline_replaces_previous ... ok test timer::tests::cancel_clears_deadline_and_counts ... ok test timer::tests::default_has_one_nanosecond_resolution ... ok test timer::tests::new_starts_at_zero_with_given_resolution ... ok test timer::tests::set_now_overrides_clock ... ok test result: ok. 58 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s running 2 tests test hal/src/console.rs - console::FmtWriter (line 51) ... ignored test hal/src/cpu.rs - cpu::IrqGuard (line 108) ... ignored test result: ok. 0 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 0.00s running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s running 3 tests test test-hal/src/context_switch.rs - context_switch::FakeContextSwitch (line 60) ... ok test test-hal/src/mmu.rs - mmu::OutOfFramesMmu (line 312) ... ok test test-hal/src/mmu.rs - mmu::BlockMappedMmu (line 446) ... ok test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.91s build that LINKS the host test binary of the hello bin crate, and hello/build.rs passed -T hello.ld unconditionally — so the bare-metal script's no-.data/.bss/.got ASSERTs fired against the host std + coverage artifacts at link time. (My earlier review-round cfg-gated the SOURCE so --workspace host-COMPILES, and the miri job passed because Miri interprets rather than links — but llvm-cov links, and I had validated with (no link) + running 46 tests test mmu::vmsav8::tests::block_descriptor_drops_low_bits_for_unaligned_pa ... ok test mmu::vmsav8::tests::descriptor_bits_to_flags_round_trips_valid_flags ... ok test mmu::vmsav8::tests::block_descriptor_v1_device_block_encoding ... ok test mmu::vmsav8::tests::descriptor_bits_to_flags_is_lock_shut ... ok test mmu::vmsav8::tests::block_descriptor_v1_kernel_ram_block_encoding ... ok test mmu::vmsav8::tests::device_flag_picks_device_attr_index ... ok test mmu::vmsav8::tests::empty_flags_kernel_ro_normal_no_execute_global_inverted ... ok test mmu::vmsav8::tests::flags_to_descriptor_bits_ignores_bits_above_four ... ok test mmu::vmsav8::tests::global_flag_clears_ng_bit ... ok test mmu::vmsav8::tests::mair_value_attr0_device_attr1_normal_others_zero ... ok test mmu::vmsav8::tests::page_descriptor_drops_low_bits_for_unaligned_pa ... ok test mmu::vmsav8::tests::page_descriptor_v1_kernel_rw_page_encoding ... ok test mmu::vmsav8::tests::sctlr_mmu_enable_mask_sets_m_c_i_only ... ok test mmu::vmsav8::tests::table_descriptor_carries_valid_and_table_bits_and_address ... ok test mmu::vmsav8::tests::table_descriptor_drops_low_bits_for_unaligned_address ... ok test mmu::vmsav8::tests::tcr_high_half_clears_only_epd1 ... ok test mmu::vmsav8::tests::tcr_value_carries_t0sz_16_and_ips_2_and_epd1_set ... ok test mmu::vmsav8::tests::user_execute_yields_user_ro_pxn_one_uxn_zero ... ok test mmu::vmsav8::tests::user_write_yields_user_rw_no_execute ... ok test mmu::vmsav8::tests::write_alone_yields_kernel_rw_no_execute ... ok test mmu::vmsav8::tests::write_plus_execute_yields_kernel_rwx_uxn_pxn_zero ... ok test timer::tests::ns_to_ticks_one_second_yields_frequency_at_any_freq ... ok test timer::tests::ns_to_ticks_round_trips_against_ticks_to_ns_at_qemu_frequency ... ok test timer::tests::ns_to_ticks_rounds_up_on_subtick ... ok test timer::tests::ns_to_ticks_saturates_at_u64_max ... ok test timer::tests::ns_to_ticks_panics_on_zero_frequency - should panic ... ok test timer::tests::ns_to_ticks_zero_ns_is_zero ... ok test timer::tests::resolution_clamps_to_one_above_2ghz ... ok test timer::tests::resolution_const_fn_works_in_const_context ... ok test timer::tests::resolution_floor_vs_round_difference_documented ... ok test timer::tests::resolution_one_gigahertz_is_one_ns ... ok test timer::tests::resolution_ns_for_freq_panics_on_zero_frequency - should panic ... ok test timer::tests::resolution_qemu_virt_is_16_ns ... ok test timer::tests::resolution_round_to_nearest_for_non_divisor ... ok test timer::tests::resolution_two_ghz_is_one_ns_exactly ... ok test timer::tests::ticks_to_ns_const_fn_works_in_const_context ... ok test timer::tests::ticks_to_ns_high_frequency_one_gigahertz ... ok test timer::tests::ticks_to_ns_is_monotonic_across_frequencies ... ok test timer::tests::ticks_to_ns_no_silent_wrap_at_64bit_boundary ... ok test timer::tests::ticks_to_ns_panics_on_zero_frequency - should panic ... ok test timer::tests::ticks_to_ns_pi3_class_non_divisor ... ok test timer::tests::ticks_to_ns_plateaus_at_u64_max_after_saturation ... ok test timer::tests::ticks_to_ns_qemu_virt_one_second ... ok test timer::tests::ticks_to_ns_qemu_virt_single_tick ... ok test timer::tests::ticks_to_ns_saturates_at_u64_max ... ok test timer::tests::ticks_to_ns_zero_count_is_zero ... ok test result: ok. 46 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s running 258 tests test cap::rights::tests::bitor_assign_adds_bits ... ok test cap::rights::tests::difference_clears_bits ... ok test cap::rights::tests::empty_contains_empty_but_nothing_else ... ok test cap::rights::tests::from_raw_and_raw_round_trip ... ok test cap::rights::tests::from_raw_masks_unknown_bits ... ok test cap::rights::tests::intersection_narrows ... ok test cap::rights::tests::union_and_contains ... ok test cap::table::tests::cap_copy_narrows_rights ... ok test cap::table::tests::cap_copy_of_root_then_revoke_root_leaves_peer_alive ... ok test cap::table::tests::cap_copy_on_stale_handle_returns_invalid_handle ... ok test cap::table::tests::cap_copy_rejects_widened_rights ... ok test cap::table::tests::cap_copy_with_same_rights_succeeds ... ok test cap::table::tests::cap_copy_without_duplicate_right_fails ... ok test cap::table::tests::cap_derive_creates_child_with_narrower_rights ... ok test cap::table::tests::cap_derive_enforces_depth_cap ... ok test cap::table::tests::cap_derive_on_full_table_returns_caps_exhausted ... ok test cap::table::tests::cap_derive_rejects_widened_rights ... ok test cap::table::tests::cap_derive_without_derive_right_fails ... ok test cap::table::tests::cap_drop_on_interior_node_returns_has_children ... ok test cap::table::tests::cap_revoke_cascades_depth_three ... ok test cap::table::tests::cap_revoke_clears_references_object ... ok test cap::table::tests::cap_revoke_on_leaf_is_a_noop ... ok test cap::table::tests::cap_revoke_on_stale_handle_fails ... ok test cap::table::tests::cap_revoke_removes_only_descendants ... ok test cap::table::tests::cap_revoke_without_revoke_right_fails ... ok test cap::table::tests::cap_take_middle_sibling_preserves_list_integrity ... ok test cap::table::tests::cap_take_on_node_with_children_fails ... ok test cap::table::tests::cap_take_returns_capability_and_invalidates_handle ... ok test cap::table::tests::cap_take_slot_reusable_with_bumped_generation ... ok test cap::table::tests::cap_take_stale_handle_fails ... ok test cap::table::tests::copy_of_a_child_shares_parent ... ok test cap::table::tests::drop_first_child_updates_parent_first_child_pointer ... ok test cap::table::tests::drop_invalidates_handle ... ok test cap::table::tests::drop_middle_sibling_preserves_list_integrity ... ok test cap::table::tests::drop_peer_does_not_affect_other_peer ... ok test cap::table::tests::drop_twice_returns_invalid_handle ... ok test cap::table::tests::freed_slot_is_reused_with_bumped_generation ... ok test cap::table::tests::is_full_transitions ... ok test cap::table::tests::lookup_on_stale_handle_returns_invalid_handle ... ok test cap::table::tests::new_table_can_accept_one_root ... ok test cap::table::tests::references_object_sees_live_caps_only ... ok test cap::table::tests::slot_entry_size_matches_adr_0023 ... ok test cap::table::tests::table_exhaustion_returns_caps_exhausted ... ok test cap::tests::capobject_debug_redacts_handle_but_shows_kind ... ok test cap::tests::debug_redacts_named_object_but_keeps_rights ... ok test ipc::tests::blocked_sender_delivered_on_subsequent_recv ... ok test ipc::tests::cancel_recv_clears_recv_waiting_back_to_idle ... ok test ipc::tests::cancel_recv_is_idempotent ... ok test ipc::tests::cancel_recv_on_idle_is_noop ... ok test ipc::tests::cancel_recv_on_recv_complete_does_not_drop_message_or_cap ... ok test ipc::tests::cancel_recv_on_send_pending_does_not_drop_message ... ok test ipc::tests::cancel_recv_to_destroyed_endpoint_returns_stale_handle ... ok test ipc::tests::cancel_recv_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::cancel_recv_without_recv_right_fails ... ok test ipc::tests::notify_sets_bits ... ok test ipc::tests::notify_with_stale_handle_after_slot_reuse_fails ... ok test ipc::tests::notify_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::notify_without_notify_right_fails ... ok test ipc::tests::receiver_first_delivers_on_send ... ok test ipc::tests::receiver_first_then_send_with_cap ... ok test ipc::tests::recv_with_full_table_preserves_pending_cap ... ok test ipc::tests::recv_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::recv_without_recv_right_fails ... ok test ipc::tests::second_recv_when_waiting_fails ... ok test ipc::tests::second_send_when_pending_fails ... ok test ipc::tests::send_to_destroyed_endpoint_returns_stale_handle ... ok test ipc::tests::send_transfers_cap_atomically ... ok test ipc::tests::send_with_bad_transfer_cap_preserves_recv_waiting ... ok test ipc::tests::send_with_dropped_cap_handle_returns_stale_handle ... ok test ipc::tests::send_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::send_without_send_right_fails ... ok test ipc::tests::send_without_transfer_right_on_xfer_cap_fails ... ok test ipc::tests::sender_first_delivers_on_recv ... ok test ipc::tests::stale_queue_state_reset_on_slot_reuse ... ok test ipc::tests::stale_recv_waiting_resets_silently ... ok test ipc::tests::stale_send_pending_without_cap_resets_silently ... ok test mm::address_space::tests::arena_alloc_returns_distinct_handles ... ok test mm::address_space::tests::arena_full_returns_arena_full_error ... ok test ipc::tests::stale_send_pending_with_some_cap_panics_in_debug - should panic ... ok test mm::address_space::tests::arena_get_with_stale_handle_returns_none ... ok test mm::address_space::tests::cap_create_address_space_consumes_one_pmm_frame_and_mints_cap ... ok test mm::address_space::tests::cap_create_address_space_rejects_missing_derive ... ok test mm::address_space::tests::cap_create_address_space_rejects_widened_rights ... ok test mm::address_space::tests::cap_create_address_space_rejects_wrong_parent_kind ... ok test mm::address_space::tests::cap_create_address_space_returns_out_of_frames_on_pmm_exhaustion ... ok test mm::address_space::tests::cap_create_rejects_too_deep_parent_without_consuming_pmm ... ok test mm::address_space::tests::cap_create_uses_cap_derive_so_revoke_parent_invalidates_child ... ok test mm::address_space::tests::cap_map_installs_mapping_and_flushes_tlb ... ok test mm::address_space::tests::cap_map_propagates_block_mapped_and_leaves_no_mapping ... ok test mm::address_space::tests::cap_map_propagates_intermediate_out_of_frames_and_does_not_consume_pa ... ok test mm::address_space::tests::cap_map_rejects_wrong_kind ... ok test mm::address_space::tests::cap_map_wraps_mmu_error_passthrough ... ok test mm::address_space::tests::cap_unmap_returns_unmapped_frame ... ok test mm::address_space::tests::cap_unmap_wraps_mmu_error_passthrough ... ok test mm::address_space::tests::destroy_with_stale_handle_returns_stale_handle_error ... ok test mm::address_space::tests::inner_accessors_provide_borrow_and_borrow_mut ... ok test mm::address_space::tests::resolve_address_space_cap_returns_handle_on_correct_kind ... ok test mm::address_space::tests::resolve_address_space_cap_returns_wrong_kind_on_endpoint_cap ... ok test mm::address_space::tests::wrap_bootstrap_returns_address_space_with_root ... ok test mm::pmm::tests::alloc_frame_implements_frame_provider ... ok test mm::pmm::tests::alloc_frame_recovers_after_free_under_exhaustion ... ok test mm::pmm::tests::alloc_frame_returns_none_when_exhausted ... ok test mm::pmm::tests::alloc_frame_returns_first_free_and_zeroes_payload ... ok test mm::pmm::tests::could_yield_pa_overlapping_interval_equals_perframe ... ok test mm::pmm::tests::extent_4f_fixture_sanity ... ok test mm::pmm::tests::could_yield_pa_overlapping_treats_allocated_frame_as_yieldable ... ok test mm::pmm::tests::free_frame_rejects_double_free_and_reserved ... ok test mm::pmm::tests::free_frame_clears_bit_and_rewinds_hint ... ok test mm::pmm::tests::free_frame_rejects_pa_outside_extent ... ok test mm::pmm::tests::free_frame_reserved_check_iterates_only_populated_slots ... ok test mm::pmm::tests::new_marks_reserved_ranges_and_initialises_counters ... ok test mm::pmm::tests::new_rejects_extent_larger_than_bitmap ... ok test mm::pmm::tests::new_rejects_overlapping_reserved_ranges ... ok test mm::pmm::tests::new_rejects_reserved_range_outside_extent ... ok test mm::pmm::tests::new_rejects_too_many_reserved_ranges ... ok test mm::pmm::tests::new_rejects_unaligned_extent ... ok test mm::pmm::tests::stats_parity_with_bitmap_bit_count ... ok test obj::arena::tests::allocate_and_get_round_trip ... ok test obj::arena::tests::empty_capacity_arena_has_no_free_slot ... ok test obj::arena::tests::exhaustion_returns_none ... ok test obj::arena::tests::free_invalidates_id ... ok test obj::arena::tests::free_middle_then_allocate_reuses_that_slot ... ok test obj::arena::tests::free_then_allocate_bumps_generation ... ok test obj::arena::tests::get_mut_permits_mutation ... ok test obj::endpoint::tests::create_destroy_round_trip ... ok test obj::notification::tests::destroy_invalidates_handle ... ok test obj::notification::tests::set_and_consume_round_trip ... ok test obj::task::tests::address_space_handle_round_trips ... ok test obj::task::tests::arena_exhaustion_returns_arena_full ... ok test obj::task::tests::create_then_get_round_trip ... ok test obj::task::tests::destroy_invalidates_handle ... ok test obj::task_loader::tests::accepts_image_base_va_exactly_at_userspace_va_limit_minus_span ... ok test obj::task_loader::tests::accepts_image_disjoint_from_pmm_extent ... ok test obj::task_loader::tests::intermediate_frame_count_8mib_image_one_stack_page_crosses_five_l2 ... ok test obj::task_loader::tests::frame_budget_includes_root_plus_intermediates ... ok test obj::task_loader::tests::intermediate_frame_count_l1_boundary_crossing ... ok test obj::task_loader::tests::intermediate_frame_count_minimal_single_l2_slot ... ok test obj::task_loader::tests::intermediate_frame_count_saturated_total_pages ... ok test obj::task_loader::tests::intermediate_frame_count_zero_span_defensive ... ok test obj::task_loader::tests::load_error_frame_budget_exceeded_fields_round_trip ... ok test obj::task_loader::tests::load_error_variants_are_distinct ... ok test obj::task_loader::tests::load_error_variants_pattern_match_exhaustively ... ok test obj::task_loader::tests::loaded_image_distinguishes_different_field_values ... ok test obj::task_loader::tests::loaded_image_struct_literal_round_trips_through_copy_and_eq ... ok test obj::task_loader::tests::maps_stack_with_user_write_flags ... ok test obj::task_loader::tests::maps_image_pages_with_user_execute_flags ... ok test obj::task_loader::tests::missing_derive_surfaces_via_address_space_creation_failed ... ok test obj::task_loader::tests::rejects_empty_image ... ok test obj::task_loader::tests::mints_address_space_cap_with_requested_non_empty_rights ... ok test obj::task_loader::tests::rejects_image_base_va_past_userspace_va_limit ... ok test obj::task_loader::tests::rejects_image_base_va_saturating_overflow ... ok test obj::task_loader::tests::rejects_invalid_parent_cap_lookup ... ok test obj::task_loader::tests::rejects_invalid_parent_cap_wrong_kind ... ok test obj::task_loader::tests::rejects_misaligned_image_base_va_with_pmm_byte_stable ... ok test obj::task_loader::tests::rejects_when_image_overlaps_allocatable_memory ... ok test obj::task_loader::tests::rejects_when_pmm_budget_exceeded ... ok test obj::task_loader::tests::rejects_zero_stack ... ok test obj::task_loader::tests::returns_loaded_image_with_correct_metadata ... ok test obj::task_loader::tests::rollback_helper_zero_pages_only_drops_cap ... ok test obj::task_loader::tests::rolls_back_on_block_mapped_mid_image_loop ... ok test obj::task_loader::tests::rolls_back_on_cap_map_failure_mid_image_loop ... ok test obj::task_loader::tests::rolls_back_on_cap_map_failure_mid_stack_loop ... ok test obj::task_loader::tests::rolls_back_on_intermediate_out_of_frames_mid_image_loop ... ok test obj::task_loader::tests::rolls_back_on_pmm_exhausted_mid_image_loop ... ok test obj::task_loader::tests::tail_zeroing_on_partial_last_page ... ok test obj::task_loader::tests::stack_top_va_is_one_past_highest_mapped ... ok test obj::task_loader::tests::task_create_from_image_mints_task_cap_bound_to_the_loaded_as ... ok test obj::task_loader::tests::task_create_from_image_rejects_stale_as_cap ... ok test obj::task_loader::tests::task_create_from_image_rejects_when_task_arena_full ... ok test obj::task_loader::tests::task_create_from_image_rejects_wrong_kind_as_cap ... ok test obj::task_loader::tests::task_create_from_image_rolls_back_task_on_cap_table_exhausted ... ok test obj::task_loader::tests::va_range_preflight_runs_before_frame_budget ... ok test obj::task_loader::tests::widened_rights_surfaces_via_address_space_creation_failed ... ok test sched::tests::add_task_sets_ready_state_and_stores_handle ... ok test sched::tests::add_user_task_seeds_el0_context_and_enqueues_ready ... ok test sched::tests::address_space_activation_target_pure_function ... ok test sched::tests::current_accessors_resolve_running_task_bindings_or_none ... ok test sched::tests::dispatcher_picks_idle_only_when_ready_queue_empty ... ok test sched::tests::ipc_recv_and_yield_deadlock_rolls_back_endpoint_state ... ok test sched::tests::ipc_recv_and_yield_resume_pending_returns_typed_err ... ok test sched::tests::ipc_recv_and_yield_returns_deadlock_when_ready_queue_empty ... ok test sched::tests::ipc_recv_and_yield_with_idle_as_current_returns_deadlock ... ok test sched::tests::ipc_recv_and_yield_with_no_current_task_leaves_endpoint_idle ... ok test sched::tests::ipc_send_and_yield_delivered_unblocks_receiver_and_yields ... ok test sched::tests::ipc_send_and_yield_enqueued_does_not_yield ... ok test sched::tests::ipc_send_and_yield_send_error_preserves_scheduler_state ... ok test sched::tests::queue_empty_dequeue_is_none ... ok test sched::tests::queue_enqueue_dequeue_fifo_order ... ok test sched::tests::queue_full_returns_error ... ok test sched::tests::queue_len_and_is_empty ... ok test sched::tests::queue_wraps_around ... ok test sched::tests::register_idle_stores_handle_in_idle_slot_and_not_in_ready_queue ... ok test sched::tests::start_prelude_dispatches_head_and_marks_ready ... ok test sched::tests::task_state_variants_are_distinct ... ok test sched::tests::unblock_after_yield_dispatches_unblocked_receiver_not_idle ... ok test sched::tests::start_prelude_panics_on_empty_ready_queue - should panic ... ok test sched::tests::unblock_receiver_on_moves_task_to_ready ... ok test sched::tests::unblock_receiver_on_wrong_ep_is_noop ... ok test sched::tests::yield_now_activates_when_tasks_differ_in_address_space ... ok test sched::tests::yield_now_masks_irqs_across_switch_and_restores_on_return ... ok test sched::tests::yield_now_skips_activation_when_tasks_share_address_space ... ok test sched::tests::yield_now_switches_context_and_updates_current ... ok test sched::tests::yield_now_with_no_current_returns_error ... ok test syscall::abi::tests::as_u64_round_trips_recognised_numbers ... ok test syscall::abi::tests::console_write_is_a_syscall_in_debug_builds ... ok test syscall::abi::tests::decode_maps_v1_numbers ... ok test syscall::abi::tests::decode_out_of_range_is_none ... ok test syscall::abi::tests::decode_send_message_reads_label_and_params ... ok test syscall::abi::tests::decode_zero_is_reserved_invalid ... ok test syscall::abi::tests::none_round_trips_through_null_sentinel ... ok test syscall::abi::tests::recv_pending_packs_pending_code_and_zeroes_rest ... ok test syscall::abi::tests::recv_received_packs_message_and_cap ... ok test syscall::abi::tests::recv_received_without_cap_packs_null_sentinel ... ok test syscall::abi::tests::required_handle_decode_ignores_sentinel_semantics ... ok test syscall::abi::tests::send_outcome_codes ... ok test syscall::abi::tests::some_handle_round_trips ... ok test syscall::abi::tests::syscall_return_with_payload_sets_indexed_word ... ok test syscall::dispatch::tests::bad_number_zero_returns_bad_syscall_number_touching_nothing ... ok test syscall::dispatch::tests::console_write_cap_ok_but_non_user_page_emits_nothing ... ok test syscall::dispatch::tests::console_write_emits_buffer_and_returns_byte_count ... ok test syscall::dispatch::tests::console_write_exactly_one_chunk_emits_all_bytes ... ok test syscall::dispatch::tests::console_write_multipage_second_page_unmapped_emits_nothing ... ok test syscall::dispatch::tests::console_write_out_of_range_buffer_faults_without_output ... ok test syscall::dispatch::tests::console_write_spanning_multiple_chunks_emits_all_bytes ... ok test syscall::dispatch::tests::console_write_with_no_cap_returns_cap_invalid_handle_no_output ... ok test syscall::dispatch::tests::console_write_with_wrong_kind_cap_returns_cap_wrong_kind ... ok test syscall::dispatch::tests::console_write_without_write_right_returns_insufficient_rights ... ok test syscall::dispatch::tests::incomplete_binding_context_fails_closed_on_both_planes ... ok test syscall::dispatch::tests::out_of_range_number_returns_bad_syscall_number ... ok test syscall::dispatch::tests::recv_of_enqueued_message_unpacks_into_registers ... ok test syscall::dispatch::tests::recv_with_no_sender_returns_pending_packing ... ok test syscall::dispatch::tests::send_with_no_receiver_enqueues_and_returns_ok ... ok test syscall::dispatch::tests::send_with_stale_transfer_handle_returns_invalid_transfer_cap ... ok test syscall::dispatch::tests::send_with_transfer_cap_then_recv_returns_cap_in_x6 ... ok test syscall::dispatch::tests::send_without_send_right_returns_typed_ipc_missing_right ... ok test syscall::dispatch::tests::task_exit_routes_to_terminate_with_code ... ok test syscall::dispatch::tests::task_exit_with_no_current_task_fails_closed ... ok test syscall::dispatch::tests::task_yield_routes_to_reschedule ... ok test syscall::dispatch::tests::task_yield_with_no_current_task_fails_closed ... ok test syscall::error::tests::cap_and_ipc_status_blocks_do_not_collide ... ok test syscall::error::tests::cap_error_from_round_trips_and_encodes_in_cap_block ... ok test syscall::error::tests::ipc_error_from_round_trips_and_encodes_in_ipc_block ... ok test syscall::error::tests::ok_status_is_zero_and_no_error_encodes_to_it ... ok test syscall::error::tests::top_level_status_codes_are_stable ... ok test syscall::user_access::tests::copy_from_user_block_mapped_page_faults ... ok test syscall::user_access::tests::copy_from_user_faults_on_unmapped_page ... ok test syscall::user_access::tests::copy_from_user_multipage_second_page_unmapped_copies_nothing ... ok test syscall::user_access::tests::copy_from_user_out_of_window_faults_before_translate ... ok test syscall::user_access::tests::copy_from_user_overrun_past_window_end_faults ... ok test syscall::user_access::tests::copy_from_user_range_ending_in_top_page_does_not_spuriously_fault ... ok test syscall::user_access::tests::copy_from_user_rejects_in_window_non_user_page ... ok test syscall::user_access::tests::copy_from_user_spanning_two_pages_copies_all ... ok test syscall::user_access::tests::copy_from_user_translates_and_copies_a_user_page ... ok test syscall::user_access::tests::copy_to_user_in_range_moves_bytes ... ok test syscall::user_access::tests::copy_to_user_rejects_read_only_user_page ... ok test syscall::user_access::tests::validate_exact_window_fit_is_ok ... ok test syscall::user_access::tests::wrapping_range_faults ... ok test syscall::user_access::tests::zero_length_copy_is_ok_even_for_unmapped_pointer ... ok test result: ok. 258 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s running 58 tests test context_switch::tests::context_switch_marks_current_and_counts ... ok test console::tests::default_fake_console_is_empty ... ok test console::tests::captures_successive_byte_writes ... ok test console::tests::fmt_writer_produces_formatted_output ... ok test context_switch::tests::default_context_is_uninitialized_and_unswitched ... ok test context_switch::tests::init_context_clears_prior_user_markers_on_reuse ... ok test context_switch::tests::init_context_records_entry_stack_and_marks_initialized ... ok test context_switch::tests::init_user_context_records_user_entry_sp_kernel_stack_and_marks_is_user ... ok test cpu::tests::default_cpu_reports_core_zero_with_irqs_enabled ... ok test cpu::tests::disable_irqs_masks_and_returns_previous_state ... ok test cpu::tests::instruction_barrier_increments_count ... ok test cpu::tests::irq_guard_enters_and_exits_critical_section ... ok test cpu::tests::irq_state_uses_daif_polarity_zero_means_enabled ... ok test cpu::tests::nested_irq_guards_restore_outer_state ... ok test cpu::tests::wait_for_interrupt_increments_count ... ok test cpu::tests::with_core_id_sets_reported_id ... ok test irq_controller::tests::ack_eoi_cycle_leaves_clean_state ... ok test irq_controller::tests::acknowledge_returns_none_when_queue_empty ... ok test irq_controller::tests::acknowledge_returns_pending_fifo ... ok test irq_controller::tests::disable_removes_enabled_state ... ok test irq_controller::tests::disabled_irq_can_still_be_injected_for_test_purposes ... ok test irq_controller::tests::enable_is_idempotent ... ok test irq_controller::tests::disable_panics_on_out_of_range_irq - should panic ... ok test irq_controller::tests::enable_marks_line_as_enabled ... ok test irq_controller::tests::end_of_interrupt_records_irq_in_order ... ok test irq_controller::tests::enable_panics_on_out_of_range_irq - should panic ... ok test mmu::tests::activate_records_root ... ok test mmu::tests::block_mapped_mmu_delegates_unblocked_addresses ... ok test mmu::tests::block_mapped_mmu_injects_block_mapped_on_map_and_unmap ... ok test mmu::tests::block_mapped_mmu_translate_injects_block_mapped ... ok test mmu::tests::bulk_map_with_ignore_then_invalidate_tlb_all ... ok test mmu::tests::create_address_space_stores_root ... ok test mmu::tests::double_map_returns_already_mapped ... ok test mmu::tests::fake_translate_returns_mapping_and_aligns_interior_offset ... ok test mmu::tests::fake_translate_unmapped_is_not_mapped ... ok test mmu::tests::map_rejects_device_plus_execute ... ok test mmu::tests::map_rejects_unaligned_va ... ok test mmu::tests::map_returns_token_with_mapped_va ... ok test mmu::tests::map_unmap_round_trip ... ok test mmu::tests::mapper_flush_carries_virt_addr ... ok test mmu::tests::mapper_flush_flush_invokes_invalidate_tlb_address ... ok test mmu::tests::mapper_flush_ignore_is_documented_noop ... ok test mmu::tests::mapping_flags_difference_clears_bits ... ok test mmu::tests::mapping_flags_union_and_contains ... ok test mmu::tests::out_of_frames_mmu_maps_while_frames_available ... ok test mmu::tests::out_of_frames_mmu_returns_out_of_frames_when_provider_empty ... ok test mmu::tests::phys_frame_rejects_unaligned ... ok test mmu::tests::tlb_invalidations_recorded_in_order ... ok test mmu::tests::unmap_missing_returns_not_mapped ... ok test mmu::tests::unmap_rejects_unaligned_va ... ok test mmu::tests::unmap_returns_token_with_unmapped_va_and_frame ... ok test timer::tests::advance_moves_clock_forward ... ok test timer::tests::arm_deadline_records_value ... ok test timer::tests::arm_deadline_replaces_previous ... ok test timer::tests::cancel_clears_deadline_and_counts ... ok test timer::tests::default_has_one_nanosecond_resolution ... ok test timer::tests::new_starts_at_zero_with_given_resolution ... ok test timer::tests::set_now_overrides_clock ... ok test result: ok. 58 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s running 2 tests test hal/src/console.rs - console::FmtWriter (line 51) ... ignored test hal/src/cpu.rs - cpu::IrqGuard (line 108) ... ignored test result: ok. 0 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 0.00s running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s running 3 tests test test-hal/src/context_switch.rs - context_switch::FakeContextSwitch (line 60) ... ok test test-hal/src/mmu.rs - mmu::OutOfFramesMmu (line 312) ... ok test test-hal/src/mmu.rs - mmu::BlockMappedMmu (line 446) ... ok test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.04s (default-members, excludes userland), missing the --workspace test-link path.) Fix: hello/build.rs applies -T hello.ld only when CARGO_CFG_TARGET_ARCH == aarch64. Host builds (coverage / check / miri / ) link the hello bin as an ordinary std stub (no script); the aarch64 build still gets the script + its ASSERTs (verified: build-userland.sh still emits the 117-byte raw-flat image). Also excluded the userland crates from the llvm-cov job (coverage of aarch64-only stubs is meaningless). Verified: running 46 tests test mmu::vmsav8::tests::block_descriptor_drops_low_bits_for_unaligned_pa ... ok test mmu::vmsav8::tests::block_descriptor_v1_device_block_encoding ... ok test mmu::vmsav8::tests::block_descriptor_v1_kernel_ram_block_encoding ... ok test mmu::vmsav8::tests::descriptor_bits_to_flags_is_lock_shut ... ok test mmu::vmsav8::tests::device_flag_picks_device_attr_index ... ok test mmu::vmsav8::tests::empty_flags_kernel_ro_normal_no_execute_global_inverted ... ok test mmu::vmsav8::tests::descriptor_bits_to_flags_round_trips_valid_flags ... ok test mmu::vmsav8::tests::flags_to_descriptor_bits_ignores_bits_above_four ... ok test mmu::vmsav8::tests::global_flag_clears_ng_bit ... ok test mmu::vmsav8::tests::mair_value_attr0_device_attr1_normal_others_zero ... ok test mmu::vmsav8::tests::page_descriptor_drops_low_bits_for_unaligned_pa ... ok test mmu::vmsav8::tests::page_descriptor_v1_kernel_rw_page_encoding ... ok test mmu::vmsav8::tests::sctlr_mmu_enable_mask_sets_m_c_i_only ... ok test mmu::vmsav8::tests::table_descriptor_carries_valid_and_table_bits_and_address ... ok test mmu::vmsav8::tests::table_descriptor_drops_low_bits_for_unaligned_address ... ok test mmu::vmsav8::tests::tcr_high_half_clears_only_epd1 ... ok test mmu::vmsav8::tests::tcr_value_carries_t0sz_16_and_ips_2_and_epd1_set ... ok test mmu::vmsav8::tests::user_execute_yields_user_ro_pxn_one_uxn_zero ... ok test mmu::vmsav8::tests::user_write_yields_user_rw_no_execute ... ok test mmu::vmsav8::tests::write_alone_yields_kernel_rw_no_execute ... ok test mmu::vmsav8::tests::write_plus_execute_yields_kernel_rwx_uxn_pxn_zero ... ok test timer::tests::ns_to_ticks_one_second_yields_frequency_at_any_freq ... ok test timer::tests::ns_to_ticks_round_trips_against_ticks_to_ns_at_qemu_frequency ... ok test timer::tests::ns_to_ticks_rounds_up_on_subtick ... ok test timer::tests::ns_to_ticks_saturates_at_u64_max ... ok test timer::tests::ns_to_ticks_panics_on_zero_frequency - should panic ... ok test timer::tests::ns_to_ticks_zero_ns_is_zero ... ok test timer::tests::resolution_clamps_to_one_above_2ghz ... ok test timer::tests::resolution_const_fn_works_in_const_context ... ok test timer::tests::resolution_floor_vs_round_difference_documented ... ok test timer::tests::resolution_one_gigahertz_is_one_ns ... ok test timer::tests::resolution_qemu_virt_is_16_ns ... ok test timer::tests::resolution_ns_for_freq_panics_on_zero_frequency - should panic ... ok test timer::tests::resolution_round_to_nearest_for_non_divisor ... ok test timer::tests::resolution_two_ghz_is_one_ns_exactly ... ok test timer::tests::ticks_to_ns_const_fn_works_in_const_context ... ok test timer::tests::ticks_to_ns_high_frequency_one_gigahertz ... ok test timer::tests::ticks_to_ns_is_monotonic_across_frequencies ... ok test timer::tests::ticks_to_ns_no_silent_wrap_at_64bit_boundary ... ok test timer::tests::ticks_to_ns_pi3_class_non_divisor ... ok test timer::tests::ticks_to_ns_panics_on_zero_frequency - should panic ... ok test timer::tests::ticks_to_ns_plateaus_at_u64_max_after_saturation ... ok test timer::tests::ticks_to_ns_qemu_virt_one_second ... ok test timer::tests::ticks_to_ns_qemu_virt_single_tick ... ok test timer::tests::ticks_to_ns_saturates_at_u64_max ... ok test timer::tests::ticks_to_ns_zero_count_is_zero ... ok test result: ok. 46 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s running 258 tests test cap::rights::tests::bitor_assign_adds_bits ... ok test cap::rights::tests::difference_clears_bits ... ok test cap::rights::tests::empty_contains_empty_but_nothing_else ... ok test cap::rights::tests::from_raw_and_raw_round_trip ... ok test cap::rights::tests::from_raw_masks_unknown_bits ... ok test cap::rights::tests::intersection_narrows ... ok test cap::rights::tests::union_and_contains ... ok test cap::table::tests::cap_copy_narrows_rights ... ok test cap::table::tests::cap_copy_of_root_then_revoke_root_leaves_peer_alive ... ok test cap::table::tests::cap_copy_on_stale_handle_returns_invalid_handle ... ok test cap::table::tests::cap_copy_rejects_widened_rights ... ok test cap::table::tests::cap_copy_with_same_rights_succeeds ... ok test cap::table::tests::cap_copy_without_duplicate_right_fails ... ok test cap::table::tests::cap_derive_creates_child_with_narrower_rights ... ok test cap::table::tests::cap_derive_enforces_depth_cap ... ok test cap::table::tests::cap_derive_on_full_table_returns_caps_exhausted ... ok test cap::table::tests::cap_derive_rejects_widened_rights ... ok test cap::table::tests::cap_derive_without_derive_right_fails ... ok test cap::table::tests::cap_drop_on_interior_node_returns_has_children ... ok test cap::table::tests::cap_revoke_cascades_depth_three ... ok test cap::table::tests::cap_revoke_clears_references_object ... ok test cap::table::tests::cap_revoke_on_leaf_is_a_noop ... ok test cap::table::tests::cap_revoke_on_stale_handle_fails ... ok test cap::table::tests::cap_revoke_removes_only_descendants ... ok test cap::table::tests::cap_revoke_without_revoke_right_fails ... ok test cap::table::tests::cap_take_middle_sibling_preserves_list_integrity ... ok test cap::table::tests::cap_take_on_node_with_children_fails ... ok test cap::table::tests::cap_take_returns_capability_and_invalidates_handle ... ok test cap::table::tests::cap_take_slot_reusable_with_bumped_generation ... ok test cap::table::tests::cap_take_stale_handle_fails ... ok test cap::table::tests::copy_of_a_child_shares_parent ... ok test cap::table::tests::drop_first_child_updates_parent_first_child_pointer ... ok test cap::table::tests::drop_invalidates_handle ... ok test cap::table::tests::drop_middle_sibling_preserves_list_integrity ... ok test cap::table::tests::drop_peer_does_not_affect_other_peer ... ok test cap::table::tests::drop_twice_returns_invalid_handle ... ok test cap::table::tests::freed_slot_is_reused_with_bumped_generation ... ok test cap::table::tests::is_full_transitions ... ok test cap::table::tests::lookup_on_stale_handle_returns_invalid_handle ... ok test cap::table::tests::new_table_can_accept_one_root ... ok test cap::table::tests::references_object_sees_live_caps_only ... ok test cap::table::tests::slot_entry_size_matches_adr_0023 ... ok test cap::table::tests::table_exhaustion_returns_caps_exhausted ... ok test cap::tests::capobject_debug_redacts_handle_but_shows_kind ... ok test cap::tests::debug_redacts_named_object_but_keeps_rights ... ok test ipc::tests::blocked_sender_delivered_on_subsequent_recv ... ok test ipc::tests::cancel_recv_clears_recv_waiting_back_to_idle ... ok test ipc::tests::cancel_recv_is_idempotent ... ok test ipc::tests::cancel_recv_on_idle_is_noop ... ok test ipc::tests::cancel_recv_on_recv_complete_does_not_drop_message_or_cap ... ok test ipc::tests::cancel_recv_on_send_pending_does_not_drop_message ... ok test ipc::tests::cancel_recv_to_destroyed_endpoint_returns_stale_handle ... ok test ipc::tests::cancel_recv_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::cancel_recv_without_recv_right_fails ... ok test ipc::tests::notify_sets_bits ... ok test ipc::tests::notify_with_stale_handle_after_slot_reuse_fails ... ok test ipc::tests::notify_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::notify_without_notify_right_fails ... ok test ipc::tests::receiver_first_delivers_on_send ... ok test ipc::tests::receiver_first_then_send_with_cap ... ok test ipc::tests::recv_with_full_table_preserves_pending_cap ... ok test ipc::tests::recv_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::recv_without_recv_right_fails ... ok test ipc::tests::second_recv_when_waiting_fails ... ok test ipc::tests::second_send_when_pending_fails ... ok test ipc::tests::send_to_destroyed_endpoint_returns_stale_handle ... ok test ipc::tests::send_transfers_cap_atomically ... ok test ipc::tests::send_with_bad_transfer_cap_preserves_recv_waiting ... ok test ipc::tests::send_with_dropped_cap_handle_returns_stale_handle ... ok test ipc::tests::send_with_wrong_object_kind_returns_wrong_object_kind ... ok test ipc::tests::send_without_send_right_fails ... ok test ipc::tests::send_without_transfer_right_on_xfer_cap_fails ... ok test ipc::tests::sender_first_delivers_on_recv ... ok test ipc::tests::stale_queue_state_reset_on_slot_reuse ... ok test ipc::tests::stale_recv_waiting_resets_silently ... ok test ipc::tests::stale_send_pending_without_cap_resets_silently ... ok test mm::address_space::tests::arena_alloc_returns_distinct_handles ... ok test mm::address_space::tests::arena_full_returns_arena_full_error ... ok test ipc::tests::stale_send_pending_with_some_cap_panics_in_debug - should panic ... ok test mm::address_space::tests::arena_get_with_stale_handle_returns_none ... ok test mm::address_space::tests::cap_create_address_space_consumes_one_pmm_frame_and_mints_cap ... ok test mm::address_space::tests::cap_create_address_space_rejects_missing_derive ... ok test mm::address_space::tests::cap_create_address_space_rejects_widened_rights ... ok test mm::address_space::tests::cap_create_address_space_rejects_wrong_parent_kind ... ok test mm::address_space::tests::cap_create_address_space_returns_out_of_frames_on_pmm_exhaustion ... ok test mm::address_space::tests::cap_create_rejects_too_deep_parent_without_consuming_pmm ... ok test mm::address_space…
ADR-0039 + T-027 — userland build pipeline (B6 step 5)
Tyrne's first real userspace program, built from Rust source and embedded into the kernel image, replacing the hand-coded
mov w0, #42; retplaceholder. This is B6 step 5 of the dependency-ordered sequence; running it in EL0 (the+0x400round-trip) is T-028.ADR-0039 (Accepted)
Settles the build orchestration ADR-0029 deferred ("exact path lands with B6"). Decision: a
tools/build-userland.shstep +rust-objcopyfrom the pinnedllvm-tools-preview(no Cargo dep) +include_bytes!of a git-ignored.bin; userland crates asdefault-members-excluded workspace members; a Rust-side base-VA source-of-truth.cargo xtaskis the named B7+ multi-binary upgrade. Two review rounds before Accept: a relayed 8-fix round + an adversarial 5-lens / 81-agent pass (37 of 38 findings refuted; the one confirmed → the CI build-ordering fix below).What landed (T-027)
userland/tyrne-user(#![no_std]lib): safeconsole_write(cap, buf)/task_exit(code)wrappers over thesvc #0ABI (x8=number,x0..x5=args;ConsoleWrite=5,TaskExit=4).HELLO_CONSOLE_CAP = 0— the T-027↔T-028 cap-handle interface (root cap of a fresh table). The twosvcshims are the first userspaceunsafe→ UNSAFE-2026-0033.userland/hello(#![no_std] #![no_main]bin):_start(in.text._start, offset 0) →console_write(greeting)→task_exit(0);panic_handler→task_exit.hello.ldfixes the entry at0x0080_0000, ASSERTs no.data/.bss(image mapsUSER|EXECUTE, noWRITE).tools/build-userland.sh:cargo build→rust-objcopy -O binary→ git-ignoreduserland/hello/hello.bin.members, excluded fromdefault-members(host commands skip them — mirrorsbsp-qemu-virt).USERSPACE_IMAGE→include_bytes!(hello.bin);build.rsassert!s the.binexists (runbuild-userland.shfirst).tools/smoke.shnow builds userland + kernel (one-command);.github/workflows/ci.ymlinstallsllvm-tools-preview+ builds userland beforekernel-build(the adversarial-confirmed fix — else the clean-checkoutkernel-buildjob hits the missing-.binassert!).Verification
The 117-byte
.bindisassembles at offset 0 to:_startprologue →x0 = 0(HELLO_CONSOLE_CAP) →adr x1(greeting) →w2 = 0x15(21 = len of"hello from userspace\n") →bl console_write→x0 = 0→bl task_exit. The real image loads dormant under the smoke (entry = 0x800000,image bytes 117,stack bytes 4096); it is not run in EL0 — that's T-028.Gates (all green)
cargo fmt --all --check✅-D warnings✅ (cargo clippy --target aarch64-unknown-none -p tyrne-userland-hello -p tyrne-user)cargo kernel-build✅tools/smoke.sh --intPASS — image loads,all tasks complete, 2 expected EL1-stub SVCs, zero new fault class ✅USERSPACE_IMAGEbytes + build infra)Audit
UNSAFE-2026-0033 — the
tyrne-usersvc #0shims (the user→kernel call side; the kernel→user trust boundary is audited under 0029/0014/0030/0032 and reviewed for T-028's first real run).Out of scope (T-028)
Loading the image into a real EL0 task (
task_create_from_image→ seed aDebugConsolecap atHELLO_CONSOLE_CAP→add_user_task), the+0x400round-trip smoke, and the explicit EL0-boundary security review.🤖 Generated with Claude Code
Summary by Sourcery
Embed a real Rust-based userspace hello program into the kernel image via a new userland build pipeline and replace the previous hand-coded placeholder image.
New Features:
tyrne-userno_std userspace library providing safe syscall wrappers for console output and task exit.tyrne-userland-hellono_std/no_main userspace binary that prints a greeting via the syscall ABI and then exits.Enhancements:
build-userland.shtool and integrate userland image generation into the smoke script and workspace configuration while excluding userland crates from default workspace members.CI:
Tests:
Summary by CodeRabbit
New Features
Documentation
Chores
Bug Fixes