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: W^X initial implementation #53

Merged
merged 2 commits into from May 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions definitions/src/asm.rs
@@ -1,4 +1,6 @@
use crate::{instructions::Instruction, RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY};
use crate::{
instructions::Instruction, RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY, RISCV_PAGESIZE,
};
use std::alloc::{alloc_zeroed, Layout};
use std::cmp::min;

Expand All @@ -11,6 +13,7 @@ pub const RET_ECALL: u8 = 2;
pub const RET_EBREAK: u8 = 3;
pub const RET_MAX_CYCLES_EXCEEDED: u8 = 4;
pub const RET_OUT_OF_BOUND: u8 = 5;
pub const RET_INVALID_PERMISSION: u8 = 6;

#[inline(always)]
pub fn calculate_slot(addr: u64) -> usize {
Expand All @@ -35,7 +38,7 @@ pub struct AsmCoreMachine {
pub pc: u64,
pub cycles: u64,
pub max_cycles: u64,
pub elf_end: usize,
pub flags: [u8; RISCV_MAX_MEMORY / RISCV_PAGESIZE],
pub memory: [u8; RISCV_MAX_MEMORY],
pub traces: [Trace; TRACE_SIZE],
}
Expand Down
36 changes: 30 additions & 6 deletions definitions/src/generate_asm_constants.rs
@@ -1,11 +1,12 @@
use ckb_vm_definitions::{
asm::{
AsmCoreMachine, Trace, RET_DECODE_TRACE, RET_EBREAK, RET_ECALL, RET_MAX_CYCLES_EXCEEDED,
RET_OUT_OF_BOUND, TRACE_ITEM_LENGTH,
AsmCoreMachine, Trace, RET_DECODE_TRACE, RET_EBREAK, RET_ECALL, RET_INVALID_PERMISSION,
RET_MAX_CYCLES_EXCEEDED, RET_OUT_OF_BOUND, TRACE_ITEM_LENGTH,
},
instructions::{Instruction, INSTRUCTION_OPCODE_NAMES},
memory::{FLAG_EXECUTABLE, FLAG_FREEZED, FLAG_WRITABLE, FLAG_WXORX_BIT},
registers::SP,
RISCV_MAX_MEMORY,
RISCV_MAX_MEMORY, RISCV_PAGESIZE, RISCV_PAGE_SHIFTS,
};
use std::mem::{size_of, zeroed};

Expand All @@ -17,7 +18,14 @@ use std::mem::{size_of, zeroed};
// of this as a workaround to the problem that build.rs cannot depend on any
// of its crate contents.
fn main() {
println!("#define CKB_VM_ASM_RISCV_MAX_MEMORY {}", RISCV_MAX_MEMORY,);
println!("#define CKB_VM_ASM_RISCV_MAX_MEMORY {}", RISCV_MAX_MEMORY);
println!("#define CKB_VM_ASM_RISCV_PAGE_SHIFTS {}", RISCV_PAGE_SHIFTS);
println!("#define CKB_VM_ASM_RISCV_PAGE_SIZE {}", RISCV_PAGESIZE);
println!("#define CKB_VM_ASM_RISCV_PAGE_MASK {}", RISCV_PAGESIZE - 1);
println!(
"#define CKB_VM_ASM_RISCV_PAGES {}",
RISCV_MAX_MEMORY / RISCV_PAGESIZE
);
println!();

println!(
Expand All @@ -34,11 +42,27 @@ fn main() {
RET_MAX_CYCLES_EXCEEDED
);
println!("#define CKB_VM_ASM_RET_OUT_OF_BOUND {}", RET_OUT_OF_BOUND);
println!(
"#define CKB_VM_ASM_RET_INVALID_PERMISSION {}",
RET_INVALID_PERMISSION
);
println!();

println!("#define CKB_VM_ASM_REGISTER_SP {}", SP);
println!();

println!("#define CKB_VM_ASM_MEMORY_FLAG_FREEZED {}", FLAG_FREEZED);
println!(
"#define CKB_VM_ASM_MEMORY_FLAG_EXECUTABLE {}",
FLAG_EXECUTABLE
);
println!(
"#define CKB_VM_ASM_MEMORY_FLAG_WXORX_BIT {}",
FLAG_WXORX_BIT
);
println!("#define CKB_VM_ASM_MEMORY_FLAG_WRITABLE {}", FLAG_WRITABLE);
println!();

println!(
"#define CKB_VM_ASM_TRACE_STRUCT_SIZE {}",
size_of::<Trace>()
Expand Down Expand Up @@ -92,8 +116,8 @@ fn main() {
(&m.max_cycles as *const u64 as usize) - m_address
);
println!(
"#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_ELF_END {}",
(&m.elf_end as *const usize as usize) - m_address
"#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_FLAGS {}",
(&m.flags as *const u8 as usize) - m_address
);
println!(
"#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_MEMORY {}",
Expand Down
4 changes: 3 additions & 1 deletion definitions/src/lib.rs
@@ -1,8 +1,10 @@
pub mod asm;
pub mod instructions;
pub mod memory;
pub mod registers;

pub const RISCV_PAGESIZE: usize = 1 << 12;
pub const RISCV_PAGE_SHIFTS: usize = 12;
pub const RISCV_PAGESIZE: usize = 1 << RISCV_PAGE_SHIFTS;
pub const RISCV_GENERAL_REGISTER_NUMBER: usize = 32;
// 4 MB
pub const RISCV_MAX_MEMORY: usize = 4 << 20;
Expand Down
6 changes: 6 additions & 0 deletions definitions/src/memory.rs
@@ -0,0 +1,6 @@
pub const FLAG_FREEZED: u8 = 0b01;
// CKB VM enforces W^X logic, if this flag is set, current memory page will
// be marked as executable, otherwise the page will be writable.
pub const FLAG_EXECUTABLE: u8 = 0b10;
pub const FLAG_WXORX_BIT: u8 = 0b10;
pub const FLAG_WRITABLE: u8 = (!FLAG_EXECUTABLE) & FLAG_WXORX_BIT;
21 changes: 3 additions & 18 deletions src/jit/machine.rs
Expand Up @@ -45,7 +45,6 @@ impl AsmData {
struct RustData {
// Machine related data, should be cleared before each run
memory: SparseMemory<u64>,
elf_end: usize,
cycles: u64,
max_cycles: Option<u64>,

Expand Down Expand Up @@ -73,7 +72,6 @@ impl RustData {
fn new(tracer: Box<Tracer>) -> Self {
Self {
memory: SparseMemory::default(),
elf_end: 0,
cycles: 0,
max_cycles: None,
buffer: None,
Expand Down Expand Up @@ -308,7 +306,6 @@ impl BaselineJitMachine {
fn reset(&mut self) {
self.asm_data.registers = [0; ASM_DATA_REGISTERS_SLOTS];
self.rust_data.memory = SparseMemory::<u64>::default();
self.rust_data.elf_end = 0;
self.rust_data.cycles = 0;
self.rust_data.max_cycles = None;
}
Expand Down Expand Up @@ -348,14 +345,6 @@ impl CoreMachine for BaselineJitMachine {
}

impl SupportMachine for BaselineJitMachine {
fn elf_end(&self) -> usize {
self.rust_data.elf_end
}

fn set_elf_end(&mut self, elf_end: usize) {
self.rust_data.elf_end = elf_end;
}

fn cycles(&self) -> u64 {
self.rust_data.cycles
}
Expand Down Expand Up @@ -517,21 +506,17 @@ impl Machine for JitCompilingMachine {
}

impl Memory<Value> for JitCompilingMachine {
fn mmap(
fn init_pages(
&mut self,
_addr: usize,
_size: usize,
_prot: u32,
_flags: u8,
_source: Option<Bytes>,
_offset: usize,
_offset_from_addr: usize,
) -> Result<(), Error> {
Err(Error::Unimplemented)
}

fn munmap(&mut self, _addr: usize, _size: usize) -> Result<(), Error> {
Err(Error::Unimplemented)
}

fn store_byte(&mut self, _addr: usize, _size: usize, _value: u8) -> Result<(), Error> {
Err(Error::Unimplemented)
}
Expand Down
21 changes: 19 additions & 2 deletions src/lib.rs
Expand Up @@ -14,7 +14,7 @@ pub use crate::{
trace::TraceMachine, CoreMachine, DefaultCoreMachine, DefaultMachine,
DefaultMachineBuilder, InstructionCycleFunc, Machine, SupportMachine,
},
memory::{flat::FlatMemory, mmu::Mmu, sparse::SparseMemory, Memory},
memory::{flat::FlatMemory, sparse::SparseMemory, wxorx::WXorXMemory, Memory},
syscalls::Syscalls,
};
use bytes::Bytes;
Expand Down Expand Up @@ -57,7 +57,24 @@ pub fn run<R: Register, M: Memory<R> + Default>(
program: &Bytes,
args: &[Bytes],
) -> Result<i8, Error> {
let mut machine = TraceMachine::new(DefaultMachine::<DefaultCoreMachine<R, M>>::default());
let mut machine =
TraceMachine::new(DefaultMachine::<DefaultCoreMachine<R, WXorXMemory<R, M>>>::default());
machine.load_program(program, args)?;
machine.run()
}

#[cfg(test)]
mod tests {
use super::bits::power_of_2;
use super::*;

#[test]
fn test_max_memory_must_be_multiple_of_pages() {
assert_eq!(RISCV_MAX_MEMORY % RISCV_PAGESIZE, 0);
}

#[test]
fn test_page_size_be_power_of_2() {
assert!(power_of_2(RISCV_PAGESIZE));
}
}
18 changes: 14 additions & 4 deletions src/machine/asm/cdefinitions_generated.h
@@ -1,4 +1,8 @@
#define CKB_VM_ASM_RISCV_MAX_MEMORY 4194304
#define CKB_VM_ASM_RISCV_PAGE_SHIFTS 12
#define CKB_VM_ASM_RISCV_PAGE_SIZE 4096
#define CKB_VM_ASM_RISCV_PAGE_MASK 4095
#define CKB_VM_ASM_RISCV_PAGES 1024

#define CKB_VM_ASM_MAXIMUM_TRACE_ADDRESS_LENGTH 64

Expand All @@ -7,24 +11,30 @@
#define CKB_VM_ASM_RET_EBREAK 3
#define CKB_VM_ASM_RET_MAX_CYCLES_EXCEEDED 4
#define CKB_VM_ASM_RET_OUT_OF_BOUND 5
#define CKB_VM_ASM_RET_INVALID_PERMISSION 6

#define CKB_VM_ASM_REGISTER_SP 2

#define CKB_VM_ASM_MEMORY_FLAG_FREEZED 1
#define CKB_VM_ASM_MEMORY_FLAG_EXECUTABLE 2
#define CKB_VM_ASM_MEMORY_FLAG_WXORX_BIT 2
#define CKB_VM_ASM_MEMORY_FLAG_WRITABLE 0

#define CKB_VM_ASM_TRACE_STRUCT_SIZE 296
#define CKB_VM_ASM_TRACE_OFFSET_ADDRESS 0
#define CKB_VM_ASM_TRACE_OFFSET_LENGTH 8
#define CKB_VM_ASM_TRACE_OFFSET_CYCLES 16
#define CKB_VM_ASM_TRACE_OFFSET_INSTRUCTIONS 24
#define CKB_VM_ASM_TRACE_OFFSET_THREAD 160

#define CKB_VM_ASM_ASM_CORE_MACHINE_STRUCT_SIZE 6619424
#define CKB_VM_ASM_ASM_CORE_MACHINE_STRUCT_SIZE 6620440
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_REGISTERS 0
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_PC 256
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_CYCLES 264
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_MAX_CYCLES 272
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_ELF_END 280
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_MEMORY 288
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_TRACES 4194592
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_FLAGS 280
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_MEMORY 1304
#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_TRACES 4195608

#define CKB_VM_ASM_OP_UNLOADED 0
#define CKB_VM_ASM_OP_ADD 1
Expand Down