mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-30 00:51:34 +00:00
Refactored relocation code
This commit is contained in:
@ -21,8 +21,8 @@ use super::super::common::slice::{BoundedSlice, UncheckedSlice};
|
|||||||
use super::errors::ErrorKind;
|
use super::errors::ErrorKind;
|
||||||
use super::import_object::ImportObject;
|
use super::import_object::ImportObject;
|
||||||
use super::memory::LinearMemory;
|
use super::memory::LinearMemory;
|
||||||
use super::module::Module;
|
|
||||||
use super::module::Export;
|
use super::module::Export;
|
||||||
|
use super::module::Module;
|
||||||
use super::relocation::{Reloc, RelocSink, RelocationType};
|
use super::relocation::{Reloc, RelocSink, RelocationType};
|
||||||
|
|
||||||
pub fn protect_codebuf(code_buf: &Vec<u8>) -> Result<(), String> {
|
pub fn protect_codebuf(code_buf: &Vec<u8>) -> Result<(), String> {
|
||||||
@ -204,11 +204,10 @@ impl Instance {
|
|||||||
// 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().enumerate() {
|
for (i, function_relocs) in relocations.iter().enumerate() {
|
||||||
// for r in function_relocs {
|
for ref reloc in function_relocs {
|
||||||
for (ref reloc, ref reloc_type) in function_relocs {
|
let target_func_address: isize = match reloc.target {
|
||||||
let target_func_address: isize = match reloc_type {
|
|
||||||
RelocationType::Normal(func_index) => {
|
RelocationType::Normal(func_index) => {
|
||||||
get_function_addr(&FuncIndex::new(*func_index as usize), &import_functions, &functions) as isize
|
get_function_addr(&FuncIndex::new(func_index as usize), &import_functions, &functions) as isize
|
||||||
},
|
},
|
||||||
RelocationType::CurrentMemory => {
|
RelocationType::CurrentMemory => {
|
||||||
current_memory as isize
|
current_memory as isize
|
||||||
@ -244,15 +243,8 @@ impl Instance {
|
|||||||
// RelocationType::Intrinsic(name) => {
|
// RelocationType::Intrinsic(name) => {
|
||||||
// get_abi_intrinsic(name)?
|
// get_abi_intrinsic(name)?
|
||||||
// },
|
// },
|
||||||
// RelocationTarget::UserFunc(index) => {
|
|
||||||
// functions[module.defined_func_index(index).expect(
|
|
||||||
// "relocation to imported function not supported yet",
|
|
||||||
// )].as_ptr() as isize
|
|
||||||
// }
|
|
||||||
// RelocationTarget::GrowMemory => grow_memory as isize,
|
|
||||||
// RelocationTarget::CurrentMemory => current_memory as isize,
|
|
||||||
};
|
};
|
||||||
// print!("FUNCTION {:?}", target_func_address);
|
|
||||||
let func_addr =
|
let func_addr =
|
||||||
get_function_addr(&FuncIndex::new(i), &import_functions, &functions);
|
get_function_addr(&FuncIndex::new(i), &import_functions, &functions);
|
||||||
match reloc.reloc {
|
match reloc.reloc {
|
||||||
@ -272,47 +264,6 @@ impl Instance {
|
|||||||
},
|
},
|
||||||
_ => panic!("unsupported reloc kind"),
|
_ => panic!("unsupported reloc kind"),
|
||||||
}
|
}
|
||||||
// let reloc_address = unsafe {
|
|
||||||
// (target_func_address.to_owned().as_mut_ptr() as *const u8).offset(reloc.offset as isize)
|
|
||||||
// };
|
|
||||||
|
|
||||||
// match reloc.reloc {
|
|
||||||
// Reloc::Abs8 => {
|
|
||||||
// unsafe {
|
|
||||||
// // (reloc_address as *mut usize).write(target_func_address.to_owned().as_ptr() as usize);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// _ => unimplemented!()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let target_func_address: isize = match r.reloc_target {
|
|
||||||
// RelocationTarget::UserFunc(index) => {
|
|
||||||
// functions[module.defined_func_index(index).expect(
|
|
||||||
// "relocation to imported function not supported yet",
|
|
||||||
// )].as_ptr() as isize
|
|
||||||
// }
|
|
||||||
// RelocationTarget::GrowMemory => grow_memory as isize,
|
|
||||||
// RelocationTarget::CurrentMemory => current_memory as isize,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let body = &mut functions[i];
|
|
||||||
// match r.reloc {
|
|
||||||
// Reloc::Abs8 => unsafe {
|
|
||||||
// let reloc_address = body.as_mut_ptr().offset(r.offset as isize) as i64;
|
|
||||||
// let reloc_addend = r.addend;
|
|
||||||
// let reloc_abs = target_func_address as i64 + reloc_addend;
|
|
||||||
// write_unaligned(reloc_address as *mut i64, reloc_abs);
|
|
||||||
// },
|
|
||||||
// Reloc::X86PCRel4 => unsafe {
|
|
||||||
// let reloc_address = body.as_mut_ptr().offset(r.offset as isize) as isize;
|
|
||||||
// let reloc_addend = r.addend as isize;
|
|
||||||
// // TODO: Handle overflow.
|
|
||||||
// let reloc_delta_i32 =
|
|
||||||
// (target_func_address - reloc_address + reloc_addend) as i32;
|
|
||||||
// write_unaligned(reloc_address as *mut i32, reloc_delta_i32);
|
|
||||||
// },
|
|
||||||
// _ => panic!("unsupported reloc kind"),
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,10 +498,10 @@ impl Clone for Instance {
|
|||||||
|
|
||||||
extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &mut VmCtx) -> i32 {
|
extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &mut VmCtx) -> i32 {
|
||||||
let mut instance = &mut vmctx.user_data.instance;
|
let mut instance = &mut vmctx.user_data.instance;
|
||||||
instance.memory_mut(memory_index as usize)
|
instance
|
||||||
.grow(size)
|
.memory_mut(memory_index as usize)
|
||||||
.unwrap_or(i32::max_value()) // Should be -1 ?
|
.grow(size)
|
||||||
|
.unwrap_or(i32::max_value()) // Should be -1 ?
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn current_memory(memory_index: u32, vmctx: &VmCtx) -> u32 {
|
extern "C" fn current_memory(memory_index: u32, vmctx: &VmCtx) -> u32 {
|
||||||
|
@ -8,7 +8,7 @@ use cranelift_codegen::ir::{self, ExternalName, LibCall, SourceLoc, TrapCode};
|
|||||||
pub use cranelift_codegen::binemit::Reloc;
|
pub use cranelift_codegen::binemit::Reloc;
|
||||||
use cranelift_wasm::FuncIndex;
|
use cranelift_wasm::FuncIndex;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Relocation {
|
pub struct Relocation {
|
||||||
/// The relocation code.
|
/// The relocation code.
|
||||||
pub reloc: binemit::Reloc,
|
pub reloc: binemit::Reloc,
|
||||||
@ -16,10 +16,12 @@ pub struct Relocation {
|
|||||||
pub offset: binemit::CodeOffset,
|
pub offset: binemit::CodeOffset,
|
||||||
/// The addend to add to the relocation value.
|
/// The addend to add to the relocation value.
|
||||||
pub addend: binemit::Addend,
|
pub addend: binemit::Addend,
|
||||||
|
/// Relocation type.
|
||||||
|
pub target: RelocationType,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specify the type of relocation
|
/// Specify the type of relocation
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum RelocationType {
|
pub enum RelocationType {
|
||||||
Normal(u32),
|
Normal(u32),
|
||||||
Intrinsic(String),
|
Intrinsic(String),
|
||||||
@ -30,9 +32,8 @@ pub enum RelocationType {
|
|||||||
|
|
||||||
/// Implementation of a relocation sink that just saves all the information for later
|
/// Implementation of a relocation sink that just saves all the information for later
|
||||||
pub struct RelocSink {
|
pub struct RelocSink {
|
||||||
// func: &'func ir::Function,
|
|
||||||
/// Relocations recorded for the function.
|
/// Relocations recorded for the function.
|
||||||
pub func_relocs: Vec<(Relocation, RelocationType)>,
|
pub func_relocs: Vec<Relocation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl binemit::RelocSink for RelocSink {
|
impl binemit::RelocSink for RelocSink {
|
||||||
@ -57,14 +58,12 @@ impl binemit::RelocSink for RelocSink {
|
|||||||
namespace: 0,
|
namespace: 0,
|
||||||
index,
|
index,
|
||||||
} => {
|
} => {
|
||||||
self.func_relocs.push((
|
self.func_relocs.push(Relocation {
|
||||||
Relocation {
|
reloc,
|
||||||
reloc,
|
offset,
|
||||||
offset,
|
addend,
|
||||||
addend,
|
target: RelocationType::Normal(index as _),
|
||||||
},
|
});
|
||||||
RelocationType::Normal(index as _),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
ExternalName::TestCase { length, ascii } => {
|
ExternalName::TestCase { length, ascii } => {
|
||||||
let (slice, _) = ascii.split_at(length as usize);
|
let (slice, _) = ascii.split_at(length as usize);
|
||||||
@ -74,25 +73,21 @@ impl binemit::RelocSink for RelocSink {
|
|||||||
"grow_memory" => RelocationType::GrowMemory,
|
"grow_memory" => RelocationType::GrowMemory,
|
||||||
_ => RelocationType::Intrinsic(name),
|
_ => RelocationType::Intrinsic(name),
|
||||||
};
|
};
|
||||||
self.func_relocs.push((
|
self.func_relocs.push(Relocation {
|
||||||
Relocation {
|
reloc,
|
||||||
reloc,
|
offset,
|
||||||
offset,
|
addend,
|
||||||
addend,
|
target: relocation_type,
|
||||||
},
|
});
|
||||||
relocation_type,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
ExternalName::LibCall(libcall) => {
|
ExternalName::LibCall(libcall) => {
|
||||||
let relocation_type = RelocationType::LibCall(libcall);
|
let relocation_type = RelocationType::LibCall(libcall);
|
||||||
self.func_relocs.push((
|
self.func_relocs.push(Relocation {
|
||||||
Relocation {
|
reloc,
|
||||||
reloc,
|
offset,
|
||||||
offset,
|
addend,
|
||||||
addend,
|
target: relocation_type,
|
||||||
},
|
});
|
||||||
relocation_type,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
@ -109,6 +104,7 @@ impl binemit::RelocSink for RelocSink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implementation of a relocation sink that just saves all the information for later
|
||||||
impl RelocSink {
|
impl RelocSink {
|
||||||
pub fn new() -> RelocSink {
|
pub fn new() -> RelocSink {
|
||||||
RelocSink {
|
RelocSink {
|
||||||
@ -117,88 +113,6 @@ impl RelocSink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of a relocation sink that just saves all the information for later
|
|
||||||
// pub struct RelocSink {
|
|
||||||
// /// Relocations recorded for the function.
|
|
||||||
// pub func_relocs: Vec<Relocation>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl binemit::RelocSink for RelocSink {
|
|
||||||
// fn reloc_ebb(
|
|
||||||
// &mut self,
|
|
||||||
// _offset: binemit::CodeOffset,
|
|
||||||
// _reloc: binemit::Reloc,
|
|
||||||
// _ebb_offset: binemit::CodeOffset,
|
|
||||||
// ) {
|
|
||||||
// // This should use the `offsets` field of `ir::Function`.
|
|
||||||
// panic!("ebb headers not yet implemented");
|
|
||||||
// }
|
|
||||||
// fn reloc_external(
|
|
||||||
// &mut self,
|
|
||||||
// offset: binemit::CodeOffset,
|
|
||||||
// reloc: binemit::Reloc,
|
|
||||||
// name: &ExternalName,
|
|
||||||
// addend: binemit::Addend,
|
|
||||||
// ) {
|
|
||||||
// let reloc_target = if let ExternalName::User { namespace, index } = *name {
|
|
||||||
// debug_assert!(namespace == 0);
|
|
||||||
// RelocationTarget::UserFunc(FuncIndex::new(index as usize))
|
|
||||||
// } else if *name == ExternalName::testcase("grow_memory") {
|
|
||||||
// RelocationTarget::GrowMemory
|
|
||||||
// } else if *name == ExternalName::testcase("current_memory") {
|
|
||||||
// RelocationTarget::CurrentMemory
|
|
||||||
// } else {
|
|
||||||
// panic!("unrecognized external name")
|
|
||||||
// };
|
|
||||||
// self.func_relocs.push(Relocation {
|
|
||||||
// reloc,
|
|
||||||
// reloc_target,
|
|
||||||
// offset,
|
|
||||||
// addend,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// fn reloc_jt(
|
|
||||||
// &mut self,
|
|
||||||
// _offset: binemit::CodeOffset,
|
|
||||||
// _reloc: binemit::Reloc,
|
|
||||||
// _jt: ir::JumpTable,
|
|
||||||
// ) {
|
|
||||||
// panic!("jump tables not yet implemented");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl RelocSink {
|
|
||||||
// pub fn new() -> Self {
|
|
||||||
// Self {
|
|
||||||
// func_relocs: Vec::new(),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// A record of a relocation to perform.
|
|
||||||
// #[derive(Debug, Clone)]
|
|
||||||
// pub struct Relocation {
|
|
||||||
// /// The relocation code.
|
|
||||||
// pub reloc: binemit::Reloc,
|
|
||||||
// /// Relocation target.
|
|
||||||
// pub reloc_target: RelocationTarget,
|
|
||||||
// /// The offset where to apply the relocation.
|
|
||||||
// pub offset: binemit::CodeOffset,
|
|
||||||
// /// The addend to add to the relocation value.
|
|
||||||
// pub addend: binemit::Addend,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Destination function. Can be either user function or some special one, like grow_memory.
|
|
||||||
// #[derive(Debug, Copy, Clone)]
|
|
||||||
// pub enum RelocationTarget {
|
|
||||||
// /// The user function index.
|
|
||||||
// UserFunc(FuncIndex),
|
|
||||||
// /// Function for growing the default memory by the specified amount of pages.
|
|
||||||
// GrowMemory,
|
|
||||||
// /// Function for query current size of the default linear memory.
|
|
||||||
// CurrentMemory,
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub struct TrapData {
|
pub struct TrapData {
|
||||||
pub offset: usize,
|
pub offset: usize,
|
||||||
pub code: TrapCode,
|
pub code: TrapCode,
|
||||||
|
Reference in New Issue
Block a user