Skip to content

Commit

Permalink
Merge pull request #10 from risc0/parker/from-1.69.0
Browse files Browse the repository at this point in the history
Update to 1.69.0
  • Loading branch information
mothran authored May 10, 2023
2 parents 84c898d + 4c9b6d9 commit 7cef530
Show file tree
Hide file tree
Showing 19 changed files with 405 additions and 8 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,7 @@ supported_targets! {
("x86_64-unknown-hermit", x86_64_unknown_hermit),

("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
("riscv32im-risc0-zkvm-elf", riscv32im_risc0_zkvm_elf),
("riscv32im-unknown-none-elf", riscv32im_unknown_none_elf),
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
("riscv32imc-esp-espidf", riscv32imc_esp_espidf),
Expand Down
36 changes: 36 additions & 0 deletions compiler/rustc_target/src/spec/riscv32im_risc0_zkvm_elf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel};
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
Target {
data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
llvm_target: "riscv32".into(),
pointer_width: 32,
arch: "riscv32".into(),

options: TargetOptions {
os: "zkvm".into(),
vendor: "risc0".into(),
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
cpu: "generic-rv32".into(),

// Some crates (*cough* crossbeam) assume you have 64 bit
// atomics if the target name is not in a hardcoded list.
// Since zkvm is singlethreaded and all operations are
// atomic, I guess we can just say we support 64-bit
// atomics.
max_atomic_width: Some(64),
atomic_cas: true,

features: "+m".into(),
executables: true,
panic_strategy: PanicStrategy::Abort,
relocation_model: RelocModel::Static,
emit_debug_gdb_scripts: false,
eh_frame_header: false,
singlethread: true,
..Default::default()
},
}
}
1 change: 1 addition & 0 deletions library/std/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ fn main() {
|| target.contains("solid")
|| target.contains("nintendo-3ds")
|| target.contains("nto")
|| target.contains("zkvm")
{
// These platforms don't have any special requirements.
} else {
Expand Down
10 changes: 5 additions & 5 deletions library/std/src/sys/common/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::ptr;
target_arch = "asmjs",
target_arch = "wasm32",
target_arch = "hexagon",
all(target_arch = "riscv32", not(target_os = "espidf")),
all(target_arch = "riscv32", not(any(target_os = "espidf", target_os = "zkvm"))),
all(target_arch = "xtensa", not(target_os = "espidf")),
))]
pub const MIN_ALIGN: usize = 8;
Expand All @@ -29,11 +29,11 @@ pub const MIN_ALIGN: usize = 8;
target_arch = "wasm64",
))]
pub const MIN_ALIGN: usize = 16;
// The allocator on the esp-idf platform guarantees 4 byte alignment.
#[cfg(any(
all(target_arch = "riscv32", target_os = "espidf"),
// The allocator on the esp-idf and zkvm platforms guarantee 4 byte alignment.
#[cfg(all(any(
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
all(target_arch = "xtensa", target_os = "espidf"),
))]
)))]
pub const MIN_ALIGN: usize = 4;

pub unsafe fn realloc_fallback(
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ cfg_if::cfg_if! {
} else if #[cfg(target_family = "wasm")] {
mod wasm;
pub use self::wasm::*;
} else if #[cfg(target_os = "zkvm")] {
mod zkvm;
pub use self::zkvm::*;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
mod sgx;
pub use self::sgx::*;
Expand Down
52 changes: 52 additions & 0 deletions library/std/src/sys/zkvm/abi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! ABI definitions for symbols exported by risc0-zkvm-platform.

// Included here so we don't have to depend on risc0-zkvm-platform.
//
// FIXME: Should we move this to the "libc" crate? It seems like other
// architectures put a lot of this kind of stuff there. But there's
// currently no risc0 fork of the libc crate, so we'd either have to
// fork it or upstream it.

#![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;
pub const JOURNAL: u32 = 3;
}

