From 8fe0f54f139149832a7916d80128f73cfd31e7e8 Mon Sep 17 00:00:00 2001 From: emteere <47253321+emteere@users.noreply.github.com> Date: Mon, 10 Aug 2026 18:25:06 -0400 Subject: [PATCH] GP-7023 Fix switch detection code for instructions with internal pcode branching like AARCH64 CSEL instruction. --- .../analysis/DecompilerSwitchAnalyzer.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/analysis/DecompilerSwitchAnalyzer.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/analysis/DecompilerSwitchAnalyzer.java index af699b90ab..d632172e4c 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/analysis/DecompilerSwitchAnalyzer.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/analysis/DecompilerSwitchAnalyzer.java @@ -478,7 +478,8 @@ public class DecompilerSwitchAnalyzer extends AbstractAnalyzer { // then it isn't a switch statment // // NOTE: Assumption, we have found all flows leading to the switch that might split the basic block - + // NOTE: This assumption is a problem for internal pcode branching. Need to check for that. + final AtomicInteger foundCount = new AtomicInteger(0); SymbolicPropogator prop = new SymbolicPropogator(program,false); prop.flowConstants(jumpBlockAt.getFirstStartAddress(), jumpBlockAt, @@ -493,6 +494,27 @@ public class DecompilerSwitchAnalyzer extends AbstractAnalyzer { } return false; } + + @Override + public boolean evaluateContextBefore(VarnodeContext context, Instruction instr) { + // There shouldn't be any branching because a branch would split a block + // but there could be internal branches, as the basic block algorithm can't + // detect these cases correctly. + PcodeOp[] pcode = instr.getPcode(); + for (PcodeOp pcodeOp : pcode) { + if (pcodeOp.getOpcode() == PcodeOp.CBRANCH) { + return true; + } + } + return false; + } + + @Override + public boolean followFalseConditionalBranches() { + // There shouldn't be any because a branch would split a block + // but there could be internal branches. + return false; + } }, false, monitor); // only found one reference