Skip to content

Commit 53dabf4

Browse files
committed
feat: succinct-zkvm std-lib support
1 parent ea4c160 commit 53dabf4

File tree

24 files changed

+400
-12
lines changed

24 files changed

+400
-12
lines changed

compiler/rustc_target/src/spec/targets/riscv32im_succinct_zkvm_elf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
1010
description: Some("Succinct's zero-knowledge Virtual Machine (RV32IM ISA)".into()),
1111
tier: Some(3),
1212
host_tools: Some(false),
13-
std: None,
13+
std: Some(true),
1414
},
1515
pointer_width: 32,
1616
arch: "riscv32".into(),

library/panic_abort/Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,10 @@ compiler_builtins = "0.1.0"
1919

2020
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
2121
libc = { version = "0.2", default-features = false }
22+
23+
[lints.rust.unexpected_cfgs]
24+
level = "warn"
25+
check-cfg = [
26+
'cfg(bootstrap)',
27+
'cfg(target_os, values("succinct-zkvm"))'
28+
]

library/panic_abort/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#[cfg(target_os = "android")]
2121
mod android;
2222

23-
#[cfg(target_os = "zkvm")]
23+
#[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))]
2424
mod zkvm;
2525

2626
use core::any::Any;
@@ -40,7 +40,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
4040
unsafe {
4141
android::android_set_abort_message(_payload);
4242
}
43-
#[cfg(target_os = "zkvm")]
43+
#[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))]
4444
unsafe {
4545
zkvm::zkvm_set_abort_message(_payload);
4646
}

library/panic_abort/src/zkvm.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use alloc::string::String;
22
use core::panic::PanicPayload;
33

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.
4+
/// Note this function works with both `zkvm` and `succinct-zkvm`.
65
pub(crate) unsafe fn zkvm_set_abort_message(payload: &mut dyn PanicPayload) {
76
let payload = payload.get();
87
let msg = match payload.downcast_ref::<&'static str>() {

library/std/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,6 @@ check-cfg = [
163163
# and to the `backtrace` crate which messes-up with Cargo list
164164
# of declared features, we therefor expect any feature cfg
165165
'cfg(feature, values(any()))',
166+
'cfg(target_os, values("succinct-zkvm"))'
166167
]
168+

library/std/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ fn main() {
6060
|| target_os == "uefi"
6161
|| target_os == "teeos"
6262
|| target_os == "zkvm"
63+
|| target_os == "succinct-zkvm"
6364
|| target_os == "rtems"
6465
|| target_os == "nuttx"
65-
6666
// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
6767
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
6868
{

library/std/src/random.rs

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use crate::sys::random as sys;
4848
/// VxWorks | `randABytes` after waiting for `randSecure` to become ready
4949
/// WASI | [`random_get`](https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-random_getbuf-pointeru8-buf_len-size---result-errno)
5050
/// ZKVM | `sys_rand`
51+
/// SUCCINCT-ZKVM | `sys_rand`
5152
///
5253
/// Note that the sources used might change over time.
5354
///

library/std/src/sys/alloc/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::ptr;
77
// add fast paths for low alignment values.
88
#[allow(dead_code)]
99
const MIN_ALIGN: usize = if cfg!(any(
10-
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
10+
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm", target_os = "succinct-zkvm")),
1111
all(target_arch = "xtensa", target_os = "espidf"),
1212
)) {
1313
// The allocator on the esp-idf and zkvm platforms guarantees 4 byte alignment.
@@ -89,7 +89,7 @@ cfg_if::cfg_if! {
8989
mod wasm;
9090
} else if #[cfg(target_os = "xous")] {
9191
mod xous;
92-
} else if #[cfg(target_os = "zkvm")] {
92+
} else if #[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] {
9393
mod zkvm;
9494
}
9595
}

library/std/src/sys/alloc/zkvm.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::alloc::{GlobalAlloc, Layout, System};
22
use crate::sys::pal::abi;
33