extern "C" {
// Wrappers around syscalls provided by risc0-zkvm-platform:
pub fn sys_halt();
pub fn sys_output(output_id: u32, output_value: u32);
pub fn sys_sha_compress(
out_state: *mut [u32; DIGEST_WORDS],
in_state: *const [u32; DIGEST_WORDS],
block1_ptr: *const [u32; DIGEST_WORDS],
block2_ptr: *const [u32; DIGEST_WORDS],
);
pub fn sys_sha_buffer(
out_state: *mut [u32; DIGEST_WORDS],
in_state: *const [u32; DIGEST_WORDS],
buf: *const u8,
count: u32,
);
pub fn sys_rand(recv_buf: *mut u32, words: usize);
pub fn sys_panic(msg_ptr: *const u8, len: usize) -> !;
pub fn sys_log(msg_ptr: *const u8, len: usize);
pub fn sys_cycle_count() -> usize;
pub fn sys_read(fd: u32, recv_buf: *mut u8, nrequested: usize) -> 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;

// Allocate memory from global HEAP.
pub fn sys_alloc_words(nwords: usize) -> *mut u32;
}
22 changes: 22 additions & 0 deletions library/std/src/sys/zkvm/alloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use super::{abi, WORD_SIZE};
use crate::alloc::{GlobalAlloc, Layout, System};

#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let nwords = layout
.align_to(WORD_SIZE)
.expect("Unable to align allocation to word size")
.pad_to_align()
.size()
/ WORD_SIZE;

abi::sys_alloc_words(nwords) as *mut u8
}

#[inline]
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {
// this allocator never deallocates memory
}
}
9 changes: 9 additions & 0 deletions library/std/src/sys/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";
}
50 changes: 50 additions & 0 deletions library/std/src/sys/zkvm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! System bindings for the risc0 zkvm platform
//!
//! This module contains the facade (aka platform-specific) implementations of
//! OS level functionality for 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.

const WORD_SIZE: usize = core::mem::size_of::<u32>();

pub mod alloc;
#[path = "../unsupported/args.rs"]
pub mod args;
#[path = "../unix/cmath.rs"]
pub mod cmath;
pub mod env;
#[path = "../unsupported/fs.rs"]
pub mod fs;
#[path = "../unsupported/io.rs"]
pub mod io;
#[path = "../unsupported/net.rs"]
pub mod net;
#[path = "../unsupported/once.rs"]
pub mod once;
pub mod os;
#[path = "../unix/os_str.rs"]
pub mod os_str;
#[path = "../unix/path.rs"]
pub mod path;
#[path = "../unsupported/pipe.rs"]
pub mod pipe;
#[path = "../unsupported/process.rs"]
pub mod process;
pub mod stdio;
pub mod thread_local_key;
#[path = "../unsupported/time.rs"]
pub mod time;

#[path = "../unsupported/locks/mod.rs"]
pub mod locks;
#[path = "../unsupported/thread.rs"]
pub mod thread;

#[path = "../unsupported/common.rs"]
#[deny(unsafe_op_in_unsafe_fn)]
mod common;
pub use common::*;

mod abi;
125 changes: 125 additions & 0 deletions library/std/src/sys/zkvm/os.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
use super::{abi, unsupported, WORD_SIZE};
use crate::error::Error as StdError;
use crate::ffi::{OsStr, OsString};
use crate::fmt;
use crate::io;
use crate::marker::PhantomData;
use crate::path::{self, PathBuf};
use crate::sys_common::FromInner;

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")
}

pub fn getenv(varname: &OsStr) -> Option<OsString> {
let varname = varname.bytes();
let nbytes =
unsafe { abi::sys_getenv(crate::ptr::null_mut(), 0, varname.as_ptr(), varname.len()) };
if nbytes == usize::MAX {
return None;
}

let nwords = (nbytes + WORD_SIZE - 1) / WORD_SIZE;
let words = unsafe { abi::sys_alloc_words(nwords) };

let nbytes2 = unsafe { abi::sys_getenv(words, nwords, varname.as_ptr(), varname.len()) };
debug_assert_eq!(nbytes, nbytes2);

// Convert to OsString.
//
// FIXME: We can probably get rid of the extra copy here if we
// reimplement "os_str" instead of just using the generic unix
// "os_str".
let u8s: &[u8] = unsafe { crate::slice::from_raw_parts(words.cast() as *const u8, nbytes) };
Some(OsString::from_inner(super::os_str::Buf { inner: u8s.to_vec() }))
}

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

pub fn unsetenv(_: &OsStr) -> io::Result<()> {
Err(io::const_io_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

0 comments on commit 7cef530

Please sign in to comment.