Skip to content

Commit 67c45e3

Browse files
committed
feat: add Succinct target, impl stdlib functionality
1 parent 249cb84 commit 67c45e3

File tree

25 files changed

+157
-31
lines changed

25 files changed

+157
-31
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/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/sys/alloc/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -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/pal/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ cfg_if::cfg_if! {
5858
} else if #[cfg(target_os = "teeos")] {
5959
mod teeos;
6060
pub use self::teeos::*;
61-
} else if #[cfg(target_os = "zkvm")] {
61+
} else if #[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] {
6262
mod zkvm;
6363
pub use self::zkvm::*;
6464
} else {

library/std/src/sys/pal/zkvm/abi.rs

+30-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
//! ABI definitions for symbols exported by risc0-zkvm-platform.
2-
3-
// Included here so we don't have to depend on risc0-zkvm-platform.
4-
//
5-
// FIXME: Should we move this to the "libc" crate? It seems like other
6-
// architectures put a lot of this kind of stuff there. But there's
7-
// currently no risc0 fork of the libc crate, so we'd either have to
8-
// fork it or upstream it.
1+
//! ABI definitions for symbols exported by <_>-zkvm targets.
2+
//!
3+
//! Ideally, these should be the minimum viable symbols to support the std-lib.
94
105
#![allow(dead_code)]
116
pub const DIGEST_WORDS: usize = 8;
@@ -15,9 +10,12 @@ pub mod fileno {
1510
pub const STDIN: u32 = 0;
1611
pub const STDOUT: u32 = 1;
1712
pub const STDERR: u32 = 2;
13+
14+
#[cfg(target_vendor = "risc0")]
1815
pub const JOURNAL: u32 = 3;
1916
}
2017

18+
#[cfg(target_vendor = "risc0")]
2119
unsafe extern "C" {
2220
// Wrappers around syscalls provided by risc0-zkvm-platform:
2321
pub fn sys_halt();
@@ -53,3 +51,27 @@ unsafe extern "C" {
5351
pub fn sys_alloc_words(nwords: usize) -> *mut u32;
5452
pub fn sys_alloc_aligned(nwords: usize, align: usize) -> *mut u8;
5553
}
54+
55+
#[cfg(target_os = "succinct-zkvm")]
56+
unsafe extern "C" {
57+
pub fn sys_halt();
58+
pub fn sys_rand(recv_buf: *mut u8, words: usize);
59+
pub fn sys_panic(msg_ptr: *const u8, len: usize) -> !;
60+
pub fn sys_write(fd: u32, write_buf: *const u8, nbytes: usize);
61+
pub fn sys_getenv(
62+
recv_buf: *mut u32,
63+
words: usize,
64+
varname: *const u8,
65+
varname_len: usize,
66+
) -> usize;
67+
pub fn sys_argv(out_words: *mut u32, out_nwords: usize, arg_index: usize) -> usize;
68+
pub fn sys_alloc_aligned(nwords: usize, align: usize) -> *mut u8;
69+
}
70+
71+
#[cfg(target_os = "succinct-zkvm")]
72+
// Note: sys_read is not implemented for succinct.
73+
// However, it is a function used in the standard library, so we need to
74+
// implement it.
75+
pub unsafe extern "C" fn sys_read(_: u32, _: *mut u8, _: usize) -> usize {
76+
panic!("sys_read not implemented for succinct");
77+
}

library/std/src/sys/pal/zkvm/args.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
1-
use super::{WORD_SIZE, abi};
21
use crate::ffi::OsString;
32
use crate::fmt;
4-
use crate::sys::os_str;
5-
use crate::sys_common::FromInner;
3+
4+
#[cfg(target_vendor = "risc0")]
5+
use {
6+
super::{WORD_SIZE, abi},
7+
crate::sys_common::FromInner,
8+
crate::sys::os_str,
9+
};
610

711
pub struct Args {
812
i_forward: usize,
913
i_back: usize,
1014
count: usize,
1115
}
1216

17+
#[cfg(target_vendor = "risc0")]
1318
pub fn args() -> Args {
1419
let count = unsafe { abi::sys_argc() };
1520
Args { i_forward: 0, i_back: 0, count }
1621
}
1722

23+
#[cfg(target_os = "succinct-zkvm")]
24+
pub fn args() -> Args {
25+
panic!("args not implemented for succinct");
26+
}
27+
1828
impl Args {
1929
/// Use sys_argv to get the arg at the requested index. Does not check that i is less than argc
2030
/// and will not return if the index is out of bounds.
31+
#[cfg(target_vendor = "risc0")]
2132
fn argv(i: usize) -> OsString {
2233
let arg_len = unsafe { abi::sys_argv(crate::ptr::null_mut(), 0, i) };
2334

@@ -36,6 +47,11 @@ impl Args {
3647
unsafe { crate::slice::from_raw_parts(words.cast() as *const u8, arg_len) };
3748
OsString::from_inner(os_str::Buf { inner: arg_bytes.to_vec() })
3849
}
50+
51+
#[cfg(target_os = "succinct-zkvm")]
52+
fn argv(_: usize) -> OsString {
53+
panic!("argv not implemented for succinct");
54+
}
3955
}
4056

4157
impl fmt::Debug for Args {

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

-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
//! will likely change over time.
99
#![forbid(unsafe_op_in_unsafe_fn)]
1010

11-
const WORD_SIZE: usize = size_of::<u32>();
12-
1311
pub mod abi;
1412
#[path = "../zkvm/args.rs"]
1513
pub mod args;

library/std/src/sys/pal/zkvm/os.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
use super::{WORD_SIZE, abi, unsupported};
1+
use super::unsupported;
22
use crate::error::Error as StdError;
33
use crate::ffi::{OsStr, OsString};
44
use crate::marker::PhantomData;
55
use crate::path::{self, PathBuf};
6-
use crate::sys::os_str;
7-
use crate::sys_common::FromInner;
86
use crate::{fmt, io};
97

8+
#[cfg(target_vendor = "risc0")]
9+
use {
10+
super::{WORD_SIZE, abi},
11+
crate::sys::os_str,
12+
crate::sys_common::FromInner,
13+
};
14+
1015
pub fn errno() -> i32 {
1116
0
1217
}
@@ -91,6 +96,7 @@ impl fmt::Debug for Env {
9196
}
9297
}
9398

99+
#[cfg(target_vendor = "risc0")]
94100
pub fn getenv(varname: &OsStr) -> Option<OsString> {
95101
let varname = varname.as_encoded_bytes();
96102
let nbytes =
@@ -114,6 +120,11 @@ pub fn getenv(varname: &OsStr) -> Option<OsString> {
114120
Some(OsString::from_inner(os_str::Buf { inner: u8s.to_vec() }))
115121
}
116122

123+
#[cfg(target_os = "succinct-zkvm")]
124+
pub fn getenv(_: &OsStr) -> Option<OsString> {
125+
panic!("getenv not implemented for succinct");
126+
}
127+
117128
pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
118129
Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
119130
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ cfg_if::cfg_if! {
6969
} else if #[cfg(target_os = "wasi")] {
7070
mod wasi;
7171
pub use wasi::fill_bytes;
72-
} else if #[cfg(target_os = "zkvm")] {
72+
} else if #[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] {
7373
mod zkvm;
7474
pub use zkvm::fill_bytes;
7575
} else if #[cfg(any(

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

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::sys::pal::abi;
22

3+
#[cfg(target_vendor = "risc0")]
34
pub fn fill_bytes(bytes: &mut [u8]) {
45
let (pre, words, post) = unsafe { bytes.align_to_mut::<u32>() };
56
if !words.is_empty() {
@@ -19,3 +20,8 @@ pub fn fill_bytes(bytes: &mut [u8]) {
1920
pre.copy_from_slice(&buf[..pre.len()]);
2021
post.copy_from_slice(&buf[pre.len()..pre.len() + post.len()]);
2122
}
23+
24+
#[cfg(target_vendor = "succinct")]
25+
pub fn fill_bytes(bytes: &mut [u8]) {
26+
unsafe { abi::sys_rand(bytes.as_mut_ptr(), bytes.len()) };
27+
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ cfg_if::cfg_if! {
2828
} else if #[cfg(target_os = "xous")] {
2929
mod xous;
3030
pub use xous::*;
31-
} else if #[cfg(target_os = "zkvm")] {
31+
} else if #[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] {
3232
mod zkvm;
3333
pub use zkvm::*;
3434
} else {

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

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ cfg_if::cfg_if! {
2828
all(target_family = "wasm", not(target_feature = "atomics")),
2929
target_os = "uefi",
3030
target_os = "zkvm",
31+
target_os = "succinct-zkvm",
3132
))] {
3233
mod statik;
3334
pub use statik::{EagerStorage, LazyStorage, thread_local_inner};
@@ -91,6 +92,7 @@ pub(crate) mod guard {
9192
)),
9293
target_os = "uefi",
9394
target_os = "zkvm",
95+
target_os = "succinct-zkvm",
9496
))] {
9597
pub(crate) fn enable() {
9698
// FIXME: Right now there is no concept of "thread exit" on

library/test/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ core = { path = "../core", public = true }
1212

1313
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
1414
libc = { version = "0.2.150", default-features = false }
15+
16+
[lints.rust.unexpected_cfgs]
17+
level = "warn"
18+
check-cfg = [
19+
'cfg(target_os, values("succinct-zkvm"))'
20+
]

library/test/src/console.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
317317
// - It's currently not supported for wasm targets without Emscripten nor WASI.
318318
// - It's currently not supported for zkvm targets.
319319
let is_instant_unsupported =
320-
(cfg!(target_family = "wasm") && cfg!(target_os = "unknown")) || cfg!(target_os = "zkvm");
320+
(cfg!(target_family = "wasm") && cfg!(target_os = "unknown")) || cfg!(target_os = "zkvm") || cfg!(target_os = "succinct-zkvm");
321321

322322
let start_time = (!is_instant_unsupported).then(Instant::now);
323323
run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;

library/test/src/lib.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ pub fn run_test(
555555

556556
// Emscripten can catch panics but other wasm targets cannot
557557
let ignore_because_no_process_support = desc.should_panic != ShouldPanic::No
558-
&& (cfg!(target_family = "wasm") || cfg!(target_os = "zkvm"))
558+
&& (cfg!(target_family = "wasm") || cfg!(target_os = "zkvm") || cfg!(target_os = "succinct-zkvm"))
559559
&& !cfg!(target_os = "emscripten");
560560

561561
if force_ignore || desc.ignore || ignore_because_no_process_support {
@@ -604,7 +604,9 @@ pub fn run_test(
604604
// level.
605605
let supports_threads = !cfg!(target_os = "emscripten")
606606
&& !cfg!(target_family = "wasm")
607-
&& !cfg!(target_os = "zkvm");
607+
&& !cfg!(target_os = "zkvm")
608+
&& !cfg!(target_os = "succinct-zkvm");
609+
608610
if supports_threads {
609611
let cfg = thread::Builder::new().name(name.as_slice().to_owned());
610612
let mut runtest = Arc::new(Mutex::new(Some(runtest)));

src/bootstrap/Cargo.lock

+2-3
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,8 @@ dependencies = [
8888

8989
[[package]]
9090
name = "cc"
91-
version = "1.1.22"
92-
source = "registry+https://github.com/rust-lang/crates.io-index"
93-
checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
91+
version = "1.2.0"
92+
source = "git+https://github.com/nhtyy/cc-rs?branch=n%2Fadd-succinct-target#424acb084e212c330de96e06cab69be0d9df55f4"
9493
dependencies = [
9594
"shlex",
9695
]

src/bootstrap/Cargo.toml

+8-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ test = false
3939
# otherwise, some targets will fail. That's why these dependencies are explicitly pinned.
4040
#
4141
# Do not upgrade this crate unless https://github.com/rust-lang/cc-rs/issues/1317 is fixed.
42-
cc = "=1.1.22"
42+
#
43+
# todo(succinct): remove this change that was explicity against the rules.
44+
# This just happens to work, and ideally cc-rs will fix the target parsing issue before our target is merged.
45+
cc = "=1.2.0"
46+
# cc = "=1.1.22"
4347
cmake = "=0.1.48"
4448

4549
build_helper = { path = "../build_helper" }
@@ -73,6 +77,9 @@ tracing-chrome = { version = "0.7", optional = true }
7377
tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter", "fmt", "registry", "std"] }
7478
tracing-tree = { version = "0.4.0", optional = true }
7579

80+
[patch.crates-io]
81+
cc = { git = "https://github.com/nhtyy/cc-rs", branch = "n/add-succinct-target" }
82+
7683
[target.'cfg(windows)'.dependencies.junction]
7784
version = "1.0.0"
7885

0 commit comments

Comments
 (0)