Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: succinct-zkvm std-lib support #1

Open
wants to merge 1 commit into
base: n/succinct-target-only
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
description: Some("Succinct's zero-knowledge Virtual Machine (RV32IM ISA)".into()),
tier: Some(3),
host_tools: Some(false),
std: None,
std: Some(true),
},
pointer_width: 32,
arch: "riscv32".into(),
Expand Down
7 changes: 7 additions & 0 deletions library/panic_abort/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ compiler_builtins = "0.1.0"

[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
libc = { version = "0.2", default-features = false }

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = [
'cfg(bootstrap)',
'cfg(target_os, values("succinct-zkvm"))'
]
4 changes: 2 additions & 2 deletions library/panic_abort/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#[cfg(target_os = "android")]
mod android;

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

use core::any::Any;
Expand All @@ -40,7 +40,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
unsafe {
android::android_set_abort_message(_payload);
}
#[cfg(target_os = "zkvm")]
#[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))]
unsafe {
zkvm::zkvm_set_abort_message(_payload);
}
Expand Down
3 changes: 1 addition & 2 deletions library/panic_abort/src/zkvm.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use alloc::string::String;
use core::panic::PanicPayload;

// Forward the abort message to zkVM's sys_panic. This is implemented by RISC Zero's
// platform crate which exposes system calls specifically for the zkVM.
/// Note this function works with both `zkvm` and `succinct-zkvm`.
pub(crate) unsafe fn zkvm_set_abort_message(payload: &mut dyn PanicPayload) {
let payload = payload.get();
let msg = match payload.downcast_ref::<&'static str>() {
Expand Down
2 changes: 2 additions & 0 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,6 @@ check-cfg = [
# and to the `backtrace` crate which messes-up with Cargo list
# of declared features, we therefor expect any feature cfg
'cfg(feature, values(any()))',
'cfg(target_os, values("succinct-zkvm"))'
]

2 changes: 1 addition & 1 deletion library/std/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ fn main() {
|| target_os == "uefi"
|| target_os == "teeos"
|| target_os == "zkvm"
|| target_os == "succinct-zkvm"
|| target_os == "rtems"
|| target_os == "nuttx"

// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
{
Expand Down
1 change: 1 addition & 0 deletions library/std/src/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use crate::sys::random as sys;
/// VxWorks | `randABytes` after waiting for `randSecure` to become ready
/// WASI | [`random_get`](https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-random_getbuf-pointeru8-buf_len-size---result-errno)
/// ZKVM | `sys_rand`
/// SUCCINCT-ZKVM | `sys_rand`
///
/// Note that the sources used might change over time.
///
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/alloc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::ptr;
// add fast paths for low alignment values.
#[allow(dead_code)]
const MIN_ALIGN: usize = if cfg!(any(
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm", target_os = "succinct-zkvm")),
all(target_arch = "xtensa", target_os = "espidf"),
)) {
// The allocator on the esp-idf and zkvm platforms guarantees 4 byte alignment.
Expand Down Expand Up @@ -89,7 +89,7 @@ cfg_if::cfg_if! {
mod wasm;
} else if #[cfg(target_os = "xous")] {
mod xous;
} else if #[cfg(target_os = "zkvm")] {
} else if #[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] {
mod zkvm;
}
}
1 change: 1 addition & 0 deletions library/std/src/sys/alloc/zkvm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::sys::pal::abi;

/// Note this allocator works with both `zkvm` and `succinct-zkvm`.
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sys/pal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ cfg_if::cfg_if! {
} else if #[cfg(target_os = "zkvm")] {
mod zkvm;
pub use self::zkvm::*;
} else if #[cfg(target_os = "succinct-zkvm")] {
mod succinct_zkvm;
pub use self::succinct_zkvm::*;
} else {
mod unsupported;
pub use self::unsupported::*;
Expand Down
35 changes: 35 additions & 0 deletions library/std/src/sys/pal/succint-zkvm/abi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! ABI definitions for symbols exported by <_>-zkvm targets.
//!
//! Ideally, these should be the minimum viable symbols to support the std-lib.

#![allow(dead_code)]
pub const DIGEST_WORDS: usize = 8;

/// Standard IO file descriptors for use with sys_read and sys_write.
pub mod fileno {
pub const STDIN: u32 = 0;
pub const STDOUT: u32 = 1;
pub const STDERR: u32 = 2;
}

unsafe extern "C" {
pub fn sys_halt();
pub fn sys_rand(recv_buf: *mut u8, words: usize);
pub fn sys_panic(msg_ptr: *const u8, len: usize) -> !;
pub fn sys_write(fd: u32, write_buf: *const u8, nbytes: usize);
pub fn sys_getenv(
recv_buf: *mut u32,
words: usize,
varname: *const u8,
varname_len: usize,
) -> usize;
pub fn sys_argv(out_words: *mut u32, out_nwords: usize, arg_index: usize) -> usize;
pub fn sys_alloc_aligned(nwords: usize, align: usize) -> *mut u8;
}

// Note: sys_read is not implemented for succinct-zkvm.
// However, it is a function used in the standard library, so we need to
// implement it.
pub unsafe extern "C" fn sys_read(_: u32, _: *mut u8, _: usize) -> usize {
panic!("sys_read not implemented for succinct");
}
61 changes: 61 additions & 0 deletions library/std/src/sys/pal/succint-zkvm/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use crate::ffi::OsString;
use crate::fmt;

pub struct Args {
i_forward: usize,
i_back: usize,
count: usize,
}

pub fn args() -> Args {
panic!("args not implemented for succinct");
}

impl Args {
#[cfg(target_os = "succinct-zkvm")]
fn argv(_: usize) -> OsString {
panic!("argv not implemented for succinct");
}
}

impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().finish()
}
}

