Push debugging stuff to help debug calls not working

This commit is contained in:
Lachlan Sneff
2019-01-09 18:31:11 -05:00
parent fcabf95f41
commit 8c74d0a551
75 changed files with 350 additions and 108 deletions

View File

@ -5,7 +5,7 @@ use std::mem;
use std::ptr::{write_unaligned, NonNull};
use wasmer_runtime::{
self,
mmap::{Mmap, Protect},
backend::{self, Mmap, Protect},
types::{FuncIndex, Map, MapIndex},
vm, vmcalls,
};
@ -38,6 +38,7 @@ impl FuncResolverBuilder {
ctx.compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink)
.map_err(|e| format!("compile error: {}", e.to_string()))?;
println!("{:?}", ctx.func);
ctx.clear();
// Round up each function's size to pointer alignment.
total_size += round_up(code_buf.len(), mem::size_of::<usize>());
@ -52,6 +53,10 @@ impl FuncResolverBuilder {
memory.protect(0..memory.size(), Protect::ReadWrite)?;
}
for i in unsafe { memory.as_slice_mut() } {
*i = 0xCC;
}
let mut map = Map::with_capacity(compiled_functions.len());
let mut previous_end = 0;
@ -77,6 +82,7 @@ impl FuncResolverBuilder {
}
pub fn finalize(mut self) -> Result<FuncResolver, String> {
print_disassembly(&*crate::get_isa(), unsafe { &self.resolver.memory.as_slice()[0..0x22] });
for (index, relocs) in self.relocations.iter() {
for ref reloc in relocs {
let target_func_address: isize = match reloc.target {
@ -84,10 +90,12 @@ impl FuncResolverBuilder {
// This will always be an internal function
// because imported functions are not
// called in this way.
self.resolver
let ptr = self.resolver
.lookup(FuncIndex::new(func_index as _))
.unwrap()
.as_ptr() as isize
.as_ptr();
println!("in {:?} {}: {:p}", index, func_index, ptr);
ptr as isize
}
RelocationType::CurrentMemory => vmcalls::memory_size as isize,
RelocationType::GrowMemory => vmcalls::memory_grow_static as isize,
@ -113,14 +121,19 @@ impl FuncResolverBuilder {
// We need the address of the current function
// because these calls are relative.
let func_addr = self.resolver.lookup(index).unwrap().as_ptr();
println!("current func addr ({:?}) {:p}", index, func_addr);
// Determine relocation type and apply relocation.
println!("{:?}", reloc);
match reloc.reloc {
Reloc::Abs8 => unsafe {
let reloc_address = func_addr.offset(reloc.offset as isize) as i64;
let reloc_addend = reloc.addend;
let reloc_abs = target_func_address as i64 + reloc_addend;
write_unaligned(reloc_address as *mut i64, reloc_abs);
let reloc_address = func_addr.add(reloc.offset as usize) as usize;
let reloc_addend = reloc.addend as isize;
let reloc_abs = (target_func_address as u64)
.checked_add(reloc_addend as u64)
.unwrap();
println!("reloc_abs: {:#x}", reloc_address);
write_unaligned(reloc_address as *mut u64, reloc_abs);
},
Reloc::X86PCRel4 => unsafe {
let reloc_address = func_addr.offset(reloc.offset as isize) as isize;
@ -135,6 +148,8 @@ impl FuncResolverBuilder {
}
}
print_disassembly(&*crate::get_isa(), unsafe { &self.resolver.memory.as_slice()[0..0x22] });
unsafe {
self.resolver
.memory
@ -164,8 +179,8 @@ impl FuncResolver {
}
// Implements FuncResolver trait.
impl wasmer_runtime::FuncResolver for FuncResolver {
fn get(&self, _module: &wasmer_runtime::Module, index: FuncIndex) -> Option<NonNull<vm::Func>> {
impl backend::FuncResolver for FuncResolver {
fn get(&self, _module: &wasmer_runtime::module::Module, index: FuncIndex) -> Option<NonNull<vm::Func>> {
self.lookup(index)
}
}
@ -174,3 +189,68 @@ impl wasmer_runtime::FuncResolver for FuncResolver {
fn round_up(n: usize, multiple: usize) -> usize {
(n + multiple - 1) & !(multiple - 1)
}
use capstone::prelude::*;
use target_lexicon::Architecture;
use std::fmt::Write;
fn get_disassembler(isa: &isa::TargetIsa) -> Result<Capstone, String> {
let cs = match isa.triple().architecture {
Architecture::Riscv32 | Architecture::Riscv64 => {
return Err(String::from("No disassembler for RiscV"))
}
Architecture::I386 | Architecture::I586 | Architecture::I686 => Capstone::new()
.x86()
.mode(arch::x86::ArchMode::Mode32)
.build(),
Architecture::X86_64 => Capstone::new()
.x86()
.mode(arch::x86::ArchMode::Mode64)
.build(),
Architecture::Arm
| Architecture::Armv4t
| Architecture::Armv5te
| Architecture::Armv7
| Architecture::Armv7s => Capstone::new().arm().mode(arch::arm::ArchMode::Arm).build(),
Architecture::Thumbv6m | Architecture::Thumbv7em | Architecture::Thumbv7m => Capstone::new(
).arm()
.mode(arch::arm::ArchMode::Thumb)
.build(),
Architecture::Aarch64 => Capstone::new()
.arm64()
.mode(arch::arm64::ArchMode::Arm)
.build(),
_ => return Err(String::from("Unknown ISA")),
};
cs.map_err(|err| err.to_string())
}
fn print_disassembly(isa: &isa::TargetIsa, mem: &[u8]) -> Result<(), String> {
let mut cs = get_disassembler(isa)?;
println!("\nDisassembly of {} bytes:", mem.len());
let insns = cs.disasm_all(&mem, 0x0).unwrap();
for i in insns.iter() {
let mut line = String::new();
write!(&mut line, "{:4x}:\t", i.address()).unwrap();
let mut bytes_str = String::new();
for b in i.bytes() {
write!(&mut bytes_str, "{:02x} ", b).unwrap();
}
write!(&mut line, "{:21}\t", bytes_str).unwrap();
if let Some(s) = i.mnemonic() {
write!(&mut line, "{}\t", s).unwrap();
}
if let Some(s) = i.op_str() {
write!(&mut line, "{}", s).unwrap();
}
println!("{}", line);
}
Ok(())
}