Skip to content

Commit 6954a67

Browse files
SchmErikflaub
andcommitted
rustc: implement support for riscv32im_risc0_zkvm_elf
This also adds changes in the rust test suite in order to get a few of them to pass. Co-authored-by: Frank Laub <[email protected]>
1 parent e88e1b8 commit 6954a67

File tree

8 files changed

+77
-2
lines changed

8 files changed

+77
-2
lines changed

compiler/rustc_target/src/spec/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,7 @@ supported_targets! {
16361636
("x86_64-unikraft-linux-musl", x86_64_unikraft_linux_musl),
16371637

16381638
("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
1639+
("riscv32im-risc0-zkvm-elf", riscv32im_risc0_zkvm_elf),
16391640
("riscv32im-unknown-none-elf", riscv32im_unknown_none_elf),
16401641
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
16411642
("riscv32imc-esp-espidf", riscv32imc_esp_espidf),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel};
2+
use crate::spec::{Target, TargetOptions};
3+
4+
pub fn target() -> Target {
5+
Target {
6+
data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
7+
llvm_target: "riscv32".into(),
8+
pointer_width: 32,
9+
arch: "riscv32".into(),
10+
11+
options: TargetOptions {
12+
os: "zkvm".into(),
13+
vendor: "risc0".into(),
14+
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
15+
linker: Some("rust-lld".into()),
16+
cpu: "generic-rv32".into(),
17+
18+
// Some crates (*cough* crossbeam) assume you have 64 bit
19+
// atomics if the target name is not in a hardcoded list.
20+
// Since zkvm is singlethreaded and all operations are
21+
// atomic, I guess we can just say we support 64-bit
22+
// atomics.
23+
max_atomic_width: Some(64),
24+
atomic_cas: true,
25+
26+
features: "+m".into(),
27+
executables: true,
28+
panic_strategy: PanicStrategy::Abort,
29+
relocation_model: RelocModel::Static,
30+
emit_debug_gdb_scripts: false,
31+
eh_frame_header: false,
32+
singlethread: true,
33+
..Default::default()
34+
},
35+
}
36+
}

library/panic_abort/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#[cfg(target_os = "android")]
2020
mod android;
2121

22+
#[cfg(target_os = "zkvm")]
23+
mod zkvm;
24+
2225
use core::any::Any;
2326
use core::panic::PanicPayload;
2427

@@ -34,6 +37,8 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
3437
// Android has the ability to attach a message as part of the abort.
3538
#[cfg(target_os = "android")]
3639
android::android_set_abort_message(_payload);
40+
#[cfg(target_os = "zkvm")]
41+
zkvm::zkvm_set_abort_message(_payload);
3742

3843
abort();
3944

library/panic_abort/src/zkvm.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use alloc::string::String;
2+
use core::panic::PanicPayload;
3+
4+
// Forward the abort message to zkVM's sys_panic. This is implemented by RISC Zero's
5+
// platform crate which exposes system calls specifically for the zkVM.
6+
pub(crate) unsafe fn zkvm_set_abort_message(payload: &mut dyn PanicPayload) {
7+
let payload = payload.get();
8+
let msg = match payload.downcast_ref::<&'static str>() {
9+
Some(msg) => msg.as_bytes(),
10+
None => match payload.downcast_ref::<String>() {
11+
Some(msg) => msg.as_bytes(),
12+
None => &[],
13+
},
14+
};
15+
if msg.is_empty() {
16+
return;
17+
}
18+
19+
extern "C" {
20+
fn sys_panic(msg_ptr: *const u8, len: usize) -> !;
21+
}
22+
23+
sys_panic(msg.as_ptr(), msg.len());
24+
}

library/test/src/console.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,8 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
323323
// Prevent the usage of `Instant` in some cases:
324324
// - It's currently not supported for wasm targets.
325325
// - We disable it for miri because it's not available when isolation is enabled.
326-
let is_instant_supported = !cfg!(target_family = "wasm") && !cfg!(miri);
326+
let is_instant_supported =
327+
!cfg!(target_family = "wasm") && !cfg!(target_os = "zkvm") && !cfg!(miri);
327328

328329
let start_time = is_instant_supported.then(Instant::now);
329330
run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;

library/test/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ pub fn run_test(
546546

547547
// Emscripten can catch panics but other wasm targets cannot
548548
let ignore_because_no_process_support = desc.should_panic != ShouldPanic::No
549-
&& cfg!(target_family = "wasm")
549+
&& (cfg!(target_family = "wasm") || cfg!(target_os = "zkvm"))
550550
&& !cfg!(target_os = "emscripten");
551551

552552
if force_ignore || desc.ignore || ignore_because_no_process_support {

src/bootstrap/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
9898
/* Extra values not defined in the built-in targets yet, but used in std */
9999
(Some(Mode::Std), "target_env", Some(&["libnx"])),
100100
// (Some(Mode::Std), "target_os", Some(&[])),
101+
(Some(Mode::Std), "target_os", Some(&["zkvm"])),
102+
(Some(Mode::Std), "target_vendor", Some(&["risc0"])),
101103
(Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa"])),
102104
/* Extra names used by dependencies */
103105
// FIXME: Used by serde_json, but we should not be triggering on external dependencies.
@@ -729,6 +731,11 @@ impl Build {
729731
if self.config.profiler_enabled(target) {
730732
features.push_str(" profiler");
731733
}
734+
// Generate memcpy, etc. FIXME: Remove this once compiler-builtins
735+
// automatically detects this target.
736+
if target.contains("zkvm") {
737+
features.push_str(" compiler-builtins-mem");
738+
}
732739
features
733740
}
734741

src/tools/build-manifest/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ static TARGETS: &[&str] = &[
120120
"powerpc64-unknown-linux-gnu",
121121
"powerpc64le-unknown-linux-gnu",
122122
"riscv32i-unknown-none-elf",
123+
"riscv32im-risc0-zkvm-elf",
123124
"riscv32im-unknown-none-elf",
124125
"riscv32imc-unknown-none-elf",
125126
"riscv32imac-unknown-none-elf",

0 commit comments

Comments
 (0)