Be more careful about integer overflow when computing relocs.
This commit is contained in:
@@ -122,8 +122,8 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
|||||||
real_call_args
|
real_call_args
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pointer_bytes(&self) -> usize {
|
fn pointer_bytes(&self) -> u8 {
|
||||||
usize::from(self.isa.pointer_bytes())
|
self.isa.pointer_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vmctx(&mut self, func: &mut Function) -> ir::GlobalValue {
|
fn vmctx(&mut self, func: &mut Function) -> ir::GlobalValue {
|
||||||
@@ -405,7 +405,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
|||||||
base_gv,
|
base_gv,
|
||||||
min_size: Imm64::new(0),
|
min_size: Imm64::new(0),
|
||||||
bound_gv,
|
bound_gv,
|
||||||
element_size: Imm64::new(i64::from(self.pointer_bytes() as i64)),
|
element_size: Imm64::new(i64::from(self.pointer_bytes())),
|
||||||
index_type: I32,
|
index_type: I32,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub fn compile_and_link_module<'data, 'module, F>(
|
|||||||
imports: F,
|
imports: F,
|
||||||
) -> Result<Compilation, String>
|
) -> Result<Compilation, String>
|
||||||
where
|
where
|
||||||
F: Fn(&str, &str) -> Option<isize>,
|
F: Fn(&str, &str) -> Option<usize>,
|
||||||
{
|
{
|
||||||
let (mut compilation, relocations) = compile_module(&translation, isa)?;
|
let (mut compilation, relocations) = compile_module(&translation, isa)?;
|
||||||
|
|
||||||
@@ -41,15 +41,15 @@ fn relocate<F>(
|
|||||||
module: &Module,
|
module: &Module,
|
||||||
imports: F,
|
imports: F,
|
||||||
) where
|
) where
|
||||||
F: Fn(&str, &str) -> Option<isize>,
|
F: Fn(&str, &str) -> Option<usize>,
|
||||||
{
|
{
|
||||||
// The relocations are relative to the relocation's address plus four bytes
|
// The relocations are relative to the relocation's address plus four bytes
|
||||||
// TODO: Support architectures other than x64, and other reloc kinds.
|
// TODO: Support architectures other than x64, and other reloc kinds.
|
||||||
for (i, function_relocs) in relocations.iter() {
|
for (i, function_relocs) in relocations.iter() {
|
||||||
for r in function_relocs {
|
for r in function_relocs {
|
||||||
let target_func_address: isize = match r.reloc_target {
|
let target_func_address: usize = match r.reloc_target {
|
||||||
RelocationTarget::UserFunc(index) => match module.defined_func_index(index) {
|
RelocationTarget::UserFunc(index) => match module.defined_func_index(index) {
|
||||||
Some(f) => compilation.functions[f].as_ptr() as isize,
|
Some(f) => compilation.functions[f].as_ptr() as usize,
|
||||||
None => {
|
None => {
|
||||||
let func = &module.imported_funcs[index.index()];
|
let func = &module.imported_funcs[index.index()];
|
||||||
match imports(&func.0, &func.1) {
|
match imports(&func.0, &func.1) {
|
||||||
@@ -60,25 +60,28 @@ fn relocate<F>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RelocationTarget::GrowMemory => grow_memory as isize,
|
RelocationTarget::GrowMemory => grow_memory as usize,
|
||||||
RelocationTarget::CurrentMemory => current_memory as isize,
|
RelocationTarget::CurrentMemory => current_memory as usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
let body = &mut compilation.functions[i];
|
let body = &mut compilation.functions[i];
|
||||||
match r.reloc {
|
match r.reloc {
|
||||||
Reloc::Abs8 => unsafe {
|
Reloc::Abs8 => unsafe {
|
||||||
let reloc_address = body.as_mut_ptr().offset(r.offset as isize) as i64;
|
let reloc_address = body.as_mut_ptr().add(r.offset as usize) as usize;
|
||||||
let reloc_addend = r.addend;
|
let reloc_addend = r.addend as isize;
|
||||||
let reloc_abs = target_func_address as i64 + reloc_addend;
|
let reloc_abs = (target_func_address as u64)
|
||||||
write_unaligned(reloc_address as *mut i64, reloc_abs);
|
.checked_add(reloc_addend as u64)
|
||||||
|
.unwrap();
|
||||||
|
write_unaligned(reloc_address as *mut u64, reloc_abs);
|
||||||
},
|
},
|
||||||
Reloc::X86PCRel4 => unsafe {
|
Reloc::X86PCRel4 => unsafe {
|
||||||
let reloc_address = body.as_mut_ptr().offset(r.offset as isize) as isize;
|
let reloc_address = body.as_mut_ptr().add(r.offset as usize) as usize;
|
||||||
let reloc_addend = r.addend as isize;
|
let reloc_addend = r.addend as isize;
|
||||||
// TODO: Handle overflow.
|
let reloc_delta_u32 = (target_func_address as u32)
|
||||||
let reloc_delta_i32 =
|
.wrapping_sub(reloc_address as u32)
|
||||||
(target_func_address - reloc_address + reloc_addend) as i32;
|
.checked_add(reloc_addend as u32)
|
||||||
write_unaligned(reloc_address as *mut i32, reloc_delta_i32);
|
.unwrap();
|
||||||
|
write_unaligned(reloc_address as *mut u32, reloc_delta_u32);
|
||||||
},
|
},
|
||||||
_ => panic!("unsupported reloc kind"),
|
_ => panic!("unsupported reloc kind"),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user