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
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -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;

@@ -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 {
@@ -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],
}
@@ -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_WXORR_BIT},
registers::SP,
RISCV_MAX_MEMORY,
RISCV_MAX_MEMORY, RISCV_PAGESIZE, RISCV_PAGE_SHIFTS,
};
use std::mem::{size_of, zeroed};

@@ -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!(
@@ -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_WXORR_BIT {}",
FLAG_WXORR_BIT
);
println!("#define CKB_VM_ASM_MEMORY_FLAG_WRITABLE {}", FLAG_WRITABLE);
println!();

println!(
"#define CKB_VM_ASM_TRACE_STRUCT_SIZE {}",
size_of::<Trace>()
@@ -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 {}",
@@ -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;
@@ -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_WXORR_BIT: u8 = 0b10;
This conversation was marked as resolved by xxuejie

This comment has been minimized.

Copy link
@janx

janx May 15, 2019

Member

Should be FLAG_WXORX_BIT.

pub const FLAG_WRITABLE: u8 = (!FLAG_EXECUTABLE) & FLAG_WXORR_BIT;
@@ -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>,

@@ -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,
@@ -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;
}
@@ -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
}
@@ -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)
}
@@ -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;
@@ -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));
}
}
@@ -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

@@ -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_WXORR_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
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.