4+
/// Note this allocator works with both `zkvm` and `succinct-zkvm`.
45
#[stable(feature = "alloc_system_type", since = "1.28.0")]
56
unsafe impl GlobalAlloc for System {
67
#[inline]

library/std/src/sys/pal/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ cfg_if::cfg_if! {
6464
} else if #[cfg(target_os = "zkvm")] {
6565
mod zkvm;
6666
pub use self::zkvm::*;
67+
} else if #[cfg(target_os = "succinct-zkvm")] {
68+
mod succinct_zkvm;
69+
pub use self::succinct_zkvm::*;
6770
} else {
6871
mod unsupported;
6972
pub use self::unsupported::*;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//! ABI definitions for symbols exported by <_>-zkvm targets.
2+
//!
3+
//! Ideally, these should be the minimum viable symbols to support the std-lib.
4+
5+
#![allow(dead_code)]
6+
pub const DIGEST_WORDS: usize = 8;
7+
8+
/// Standard IO file descriptors for use with sys_read and sys_write.
9+
pub mod fileno {
10+
pub const STDIN: u32 = 0;
11+
pub const STDOUT: u32 = 1;
12+
pub const STDERR: u32 = 2;
13+
}
14+
15+
unsafe extern "C" {
16+
pub fn sys_halt();
17+
pub fn sys_rand(recv_buf: *mut u8, words: usize);
18+
pub fn sys_panic(msg_ptr: *const u8, len: usize) -> !;
19+
pub fn sys_write(fd: u32, write_buf: *const u8, nbytes: usize);
20+
pub fn sys_getenv(
21+
recv_buf: *mut u32,
22+
words: usize,
23+
varname: *const u8,
24+
varname_len: usize,
25+
) -> usize;
26+
pub fn sys_argv(out_words: *mut u32, out_nwords: usize, arg_index: usize) -> usize;
27+
pub fn sys_alloc_aligned(nwords: usize, align: usize) -> *mut u8;
28+
}
29+
30+
// Note: sys_read is not implemented for succinct-zkvm.
31+
// However, it is a function used in the standard library, so we need to
32+
// implement it.
33+
pub unsafe extern "C" fn sys_read(_: u32, _: *mut u8, _: usize) -> usize {
34+
panic!("sys_read not implemented for succinct");
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
use crate::ffi::OsString;
2+
use crate::fmt;
3+
4+
pub struct Args {
5+
i_forward: usize,
6+
i_back: usize,
7+
count: usize,
8+
}
9+
10+
pub fn args() -> Args {
11+
panic!("args not implemented for succinct");
12+
}
13+
14+
impl Args {
15+
#[cfg(target_os = "succinct-zkvm")]
16+
fn argv(_: usize) -> OsString {
17+
panic!("argv not implemented for succinct");
18+
}
19+
}
20+
21+
impl fmt::Debug for Args {
22+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23+
f.debug_list().finish()
24+
}
25+
}
26+
27+
impl Iterator for Args {
28+
type Item = OsString;
29+
30+
fn next(&mut self) -> Option<OsString> {
31+
if self.i_forward >= self.count - self.i_back {
32+
None
33+
} else {
34+
let arg = Self::argv(self.i_forward);
35+
self.i_forward += 1;
36+
Some(arg)
37+
}
38+
}
39+
40+
fn size_hint(&self) -> (usize, Option<usize>) {
41+
(self.count, Some(self.count))
42+
}
43+
}
44+
45+
impl ExactSizeIterator for Args {
46+
fn len(&self) -> usize {
47+
self.count
48+
}
49+
}
50+
51+
impl DoubleEndedIterator for Args {
52+
fn next_back(&mut self) -> Option<OsString> {
53+
if self.i_back >= self.count - self.i_forward {
54+
None
55+
} else {
56+
let arg = Self::argv(self.count - 1 - self.i_back);
57+
self.i_back += 1;
58+
Some(arg)
59+
}
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
pub mod os {
2+
pub const FAMILY: &str = "";
3+
pub const OS: &str = "";
4+
pub const DLL_PREFIX: &str = "";
5+
pub const DLL_SUFFIX: &str = ".elf";
6+
pub const DLL_EXTENSION: &str = "elf";
7+
pub const EXE_SUFFIX: &str = ".elf";
8+
pub const EXE_EXTENSION: &str = "elf";
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//! System bindings for the succinct-zkvm platform
2+
//!
3+
//! This module contains the facade (aka platform-specific) implementations of
4+
//! OS level functionality for succinct-zkvm.
5+
//!
6+
//! This is all super highly experimental and not actually intended for
7+
//! wide/production use yet, it's still all in the experimental category. This
8+
//! will likely change over time.
9+
#![forbid(unsafe_op_in_unsafe_fn)]
10+
11+
pub mod abi;
12+
#[path = "../succinct-zkvm/args.rs"]
13+
pub mod args;
14+
pub mod env;
15+
pub mod os;
16+
#[path = "../unsupported/pipe.rs"]
17+
pub mod pipe;
18+
#[path = "../unsupported/process.rs"]
19+
pub mod process;
20+
#[path = "../unsupported/thread.rs"]
21+
pub mod thread;
22+
#[path = "../unsupported/time.rs"]
23+
pub mod time;
24+
25+
use crate::io as std_io;
26+
27+
// SAFETY: must be called only once during runtime initialization.
28+
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
29+
pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {}
30+
31+
// SAFETY: must be called only once during runtime cleanup.
32+
// NOTE: this is not guaranteed to run, for example when the program aborts.
33+
pub unsafe fn cleanup() {}
34+
35+
pub fn unsupported<T>() -> std_io::Result<T> {
36+
Err(unsupported_err())
37+
}
38+
39+
pub fn unsupported_err() -> std_io::Error {
40+
std_io::Error::UNSUPPORTED_PLATFORM
41+
}
42+
43+
pub fn is_interrupted(_code: i32) -> bool {
44+
false
45+
}
46+
47+
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
48+
crate::io::ErrorKind::Uncategorized
49+
}
50+
51+
pub fn abort_internal() -> ! {
52+
core::intrinsics::abort();
53+
}
+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
use super::unsupported;
2+
use crate::error::Error as StdError;
3+
use crate::ffi::{OsStr, OsString};
4+
use crate::marker::PhantomData;
5+
use crate::path::{self, PathBuf};
6+
use crate::{fmt, io};
7+
8+
pub fn errno() -> i32 {
9+
0
10+
}
11+
12+
pub fn error_string(_errno: i32) -> String {
13+
"operation successful".to_string()
14+
}
15+
16+
pub fn getcwd() -> io::Result<PathBuf> {
17+
unsupported()
18+
}
19+
20+
pub fn chdir(_: &path::Path) -> io::Result<()> {
21+
unsupported()
22+
}
23+
24+
pub struct SplitPaths<'a>(!, PhantomData<&'a ()>);
25+
26+
pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
27+
panic!("unsupported")
28+
}
29+
30+
impl<'a> Iterator for SplitPaths<'a> {
31+
type Item = PathBuf;
32+
fn next(&mut self) -> Option<PathBuf> {
33+
self.0
34+
}
35+
}
36+
37+
#[derive(Debug)]
38+
pub struct JoinPathsError;
39+
40+
pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
41+
where
42+
I: Iterator<Item = T>,
43+
T: AsRef<OsStr>,
44+
{
45+
Err(JoinPathsError)
46+
}
47+
48+
impl fmt::Display for JoinPathsError {
49+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50+
"not supported on this platform yet".fmt(f)
51+
}
52+
}
53+
54+
impl StdError for JoinPathsError {
55+
#[allow(deprecated)]
56+
fn description(&self) -> &str {
57+
"not supported on this platform yet"
58+
}
59+
}
60+
61+
pub fn current_exe() -> io::Result<PathBuf> {
62+
unsupported()
63+
}
64+
65+
pub struct Env(!);
66+
67+
impl Iterator for Env {
68+
type Item = (OsString, OsString);
69+
fn next(&mut self) -> Option<(OsString, OsString)> {
70+
self.0
71+
}
72+
}
73+
74+
pub fn env() -> Env {
75+
panic!("not supported on this platform")
76+
}
77+
78+
impl Env {
79+
pub fn str_debug(&self) -> impl fmt::Debug + '_ {
80+
let Self(inner) = self;
81+
match *inner {}
82+
}
83+
}
84+
85+
impl fmt::Debug for Env {
86+
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
87+
let Self(inner) = self;
88+
match *inner {}
89+
}
90+
}
91+
92+
pub fn getenv(_: &OsStr) -> Option<OsString> {
93+
panic!("getenv not implemented for succinct");
94+
}
95+
96+
pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
97+
Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
98+
}
99+
100+
pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> {
101+
Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
102+
}
103+
104+
pub fn temp_dir() -> PathBuf {
105+
panic!("no filesystem on this platform")
106+
}
107+
108+
pub fn home_dir() -> Option<PathBuf> {
109+
None
110+
}
111+
112+
pub fn exit(_code: i32) -> ! {
113+
crate::intrinsics::abort()
114+
}
115+
116+
pub fn getpid() -> u32 {
117+
panic!("no pids on this platform")
118+
}

0 commit comments

Comments
 (0)