impl Iterator for Args {
type Item = OsString;

fn next(&mut self) -> Option<OsString> {
if self.i_forward >= self.count - self.i_back {
None
} else {
let arg = Self::argv(self.i_forward);
self.i_forward += 1;
Some(arg)
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
(self.count, Some(self.count))
}
}

impl ExactSizeIterator for Args {
fn len(&self) -> usize {
self.count
}
}

impl DoubleEndedIterator for Args {
fn next_back(&mut self) -> Option<OsString> {
if self.i_back >= self.count - self.i_forward {
None
} else {
let arg = Self::argv(self.count - 1 - self.i_back);
self.i_back += 1;
Some(arg)
}
}
}
9 changes: 9 additions & 0 deletions library/std/src/sys/pal/succint-zkvm/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pub mod os {
pub const FAMILY: &str = "";
pub const OS: &str = "";
pub const DLL_PREFIX: &str = "";
pub const DLL_SUFFIX: &str = ".elf";
pub const DLL_EXTENSION: &str = "elf";
pub const EXE_SUFFIX: &str = ".elf";
pub const EXE_EXTENSION: &str = "elf";
}
53 changes: 53 additions & 0 deletions library/std/src/sys/pal/succint-zkvm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//! System bindings for the succinct-zkvm platform
//!
//! This module contains the facade (aka platform-specific) implementations of
//! OS level functionality for succinct-zkvm.
//!
//! This is all super highly experimental and not actually intended for
//! wide/production use yet, it's still all in the experimental category. This
//! will likely change over time.
#![forbid(unsafe_op_in_unsafe_fn)]

pub mod abi;
#[path = "../succinct-zkvm/args.rs"]
pub mod args;
pub mod env;
pub mod os;
#[path = "../unsupported/pipe.rs"]
pub mod pipe;
#[path = "../unsupported/process.rs"]
pub mod process;
#[path = "../unsupported/thread.rs"]
pub mod thread;
#[path = "../unsupported/time.rs"]
pub mod time;

use crate::io as std_io;

// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {}

// SAFETY: must be called only once during runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts.
pub unsafe fn cleanup() {}

pub fn unsupported<T>() -> std_io::Result<T> {
Err(unsupported_err())
}

pub fn unsupported_err() -> std_io::Error {
std_io::Error::UNSUPPORTED_PLATFORM
}

pub fn is_interrupted(_code: i32) -> bool {
false
}

pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Uncategorized
}

pub fn abort_internal() -> ! {
core::intrinsics::abort();
}
118 changes: 118 additions & 0 deletions library/std/src/sys/pal/succint-zkvm/os.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
use super::unsupported;
use crate::error::Error as StdError;
use crate::ffi::{OsStr, OsString};
use crate::marker::PhantomData;
use crate::path::{self, PathBuf};
use crate::{fmt, io};

pub fn errno() -> i32 {
0
}

pub fn error_string(_errno: i32) -> String {
"operation successful".to_string()
}

pub fn getcwd() -> io::Result<PathBuf> {
unsupported()
}

pub fn chdir(_: &path::Path) -> io::Result<()> {
unsupported()
}

pub struct SplitPaths<'a>(!, PhantomData<&'a ()>);

pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
panic!("unsupported")
}

impl<'a> Iterator for SplitPaths<'a> {
type Item = PathBuf;
fn next(&mut self) -> Option<PathBuf> {
self.0
}
}

#[derive(Debug)]
pub struct JoinPathsError;

pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
where
I: Iterator<Item = T>,
T: AsRef<OsStr>,
{
Err(JoinPathsError)
}

impl fmt::Display for JoinPathsError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
"not supported on this platform yet".fmt(f)
}
}

impl StdError for JoinPathsError {
#[allow(deprecated)]
fn description(&self) -> &str {
"not supported on this platform yet"
}
}

pub fn current_exe() -> io::Result<PathBuf> {
unsupported()
}

pub struct Env(!);

impl Iterator for Env {
type Item = (OsString, OsString);
fn next(&mut self) -> Option<(OsString, OsString)> {
self.0
}
}

pub fn env() -> Env {
panic!("not supported on this platform")
}

impl Env {
pub fn str_debug(&self) -> impl fmt::Debug + '_ {
let Self(inner) = self;
match *inner {}
}
}

impl fmt::Debug for Env {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self(inner) = self;
match *inner {}
}
}

pub fn getenv(_: &OsStr) -> Option<OsString> {
panic!("getenv not implemented for succinct");
}

pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
}

pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> {
Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
}

pub fn temp_dir() -> PathBuf {
panic!("no filesystem on this platform")
}

pub fn home_dir() -> Option<PathBuf> {
None
}

pub fn exit(_code: i32) -> ! {
crate::intrinsics::abort()
}

pub fn getpid() -> u32 {
panic!("no pids on this platform")
}
Loading