Skip to content

Commit

Permalink
cleanup log and elf patching
Browse files Browse the repository at this point in the history
  • Loading branch information
hero78119 committed Jun 27, 2023
1 parent cb85911 commit c44038f
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 23 deletions.
8 changes: 7 additions & 1 deletion risc0/r0vm/src/bin/r0vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ struct Args {
#[clap(long)]
elf: PathBuf,

/// The ELF file to run
#[clap(long)]
memory_data: Option<PathBuf>,

/// Receipt output file.
#[clap(long)]
receipt: Option<PathBuf>,
Expand All @@ -47,6 +51,7 @@ fn main() {

let args = Args::parse();
let elf_contents = fs::read(&args.elf).unwrap();
let memory_data = args.memory_data.map(|path| fs::read(&path).unwrap());

if args.verbose > 0 {
eprintln!(
Expand All @@ -70,10 +75,11 @@ fn main() {
}

let env = builder.build();
let mut exec = Executor::from_elf(env, &elf_contents).unwrap();
let mut exec = Executor::from_elf(env, &elf_contents, memory_data).unwrap();
let session = match exec.run() {
Ok(session) => session,
Err(err) => {
println!("failed at PC value {:08x}", exec.pc);
let regs: [u64; 32] = exec.monitor.load_registers(array::from_fn(|idx| idx));
regs.iter().enumerate().for_each(|(idx, value)| {
println!("value loaded {:08x}, idx: {:?}", value, idx,);
Expand Down
2 changes: 2 additions & 0 deletions risc0/zkvm/platform/src/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ pub mod ecall {
pub const SIGACTION: u64 = 134;
pub const SIGPROCMASK: u64 = 135;

pub const GETRLIMIT: u64 = 163;
pub const GETTID: u64 = 178;
pub const GETAFFINITY: u64 = 123;
pub const MMAP: u64 = 222;
pub const MUNMAP: u64 = 215;

pub const MINCORE: u64 = 232;
pub const MADVICE: u64 = 233;
}

pub mod halt {
Expand Down
3 changes: 2 additions & 1 deletion risc0/zkvm/src/binfmt/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ impl Program {
// We need to patch this out, we don't pass float64nan because we don't support floats
| "runtime.initsig" // we dont need init signal since target on baremental env https://github.com/golang/go/blob/512361fb1fa805f10f183e0b96248e523e68c192/src/runtime/signal_unix.go#LL114C6-L114C13
| "runtime.check"
| "runtime.doInit" // patch out doInit https://github.com/golang/go/blob/512361fb1fa805f10f183e0b96248e523e68c192/src/runtime/proc.go#L198, since it got float point inside
| "runtime.init" // patch out init, with float point initialization
// | "runtime.doInit1" // patch out doInit https://github.com/golang/go/blob/512361fb1fa805f10f183e0b96248e523e68c192/src/runtime/proc.go#L198, since it got float point inside
// | "runtime.lock2" // another choice is implement lock, which just need to implement `amoswap.w.aq`,
// | "runtime.args"
// | "runtime.osinit"
Expand Down
30 changes: 27 additions & 3 deletions risc0/zkvm/src/binfmt/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl MemoryImage {
/// The result is a MemoryImage with the ELF of `program` loaded (but
/// execution not yet begun), and with the page table Merkle tree
/// constructed.
pub fn new(program: &Program, page_size: u64) -> Self {
pub fn new(program: &Program, page_size: u64, memory_data: Option<Vec<u8>>) -> Self {
// let mut buf = vec![0_u8; MEM_SIZE];

let mut memory_space = MemorySpace::new();
Expand All @@ -64,14 +64,38 @@ impl MemoryImage {
for (addr, data) in program.image.iter() {
program_region.write_mem(*addr, MemAccessSize::Word, u64::from(*data));
}
// add memory region `0xd000000000` as playground
// add memory region `0xd0000deadbeef` as playground
let _ = memory_space
.add_memory(
0xd000000000,
0xd0000deadbee0,
MEM_SIZE as u64,
Box::new(VecMemory::new(vec![0_u64; MEM_SIZE / 8])),
)
.unwrap();

// Load the ELF into the memory image.
let _ = memory_data.map(|memory_data| {
println!("first length {:?}", memory_data[..4].to_vec());
let memory_data = memory_data
.chunks(8)
.map(|chunk| {
let mut chunk = chunk.to_vec();
if chunk.len() < 8 {
chunk.resize(8, 0)
}
u64::from_le_bytes(chunk.try_into().unwrap())
})
.collect::<Vec<u64>>();
// memory data space
let _ = memory_space
.add_memory(
0x100000000000,
memory_data.len() as u64 * 8 as u64,
Box::new(VecMemory::new(memory_data)),
)
.unwrap();
});

// Compute the page table hashes except for the very last root hash.
Self { memory_space }
}
Expand Down
56 changes: 40 additions & 16 deletions risc0/zkvm/src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ pub struct Executor<'a> {
/// MemoryMonitor
pub monitor: MemoryMonitor,
pre_pc: u64,
pc: u64,
/// program counter
pub pc: u64,
anonymous_heap_watermark: u64,
// segments: Vec<Segment>,
insn_counter: u32,
Expand Down Expand Up @@ -124,9 +125,13 @@ impl<'a> Executor<'a> {
}

/// Construct a new [Executor] from an ELF binary.
pub fn from_elf(env: ExecutorEnv<'a>, elf: &[u8]) -> Result<Self> {
pub fn from_elf(
env: ExecutorEnv<'a>,
elf: &[u8],
memory_data: Option<Vec<u8>>,
) -> Result<Self> {
let program = Program::load_elf(&elf, MEM_SIZE as u64)?;
let image = MemoryImage::new(&program, PAGE_SIZE as u64);
let image = MemoryImage::new(&program, PAGE_SIZE as u64, memory_data);
Ok(Self::new(env, image, program.entry))
}

Expand Down Expand Up @@ -195,11 +200,13 @@ impl<'a> Executor<'a> {
self.ecall()?
} else {
let registers = self.monitor.load_registers(array::from_fn(|idx| idx));
// if self.pc >= 0x00011ad4 && self.pc <= 0x00011ad4 {
// registers.iter().enumerate().for_each(|(idx, value)| {
// println!("value loaded {:08x}, idx: {:?}", value, idx,);
// });
// }
if self.pc >= 0x00073138 && self.pc <= 0x000731fc {
let pc = self.pc;
println!("decode: 0x{insn:08x} at pc 0x{pc:08x}");
registers.iter().enumerate().for_each(|(idx, value)| {
println!("value loaded {:08x}, idx: {:?}", value, idx,);
});
}
let mut hart = HartState {
registers,
pc: self.pc,
Expand Down Expand Up @@ -308,6 +315,9 @@ impl<'a> Executor<'a> {
ecall::SIGACTION => self.ecall_do_nth(),
ecall::GETAFFINITY => self.ecall_do_nth(),
ecall::CLOCKGETTIME => self.ecall_do_nth(),
ecall::MADVICE => self.ecall_do_nth(),
// return error so it will skip ratelimit set https://github.com/golang/go/blob/f5015b5164d6948266df74943f26c4007c6bea50/src/syscall/rlimit.go#L34
ecall::GETRLIMIT => self.ecall_do_return_error(-1i64 as u64),
ecall => bail!("Unknown ecall {ecall:08x} in decimal {ecall:?}"),
}
}
Expand Down Expand Up @@ -362,6 +372,11 @@ impl<'a> Executor<'a> {
Ok(OpCodeResult::new(self.pc + WORD_SIZE as u64, None, 0, None))
}

fn ecall_do_return_error(&mut self, error: u64) -> Result<OpCodeResult> {
self.monitor.store_register(REG_A0, error);
Ok(OpCodeResult::new(self.pc + WORD_SIZE as u64, None, 0, None))
}

fn ecall_mmap(&mut self) -> Result<OpCodeResult> {
let page_size_align: u64 = 1u64 << 12u64;
let page_size_mask = page_size_align - 1;
Expand Down Expand Up @@ -461,8 +476,17 @@ impl<'a> Executor<'a> {
})
.collect();
let key = str::from_utf8(&raw);
println!("ecall_open key {:?}", key);
let result_code = match key {
Ok("hello") => 1000i64,
Ok(msg) => {
if msg.starts_with("DBG") {
println!("open success {:?}", key);
1000i64
} else {
println!("open failed {:?}", key);
-100i64
}
}
_ => -100i64,
};

Expand All @@ -471,15 +495,17 @@ impl<'a> Executor<'a> {
}

fn ecall_write(&mut self) -> Result<OpCodeResult> {
println!("got write!");
let a0 = self.monitor.load_register(REG_A0);
let a1 = self.monitor.load_register(REG_A1);
let a2 = self.monitor.load_register(REG_A2);
let a3 = self.monitor.load_register(REG_A3);

println!(
log::debug!(
"ecall_write a0 {:16x}, a1 {:16x}, a2 {:16x}, a3 {:16x}",
a0, a1, a2, a3
a0,
a1,
a2,
a3
);

let raw: Vec<u8> = (0..a2)
Expand All @@ -491,10 +517,8 @@ impl<'a> Executor<'a> {
.unwrap() as u8
})
.collect();
println!(
"ecall_write res {:?}",
u64::from_le_bytes(raw.try_into().unwrap())
);

println!("ecall_write res {:?}", String::from_utf8_lossy(&raw));

let value = self.monitor.load_register(REG_A2); // write A2 length to A0 return value as write convention
self.monitor.store_register(REG_A0, value);
Expand Down
2 changes: 0 additions & 2 deletions risc0/zkvm/src/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ impl OpCode {
// RV64 bit 25 is used as shamt[5]
let funct7_rv64 = (insn & 0xfc000000) >> 26;
let funct5 = (insn & 0xf8000000) >> 27;
// log::debug!("decode: 0x{word:08X}");
println!("decode: 0x{insn:08x} at pc 0x{insn_pc:08x}");
Ok(match opcode {
0b0000011 => match funct3 {
0x0 => OpCode::new(insn, insn_pc, "LB", 24, 1),
Expand Down

0 comments on commit c44038f

Please sign in to comment.