mirror of https://github.com/encounter/objdiff.git
Fix MIPS operands with base
This commit is contained in:
parent
2ab519d361
commit
fa28352e08
|
@ -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) {
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue