mirror of
https://github.com/encounter/objdiff.git
synced 2025-08-03 18:55:43 +00:00
Use let chains (a.k.a. cargo clippy --fix
)
This commit is contained in:
parent
0dc123b064
commit
c9c3b32376
@ -248,13 +248,12 @@ fn report_object(
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if let Some(existing_functions) = &mut existing_functions {
|
||||
if (symbol.flags.contains(SymbolFlag::Global)
|
||||
if let Some(existing_functions) = &mut existing_functions
|
||||
&& (symbol.flags.contains(SymbolFlag::Global)
|
||||
|| symbol.flags.contains(SymbolFlag::Weak))
|
||||
&& !existing_functions.insert(symbol.name.clone())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
&& !existing_functions.insert(symbol.name.clone())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let match_percent = symbol_diff.match_percent.unwrap_or_else(|| {
|
||||
// Support cases where we don't have a target object,
|
||||
|
@ -170,32 +170,31 @@ impl UiView for FunctionDiffUi {
|
||||
|
||||
let mut prev_text = None;
|
||||
let mut prev_margin_text = None;
|
||||
if self.three_way {
|
||||
if let Some((obj, symbol_idx, symbol_diff)) =
|
||||
if self.three_way
|
||||
&& let Some((obj, symbol_idx, symbol_diff)) =
|
||||
get_symbol(state.prev_obj.as_ref(), self.prev_sym)
|
||||
{
|
||||
let mut text = Text::default();
|
||||
let rect = content_chunks[4].inner(Margin::new(0, 1));
|
||||
self.print_sym(
|
||||
&mut text,
|
||||
obj,
|
||||
symbol_idx,
|
||||
symbol_diff,
|
||||
&state.diff_obj_config,
|
||||
rect,
|
||||
&self.right_highlight,
|
||||
result,
|
||||
true,
|
||||
);
|
||||
max_width = max_width.max(text.width());
|
||||
prev_text = Some(text);
|
||||
{
|
||||
let mut text = Text::default();
|
||||
let rect = content_chunks[4].inner(Margin::new(0, 1));
|
||||
self.print_sym(
|
||||
&mut text,
|
||||
obj,
|
||||
symbol_idx,
|
||||
symbol_diff,
|
||||
&state.diff_obj_config,
|
||||
rect,
|
||||
&self.right_highlight,
|
||||
result,
|
||||
true,
|
||||
);
|
||||
max_width = max_width.max(text.width());
|
||||
prev_text = Some(text);
|
||||
|
||||
// Render margin
|
||||
let mut text = Text::default();
|
||||
let rect = content_chunks[3].inner(Margin::new(1, 1));
|
||||
self.print_margin(&mut text, symbol_diff, rect);
|
||||
prev_margin_text = Some(text);
|
||||
}
|
||||
// Render margin
|
||||
let mut text = Text::default();
|
||||
let rect = content_chunks[3].inner(Margin::new(1, 1));
|
||||
self.print_margin(&mut text, symbol_diff, rect);
|
||||
prev_margin_text = Some(text);
|
||||
}
|
||||
|
||||
let max_scroll_x =
|
||||
@ -561,10 +560,12 @@ impl FunctionDiffUi {
|
||||
let len = label_text.len();
|
||||
let highlighted =
|
||||
highlight_kind != HighlightKind::None && *highlight == highlight_kind;
|
||||
if let Some((cx, cy)) = result.click_xy {
|
||||
if cx >= sx && cx < sx + len as u16 && cy == sy {
|
||||
new_highlight = Some(highlight_kind);
|
||||
}
|
||||
if let Some((cx, cy)) = result.click_xy
|
||||
&& cx >= sx
|
||||
&& cx < sx + len as u16
|
||||
&& cy == sy
|
||||
{
|
||||
new_highlight = Some(highlight_kind);
|
||||
}
|
||||
let mut style = Style::new().fg(match segment.color {
|
||||
DiffTextColor::Normal => Color::Gray,
|
||||
|
@ -509,25 +509,25 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
return "ubfx";
|
||||
}
|
||||
Opcode::SBFM => {
|
||||
if let Operand::Immediate(63) = ins.operands[3] {
|
||||
if let Operand::Register(SizeCode::X, _) = ins.operands[0] {
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return "asr";
|
||||
}
|
||||
if let Operand::Immediate(63) = ins.operands[3]
|
||||
&& let Operand::Register(SizeCode::X, _) = ins.operands[0]
|
||||
{
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return "asr";
|
||||
}
|
||||
if let Operand::Immediate(31) = ins.operands[3] {
|
||||
if let Operand::Register(SizeCode::W, _) = ins.operands[0] {
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return "asr";
|
||||
}
|
||||
if let Operand::Immediate(31) = ins.operands[3]
|
||||
&& let Operand::Register(SizeCode::W, _) = ins.operands[0]
|
||||
{
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return "asr";
|
||||
}
|
||||
if let Operand::Immediate(0) = ins.operands[2] {
|
||||
let newsrc = if let Operand::Register(_size, srcnum) = ins.operands[1] {
|
||||
@ -554,22 +554,21 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
if let (Operand::Immediate(imms), Operand::Immediate(immr)) =
|
||||
(ins.operands[2], ins.operands[3])
|
||||
&& immr < imms
|
||||
{
|
||||
if immr < imms {
|
||||
let size = if let Operand::Register(size, _) = ins.operands[0] {
|
||||
if size == SizeCode::W { 32 } else { 64 }
|
||||
} else {
|
||||
unreachable!("operand 0 is always a register");
|
||||
};
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
push_separator(args);
|
||||
push_unsigned(args, (size - imms) as u64);
|
||||
push_separator(args);
|
||||
push_unsigned(args, (immr + 1) as u64);
|
||||
return "sbfiz";
|
||||
}
|
||||
let size = if let Operand::Register(size, _) = ins.operands[0] {
|
||||
if size == SizeCode::W { 32 } else { 64 }
|
||||
} else {
|
||||
unreachable!("operand 0 is always a register");
|
||||
};
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
push_separator(args);
|
||||
push_unsigned(args, (size - imms) as u64);
|
||||
push_separator(args);
|
||||
push_unsigned(args, (immr + 1) as u64);
|
||||
return "sbfiz";
|
||||
}
|
||||
// `sbfm` is never actually displayed: in the remaining case, it is always aliased to `sbfx`
|
||||
let width = if let (Operand::Immediate(lsb), Operand::Immediate(width)) =
|
||||
@ -593,15 +592,14 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
Opcode::EXTR => {
|
||||
if let (Operand::Register(_, rn), Operand::Register(_, rm)) =
|
||||
(ins.operands[1], ins.operands[2])
|
||||
&& rn == rm
|
||||
{
|
||||
if rn == rm {
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[3], ctx);
|
||||
return "ror";
|
||||
}
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[3], ctx);
|
||||
return "ror";
|
||||
}
|
||||
"extr"
|
||||
}
|
||||
@ -804,27 +802,24 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
"csneg"
|
||||
}
|
||||
Opcode::CSINC => {
|
||||
if let (
|
||||
Operand::Register(_, n),
|
||||
Operand::Register(_, m),
|
||||
Operand::ConditionCode(cond),
|
||||
) = (ins.operands[1], ins.operands[2], ins.operands[3])
|
||||
if let (Operand::Register(_, n), Operand::Register(_, m), Operand::ConditionCode(cond)) =
|
||||
(ins.operands[1], ins.operands[2], ins.operands[3])
|
||||
&& n == m
|
||||
&& cond < 0b1110
|
||||
{
|
||||
if n == m && cond < 0b1110 {
|
||||
return if n == 31 {
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_condition_code(args, cond ^ 0x01);
|
||||
"cset"
|
||||
} else {
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
push_separator(args);
|
||||
push_condition_code(args, cond ^ 0x01);
|
||||
"cinc"
|
||||
};
|
||||
}
|
||||
return if n == 31 {
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_condition_code(args, cond ^ 0x01);
|
||||
"cset"
|
||||
} else {
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
push_separator(args);
|
||||
push_condition_code(args, cond ^ 0x01);
|
||||
"cinc"
|
||||
};
|
||||
}
|
||||
"csinc"
|
||||
}
|
||||
@ -1200,15 +1195,13 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
Operand::Register(reg_sz, _),
|
||||
Operand::SIMDRegisterElementsLane(_, _, elem_sz, _),
|
||||
) = (ins.operands[0], ins.operands[1])
|
||||
&& ((reg_sz == SizeCode::W && elem_sz == SIMDSizeCode::S)
|
||||
|| (reg_sz == SizeCode::X && elem_sz == SIMDSizeCode::D))
|
||||
{
|
||||
if (reg_sz == SizeCode::W && elem_sz == SIMDSizeCode::S)
|
||||
|| (reg_sz == SizeCode::X && elem_sz == SIMDSizeCode::D)
|
||||
{
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
return "mov";
|
||||
}
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[1], ctx);
|
||||
return "mov";
|
||||
}
|
||||
"umov"
|
||||
}
|
||||
@ -1308,14 +1301,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDADDB(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "staddb" } else { "staddlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "staddb" } else { "staddlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldaddb"
|
||||
@ -1328,14 +1322,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDCLRB(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stclrb" } else { "stclrlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stclrb" } else { "stclrlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldclrb"
|
||||
@ -1348,14 +1343,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDEORB(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "steorb" } else { "steorlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "steorb" } else { "steorlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldeorb"
|
||||
@ -1368,14 +1364,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDSETB(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stsetb" } else { "stsetlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stsetb" } else { "stsetlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldsetb"
|
||||
@ -1388,14 +1385,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDSMAXB(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stsmaxb" } else { "stsmaxlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stsmaxb" } else { "stsmaxlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldsmaxb"
|
||||
@ -1408,14 +1406,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDSMINB(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stsminb" } else { "stsminlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stsminb" } else { "stsminlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldsminb"
|
||||
@ -1428,14 +1427,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDUMAXB(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stumaxb" } else { "stumaxlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stumaxb" } else { "stumaxlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldumaxb"
|
||||
@ -1448,14 +1448,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDUMINB(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stuminb" } else { "stuminlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stuminb" } else { "stuminlb" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
// write!(fmt, "{}", self.opcode)?;
|
||||
if ar == 0 {
|
||||
@ -1469,14 +1470,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDADDH(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "staddh" } else { "staddlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "staddh" } else { "staddlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldaddh"
|
||||
@ -1489,14 +1491,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDCLRH(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stclrh" } else { "stclrlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stclrh" } else { "stclrlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldclrh"
|
||||
@ -1509,14 +1512,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDEORH(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "steorh" } else { "steorlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "steorh" } else { "steorlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldeorh"
|
||||
@ -1529,14 +1533,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDSETH(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stseth" } else { "stsetlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stseth" } else { "stsetlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldseth"
|
||||
@ -1549,14 +1554,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDSMAXH(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stsmaxh" } else { "stsmaxlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stsmaxh" } else { "stsmaxlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldsmaxh"
|
||||
@ -1569,14 +1575,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDSMINH(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stsminh" } else { "stsminlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stsminh" } else { "stsminlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldsminh"
|
||||
@ -1589,14 +1596,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDUMAXH(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stumaxh" } else { "stumaxlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stumaxh" } else { "stumaxlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldumaxh"
|
||||
@ -1609,14 +1617,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDUMINH(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stuminh" } else { "stuminlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stuminh" } else { "stuminlh" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"lduminh"
|
||||
@ -1629,14 +1638,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDADD(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stadd" } else { "staddl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stadd" } else { "staddl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldadd"
|
||||
@ -1649,14 +1659,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDCLR(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stclr" } else { "stclrl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stclr" } else { "stclrl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldclr"
|
||||
@ -1669,14 +1680,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDEOR(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "steor" } else { "steorl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "steor" } else { "steorl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldeor"
|
||||
@ -1689,14 +1701,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDSET(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stset" } else { "stsetl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stset" } else { "stsetl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldset"
|
||||
@ -1709,14 +1722,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDSMAX(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stsmax" } else { "stsmaxl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stsmax" } else { "stsmaxl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldsmax"
|
||||
@ -1729,14 +1743,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDSMIN(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stsmin" } else { "stsminl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stsmin" } else { "stsminl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldsmin"
|
||||
@ -1749,14 +1764,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDUMAX(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stumax" } else { "stumaxl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stumax" } else { "stumaxl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldumax"
|
||||
@ -1769,14 +1785,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
}
|
||||
}
|
||||
Opcode::LDUMIN(ar) => {
|
||||
if let Operand::Register(_, rt) = ins.operands[1] {
|
||||
if rt == 31 && ar & 0b10 == 0b00 {
|
||||
let inst = if ar & 0b01 == 0b00 { "stumin" } else { "stuminl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if let Operand::Register(_, rt) = ins.operands[1]
|
||||
&& rt == 31
|
||||
&& ar & 0b10 == 0b00
|
||||
{
|
||||
let inst = if ar & 0b01 == 0b00 { "stumin" } else { "stuminl" };
|
||||
push_operand(args, &ins.operands[0], ctx);
|
||||
push_separator(args);
|
||||
push_operand(args, &ins.operands[2], ctx);
|
||||
return inst;
|
||||
}
|
||||
if ar == 0 {
|
||||
"ldumin"
|
||||
@ -2067,16 +2084,15 @@ where Cb: FnMut(InstructionPart<'static>) {
|
||||
|
||||
/// Relocations that appear in Operand::PCOffset.
|
||||
fn is_pc_offset_reloc(reloc: Option<ResolvedRelocation>) -> Option<ResolvedRelocation> {
|
||||
if let Some(resolved) = reloc {
|
||||
if let RelocationFlags::Elf(
|
||||
if let Some(resolved) = reloc
|
||||
&& let RelocationFlags::Elf(
|
||||
elf::R_AARCH64_ADR_PREL_PG_HI21
|
||||
| elf::R_AARCH64_JUMP26
|
||||
| elf::R_AARCH64_CALL26
|
||||
| elf::R_AARCH64_ADR_GOT_PAGE,
|
||||
) = resolved.relocation.flags
|
||||
{
|
||||
return Some(resolved);
|
||||
}
|
||||
{
|
||||
return Some(resolved);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -242,17 +242,16 @@ impl Arch for ArchMips {
|
||||
object::RelocationFlags::Elf { r_type } => {
|
||||
if relocation.has_implicit_addend() {
|
||||
// Check for paired R_MIPS_HI16 and R_MIPS_LO16 relocations.
|
||||
if let elf::R_MIPS_HI16 | elf::R_MIPS_LO16 = r_type {
|
||||
if let Some(addend) = self
|
||||
if let elf::R_MIPS_HI16 | elf::R_MIPS_LO16 = r_type
|
||||
&& let Some(addend) = self
|
||||
.paired_relocations
|
||||
.get(section.index().0)
|
||||
.and_then(|m| m.get(&address).copied())
|
||||
{
|
||||
return Ok(Some(RelocationOverride {
|
||||
target: RelocationOverrideTarget::Keep,
|
||||
addend,
|
||||
}));
|
||||
}
|
||||
{
|
||||
return Ok(Some(RelocationOverride {
|
||||
target: RelocationOverrideTarget::Keep,
|
||||
addend,
|
||||
}));
|
||||
}
|
||||
|
||||
let data = section.data()?;
|
||||
|
@ -215,10 +215,10 @@ impl dyn Arch {
|
||||
|
||||
// Remove any branch destinations that are outside the function range
|
||||
for ins in result.iter_mut() {
|
||||
if let Some(branch_dest) = ins.branch_dest {
|
||||
if branch_dest < function_start || branch_dest >= function_end {
|
||||
ins.branch_dest = None;
|
||||
}
|
||||
if let Some(branch_dest) = ins.branch_dest
|
||||
&& (branch_dest < function_start || branch_dest >= function_end)
|
||||
{
|
||||
ins.branch_dest = None;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,14 +514,14 @@ pub fn ppc_data_flow_analysis(
|
||||
}
|
||||
|
||||
fn get_string_data(obj: &Object, symbol_index: usize, offset: Simm) -> Option<&str> {
|
||||
if let Some(sym) = obj.symbols.get(symbol_index) {
|
||||
if sym.name.starts_with("@stringBase") && offset.0 != 0 {
|
||||
if let Some(data) = obj.symbol_data(symbol_index) {
|
||||
let bytes = &data[offset.0 as usize..];
|
||||
if let Ok(Ok(str)) = CStr::from_bytes_until_nul(bytes).map(|x| x.to_str()) {
|
||||
return Some(str);
|
||||
}
|
||||
}
|
||||
if let Some(sym) = obj.symbols.get(symbol_index)
|
||||
&& sym.name.starts_with("@stringBase")
|
||||
&& offset.0 != 0
|
||||
&& let Some(data) = obj.symbol_data(symbol_index)
|
||||
{
|
||||
let bytes = &data[offset.0 as usize..];
|
||||
if let Ok(Ok(str)) = CStr::from_bytes_until_nul(bytes).map(|x| x.to_str()) {
|
||||
return Some(str);
|
||||
}
|
||||
}
|
||||
None
|
||||
@ -577,19 +577,17 @@ fn generate_flow_analysis_result(
|
||||
let registers = register_state_at.get(index as usize).unwrap_or(&default_register_state);
|
||||
if let (powerpc::Opcode::Addi, Argument::GPR(rel), Argument::Simm(offset)) =
|
||||
(ins.op, args[1], args[2])
|
||||
&& let RegisterContent::Symbol(sym_index) = registers[rel]
|
||||
&& let Some(str) = get_string_data(obj, sym_index, offset)
|
||||
{
|
||||
if let RegisterContent::Symbol(sym_index) = registers[rel] {
|
||||
if let Some(str) = get_string_data(obj, sym_index, offset) {
|
||||
// Show the string constant in the analysis result
|
||||
let formatted = format!("\"{str}\"");
|
||||
analysis_result.set_argument_value_at_address(
|
||||
ins_address,
|
||||
2,
|
||||
FlowAnalysisValue::Text(clamp_text_length(formatted, 20)),
|
||||
);
|
||||
// Don't continue, we want to show the stringbase value as well
|
||||
}
|
||||
}
|
||||
// Show the string constant in the analysis result
|
||||
let formatted = format!("\"{str}\"");
|
||||
analysis_result.set_argument_value_at_address(
|
||||
ins_address,
|
||||
2,
|
||||
FlowAnalysisValue::Text(clamp_text_length(formatted, 20)),
|
||||
);
|
||||
// Don't continue, we want to show the stringbase value as well
|
||||
}
|
||||
|
||||
let is_store = is_store_instruction(ins.op);
|
||||
|
@ -866,44 +866,43 @@ fn generate_fake_pool_relocations_for_function(
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(branch_dest) = branch_dest {
|
||||
if branch_dest >= func_address as u32
|
||||
&& (branch_dest - func_address as u32) < code.len() as u32
|
||||
{
|
||||
let dest_offset_into_func = branch_dest - func_address as u32;
|
||||
let dest_code_slice = &code[dest_offset_into_func as usize..];
|
||||
match ins.op {
|
||||
Opcode::Bc => {
|
||||
// Conditional branch.
|
||||
// Add the branch destination to the queue to do later.
|
||||
if let Some(branch_dest) = branch_dest
|
||||
&& branch_dest >= func_address as u32
|
||||
&& (branch_dest - func_address as u32) < code.len() as u32
|
||||
{
|
||||
let dest_offset_into_func = branch_dest - func_address as u32;
|
||||
let dest_code_slice = &code[dest_offset_into_func as usize..];
|
||||
match ins.op {
|
||||
Opcode::Bc => {
|
||||
// Conditional branch.
|
||||
// Add the branch destination to the queue to do later.
|
||||
ins_iters_with_gpr_state.push((
|
||||
InsIter::new(dest_code_slice, branch_dest, extensions),
|
||||
gpr_pool_relocs.clone(),
|
||||
));
|
||||
// Then continue on with the current iterator.
|
||||
}
|
||||
Opcode::B => {
|
||||
if simplified.mnemonic != "bl" {
|
||||
// Unconditional branch.
|
||||
// Add the branch destination to the queue.
|
||||
ins_iters_with_gpr_state.push((
|
||||
InsIter::new(dest_code_slice, branch_dest, extensions),
|
||||
gpr_pool_relocs.clone(),
|
||||
));
|
||||
// Then continue on with the current iterator.
|
||||
// Break out of the current iterator so we can do the newly added one.
|
||||
break;
|
||||
}
|
||||
Opcode::B => {
|
||||
if simplified.mnemonic != "bl" {
|
||||
// Unconditional branch.
|
||||
// Add the branch destination to the queue.
|
||||
ins_iters_with_gpr_state.push((
|
||||
InsIter::new(dest_code_slice, branch_dest, extensions),
|
||||
gpr_pool_relocs.clone(),
|
||||
));
|
||||
// Break out of the current iterator so we can do the newly added one.
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
if let Opcode::Bcctr = ins.op {
|
||||
if simplified.mnemonic == "bctr" {
|
||||
// Unconditional branch to count register.
|
||||
// Likely a jump table.
|
||||
gpr_state_at_bctr.insert(cur_addr, gpr_pool_relocs.clone());
|
||||
}
|
||||
if let Opcode::Bcctr = ins.op
|
||||
&& simplified.mnemonic == "bctr"
|
||||
{
|
||||
// Unconditional branch to count register.
|
||||
// Likely a jump table.
|
||||
gpr_state_at_bctr.insert(cur_addr, gpr_pool_relocs.clone());
|
||||
}
|
||||
|
||||
// Then handle keeping track of which GPR contains which pool relocation.
|
||||
|
@ -385,13 +385,13 @@ pub fn symbol_context(obj: &Object, symbol_index: usize) -> Vec<ContextItem> {
|
||||
if let Some(name) = &symbol.demangled_name {
|
||||
out.push(ContextItem::Copy { value: name.clone(), label: None });
|
||||
}
|
||||
if symbol.section.is_some() {
|
||||
if let Some(address) = symbol.virtual_address {
|
||||
out.push(ContextItem::Copy {
|
||||
value: format!("{address:x}"),
|
||||
label: Some("virtual address".to_string()),
|
||||
});
|
||||
}
|
||||
if symbol.section.is_some()
|
||||
&& let Some(address) = symbol.virtual_address
|
||||
{
|
||||
out.push(ContextItem::Copy {
|
||||
value: format!("{address:x}"),
|
||||
label: Some("virtual address".to_string()),
|
||||
});
|
||||
}
|
||||
out.append(&mut obj.arch.symbol_context(obj, symbol_index));
|
||||
out
|
||||
|
@ -467,15 +467,15 @@ fn apply_symbol_mappings(
|
||||
) -> Result<()> {
|
||||
// If we're selecting a symbol to use as a comparison, mark it as used
|
||||
// This ensures that we don't match it to another symbol at any point
|
||||
if let Some(left_name) = &mapping_config.selecting_left {
|
||||
if let Some(left_symbol) = left.symbol_by_name(left_name) {
|
||||
left_used.insert(left_symbol);
|
||||
}
|
||||
if let Some(left_name) = &mapping_config.selecting_left
|
||||
&& let Some(left_symbol) = left.symbol_by_name(left_name)
|
||||
{
|
||||
left_used.insert(left_symbol);
|
||||
}
|
||||
if let Some(right_name) = &mapping_config.selecting_right {
|
||||
if let Some(right_symbol) = right.symbol_by_name(right_name) {
|
||||
right_used.insert(right_symbol);
|
||||
}
|
||||
if let Some(right_name) = &mapping_config.selecting_right
|
||||
&& let Some(right_symbol) = right.symbol_by_name(right_name)
|
||||
{
|
||||
right_used.insert(right_symbol);
|
||||
}
|
||||
|
||||
// Apply manual symbol mappings
|
||||
@ -639,17 +639,16 @@ fn find_symbol(
|
||||
// If they are at the same address in the same section
|
||||
if in_symbol.name.starts_with('@')
|
||||
&& matches!(section_kind, SectionKind::Data | SectionKind::Bss)
|
||||
{
|
||||
if let Some((symbol_idx, _)) = unmatched_symbols(obj, used).find(|(_, symbol)| {
|
||||
&& let Some((symbol_idx, _)) = unmatched_symbols(obj, used).find(|(_, symbol)| {
|
||||
let Some(section_index) = symbol.section else {
|
||||
return false;
|
||||
};
|
||||
symbol.name.starts_with('@')
|
||||
&& symbol.address == in_symbol.address
|
||||
&& obj.sections[section_index].name == section_name
|
||||
}) {
|
||||
return Some(symbol_idx);
|
||||
}
|
||||
})
|
||||
{
|
||||
return Some(symbol_idx);
|
||||
}
|
||||
// Match Metrowerks symbol$1234 against symbol$2345
|
||||
if let Some((prefix, suffix)) = in_symbol.name.split_once('$') {
|
||||
|
@ -550,12 +550,11 @@ fn perform_data_flow_analysis(obj: &mut Object, config: &DiffObjConfig) -> Resul
|
||||
}
|
||||
|
||||
// Optional full data flow analysis
|
||||
if config.analyze_data_flow {
|
||||
if let Some(flow_result) =
|
||||
if config.analyze_data_flow
|
||||
&& let Some(flow_result) =
|
||||
obj.arch.data_flow_analysis(obj, symbol, code, §ion.relocations)
|
||||
{
|
||||
generated_flow_results.push((symbol.clone(), flow_result));
|
||||
}
|
||||
{
|
||||
generated_flow_results.push((symbol.clone(), flow_result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ pub fn align_data_to_4<W: std::io::Write + ?Sized>(
|
||||
len: usize,
|
||||
) -> std::io::Result<()> {
|
||||
const ALIGN_BYTES: &[u8] = &[0; 4];
|
||||
if len % 4 != 0 {
|
||||
if !len.is_multiple_of(4) {
|
||||
writer.write_all(&ALIGN_BYTES[..4 - len % 4])?;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -526,14 +526,12 @@ impl App {
|
||||
mod_check = true;
|
||||
}
|
||||
|
||||
if mod_check {
|
||||
if let Some(info) = &state.project_config_info {
|
||||
if let Some(last_ts) = info.timestamp {
|
||||
if file_modified(&info.path, last_ts) {
|
||||
state.config_change = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if mod_check
|
||||
&& let Some(info) = &state.project_config_info
|
||||
&& let Some(last_ts) = info.timestamp
|
||||
&& file_modified(&info.path, last_ts)
|
||||
{
|
||||
state.config_change = true;
|
||||
}
|
||||
|
||||
if state.config_change {
|
||||
@ -581,22 +579,20 @@ impl App {
|
||||
state.queue_build = true;
|
||||
}
|
||||
|
||||
if let Some(result) = &diff_state.build {
|
||||
if mod_check {
|
||||
if let Some((obj, _)) = &result.first_obj {
|
||||
if let (Some(path), Some(timestamp)) = (&obj.path, obj.timestamp) {
|
||||
if file_modified(path, timestamp) {
|
||||
state.queue_reload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some((obj, _)) = &result.second_obj {
|
||||
if let (Some(path), Some(timestamp)) = (&obj.path, obj.timestamp) {
|
||||
if file_modified(path, timestamp) {
|
||||
state.queue_reload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(result) = &diff_state.build
|
||||
&& mod_check
|
||||
{
|
||||
if let Some((obj, _)) = &result.first_obj
|
||||
&& let (Some(path), Some(timestamp)) = (&obj.path, obj.timestamp)
|
||||
&& file_modified(path, timestamp)
|
||||
{
|
||||
state.queue_reload = true;
|
||||
}
|
||||
if let Some((obj, _)) = &result.second_obj
|
||||
&& let (Some(path), Some(timestamp)) = (&obj.path, obj.timestamp)
|
||||
&& file_modified(path, timestamp)
|
||||
{
|
||||
state.queue_reload = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,13 +614,12 @@ impl App {
|
||||
state.queue_reload = false;
|
||||
}
|
||||
|
||||
if graphics_state.should_relaunch {
|
||||
if let Some(app_path) = &self.app_path {
|
||||
if let Ok(mut guard) = self.relaunch_path.lock() {
|
||||
*guard = Some(app_path.clone());
|
||||
self.should_relaunch = true;
|
||||
}
|
||||
}
|
||||
if graphics_state.should_relaunch
|
||||
&& let Some(app_path) = &self.app_path
|
||||
&& let Ok(mut guard) = self.relaunch_path.lock()
|
||||
{
|
||||
*guard = Some(app_path.clone());
|
||||
self.should_relaunch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -173,23 +173,23 @@ fn main() -> ExitCode {
|
||||
}
|
||||
|
||||
// Attempt to relaunch application from the updated path
|
||||
if let Ok(mut guard) = exec_path.lock() {
|
||||
if let Some(path) = guard.take() {
|
||||
cfg_if! {
|
||||
if #[cfg(unix)] {
|
||||
let e = exec::Command::new(path)
|
||||
.args(&std::env::args().collect::<Vec<String>>())
|
||||
.exec();
|
||||
if let Ok(mut guard) = exec_path.lock()
|
||||
&& let Some(path) = guard.take()
|
||||
{
|
||||
cfg_if! {
|
||||
if #[cfg(unix)] {
|
||||
let e = exec::Command::new(path)
|
||||
.args(&std::env::args().collect::<Vec<String>>())
|
||||
.exec();
|
||||
log::error!("Failed to relaunch: {e:?}");
|
||||
return ExitCode::FAILURE;
|
||||
} else {
|
||||
let result = std::process::Command::new(path)
|
||||
.args(std::env::args())
|
||||
.spawn();
|
||||
if let Err(e) = result {
|
||||
log::error!("Failed to relaunch: {e:?}");
|
||||
return ExitCode::FAILURE;
|
||||
} else {
|
||||
let result = std::process::Command::new(path)
|
||||
.args(std::env::args())
|
||||
.spawn();
|
||||
if let Err(e) = result {
|
||||
log::error!("Failed to relaunch: {e:?}");
|
||||
return ExitCode::FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,16 +185,15 @@ pub fn config_ui(
|
||||
if result.update_available {
|
||||
ui.colored_label(appearance.insert_color, "Update available");
|
||||
ui.horizontal(|ui| {
|
||||
if let Some(bin_name) = &result.found_binary {
|
||||
if ui
|
||||
if let Some(bin_name) = &result.found_binary
|
||||
&& ui
|
||||
.add_enabled(!config_state.update_running, egui::Button::new("Automatic"))
|
||||
.on_hover_text_at_pointer(
|
||||
"Automatically download and replace the current build",
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
config_state.queue_update = Some(bin_name.clone());
|
||||
}
|
||||
{
|
||||
config_state.queue_update = Some(bin_name.clone());
|
||||
}
|
||||
if ui
|
||||
.button("Manual")
|
||||
@ -329,12 +328,12 @@ pub fn config_ui(
|
||||
});
|
||||
});
|
||||
}
|
||||
if new_selected_index != selected_index {
|
||||
if let Some(idx) = new_selected_index {
|
||||
// Will set obj_changed, which will trigger a rebuild
|
||||
let config = objects[idx].clone();
|
||||
state_guard.set_selected_obj(config);
|
||||
}
|
||||
if new_selected_index != selected_index
|
||||
&& let Some(idx) = new_selected_index
|
||||
{
|
||||
// Will set obj_changed, which will trigger a rebuild
|
||||
let config = objects[idx].clone();
|
||||
state_guard.set_selected_obj(config);
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,18 +373,17 @@ fn display_unit(
|
||||
}
|
||||
|
||||
fn object_context_ui(ui: &mut egui::Ui, object: &ObjectConfig) {
|
||||
if let Some(source_path) = &object.source_path {
|
||||
if ui
|
||||
if let Some(source_path) = &object.source_path
|
||||
&& ui
|
||||
.button("Open source file")
|
||||
.on_hover_text("Open the source file in the default editor")
|
||||
.clicked()
|
||||
{
|
||||
log::info!("Opening file {source_path}");
|
||||
if let Err(e) = open::that_detached(source_path.as_str()) {
|
||||
log::error!("Failed to open source file: {e}");
|
||||
}
|
||||
ui.close();
|
||||
{
|
||||
log::info!("Opening file {source_path}");
|
||||
if let Err(e) = open::that_detached(source_path.as_str()) {
|
||||
log::error!("Failed to open source file: {e}");
|
||||
}
|
||||
ui.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -835,12 +833,11 @@ fn split_obj_config_ui(
|
||||
.add_enabled(state.project_config_info.is_none(), egui::Button::new("+").small())
|
||||
.on_disabled_hover_text(CONFIG_DISABLED_TEXT)
|
||||
.clicked()
|
||||
&& let Ok(glob) = Glob::new(&config_state.watch_pattern_text)
|
||||
{
|
||||
if let Ok(glob) = Glob::new(&config_state.watch_pattern_text) {
|
||||
state.config.watch_patterns.push(glob);
|
||||
state.watcher_change = true;
|
||||
config_state.watch_pattern_text.clear();
|
||||
}
|
||||
state.config.watch_patterns.push(glob);
|
||||
state.watcher_change = true;
|
||||
config_state.watch_pattern_text.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ pub(crate) fn data_row_ui(
|
||||
write_text(byte_text.as_str(), byte_color, &mut job, appearance.code_font.clone());
|
||||
cur_addr += 1;
|
||||
cur_addr_actual += 1;
|
||||
if cur_addr % 8 == 0 {
|
||||
if cur_addr.is_multiple_of(8) {
|
||||
write_text(" ", base_color, &mut job, appearance.code_font.clone());
|
||||
}
|
||||
}
|
||||
|
@ -128,10 +128,10 @@ pub fn diff_view_ui(
|
||||
let mut navigation = current_navigation.clone();
|
||||
if let Some((_symbol, symbol_diff, _symbol_idx)) = left_ctx.symbol {
|
||||
// If a matching symbol appears, select it
|
||||
if !right_ctx.has_symbol() {
|
||||
if let Some(target_symbol_ref) = symbol_diff.target_symbol {
|
||||
navigation.right_symbol = Some(target_symbol_ref);
|
||||
}
|
||||
if !right_ctx.has_symbol()
|
||||
&& let Some(target_symbol_ref) = symbol_diff.target_symbol
|
||||
{
|
||||
navigation.right_symbol = Some(target_symbol_ref);
|
||||
}
|
||||
} else if navigation.left_symbol.is_some()
|
||||
&& left_ctx.obj.is_some()
|
||||
@ -142,10 +142,10 @@ pub fn diff_view_ui(
|
||||
}
|
||||
if let Some((_symbol, symbol_diff, _symbol_idx)) = right_ctx.symbol {
|
||||
// If a matching symbol appears, select it
|
||||
if !left_ctx.has_symbol() {
|
||||
if let Some(target_symbol_ref) = symbol_diff.target_symbol {
|
||||
navigation.left_symbol = Some(target_symbol_ref);
|
||||
}
|
||||
if !left_ctx.has_symbol()
|
||||
&& let Some(target_symbol_ref) = symbol_diff.target_symbol
|
||||
{
|
||||
navigation.left_symbol = Some(target_symbol_ref);
|
||||
}
|
||||
} else if navigation.right_symbol.is_some()
|
||||
&& right_ctx.obj.is_some()
|
||||
@ -247,16 +247,15 @@ pub fn diff_view_ui(
|
||||
|
||||
// Third row
|
||||
if left_ctx.has_symbol() && right_ctx.has_symbol() {
|
||||
if state.current_view == View::FunctionDiff
|
||||
if (state.current_view == View::FunctionDiff
|
||||
&& ui
|
||||
.button("Change target")
|
||||
.on_hover_text_at_pointer("Choose a different symbol to use as the target")
|
||||
.clicked()
|
||||
|| hotkeys::consume_change_target_shortcut(ui.ctx())
|
||||
|| hotkeys::consume_change_target_shortcut(ui.ctx()))
|
||||
&& let Some(symbol_ref) = state.symbol_state.right_symbol.as_ref()
|
||||
{
|
||||
if let Some(symbol_ref) = state.symbol_state.right_symbol.as_ref() {
|
||||
ret = Some(DiffViewAction::SelectingLeft(symbol_ref.clone()));
|
||||
}
|
||||
ret = Some(DiffViewAction::SelectingLeft(symbol_ref.clone()));
|
||||
}
|
||||
} else if left_ctx.status.success && !left_ctx.has_symbol() {
|
||||
ui.horizontal(|ui| {
|
||||
@ -409,17 +408,16 @@ pub fn diff_view_ui(
|
||||
if needs_separator {
|
||||
ui.separator();
|
||||
}
|
||||
if ui
|
||||
if (ui
|
||||
.button("Change base")
|
||||
.on_hover_text_at_pointer(
|
||||
"Choose a different symbol to use as the base",
|
||||
)
|
||||
.clicked()
|
||||
|| hotkeys::consume_change_base_shortcut(ui.ctx())
|
||||
|| hotkeys::consume_change_base_shortcut(ui.ctx()))
|
||||
&& let Some(symbol_ref) = state.symbol_state.left_symbol.as_ref()
|
||||
{
|
||||
if let Some(symbol_ref) = state.symbol_state.left_symbol.as_ref() {
|
||||
ret = Some(DiffViewAction::SelectingRight(symbol_ref.clone()));
|
||||
}
|
||||
ret = Some(DiffViewAction::SelectingRight(symbol_ref.clone()));
|
||||
}
|
||||
}
|
||||
} else if right_ctx.status.success && !right_ctx.has_symbol() {
|
||||
@ -583,8 +581,8 @@ pub fn diff_view_ui(
|
||||
) {
|
||||
ret = Some(action);
|
||||
}
|
||||
} else if column == 1 {
|
||||
if let Some(action) = diff_col_ui(
|
||||
} else if column == 1
|
||||
&& let Some(action) = diff_col_ui(
|
||||
ui,
|
||||
state,
|
||||
appearance,
|
||||
@ -594,9 +592,9 @@ pub fn diff_view_ui(
|
||||
available_width,
|
||||
open_sections.1,
|
||||
diff_config,
|
||||
) {
|
||||
ret = Some(action);
|
||||
}
|
||||
)
|
||||
{
|
||||
ret = Some(action);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -211,19 +211,19 @@ impl DiffViewState {
|
||||
|
||||
let mut resolved_left = self.resolve_symbol(nav.left_symbol, 0);
|
||||
let mut resolved_right = self.resolve_symbol(nav.right_symbol, 1);
|
||||
if let Some(resolved_right) = &resolved_right {
|
||||
if resolved_left.is_none() {
|
||||
resolved_left = resolved_right
|
||||
.target_symbol
|
||||
.and_then(|idx| self.resolve_symbol(Some(idx), 0));
|
||||
}
|
||||
if let Some(resolved_right) = &resolved_right
|
||||
&& resolved_left.is_none()
|
||||
{
|
||||
resolved_left = resolved_right
|
||||
.target_symbol
|
||||
.and_then(|idx| self.resolve_symbol(Some(idx), 0));
|
||||
}
|
||||
if let Some(resolved_left) = &resolved_left {
|
||||
if resolved_right.is_none() {
|
||||
resolved_right = resolved_left
|
||||
.target_symbol
|
||||
.and_then(|idx| self.resolve_symbol(Some(idx), 1));
|
||||
}
|
||||
if let Some(resolved_left) = &resolved_left
|
||||
&& resolved_right.is_none()
|
||||
{
|
||||
resolved_right = resolved_left
|
||||
.target_symbol
|
||||
.and_then(|idx| self.resolve_symbol(Some(idx), 1));
|
||||
}
|
||||
let resolved_nav = resolve_navigation(nav.kind, resolved_left, resolved_right);
|
||||
if (resolved_nav.left_symbol.is_some() && resolved_nav.right_symbol.is_some())
|
||||
@ -500,16 +500,16 @@ pub fn symbol_context_menu_ui(
|
||||
ret = Some(action);
|
||||
}
|
||||
|
||||
if let Some(section) = section {
|
||||
if ui.button("Map symbol").clicked() {
|
||||
let symbol_ref = SymbolRefByName::new(symbol, Some(section));
|
||||
if column == 0 {
|
||||
ret = Some(DiffViewAction::SelectingRight(symbol_ref));
|
||||
} else {
|
||||
ret = Some(DiffViewAction::SelectingLeft(symbol_ref));
|
||||
}
|
||||
ui.close();
|
||||
if let Some(section) = section
|
||||
&& ui.button("Map symbol").clicked()
|
||||
{
|
||||
let symbol_ref = SymbolRefByName::new(symbol, Some(section));
|
||||
if column == 0 {
|
||||
ret = Some(DiffViewAction::SelectingRight(symbol_ref));
|
||||
} else {
|
||||
ret = Some(DiffViewAction::SelectingLeft(symbol_ref));
|
||||
}
|
||||
ui.close();
|
||||
}
|
||||
});
|
||||
ret
|
||||
@ -664,10 +664,10 @@ pub fn symbol_list_ui(
|
||||
let mut ret = None;
|
||||
ScrollArea::both().auto_shrink([false, false]).show(ui, |ui| {
|
||||
let mut show_mapped_symbols = state.show_mapped_symbols;
|
||||
if let SymbolFilter::Mapping(_, _) = filter {
|
||||
if ui.checkbox(&mut show_mapped_symbols, "Show mapped symbols").changed() {
|
||||
ret = Some(DiffViewAction::SetShowMappedSymbols(show_mapped_symbols));
|
||||
}
|
||||
if let SymbolFilter::Mapping(_, _) = filter
|
||||
&& ui.checkbox(&mut show_mapped_symbols, "Show mapped symbols").changed()
|
||||
{
|
||||
ret = Some(DiffViewAction::SetShowMappedSymbols(show_mapped_symbols));
|
||||
}
|
||||
let section_display = display_sections(
|
||||
ctx.obj,
|
||||
|
Loading…
x
Reference in New Issue
Block a user