Fix MIPS operands with base

This commit is contained in:
Luke Street 2023-01-21 01:35:42 -05:00
parent 2ab519d361
commit fa28352e08
5 changed files with 48 additions and 32 deletions

View File

@ -268,8 +268,8 @@ fn arg_eq(
right_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()), right_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()),
) )
} }
ObjInsArg::MipsArg(ls) => { ObjInsArg::MipsArg(ls) | ObjInsArg::MipsArgWithBase(ls) => {
matches!(right, ObjInsArg::MipsArg(rs) if ls == rs) matches!(right, ObjInsArg::MipsArg(rs) | ObjInsArg::MipsArgWithBase(rs) if ls == rs)
} }
ObjInsArg::BranchOffset(_) => { ObjInsArg::BranchOffset(_) => {
// Compare dest instruction idx after diffing // Compare dest instruction idx after diffing
@ -324,7 +324,7 @@ fn compare_ins(
let a_str = match a { let a_str = match a {
ObjInsArg::PpcArg(arg) => format!("{arg}"), ObjInsArg::PpcArg(arg) => format!("{arg}"),
ObjInsArg::Reloc | ObjInsArg::RelocWithBase => String::new(), ObjInsArg::Reloc | ObjInsArg::RelocWithBase => String::new(),
ObjInsArg::MipsArg(str) => str.clone(), ObjInsArg::MipsArg(str) | ObjInsArg::MipsArgWithBase(str) => str.clone(),
ObjInsArg::BranchOffset(arg) => format!("{arg}"), ObjInsArg::BranchOffset(arg) => format!("{arg}"),
}; };
let a_diff = if let Some(idx) = state.left_args_idx.get(&a_str) { let a_diff = if let Some(idx) = state.left_args_idx.get(&a_str) {
@ -338,7 +338,7 @@ fn compare_ins(
let b_str = match b { let b_str = match b {
ObjInsArg::PpcArg(arg) => format!("{arg}"), ObjInsArg::PpcArg(arg) => format!("{arg}"),
ObjInsArg::Reloc | ObjInsArg::RelocWithBase => String::new(), ObjInsArg::Reloc | ObjInsArg::RelocWithBase => String::new(),
ObjInsArg::MipsArg(str) => str.clone(), ObjInsArg::MipsArg(str) | ObjInsArg::MipsArgWithBase(str) => str.clone(),
ObjInsArg::BranchOffset(arg) => format!("{arg}"), ObjInsArg::BranchOffset(arg) => format!("{arg}"),
}; };
let b_diff = if let Some(idx) = state.right_args_idx.get(&b_str) { let b_diff = if let Some(idx) = state.right_args_idx.get(&b_str) {

View File

@ -42,10 +42,7 @@ pub struct LevEditOp {
pub fn editops_find<T>(query: &[T], choice: &[T]) -> Vec<LevEditOp> pub fn editops_find<T>(query: &[T], choice: &[T]) -> Vec<LevEditOp>
where T: PartialEq { where T: PartialEq {
let Affix { let Affix { prefix_len, suffix_len } = Affix::find(query, choice);
prefix_len,
suffix_len,
} = Affix::find(query, choice);
let first_string = &query[prefix_len..query.len() - suffix_len]; let first_string = &query[prefix_len..query.len() - suffix_len];
let second_string = &choice[prefix_len..choice.len() - suffix_len]; let second_string = &choice[prefix_len..choice.len() - suffix_len];
@ -185,19 +182,14 @@ pub struct Affix {
impl Affix { impl Affix {
pub fn find<T>(s1: &[T], s2: &[T]) -> Affix pub fn find<T>(s1: &[T], s2: &[T]) -> Affix
where T: PartialEq { where T: PartialEq {
let prefix_len = s1.iter() let prefix_len = s1.iter().zip(s2.iter()).take_while(|t| t.0 == t.1).count();
.zip(s2.iter()) let suffix_len = s1[prefix_len..]
.take_while(|t| t.0 == t.1) .iter()
.count();
let suffix_len = s1[prefix_len..].iter()
.rev() .rev()
.zip(s2[prefix_len..].iter().rev()) .zip(s2[prefix_len..].iter().rev())
.take_while(|t| t.0 == t.1) .take_while(|t| t.0 == t.1)
.count(); .count();
Affix { Affix { prefix_len, suffix_len }
prefix_len,
suffix_len,
}
} }
} }

View File

@ -1,7 +1,7 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use anyhow::Result; use anyhow::Result;
use rabbitizer::{config, Abi, Instruction, InstrCategory, OperandType}; use rabbitizer::{config, Abi, InstrCategory, Instruction, OperandType};
use crate::obj::{ObjIns, ObjInsArg, ObjReloc}; use crate::obj::{ObjIns, ObjInsArg, ObjReloc};
@ -37,37 +37,49 @@ pub fn process_code(
let branch_offset = instruction.branch_offset(); let branch_offset = instruction.branch_offset();
let branch_dest = let branch_dest =
if is_branch { Some((cur_addr as i32 + branch_offset) as u32) } else { None }; if is_branch { Some((cur_addr as i32 + branch_offset) as u32) } else { None };
let args = instruction
.get_operands_slice() println!("{:?}", instruction.get_operands_slice());
.iter() let mut args = Vec::new();
.map(|op| match op { for op in instruction.get_operands_slice() {
OperandType::cpu_immediate | OperandType::cpu_label | OperandType::cpu_branch_target_label => { match op {
OperandType::cpu_immediate
| OperandType::cpu_label
| OperandType::cpu_branch_target_label => {
if is_branch { if is_branch {
ObjInsArg::BranchOffset(branch_offset) args.push(ObjInsArg::BranchOffset(branch_offset));
} else if let Some(reloc) = reloc { } else if let Some(reloc) = reloc {
if matches!(&reloc.target_section, Some(s) if s == ".text") if matches!(&reloc.target_section, Some(s) if s == ".text")
&& reloc.target.address > start_address && reloc.target.address > start_address
&& reloc.target.address < end_address && reloc.target.address < end_address
{ {
// Inter-function reloc, convert to branch offset // Inter-function reloc, convert to branch offset
ObjInsArg::BranchOffset(reloc.target.address as i32 - cur_addr as i32) args.push(ObjInsArg::BranchOffset(
reloc.target.address as i32 - cur_addr as i32,
));
} else { } else {
ObjInsArg::Reloc args.push(ObjInsArg::Reloc);
} }
} else { } else {
ObjInsArg::MipsArg(op.disassemble(&instruction, None)) args.push(ObjInsArg::MipsArg(op.disassemble(&instruction, None)));
} }
} }
OperandType::cpu_immediate_base => { OperandType::cpu_immediate_base => {
if reloc.is_some() { if reloc.is_some() {
ObjInsArg::RelocWithBase args.push(ObjInsArg::RelocWithBase);
} else { } else {
ObjInsArg::MipsArg(op.disassemble(&instruction, None)) args.push(ObjInsArg::MipsArgWithBase(
OperandType::cpu_immediate.disassemble(&instruction, None),
));
} }
args.push(ObjInsArg::MipsArg(
OperandType::cpu_rs.disassemble(&instruction, None),
));
} }
_ => ObjInsArg::MipsArg(op.disassemble(&instruction, None)), _ => {
}) args.push(ObjInsArg::MipsArg(op.disassemble(&instruction, None)));
.collect(); }
}
}
let line = let line =
line_info.as_ref().and_then(|map| map.range(..=cur_addr).last().map(|(_, &b)| b)); line_info.as_ref().and_then(|map| map.range(..=cur_addr).last().map(|(_, &b)| b));
insts.push(ObjIns { insts.push(ObjIns {

View File

@ -41,6 +41,7 @@ pub struct ObjSection {
pub enum ObjInsArg { pub enum ObjInsArg {
PpcArg(ppc750cl::Argument), PpcArg(ppc750cl::Argument),
MipsArg(String), MipsArg(String),
MipsArgWithBase(String),
Reloc, Reloc,
RelocWithBase, RelocWithBase,
BranchOffset(i32), BranchOffset(i32),

View File

@ -132,6 +132,17 @@ fn write_ins(
config.code_font.clone(), config.code_font.clone(),
); );
} }
ObjInsArg::MipsArgWithBase(str) => {
write_text(
str.strip_prefix('$').unwrap_or(str),
color,
job,
config.code_font.clone(),
);
write_text("(", base_color, job, config.code_font.clone());
writing_offset = true;
continue;
}
ObjInsArg::BranchOffset(offset) => { ObjInsArg::BranchOffset(offset) => {
let addr = offset + ins.address as i32 - base_addr as i32; let addr = offset + ins.address as i32 - base_addr as i32;
write_text(&format!("{addr:x}"), color, job, config.code_font.clone()); write_text(&format!("{addr:x}"), color, job, config.code_font.clone());