Skip to content

Commit 5c1dbd3

Browse files
committed
feat: succinct target
1 parent 249cb84 commit 5c1dbd3

File tree

30 files changed

+457
-15
lines changed

30 files changed

+457
-15
lines changed

compiler/rustc_target/src/spec/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1954,6 +1954,7 @@ supported_targets! {
19541954

19551955
("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
19561956
("riscv32im-risc0-zkvm-elf", riscv32im_risc0_zkvm_elf),
1957+
("riscv32im-succinct-zkvm-elf", riscv32im_succinct_zkvm_elf),
19571958
("riscv32im-unknown-none-elf", riscv32im_unknown_none_elf),
19581959
("riscv32ima-unknown-none-elf", riscv32ima_unknown_none_elf),
19591960
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use crate::spec::{
2+
Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions,
3+
};
4+
5+
pub(crate) fn target() -> Target {
6+
Target {
7+
data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
8+
llvm_target: "riscv32".into(),
9+
metadata: TargetMetadata {
10+
description: Some("Succinct's zero-knowledge Virtual Machine (RV32IM ISA)".into()),
11+
tier: Some(3),
12+
host_tools: Some(false),
13+
std: Some(true),
14+
},
15+
pointer_width: 32,
16+
arch: "riscv32".into(),
17+
18+
options: TargetOptions {
19+
os: "succinct-zkvm".into(),
20+
vendor: "succinct".into(),
21+
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
22+
linker: Some("rust-lld".into()),
23+
cpu: "generic-rv32".into(),
24+
25+
// The zkvm is singlethreaded and all operations are atomic.
26+
// The std-lib is compiled with lowered atomicsa and the default Succinct build tools
27+
// enforce this on programs.
28+
max_atomic_width: Some(64),
29+
atomic_cas: true,
30+
31+
features: "+m".into(),
32+
llvm_abiname: "ilp32".into(),
33+
executables: true,
34+
panic_strategy: PanicStrategy::Abort,
35+
relocation_model: RelocModel::Static,
36+
emit_debug_gdb_scripts: false,
37+
eh_frame_header: false,
38+
singlethread: true,
39+
..Default::default()
40+
},
41+
}
42+
}

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
@@ -59,9 +59,9 @@ fn main() {
5959
|| target_os == "uefi"
6060
|| target_os == "teeos"
6161
|| target_os == "zkvm"
62+
|| target_os == "succinct-zkvm"
6263
|| target_os == "rtems"
6364
|| target_os == "nuttx"
64-
6565
// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
6666
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
6767
{

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.
@@ -88,7 +88,7 @@ cfg_if::cfg_if! {
8888
mod wasm;
8989
} else if #[cfg(target_os = "xous")] {
9090
mod xous;
91-
} else if #[cfg(target_os = "zkvm")] {
91+
} else if #[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] {
9292
mod zkvm;
9393
}
9494
}

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
@@ -61,6 +61,9 @@ cfg_if::cfg_if! {
6161
} else if #[cfg(target_os = "zkvm")] {
6262
mod zkvm;
6363
pub use self::zkvm::*;
64+
} else if #[cfg(target_os = "succinct-zkvm")] {
65+
mod succinct_zkvm;
66+
pub use self::succinct_zkvm::*;
6467
} else {
6568
mod unsupported;
6669
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+
}

0 commit comments

Comments
 (0)