From bf21b98498469066ece6933d8d7d724b63ac8c64 Mon Sep 17 00:00:00 2001 From: pjht Date: Sat, 9 Mar 2024 12:25:55 -0600 Subject: [PATCH] Fix PC displacement being treated as unsigned --- src/disas.rs | 5 ++++- src/instruction.rs | 2 +- src/m68k.rs | 36 ++++++++++++++++++++++++++---------- src/symbol.rs | 9 ++++----- src/symbol_table.rs | 12 ++++++++++-- 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/disas.rs b/src/disas.rs index 710edad..97f7d2c 100644 --- a/src/disas.rs +++ b/src/disas.rs @@ -889,7 +889,10 @@ impl Disasm<'_, T> { match misc_mode { MiscMode::PcDisplacement => { let pc = self.pc; - Ok(EffectiveAddress::PcDisplacement(pc, self.read_prog_word()?)) + Ok(EffectiveAddress::PcDisplacement( + pc, + self.read_prog_word()? as i16, + )) } MiscMode::PcIndex => { let pc = self.pc; diff --git a/src/instruction.rs b/src/instruction.rs index 850cc27..2ef9a46 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -43,7 +43,7 @@ pub enum EffectiveAddress { idx: RegisterEffective, idx_size: Size, }, - PcDisplacement(u32, u16), + PcDisplacement(u32, i16), PcIndex(u32, u8, RegisterEffective, Size), AbsoluteShort(u16), AbsoluteLong(u32), diff --git a/src/m68k.rs b/src/m68k.rs index 7c5d253..2388ba8 100644 --- a/src/m68k.rs +++ b/src/m68k.rs @@ -1381,7 +1381,11 @@ impl M68K { self.read_address(address, size) } EffectiveAddress::PcDisplacement(pc, d) => { - let address = pc.wrapping_add(d.into()); + let address = if d > 0 { + pc.wrapping_add((d as u16).into()) + } else { + pc.wrapping_sub((-d as u16).into()) + }; self.read_address(address, size) } EffectiveAddress::PcIndex(pc, displacement, idx, idx_size) => { @@ -1518,10 +1522,13 @@ impl M68K { self.store_mem_cycles = true; } } - let result = self.bus.read_byte(address, self.is_supervisor()).map_err(|_| DetailedBusError { - address, - cause: BusErrorCause::ReadingByte, - }); + let result = self + .bus + .read_byte(address, self.is_supervisor()) + .map_err(|_| DetailedBusError { + address, + cause: BusErrorCause::ReadingByte, + }); if self.store_mem_cycles { self.stored_mem_cycles .push(MemCycleInfo::ReadByte { address, result }); @@ -1588,10 +1595,13 @@ impl M68K { self.store_mem_cycles = true; } } - let result = self.bus.read_word(address, self.is_supervisor()).map_err(|_| DetailedBusError { - address, - cause: BusErrorCause::ReadingWord, - }); + let result = self + .bus + .read_word(address, self.is_supervisor()) + .map_err(|_| DetailedBusError { + address, + cause: BusErrorCause::ReadingWord, + }); if self.store_mem_cycles { self.stored_mem_cycles .push(MemCycleInfo::ReadWord { address, result }); @@ -1674,7 +1684,13 @@ impl M68K { .wrapping_sub((-d as u16).into())) } } - EffectiveAddress::PcDisplacement(pc, d) => Ok(pc.wrapping_add(d.into())), + EffectiveAddress::PcDisplacement(pc, d) => { + if d > 0 { + Ok(pc.wrapping_add((d as u16).into())) + } else { + Ok(pc.wrapping_sub((-d as u16).into())) + } + }, EffectiveAddress::AbsoluteShort(x) => Ok(u32::from(x)), EffectiveAddress::AbsoluteLong(x) => Ok(x), EffectiveAddress::DataReg(_) diff --git a/src/symbol.rs b/src/symbol.rs index f8bc521..f8ae4da 100644 --- a/src/symbol.rs +++ b/src/symbol.rs @@ -40,14 +40,13 @@ impl Symbol { impl Display for Symbol { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.size == 0 { - f.write_fmt(format_args!( - "{:#010x} ({})", - self.value, self.sect_name - )) + f.write_fmt(format_args!("{:#010x} ({})", self.value, self.sect_name)) } else { f.write_fmt(format_args!( "{:#010x}..{:#010x} ({})", - self.value, self.value+self.size, self.sect_name + self.value, + self.value + self.size, + self.sect_name )) } } diff --git a/src/symbol_table.rs b/src/symbol_table.rs index f88dd2a..26a34e7 100644 --- a/src/symbol_table.rs +++ b/src/symbol_table.rs @@ -62,7 +62,10 @@ impl SymbolTable { let mut file = ElfStream::::open_stream(File::open(path)?)?; let (sect_headers, shstrtab) = file.section_headers_with_strtab()?; let shstrtab = shstrtab.unwrap(); - let sect_names = sect_headers.iter().map(|sect| shstrtab.get(sect.sh_name as usize).unwrap().to_string()).collect::>(); + let sect_names = sect_headers + .iter() + .map(|sect| shstrtab.get(sect.sh_name as usize).unwrap().to_string()) + .collect::>(); let (symtab, symstrtab) = file .symbol_table()? .ok_or_else(|| anyhow!("No symbol table in {}", path))?; @@ -73,7 +76,12 @@ impl SymbolTable { .map(|sym| { ( symstrtab.get(sym.st_name as usize).unwrap().to_string(), - Symbol::new(&sym, sect_names.get(sym.st_shndx as usize).map_or_else(|| "UNKNOWN".to_string(), |x| x.to_string())), + Symbol::new( + &sym, + sect_names + .get(sym.st_shndx as usize) + .map_or_else(|| "UNKNOWN".to_string(), |x| x.to_string()), + ), ) }) .collect::>();