Mask top 5 bits of PC for symbols
This commit is contained in:
parent
f7f112f7c1
commit
d610e3de14
|
@ -174,13 +174,13 @@ fn extract_isx_symbols(input: &[u8]) -> Option<Vec<Symbol>> {
|
||||||
let name_str = String::from_utf8_lossy(name_bytes);
|
let name_str = String::from_utf8_lossy(name_bytes);
|
||||||
let address = u32::from_le_bytes(*address_bytes);
|
let address = u32::from_le_bytes(*address_bytes);
|
||||||
syms.push(Symbol {
|
syms.push(Symbol {
|
||||||
address,
|
address: address & 0x07ffffff,
|
||||||
size: Some(4),
|
size: Some(4),
|
||||||
name: demangle_any(&name_str),
|
name: demangle_any(&name_str),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x20 | 0x21 | 0x22 => {
|
0x20..=0x22 => {
|
||||||
// System (undocumented)
|
// System (undocumented)
|
||||||
let length_bytes;
|
let length_bytes;
|
||||||
(length_bytes, buf) = buf.split_first_chunk()?;
|
(length_bytes, buf) = buf.split_first_chunk()?;
|
||||||
|
@ -253,8 +253,8 @@ fn parse_inline(ctx: &mut ParseContext, node: gimli::EntriesTreeNode<Reader>) ->
|
||||||
let name = Arc::new(name);
|
let name = Arc::new(name);
|
||||||
let mut ranges = ctx.dorf.die_ranges(ctx.unit, node.entry())?;
|
let mut ranges = ctx.dorf.die_ranges(ctx.unit, node.entry())?;
|
||||||
while let Some(range) = ranges.next()? {
|
while let Some(range) = ranges.next()? {
|
||||||
let start = range.begin as u32;
|
let start = range.begin as u32 & 0x07ffffff;
|
||||||
let end = range.end as u32;
|
let end = range.end as u32 & 0x07ffffff;
|
||||||
ctx.frames.add(start, end, name.clone());
|
ctx.frames.add(start, end, name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,7 +261,7 @@ extern "C" fn on_exception(sim: *mut VB, cause: *mut u16) -> c_int {
|
||||||
};
|
};
|
||||||
data.monitor.event = data.monitor.queued_event.take();
|
data.monitor.event = data.monitor.queued_event.take();
|
||||||
data.monitor.new_inline_stack = data.monitor.detect_new_inline_stack(pc);
|
data.monitor.new_inline_stack = data.monitor.detect_new_inline_stack(pc);
|
||||||
data.monitor.queued_event = Some(SimEvent::Interrupt(cause, pc));
|
data.monitor.queued_event = Some(SimEvent::Interrupt(cause, pc & 0x07ffffff));
|
||||||
unsafe { vb_set_exception_callback(sim, None) };
|
unsafe { vb_set_exception_callback(sim, None) };
|
||||||
if data.monitor.event.is_some() || data.monitor.new_inline_stack.is_some() {
|
if data.monitor.event.is_some() || data.monitor.new_inline_stack.is_some() {
|
||||||
1
|
1
|
||||||
|
@ -439,7 +439,9 @@ impl EventMonitor {
|
||||||
// JAL .+4 is how programs get r31 to a known value for indirect calls
|
// JAL .+4 is how programs get r31 to a known value for indirect calls
|
||||||
// (which we detect later.)
|
// (which we detect later.)
|
||||||
// Any other JAL is a function call.
|
// Any other JAL is a function call.
|
||||||
return Some(SimEvent::Call(address.wrapping_add_signed(disp)));
|
return Some(SimEvent::Call(
|
||||||
|
address.wrapping_add_signed(disp) & 0x07ffffff,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,7 +455,7 @@ impl EventMonitor {
|
||||||
if r31 as u32 == address.wrapping_add(2) {
|
if r31 as u32 == address.wrapping_add(2) {
|
||||||
// JMP anywhere else, if r31 points to after the JMP, is an indirect call
|
// JMP anywhere else, if r31 points to after the JMP, is an indirect call
|
||||||
let target = unsafe { vb_get_program_register(sim, jmp_reg as u32) };
|
let target = unsafe { vb_get_program_register(sim, jmp_reg as u32) };
|
||||||
return Some(SimEvent::Call(target as u32));
|
return Some(SimEvent::Call(target as u32 & 0x07ffffff));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,11 @@ pub fn rom_from_isx(bytes: &[u8]) -> Option<Vec<u8>> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let mut rom_length = 0;
|
let mut rom_length = 0;
|
||||||
let raw_rom =
|
let raw_rom = unsafe { vbu_from_isx(bytes.as_ptr().cast(), bytes.len(), &mut rom_length) };
|
||||||
unsafe { vbu_from_isx(bytes.as_ptr().cast(), bytes.len(), &mut rom_length) };
|
|
||||||
if raw_rom.is_null() {
|
if raw_rom.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// SAFETY: the rom was allocated by vbu_realloc_shim, which created it from a Vec<u8>.
|
// SAFETY: the rom was allocated by vbu_realloc_shim, which created it from a Vec<u8>.
|
||||||
let rom =
|
let rom = unsafe { Vec::from_raw_parts(raw_rom.cast(), rom_length, rom_length) };
|
||||||
unsafe { Vec::from_raw_parts(raw_rom.cast(), rom_length, rom_length) };
|
|
||||||
Some(rom)
|
Some(rom)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue