diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/EndInstructionValueSolver.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/EndInstructionValueSolver.java index b3d9d74227..f9211afa75 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/EndInstructionValueSolver.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/EndInstructionValueSolver.java @@ -43,6 +43,11 @@ public class EndInstructionValueSolver extends AbstractExpressionSolver hints, String description) { throw new AssertionError( "INTERNAL: Should never be asked to solve for " + AssemblyTreeResolver.INST_NEXT); + /** + * I suppose we could instead throw NeedsBackfillExcpeiton(INST_NEXT) here, too, but this + * serves as a sanity check on the SLEIGH spec. I can't think of a good reason to try to + * solve INST_NEXT == const. + */ } @Override diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/Next2InstructionValueSolver.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/Next2InstructionValueSolver.java index 48e2185250..1ada36e056 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/Next2InstructionValueSolver.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/Next2InstructionValueSolver.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.Set; import ghidra.app.plugin.assembler.sleigh.sem.*; -import ghidra.app.plugin.processors.sleigh.expression.EndInstructionValue; +import ghidra.app.plugin.processors.sleigh.expression.Next2InstructionValue; /** * "Solves" expressions of {@code inst_next2} @@ -32,21 +32,22 @@ import ghidra.app.plugin.processors.sleigh.expression.EndInstructionValue; * NOTE: This solver requires backfill, since the value of {@code inst_next2} is not known * until possible prefixes have been considered. */ -public class Next2InstructionValueSolver extends AbstractExpressionSolver { +public class Next2InstructionValueSolver extends AbstractExpressionSolver { public Next2InstructionValueSolver() { - super(EndInstructionValue.class); + super(Next2InstructionValue.class); } @Override - public AssemblyResolution solve(EndInstructionValue iv, MaskedLong goal, Map vals, + public AssemblyResolution solve(Next2InstructionValue iv, MaskedLong goal, + Map vals, AssemblyResolvedPatterns cur, Set hints, String description) { throw new AssertionError( "INTERNAL: Should never be asked to solve for " + AssemblyTreeResolver.INST_NEXT2); } @Override - public MaskedLong getValue(EndInstructionValue iv, Map vals, + public MaskedLong getValue(Next2InstructionValue iv, Map vals, AssemblyResolvedPatterns cur) throws NeedsBackfillException { Long instNext = vals.get(AssemblyTreeResolver.INST_NEXT2); if (instNext == null) { @@ -56,12 +57,12 @@ public class Next2InstructionValueSolver extends AbstractExpressionSolver vals, + public MaskedLong valueForResolution(Next2InstructionValue exp, Map vals, AssemblyResolvedPatterns rc) { Long instNext = vals.get(AssemblyTreeResolver.INST_NEXT2); if (instNext == null) { diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/ARMAssemblyTest.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/ARMAssemblyTest.java index b4c5f1eb52..9d4a6ea3c3 100644 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/ARMAssemblyTest.java +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/ARMAssemblyTest.java @@ -121,4 +121,19 @@ public class ARMAssemblyTest extends AbstractAssemblyTest { assertOneCompatRestExact("vmov.i64 d0,simdExpand(0x1,0xe,0xb1)", "83:ff:31:0e", THUMB, 0x00010100, "vmov.i64 d0,simdExpand(0x1,0xe,0xb1)"); } + + @Test + public void testAssemble_T_tbb_mr0_r1() { + assertOneCompatRestExact("tbb [r0, r1]", "d0:e8:01:f0", THUMB, 0x00400000, "tbb [r0,r1]"); + } + + @Test + public void testAssemble_T_tbb_mpc_r0() { + assertOneCompatRestExact("tbb [pc, r1]", "df:e8:01:f0", THUMB, 0x00400000, "tbb [pc,r1]"); + } + + @Test + public void testAssemble_T_tbb_m0_r0() { + assertAllSyntaxErrors("tbb [0, r0]"); + } } diff --git a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc index 85dad7d02b..bebb3ea0e9 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc @@ -4764,13 +4764,13 @@ thumbEndianNess: "BE" is op0=0xb658 { export 1:1; } goto [pc]; } -Pcrel: [cloc,Rm0003] is Rm0003 & thc0404=0 [ cloc = inst_next; ] +Pcrel: [pc,Rm0003] is Rm0003 & thc0404=0 & pc { - local tmp = Rm0003; tmp = cloc + tmp; val:1 = *tmp; tmp = zext(val); export tmp; + local tmp = Rm0003; tmp = inst_next + tmp; val:1 = *tmp; tmp = zext(val); export tmp; } -Pcrel: [cloc,Rm0003] is Rm0003 & thc0404=1 [ cloc = inst_next; ] +Pcrel: [pc,Rm0003] is Rm0003 & thc0404=1 & pc { - local tmp = Rm0003; tmp = cloc + (tmp * 2); val:2 = *tmp; tmp = zext(val); export tmp; + local tmp = Rm0003; tmp = inst_next + (tmp * 2); val:2 = *tmp; tmp = zext(val); export tmp; } :tbb^ItCond Pcrel is TMode=1 & ItCond & op4=0xe8d & thc0003=15; op8=0xf0 & thc0507=0 & thc0404=0 & Pcrel