Skip to content

Commit

Permalink
Handle invalid jumps
Browse files Browse the repository at this point in the history
  • Loading branch information
koute committed May 11, 2024
1 parent 5540629 commit 9b2973c
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 10 deletions.
10 changes: 7 additions & 3 deletions crates/polkavm/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,15 +349,19 @@ impl<'a, S> CompilerVisitor<'a, S> where S: Sandbox {
log::trace!("Compiling {}", self.current_instruction(code_offset));
}

fn get_or_forward_declare_label(&mut self, code_offset: u32) -> Label {
fn get_or_forward_declare_label(&mut self, code_offset: u32) -> Option<Label> {
match self.code_offset_to_label.get(code_offset) {
Some(label) => label,
Some(label) => Some(label),
None => {
if code_offset > self.code_offset_to_label.len() {
return None;
}

let label = self.asm.forward_declare_label();
log::trace!("Label: {label} -> {code_offset} (forward declare)");

self.code_offset_to_label.insert(code_offset, label);
label
Some(label)
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/polkavm/src/compiler/amd64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ impl<'r, 'a, S> ArchVisitor<'r, 'a, S> where S: Sandbox {
fn branch(&mut self, s1: RawReg, s2: impl Into<RegImm>, target: u32, condition: Condition) {
let reg_size = self.reg_size();
let s1 = conv_reg(s1);
let label = self.get_or_forward_declare_label(target);
let label = self.get_or_forward_declare_label(target).unwrap_or(self.trap_label);

let asm = self.asm.reserve::<U2>();
let asm = match s2.into() {
Expand Down Expand Up @@ -580,7 +580,7 @@ impl<'r, 'a, S> ArchVisitor<'r, 'a, S> where S: Sandbox {
self.branch_to_label(Condition::Sign, self.trap_label);
}

let target_label = self.get_or_forward_declare_label(export.target_code_offset());
let target_label = self.get_or_forward_declare_label(export.target_code_offset()).unwrap_or(self.trap_label);
self.jump_to_label(target_label);
}
}
Expand Down Expand Up @@ -1406,13 +1406,13 @@ impl<'r, 'a, S> InstructionVisitor for ArchVisitor<'r, 'a, S> where S: Sandbox {

#[inline(always)]
fn jump(&mut self, target: u32) -> Self::ReturnTy {
let label = self.get_or_forward_declare_label(target);
let label = self.get_or_forward_declare_label(target).unwrap_or(self.trap_label);
self.jump_to_label(label);
}

#[inline(always)]
fn load_imm_and_jump(&mut self, ra: RawReg, value: u32, target: u32) -> Self::ReturnTy {
let label = self.get_or_forward_declare_label(target);
let label = self.get_or_forward_declare_label(target).unwrap_or(self.trap_label);
let asm = self.asm.reserve::<U2>();
let asm = asm.push(mov_imm(conv_reg(ra), imm32(value)));
let asm = jump_to_label(asm, label);
Expand Down
9 changes: 6 additions & 3 deletions crates/polkavm/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ impl InterpretedInstance {
self.compiled_offset = (compiled_offset.get() - 1) as usize;
} else {
self.compiled_offset = self.compiled_instructions.len();
self.compile_block::<DEBUG>();
self.compile_block::<DEBUG>()?;
}

if self.gas_remaining.is_some() {
Expand Down Expand Up @@ -469,10 +469,11 @@ impl InterpretedInstance {

#[inline(never)]
#[cold]
fn compile_block<const DEBUG: bool>(&mut self) {
fn compile_block<const DEBUG: bool>(&mut self) -> Result<(), ExecutionError> {
let Some(instructions) = self.module.blob().instructions_at(self.instruction_offset) else {
return;
return Err(ExecutionError::Trap(Default::default()));
};

if DEBUG {
log::debug!("Compiling block at {}:", self.instruction_offset);
}
Expand All @@ -496,6 +497,8 @@ impl InterpretedInstance {

self.compiled_offset_for_block
.insert(self.instruction_offset, NonZeroU32::new((starting_offset + 1) as u32).unwrap());

Ok(())
}

fn check_gas(&mut self) -> Result<(), ExecutionError> {
Expand Down
5 changes: 5 additions & 0 deletions crates/polkavm/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ where
self.inner.get(key as usize).and_then(|value| *value)
}

#[inline]
pub fn len(&self) -> u32 {
self.inner.len() as u32
}

#[inline]
pub fn insert(&mut self, key: u32, value: T) {
self.inner[key as usize] = Some(value);
Expand Down

0 comments on commit 9b2973c

Please sign in to comment.