diff --git a/Ghidra/Debug/Debugger/ghidra_scripts/DebuggerEmuExampleScript.java b/Ghidra/Debug/Debugger/ghidra_scripts/DebuggerEmuExampleScript.java index 98d136fc60..916fa7567f 100644 --- a/Ghidra/Debug/Debugger/ghidra_scripts/DebuggerEmuExampleScript.java +++ b/Ghidra/Debug/Debugger/ghidra_scripts/DebuggerEmuExampleScript.java @@ -24,7 +24,6 @@ //@toolbar import java.nio.charset.Charset; -import java.util.List; import ghidra.app.plugin.assembler.Assembler; import ghidra.app.plugin.assembler.Assemblers; @@ -149,9 +148,10 @@ public class DebuggerEmuExampleScript extends GhidraScript { * Inject a call to our custom print userop. Otherwise, the language itself will never * invoke it. */ - emulator.inject(injectHere, List.of( - "print_utf8(RCX);", - "emu_exec_decoded();")); + emulator.inject(injectHere, """ + print_utf8(RCX); + emu_exec_decoded(); + """); /* * Run the experiment: This should interrupt on the second SYSCALL, because any value other diff --git a/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneEmuExampleScript.java b/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneEmuExampleScript.java index cbcecf9a34..92d2a0e968 100644 --- a/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneEmuExampleScript.java +++ b/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneEmuExampleScript.java @@ -22,7 +22,6 @@ //@toolbar import java.nio.charset.Charset; -import java.util.List; import ghidra.app.plugin.assembler.*; import ghidra.app.plugin.processors.sleigh.SleighLanguage; @@ -102,10 +101,10 @@ public class StandAloneEmuExampleScript extends GhidraScript { */ byte[] hw = "Hello, World!\n".getBytes(UTF8); emulator.getSharedState().setVar(dyn, 0xdeadbeefL, hw.length, true, hw); - PcodeProgram init = SleighProgramCompiler.compileProgram(language, "init", List.of( - "RIP = 0x" + entry + ";", - "RSP = 0x00001000;"), - library); + PcodeProgram init = SleighProgramCompiler.compileProgram(language, "init", String.format(""" + RIP = 0x%s; + RSP = 0x00001000; + """, entry), library); thread.getExecutor().execute(init, library); thread.overrideContextWithDefault(); thread.reInitialize(); @@ -114,9 +113,10 @@ public class StandAloneEmuExampleScript extends GhidraScript { * Inject a call to our custom print userop. Otherwise, the language itself will never * invoke it. */ - emulator.inject(injectHere, List.of( - "print_utf8(RCX);", - "emu_exec_decoded();")); + emulator.inject(injectHere, """ + print_utf8(RCX); + emu_exec_decoded(); + """); /* * Run the experiment: This should interrupt on the second SYSCALL, because any value other diff --git a/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneStructuredSleighScript.java b/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneStructuredSleighScript.java index c0f7963622..17becfef78 100644 --- a/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneStructuredSleighScript.java +++ b/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneStructuredSleighScript.java @@ -103,9 +103,7 @@ public class StandAloneStructuredSleighScript extends GhidraScript { print(userop.getName() + "("); print(userop.getInputs().stream().collect(Collectors.joining(","))); print(") {\n"); - for (String line : userop.getLines()) { - print(line); - } + print(userop.getBody()); print("}\n\n"); } } diff --git a/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneSyscallEmuExampleScript.java b/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneSyscallEmuExampleScript.java index 3c5fa8e464..c8c10eae58 100644 --- a/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneSyscallEmuExampleScript.java +++ b/Ghidra/Debug/Debugger/ghidra_scripts/StandAloneSyscallEmuExampleScript.java @@ -22,7 +22,6 @@ //@toolbar import java.nio.charset.Charset; -import java.util.List; import ghidra.app.plugin.assembler.Assembler; import ghidra.app.plugin.assembler.Assemblers; @@ -184,10 +183,11 @@ public class StandAloneSyscallEmuExampleScript extends GhidraScript { /* * Initialize the thread */ - PcodeProgram init = SleighProgramCompiler.compileProgram(language, "init", List.of( - "RIP = 0x" + entry + ";", - "RSP = 0x00001000;"), - library); + PcodeProgram init = + SleighProgramCompiler.compileProgram(language, "init", String.format(""" + RIP = 0x%s; + RSP = 0x00001000; + """, entry), library); thread.getExecutor().execute(init, library); thread.overrideContextWithDefault(); thread.reInitialize(); diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperPluginScreenShots.java index 36da1cfdf6..bd4be62d2e 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperPluginScreenShots.java @@ -69,8 +69,10 @@ public class DebuggerPcodeStepperPluginScreenShots extends GhidraScreenShotGener PcodeExecutor exe = TraceSleighUtils.buildByteExecutor(tb.trace, snap0, thread, 0); - exe.executeSleighLine("RIP = 0x00400000"); - exe.executeSleighLine("RSP = 0x0010fff8"); + exe.executeSleigh(""" + RIP = 0x00400000; + RSP = 0x0010fff8; + """); Assembler asm = Assemblers.getAssembler(tb.trace.getFixedProgramView(snap0)); asm.assemble(tb.addr(0x00400000), "SUB RSP,0x40"); diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesPluginScreenShots.java index 3b2c331a66..0debdde11c 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesPluginScreenShots.java @@ -69,14 +69,18 @@ public class DebuggerWatchesPluginScreenShots extends GhidraScreenShotGenerator PcodeExecutor executor0 = TraceSleighUtils.buildByteExecutor(tb.trace, snap0, thread, 0); - executor0.executeSleighLine("RSP = 0x7ffefff8"); - executor0.executeSleighLine("*:4 (RSP+8) = 0x4030201"); + executor0.executeSleigh(""" + RSP = 0x7ffefff8; + *:4 (RSP+8) = 0x4030201; + """); PcodeExecutor executor1 = TraceSleighUtils.buildByteExecutor(tb.trace, snap1, thread, 0); - executor1.executeSleighLine("RSP = 0x7ffefff8"); - executor1.executeSleighLine("*:4 (RSP+8) = 0x1020304"); - executor1.executeSleighLine("*:4 0x7fff0004:8 = 0x4A9A70C8"); + executor1.executeSleigh(""" + RSP = 0x7ffefff8; + *:4 (RSP+8) = 0x1020304; + *:4 0x7fff0004:8 = 0x4A9A70C8; + """); } watchesProvider.addWatch("RSP"); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginTest.java index 6b9105e5aa..fbdbbda177 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginTest.java @@ -134,11 +134,12 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu }); } - protected TraceRecorder addMappedBreakpointOpenAndWait() throws Exception { + protected TraceRecorder addMappedBreakpointOpenAndWait() throws Throwable { createTestModel(); mb.createTestProcessesAndThreads(); TraceRecorder recorder = modelService.recordTarget(mb.testProcess1, createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC); + waitRecorder(recorder); Trace trace = recorder.getTrace(); createProgramFromTrace(trace); intoProject(trace); @@ -260,7 +261,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu Set.of("SW_EXECUTE", "HW_EXECUTE", "READ,WRITE", "READ", "WRITE"); @Test - public void testProgramNoBreakPopupMenus() throws Exception { + public void testProgramNoBreakPopupMenus() throws Throwable { // NOTE: Need a target to have any breakpoint actions, even on programs addMappedBreakpointOpenAndWait(); @@ -276,7 +277,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testTraceNoBreakPopupMenus() throws Exception { + public void testTraceNoBreakPopupMenus() throws Throwable { TraceRecorder recorder = addMappedBreakpointOpenAndWait(); Trace trace = recorder.getTrace(); traceManager.activateTrace(trace); @@ -414,7 +415,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu @Test public void testActionToggleBreakpointProgramWithNoCurrentBreakpointOnInstruction() - throws Exception { + throws Throwable { addMappedBreakpointOpenAndWait(); // wasteful, but whatever for (LogicalBreakpoint lb : List.copyOf(breakpointService.getAllBreakpoints())) { lb.delete(); @@ -442,7 +443,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testActionToggleBreakpointProgramWithNoCurrentBreakpointOnData() throws Exception { + public void testActionToggleBreakpointProgramWithNoCurrentBreakpointOnData() throws Throwable { addMappedBreakpointOpenAndWait(); // wasteful, but whatever for (LogicalBreakpoint lb : List.copyOf(breakpointService.getAllBreakpoints())) { lb.delete(); @@ -470,7 +471,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testActionToggleBreakpointProgram() throws Exception { + public void testActionToggleBreakpointProgram() throws Throwable { addMappedBreakpointOpenAndWait(); LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints()); @@ -486,7 +487,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testActionToggleBreakpointTrace() throws Exception { + public void testActionToggleBreakpointTrace() throws Throwable { TraceRecorder recorder = addMappedBreakpointOpenAndWait(); Trace trace = recorder.getTrace(); LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints()); @@ -527,14 +528,16 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } protected void testActionSetBreakpointProgram(DockingAction action, - Set expectedKinds) throws Exception { + Set expectedKinds) throws Throwable { addMappedBreakpointOpenAndWait(); // Adds an unneeded breakpoint. Aw well. performAction(action, staticCtx(addr(program, 0x0400321)), false); DebuggerPlaceBreakpointDialog dialog = waitForDialogComponent(DebuggerPlaceBreakpointDialog.class); - dialog.setName("Test name"); - runSwing(() -> dialog.okCallback()); + runSwing(() -> { + dialog.setName("Test name"); + dialog.okCallback(); + }); waitForPass(() -> { LogicalBreakpoint lb = Unique.assertOne( @@ -546,7 +549,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } protected void testActionSetBreakpointTrace(DockingAction action, - Set expectedKinds) throws Exception { + Set expectedKinds) throws Throwable { TraceRecorder recorder = addMappedBreakpointOpenAndWait(); // Adds an unneeded breakpoint. Aw well. Trace trace = recorder.getTrace(); @@ -568,67 +571,67 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testActionSetSoftwareBreakpointProgram() throws Exception { + public void testActionSetSoftwareBreakpointProgram() throws Throwable { testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetSoftwareBreakpoint, Set.of(TraceBreakpointKind.SW_EXECUTE)); } @Test - public void testActionSetSoftwareBreakpointTrace() throws Exception { + public void testActionSetSoftwareBreakpointTrace() throws Throwable { testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetSoftwareBreakpoint, Set.of(TraceBreakpointKind.SW_EXECUTE)); } @Test - public void testActionSetExecuteBreakpointProgram() throws Exception { + public void testActionSetExecuteBreakpointProgram() throws Throwable { testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetExecuteBreakpoint, Set.of(TraceBreakpointKind.HW_EXECUTE)); } @Test - public void testActionSetExecuteBreakpointTrace() throws Exception { + public void testActionSetExecuteBreakpointTrace() throws Throwable { testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetExecuteBreakpoint, Set.of(TraceBreakpointKind.HW_EXECUTE)); } @Test - public void testActionSetReadWriteBreakpointProgram() throws Exception { + public void testActionSetReadWriteBreakpointProgram() throws Throwable { testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetReadWriteBreakpoint, Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE)); } @Test - public void testActionSetReadWriteBreakpointTrace() throws Exception { + public void testActionSetReadWriteBreakpointTrace() throws Throwable { testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetReadWriteBreakpoint, Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE)); } @Test - public void testActionSetReadBreakpointProgram() throws Exception { + public void testActionSetReadBreakpointProgram() throws Throwable { testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetReadBreakpoint, Set.of(TraceBreakpointKind.READ)); } @Test - public void testActionSetReadBreakpointTrace() throws Exception { + public void testActionSetReadBreakpointTrace() throws Throwable { testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetReadBreakpoint, Set.of(TraceBreakpointKind.READ)); } @Test - public void testActionSetWriteBreakpointProgram() throws Exception { + public void testActionSetWriteBreakpointProgram() throws Throwable { testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetWriteBreakpoint, Set.of(TraceBreakpointKind.WRITE)); } @Test - public void testActionSetWriteBreakpointTrace() throws Exception { + public void testActionSetWriteBreakpointTrace() throws Throwable { testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetWriteBreakpoint, Set.of(TraceBreakpointKind.WRITE)); } @Test - public void testActionEnableBreakpointProgram() throws Exception { + public void testActionEnableBreakpointProgram() throws Throwable { addMappedBreakpointOpenAndWait(); LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints()); lb.disable(); @@ -641,7 +644,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testActionEnableBreakpointTrace() throws Exception { + public void testActionEnableBreakpointTrace() throws Throwable { TraceRecorder recorder = addMappedBreakpointOpenAndWait(); Trace trace = recorder.getTrace(); LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints()); @@ -656,7 +659,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testActionDisableBreakpointProgram() throws Exception { + public void testActionDisableBreakpointProgram() throws Throwable { addMappedBreakpointOpenAndWait(); LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints()); @@ -667,7 +670,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testActionDisableBreakpointTrace() throws Exception { + public void testActionDisableBreakpointTrace() throws Throwable { TraceRecorder recorder = addMappedBreakpointOpenAndWait(); Trace trace = recorder.getTrace(); LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints()); @@ -680,7 +683,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testActionClearBreakpointProgram() throws Exception { + public void testActionClearBreakpointProgram() throws Throwable { addMappedBreakpointOpenAndWait(); performAction(breakpointMarkerPlugin.actionClearBreakpoint, @@ -690,7 +693,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu } @Test - public void testActionClearBreakpointTrace() throws Exception { + public void testActionClearBreakpointTrace() throws Throwable { TraceRecorder recorder = addMappedBreakpointOpenAndWait(); Trace trace = recorder.getTrace(); LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints()); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java index a1c9e461e0..941b6ab668 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java @@ -1269,7 +1269,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI .createRegion(".text", 0, tb.range(0x00400000, 0x0040ffff), TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE); thread1 = tb.getOrAddThread("Thread1", 0); - tb.exec(0, 0, thread1, java.util.List.of("RIP = 0x00400000;")); + tb.exec(0, 0, thread1, "RIP = 0x00400000;"); } TraceThread thread2; @@ -1279,7 +1279,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI .createRegion(".text", 0, tb2.range(0x200, 0x3ff), TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE); thread2 = tb2.getOrAddThread("Thread2", 0); - tb2.exec(0, 0, thread2, java.util.List.of("PC = 0x100;")); + tb2.exec(0, 0, thread2, "PC = 0x100;"); } traceManager.openTrace(tb.trace); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProviderTest.java index f2e332e935..77f679f1ad 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProviderTest.java @@ -82,7 +82,7 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg thread = tb.getOrAddThread("1", 0); PcodeExecutor init = TraceSleighUtils.buildByteExecutor(tb.trace, 0, thread, 0); - init.executeSleighLine("pc = 0x00400000"); + init.executeSleigh("pc = 0x00400000;"); Assembler asm = Assemblers.getAssembler(tb.trace.getFixedProgramView(0)); iit = asm.assemble(start, @@ -166,7 +166,7 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg .anyMatch(r -> r.getCode().contains("emu_swi")))); } - protected List format(List sleigh) { + protected List format(String sleigh) { SleighLanguage language = (SleighLanguage) getToyBE64Language(); PcodeProgram prog = SleighProgramCompiler.compileProgram(language, "test", sleigh, PcodeUseropLibrary.nil()); @@ -179,7 +179,7 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg @Test public void testPcodeFormatterSimple() { - List rows = format(List.of("r0 = 1;")); + List rows = format("r0 = 1;"); assertEquals(2, rows.size()); assertEquals("", rows.get(0).getLabel()); assertEquals(FallthroughPcodeRow.class, rows.get(1).getClass()); @@ -187,9 +187,10 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg @Test public void testPcodeFormatterStartsLabel() { - List rows = format(List.of( - " r0 = 1;", - "goto ;")); + List rows = format(""" + r0 = 1; + goto ; + """); assertEquals(3, rows.size()); assertEquals("<0>", rows.get(0).getLabel()); assertEquals("", rows.get(1).getLabel()); @@ -198,10 +199,11 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg @Test public void testPcodeFormatterMiddleLabel() { - List rows = format(List.of( - "if 1:1 goto ;", - "r0 = 1;", - " r1 = 2;")); + List rows = format(""" + if 1:1 goto ; + r0 = 1; + r1 = 2; + """); assertEquals(4, rows.size()); assertEquals("", rows.get(0).getLabel()); assertEquals("", rows.get(1).getLabel()); @@ -211,10 +213,11 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg @Test public void testPcodeFormatterFallthroughLabel() { - List rows = format(List.of( - "if 1:1 goto ;", - "r0 = 1;", - "")); + List rows = format(""" + if 1:1 goto ; + r0 = 1; + + """); assertEquals(3, rows.size()); assertEquals("", rows.get(0).getLabel()); assertEquals("", rows.get(1).getLabel()); @@ -224,12 +227,13 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg @Test public void testPcodeFormatterManyLabel() { - List rows = format(List.of( - " goto ;", - " goto ;", - " goto ;", - "goto ;", - "")); + List rows = format(""" + goto ; + goto ; + goto ; + goto ; + + """); assertEquals(5, rows.size()); // NB. templates number labels in order of appearance in BRANCHes assertEquals("<3>", rows.get(0).getLabel()); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java index 2dca96d66e..a479520dfe 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java @@ -469,7 +469,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG TraceThread thread = addThread(); try (UndoableTransaction tid = tb.startTransaction()) { - tb.exec(0, 0, thread, List.of("pc = 100;")); + tb.exec(0, 0, thread, "pc = 100;"); } traceManager.activateThread(thread); waitForSwing(); @@ -800,10 +800,11 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG modelData.stream().filter(r -> r.getRegister() == pc).findFirst().orElse(null); assertNotNull(pcAvail); - pcAvail.setSelected(false); - dialog.availableTableModel.fireTableDataChanged(); - dialog.okCallback(); - waitForSwing(); + runSwing(() -> { + pcAvail.setSelected(false); + dialog.availableTableModel.fireTableDataChanged(); + dialog.okCallback(); + }); assertNull(getRegisterRow(pc)); assertTrue(registersProvider.actionSelectRegisters.isEnabled()); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/editing/DebuggerStateEditingServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/editing/DebuggerStateEditingServiceTest.java index 1e36efff9f..92d086de3d 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/editing/DebuggerStateEditingServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/editing/DebuggerStateEditingServiceTest.java @@ -148,7 +148,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge Assembler asm = Assemblers.getAssembler(tb.trace.getFixedProgramView(0)); asm.assemble(tb.addr(0x00400000), "imm r0,#123"); - executor.executeSleighLine("pc = 0x00400000"); + executor.executeSleigh("pc = 0x00400000;"); } traceManager.activateTrace(tb.trace); editingService.setCurrentMode(tb.trace, StateEditingMode.WRITE_EMULATOR); @@ -186,7 +186,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge Assembler asm = Assemblers.getAssembler(tb.trace.getFixedProgramView(0)); asm.assemble(tb.addr(0x00400000), "imm r0,#123"); - executor.executeSleighLine("pc = 0x00400000"); + executor.executeSleigh("pc = 0x00400000;"); } traceManager.activateTrace(tb.trace); editingService.setCurrentMode(tb.trace, StateEditingMode.WRITE_EMULATOR); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java index e5fd7d20f3..643ab26953 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java @@ -337,7 +337,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge } @Test - public void testAutoActivatePresent() throws Exception { + public void testAutoActivatePresent() throws Throwable { assertTrue(traceManager.isAutoActivatePresent()); createTestModel(); @@ -345,6 +345,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge TraceRecorder recorder = modelService.recordTarget(mb.testProcess1, createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC); + waitRecorder(recorder); Trace trace = recorder.getTrace(); traceManager.openTrace(trace); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecTest.java index 02a498ac48..c74c232d0e 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecTest.java @@ -18,7 +18,6 @@ package ghidra.pcode.exec; import static org.junit.Assert.*; import java.math.BigInteger; -import java.util.List; import java.util.Map; import org.junit.Test; @@ -29,7 +28,6 @@ import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.services.ActionSource; import ghidra.app.services.TraceRecorder; import ghidra.dbg.model.TestTargetRegisterBankInThread; -import ghidra.pcode.exec.*; import ghidra.pcode.utils.Utils; import ghidra.program.model.lang.Register; import ghidra.trace.model.Trace; @@ -100,7 +98,7 @@ public class TraceRecorderAsyncPcodeExecTest extends AbstractGhidraHeadedDebugge SleighLanguage language = (SleighLanguage) trace.getBaseLanguage(); PcodeProgram prog = SleighProgramCompiler.compileProgram(language, "test", - List.of("r2 = r0 + r1;"), PcodeUseropLibrary.NIL); + "r2 = r0 + r1;", PcodeUseropLibrary.NIL); Register r0 = language.getRegister("r0"); Register r1 = language.getRegister("r1"); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/PatchStep.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/PatchStep.java index 6dd5d8087a..395847e676 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/PatchStep.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/PatchStep.java @@ -314,7 +314,7 @@ public class PatchStep implements Step { @Override public void execute(PcodeThread emuThread, Stepper stepper, TaskMonitor monitor) throws CancelledException { - PcodeProgram prog = emuThread.getMachine().compileSleigh("schedule", List.of(sleigh + ";")); + PcodeProgram prog = emuThread.getMachine().compileSleigh("schedule", sleigh + ";"); emuThread.getExecutor().execute(prog, emuThread.getUseropLibrary()); } @@ -368,7 +368,7 @@ public class PatchStep implements Step { protected Map getPatches(Language language) { PcodeProgram prog = SleighProgramCompiler.compileProgram((SleighLanguage) language, - "schedule", List.of(sleigh + ";"), PcodeUseropLibrary.nil()); + "schedule", sleigh + ";", PcodeUseropLibrary.nil()); // SemisparseArray is a bit overkill, no? Map result = new TreeMap<>(); for (PcodeOp op : prog.getCode()) { diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/AbstractTracePcodeEmulatorTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/AbstractTracePcodeEmulatorTest.java index ca921f02a8..239b7b6707 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/AbstractTracePcodeEmulatorTest.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/AbstractTracePcodeEmulatorTest.java @@ -35,7 +35,7 @@ import ghidra.util.database.UndoableTransaction; public class AbstractTracePcodeEmulatorTest extends AbstractGhidraHeadlessIntegrationTest { - public TraceThread initTrace(ToyDBTraceBuilder tb, List stateInit, + public TraceThread initTrace(ToyDBTraceBuilder tb, String stateInit, List assembly) throws Throwable { return initTrace(tb, tb.range(0x00400000, 0x0040ffff), tb.range(0x00100000, 0x0010ffff), stateInit, assembly); @@ -53,14 +53,13 @@ public class AbstractTracePcodeEmulatorTest extends AbstractGhidraHeadlessIntegr * memory where it was assembled. * * @param tb the trace builder - * @param stateInit SLEIGH source lines to execute to initialize the trace state before - * emulation. Each line must end with ";" + * @param stateInit Sleigh source to execute to initialize the trace state before emulation * @param assembly lines of assembly to place starting at {@code 0x00400000} * @return a new trace thread, whose register state is initialized as specified * @throws Throwable if anything goes wrong */ public TraceThread initTrace(ToyDBTraceBuilder tb, AddressRange text, AddressRange stack, - List stateInit, List assembly) throws Throwable { + String stateInit, List assembly) throws Throwable { TraceMemoryManager mm = tb.trace.getMemoryManager(); TraceThread thread; try (UndoableTransaction tid = tb.startTransaction()) { diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/BytesTracePcodeEmulatorTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/BytesTracePcodeEmulatorTest.java index 253aa1b6ee..a106edc799 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/BytesTracePcodeEmulatorTest.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/BytesTracePcodeEmulatorTest.java @@ -54,10 +54,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testSinglePUSH() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + """, List.of( "PUSH 0xdeadbeef")); @@ -94,10 +94,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testDoublePUSH() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + """, List.of( "PUSH 0xdeadbeef", "PUSH 0xbaadf00d")); @@ -133,11 +133,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { Register pc = tb.language.getProgramCounter(); - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;", - "RAX = 0x12345678;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + RAX = 0x12345678; + """, List.of( "JMP 0x00400007", // 2 bytes "MOV EAX,0xdeadbeef", // 5 bytes @@ -189,11 +189,12 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest AssemblyPatternBlock thumbPat = AssemblyPatternBlock.fromRegisterValue(thumbCtx); // NOTE: Assemble the thumb section separately - TraceThread thread = initTrace(tb, - List.of( - "pc = 0x00400000;", - "sp = 0x00110000;", - "*:4 0x00400008:4 = 0x00401001;"), // immediately after bx + // write 0x00401001 immediately after bx (0x00400008) + TraceThread thread = initTrace(tb, """ + pc = 0x00400000; + sp = 0x00110000; + *:4 0x00400008:4 = 0x00401001; + """, List.of( "ldr r6, [pc,#0]!", // 4 bytes, pc+4 should be 00400008 "bx r6")); // 4 bytes @@ -241,10 +242,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "Toy:BE:64:default")) { assertEquals(Register.NO_CONTEXT, tb.language.getContextBaseRegister()); - TraceThread thread = initTrace(tb, - List.of( - "pc = 0x00400000;", - "sp = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + pc = 0x00400000; + sp = 0x00110000; + """, List.of( "imm r0, #911")); // decimal @@ -272,10 +273,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testBRDS() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "Toy:BE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "pc = 0x00400000;", - "sp = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + pc = 0x00400000; + sp = 0x00110000; + """, List.of( "brds 0x00400006", "imm r0, #911", // decimal @@ -314,13 +315,13 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testSelfModifyingX86() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;", - "RAX = 0x12345678;", - // NB. Assembly actually happens first, so this is modifying - "*:1 0x00400007:8 = *0x00400007:8 ^ 0xcc;"), + // NB. Assembly actually happens first, so Sleigh will modify it + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + RAX = 0x12345678; + *:1 0x00400007:8 = *0x00400007:8 ^ 0xcc; + """, List.of( // First instruction undoes the modification above "XOR byte ptr [0x00400007], 0xcc", // 7 bytes @@ -356,10 +357,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testDoublePUSH_pCode() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + """, List.of( "PUSH 0xdeadbeef", "PUSH 0xbaadf00d")); @@ -424,10 +425,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest dumped.append(NumericUtilities.convertBytesToString(in)); } }; - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + """, List.of( "PUSH 0xdeadbeef", "PUSH 0xbaadf00d")); @@ -438,7 +439,7 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest return hexLib; } }; - emu.inject(tb.addr(0x00400006), List.of("hexdump(RSP);")); + emu.inject(tb.addr(0x00400006), "hexdump(RSP);"); PcodeThread emuThread = emu.newThread(thread.getPath()); emuThread.overrideContextWithDefault(); @@ -472,10 +473,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest dumped.append(NumericUtilities.convertBytesToString(in)); } }; - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + """, List.of( "PUSH 0xdeadbeef", "PUSH 0xbaadf00d")); @@ -486,12 +487,13 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest return hexLib; } }; - emu.inject(tb.addr(0x00400006), List.of( - "hexdump(RSP);", - "emu_swi();", - "hexdump(RIP);", - "emu_exec_decoded();", - "hexdump(RIP);")); + emu.inject(tb.addr(0x00400006), """ + hexdump(RSP); + emu_swi(); + hexdump(RIP); + emu_exec_decoded(); + hexdump(RIP); + """); PcodeThread emuThread = emu.newThread(thread.getPath()); emuThread.overrideContextWithDefault(); @@ -527,11 +529,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testBreakpoints() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;", - "RAX = 0;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + RAX = 0; + """, List.of( "PUSH 0xdeadbeef", "PUSH 0xbaadf00d")); @@ -561,11 +563,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testCLZ() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "ARM:LE:32:v8")) { - TraceThread thread = initTrace(tb, - List.of( - "pc = 0x00400000;", - "sp = 0x00110000;", - "r0 = 0x00008000;"), + TraceThread thread = initTrace(tb, """ + pc = 0x00400000; + sp = 0x00110000; + r0 = 0x00008000; + """, List.of( "clz r1, r0")); @@ -594,12 +596,12 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { Register pc = tb.language.getProgramCounter(); - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;", - "*:8 0x00600008:8 = 0x0123456789abcdef;", // LE - "*:8 0x00600000:8 = 0xfedcba9876543210;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + *:8 0x00600008:8 = 0x0123456789abcdef; + *:8 0x00600000:8 = 0xfedcba9876543210; + """, List.of( "MOVAPS XMM0, xmmword ptr [0x00600000]")); @@ -632,12 +634,12 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { Register pc = tb.language.getProgramCounter(); - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;", - "RAX = 0x7fffffff;", - "RCX = 4;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + RAX = 0x7fffffff; + RCX = 4; + """, List.of( "SAR EAX, CL")); @@ -662,11 +664,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testCachedReadAfterSmallWrite() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;", - "RAX = 0x12345678;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + RAX = 0x12345678; + """, List.of( "XOR AH, AH", "MOV RCX, RAX")); @@ -689,9 +691,9 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test(expected = AccessPcodeExecutionException.class) public void testCheckedMOV_err() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + """, List.of( "MOV RCX,RAX")); @@ -711,10 +713,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testCheckedMOV_known() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RAX = 0x1234;"), // Make it known in the trace + // Make RAX known in the trace + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RAX = 0x1234; + """, List.of( "MOV RCX,RAX")); @@ -735,10 +738,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test(expected = AccessPcodeExecutionException.class) public void testCheckedMOV_knownPast_err() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RAX = 0x1234;"), // Make it known in the trace + // Make RAX known in the trace + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RAX = 0x1234; + """, List.of( "MOV RCX,RAX")); @@ -760,10 +764,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testCheckedMOV_knownPast_has() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RAX = 0x1234;"), // Make it known in the trace + // Make RAX known in the trace + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RAX = 0x1234; + """, List.of( "MOV RCX,RAX")); @@ -785,9 +790,9 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testCheckedMOV_initialized() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + """, List.of( "MOV RAX,0", // Have the program initialize it "MOV RCX,RAX")); @@ -820,11 +825,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest ctxManager.setValue(lang, ctxVal, Range.atLeast(0L), tb.range(0x00400000, 0x00400002)); } - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;", - "RAX = 0xff12345678;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + RAX = 0xff12345678; + """, List.of( "DEC EAX", "MOV ECX,EAX")); @@ -863,11 +868,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testMOV_EAX_dword_RBPm4() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;", - "*:4 (0:8-4) = 0x12345678;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + *:4 (0:8-4) = 0x12345678; + """, List.of( "MOV EAX, dword ptr [RBP + -0x4]")); @@ -898,10 +903,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test(expected = PcodeExecutionException.class) public void testMOV_EAX_dword_RBPm2_x64() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;", - "RSP = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + RSP = 0x00110000; + """, List.of( "MOV EAX, dword ptr [RBP + -0x2]")); @@ -921,10 +926,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test(expected = PcodeExecutionException.class) public void testMOV_EAX_dword_EBPm2_x86() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:32:default")) { - TraceThread thread = initTrace(tb, - List.of( - "EIP = 0x00400000;", - "ESP = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + EIP = 0x00400000; + ESP = 0x00110000; + """, List.of( "MOV EAX, dword ptr [EBP + -0x2]")); @@ -944,10 +949,10 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "Toy:BE:64:default")) { assertEquals(Register.NO_CONTEXT, tb.language.getContextBaseRegister()); - TraceThread thread = initTrace(tb, - List.of( - "pc = 0x00400000;", - "sp = 0x00110000;"), + TraceThread thread = initTrace(tb, """ + pc = 0x00400000; + sp = 0x00110000; + """, List.of( "unimpl")); @@ -966,11 +971,11 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest Address stackStart = tb.language.getDefaultDataSpace().getAddress(0, true); TraceThread thread = initTrace(tb, new AddressRangeImpl(textStart, 0x200), - new AddressRangeImpl(stackStart, 1), - List.of( - "PC = 0x000100;", - "W1 = 0x0800;", - "*[ram]:2 0x000800:3 = 0x1234;"), + new AddressRangeImpl(stackStart, 1), """ + PC = 0x000100; + W1 = 0x0800; + *[ram]:2 0x000800:3 = 0x1234; + """, List.of( "mov.w [W1], W0")); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/TraceSleighUtilsTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/TraceSleighUtilsTest.java index 3b253d4438..4e411ae10e 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/TraceSleighUtilsTest.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/TraceSleighUtilsTest.java @@ -19,7 +19,6 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import java.math.BigInteger; -import java.util.List; import java.util.Map; import org.junit.Before; @@ -207,14 +206,14 @@ public class TraceSleighUtilsTest extends AbstractGhidraHeadlessIntegrationTest public void testCompileSleighProgram() throws Exception { try (ToyDBTraceBuilder b = new ToyDBTraceBuilder("test", TOY_BE_64_HARVARD)) { PcodeProgram sp = SleighProgramCompiler.compileProgram((SleighLanguage) b.language, - "test", List.of( - "if (r0) goto ;", - " r1 = 6;", - " goto ;", - "", - " r1 = 7;", - ""), - PcodeUseropLibrary.NIL); + "test", """ + if (r0) goto ; + r1 = 6; + goto ; + + r1 = 7; + + """, PcodeUseropLibrary.NIL); TraceThread thread; try (UndoableTransaction tid = b.startTransaction()) { thread = b.getOrAddThread("Thread1", 0); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/ToyDBTraceBuilder.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/ToyDBTraceBuilder.java index c30e8a4aa8..98340dae4e 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/ToyDBTraceBuilder.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/ToyDBTraceBuilder.java @@ -27,7 +27,6 @@ import java.nio.charset.CharsetEncoder; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; -import java.util.List; import com.google.common.collect.Range; @@ -131,9 +130,9 @@ public class ToyDBTraceBuilder implements AutoCloseable { * @param snap the snap to modify * @param frame the frame to modify * @param thread the thread to modify, can be {@code null} if only memory is used - * @param sleigh the lines of Sleigh, including semicolons. + * @param sleigh the Sleigh source */ - public void exec(long snap, int frame, TraceThread thread, List sleigh) { + public void exec(long snap, int frame, TraceThread thread, String sleigh) { PcodeProgram program = SleighProgramCompiler.compileProgram((SleighLanguage) language, "builder", sleigh, PcodeUseropLibrary.nil()); TraceSleighUtils.buildByteExecutor(trace, snap, thread, frame) diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TestThread.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TestThread.java index 94f1eebaff..468fc60cfb 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TestThread.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TestThread.java @@ -15,8 +15,6 @@ */ package ghidra.trace.model.time.schedule; -import java.util.List; - import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.pcode.emu.PcodeThread; import ghidra.pcode.emu.ThreadPcodeExecutorState; @@ -167,7 +165,7 @@ class TestThread implements PcodeThread { } @Override - public void inject(Address address, List sleigh) { + public void inject(Address address, String source) { } @Override diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/AbstractPcodeMachine.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/AbstractPcodeMachine.java index 650445aadf..24e9a181da 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/AbstractPcodeMachine.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/AbstractPcodeMachine.java @@ -257,19 +257,19 @@ public abstract class AbstractPcodeMachine implements PcodeMachine { } @Override - public PcodeProgram compileSleigh(String sourceName, List lines) { - return SleighProgramCompiler.compileProgram(language, sourceName, lines, stubLibrary); + public PcodeProgram compileSleigh(String sourceName, String source) { + return SleighProgramCompiler.compileProgram(language, sourceName, source, stubLibrary); } @Override - public void inject(Address address, List sleigh) { + public void inject(Address address, String source) { /** * TODO: Can I compile the template and build as if the inject were a * instruction:^instruction constructor? This would require me to delay that build until * execution, or at least check for instruction modification, if I do want to cache the * built p-code. */ - PcodeProgram pcode = compileSleigh("machine_inject:" + address, sleigh); + PcodeProgram pcode = compileSleigh("machine_inject:" + address, source); injects.put(address, pcode); } @@ -292,11 +292,12 @@ public abstract class AbstractPcodeMachine implements PcodeMachine { * addressed by formalizing and better exposing the notion of p-code stacks (of p-code * frames) */ - PcodeProgram pcode = compileSleigh("breakpoint:" + address, List.of( - "if (!(" + sleighCondition + ")) goto ;", - " emu_swi();", - "", - " emu_exec_decoded();")); + PcodeProgram pcode = compileSleigh("breakpoint:" + address, String.format(""" + if (!(%s)) goto ; + emu_swi(); + + emu_exec_decoded(); + """, sleighCondition)); injects.put(address, pcode); } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/DefaultPcodeThread.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/DefaultPcodeThread.java index 2fbacf3a17..6eb63f3123 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/DefaultPcodeThread.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/DefaultPcodeThread.java @@ -33,10 +33,10 @@ import ghidra.util.Msg; * The default implementation of {@link PcodeThread} suitable for most applications * *

- * When emulating on concrete state, consider using {@link ModifiedPcodeThread}, so that - * state modifiers from the older {@link Emulator} are incorporated. In either case, it may be - * worthwhile to examine existing state modifiers to ensure they are appropriately represented in - * any abstract state. It may be necessary to port them. + * When emulating on concrete state, consider using {@link ModifiedPcodeThread}, so that state + * modifiers from the older {@link Emulator} are incorporated. In either case, it may be worthwhile + * to examine existing state modifiers to ensure they are appropriately represented in any abstract + * state. It may be necessary to port them. * *

* This class implements the control-flow logic of the target machine, cooperating with the p-code @@ -148,9 +148,9 @@ public class DefaultPcodeThread implements PcodeThread { } @Override - public void executeSleighLine(String line) { - PcodeProgram program = SleighProgramCompiler.compileProgram(language, "line", - List.of(line + ";"), thread.library); + public void executeSleigh(String source) { + PcodeProgram program = + SleighProgramCompiler.compileProgram(language, "exec", source, thread.library); execute(program, thread.library); } @@ -588,9 +588,9 @@ public class DefaultPcodeThread implements PcodeThread { } @Override - public void inject(Address address, List sleigh) { + public void inject(Address address, String source) { PcodeProgram pcode = SleighProgramCompiler.compileProgram( - language, "thread_inject:" + address, sleigh, library); + language, "thread_inject:" + address, source, library); injects.put(address, pcode); } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/PcodeMachine.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/PcodeMachine.java index e99ed2a991..d9744b1292 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/PcodeMachine.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/PcodeMachine.java @@ -16,7 +16,6 @@ package ghidra.pcode.emu; import java.util.Collection; -import java.util.List; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.pcode.emu.DefaultPcodeThread.PcodeEmulationLibrary; @@ -31,7 +30,7 @@ import ghidra.program.model.address.Address; public interface PcodeMachine { /** - * Get the machine's SLEIGH language (processor model) + * Get the machine's Sleigh language (processor model) * * @return the language */ @@ -61,7 +60,7 @@ public interface PcodeMachine { * *

* Thread userop libraries may have more userops than are defined in the machine's userop - * library. However, to compile SLEIGH programs linked to thread libraries, the thread's userops + * library. However, to compile Sleigh programs linked to thread libraries, the thread's userops * must be known to the compiler. The stub library will name all userops common among the * threads, even if their definitions vary. WARNING: The stub library is not required to * provide implementations of the userops. Often they will throw exceptions, so do not attempt @@ -114,26 +113,26 @@ public interface PcodeMachine { PcodeExecutorState getSharedState(); /** - * Compile the given SLEIGH code for execution by a thread of this machine + * Compile the given Sleigh code for execution by a thread of this machine * *

* This links in the userop library given at construction time and those defining the emulation * userops, e.g., {@code emu_swi}. * * @param sourceName a user-defined source name for the resulting "program" - * @param lines the lines of SLEIGH source code + * @param lines the Sleigh source * @return the compiled program */ - PcodeProgram compileSleigh(String sourceName, List lines); + PcodeProgram compileSleigh(String sourceName, String source); /** - * Override the p-code at the given address with the given SLEIGH source + * Override the p-code at the given address with the given Sleigh source * *

* This will attempt to compile the given source against this machine's userop library and then * will inject it at the given address. The resulting p-code replaces that which would * be executed by decoding the instruction at the given address. The means the machine will not - * decode, nor advance its counter, unless the SLEIGH causes it. In most cases, the SLEIGH will + * decode, nor advance its counter, unless the Sleigh causes it. In most cases, the Sleigh will * call {@link PcodeEmulationLibrary#emu_exec_decoded()} to cause the machine to decode and * execute the overridden instruction. * @@ -143,9 +142,9 @@ public interface PcodeMachine { * double-wrapping, etc. * * @param address the address to inject at - * @param sleigh the SLEIGH source to compile and inject + * @param source the Sleigh source to compile and inject */ - void inject(Address address, List sleigh); + void inject(Address address, String source); /** * Remove the inject, if present, at the given address @@ -165,10 +164,10 @@ public interface PcodeMachine { *

* Breakpoints are implemented at the p-code level using an inject, without modification to the * emulated image. As such, it cannot coexist with another inject. A client needing to break - * during an inject must use {@link PcodeEmulationLibrary#emu_swi()} in the injected SLEIGH. + * during an inject must use {@link PcodeEmulationLibrary#emu_swi()} in the injected Sleigh. * * @param address the address at which to break - * @param sleighCondition a SLEIGH expression which controls the breakpoint + * @param sleighCondition a Sleigh expression which controls the breakpoint */ void addBreakpoint(Address address, String sleighCondition); } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/PcodeThread.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/PcodeThread.java index 7b5f7d1871..cb81f3f5b6 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/PcodeThread.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/PcodeThread.java @@ -336,9 +336,9 @@ public interface PcodeThread { * inject. * * @param address the address to inject at - * @param sleigh the SLEIGH source to compile and inject + * @param source the Sleigh source to compile and inject */ - void inject(Address address, List sleigh); + void inject(Address address, String source); /** * Remove the per-thread inject, if present, at the given address diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/x86/X86PcodeStateInitializer.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/x86/X86PcodeStateInitializer.java index d21bc0dfb4..bd4d210f1a 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/x86/X86PcodeStateInitializer.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/x86/X86PcodeStateInitializer.java @@ -28,9 +28,10 @@ public class X86PcodeStateInitializer implements PcodeStateInitializer { private static final List LANG_IDS = List.of( new LanguageID("x86:LE:32:default"), new LanguageID("x86:LE:64:default")); - private static final List SOURCE = List.of( - "FS_OFFSET = 0;", - "GS_OFFSET = 0;"); + private static final String SOURCE = """ + FS_OFFSET = 0; + GS_OFFSET = 0; + """; @Override public boolean isApplicable(Language language) { diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/PcodeExecutor.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/PcodeExecutor.java index ca40c7a5b7..8d7a41dc76 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/PcodeExecutor.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/PcodeExecutor.java @@ -91,13 +91,13 @@ public class PcodeExecutor { } /** - * Compile and execute a line of Sleigh + * Compile and execute a block of Sleigh * - * @param line the line, excluding the semicolon + * @param source the Sleigh source */ - public void executeSleighLine(String line) { - PcodeProgram program = SleighProgramCompiler.compileProgram(language, - "line", List.of(line + ";"), PcodeUseropLibrary.NIL); + public void executeSleigh(String source) { + PcodeProgram program = + SleighProgramCompiler.compileProgram(language, "exec", source, PcodeUseropLibrary.NIL); execute(program, PcodeUseropLibrary.nil()); } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighPcodeUseropDefinition.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighPcodeUseropDefinition.java index ffdf3af005..9a0110575a 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighPcodeUseropDefinition.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighPcodeUseropDefinition.java @@ -15,7 +15,6 @@ */ package ghidra.pcode.exec; -import java.text.MessageFormat; import java.util.*; import ghidra.app.plugin.processors.sleigh.SleighLanguage; @@ -65,7 +64,7 @@ public class SleighPcodeUseropDefinition implements PcodeUseropDefinition private final Factory factory; private final String name; private final List params = new ArrayList<>(); - private final List lines = new ArrayList<>(); + private final StringBuffer body = new StringBuffer(); protected Builder(Factory factory, String name) { this.factory = factory; @@ -93,41 +92,12 @@ public class SleighPcodeUseropDefinition implements PcodeUseropDefinition } /** - * Add lines of SLEIGH source + * Add Sleigh source to the body * - *

- * NOTE: The lines are joined only with line separators. No semicolons (;) are added at the - * end of each line. - * - *

- * TODO: See if this can be made any prettier with text blocks in newer Java versions. - * - * @param additionalLines the additional lines - * @return this builder + * @param additionalBody the additional source */ - public Builder sleigh(Collection additionalLines) { - this.lines.addAll(additionalLines); - return this; - } - - /** - * @see #sleigh(Collection) - */ - public Builder sleigh(String... additionalLines) { - return this.sleigh(Arrays.asList(additionalLines)); - } - - /** - * Treat each line as a pattern as in {@link MessageFormat#format(String, Object...)}, - * replacing each with the result. - * - * @param arguments the arguments to pass to the formatter - * @return this builder - */ - public Builder applyAsPattern(Object[] arguments) { - for (int i = 0; i < lines.size(); i++) { - lines.set(i, MessageFormat.format(lines.get(i), arguments)); - } + public Builder body(CharSequence additionalBody) { + body.append(additionalBody); return this; } @@ -144,23 +114,23 @@ public class SleighPcodeUseropDefinition implements PcodeUseropDefinition */ public SleighPcodeUseropDefinition build() { return new SleighPcodeUseropDefinition<>(factory.language, name, List.copyOf(params), - List.copyOf(lines)); + body.toString()); } } private final SleighLanguage language; private final String name; private final List params; - private final List lines; + private final String body; private final Map, PcodeProgram> cacheByArgs = new HashMap<>(); protected SleighPcodeUseropDefinition(SleighLanguage language, String name, List params, - List lines) { + String body) { this.language = language; this.name = name; this.params = params; - this.lines = lines; + this.body = body; } /** @@ -181,7 +151,7 @@ public class SleighPcodeUseropDefinition implements PcodeUseropDefinition args.add(outArg); args.addAll(inArgs); return cacheByArgs.computeIfAbsent(args, - a -> SleighProgramCompiler.compileUserop(language, name, params, lines, library, a)); + a -> SleighProgramCompiler.compileUserop(language, name, params, body, library, a)); } @Override @@ -211,11 +181,11 @@ public class SleighPcodeUseropDefinition implements PcodeUseropDefinition } /** - * Get the lines of source that define this userop + * Get the Sleigh source that defines this userop * * @return the lines */ - public List getLines() { - return lines; + public String getBody() { + return body; } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java index f27a449d23..d8d8986a3f 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java @@ -19,8 +19,6 @@ import java.io.IOException; import java.util.List; import java.util.Map; -import org.apache.commons.lang3.StringUtils; - import ghidra.app.plugin.processors.sleigh.*; import ghidra.app.plugin.processors.sleigh.template.ConstructTpl; import ghidra.pcodeCPort.pcoderaw.VarnodeData; @@ -66,12 +64,12 @@ public class SleighProgramCompiler { * @param language the language * @param parser the parser * @param sourceName the name of the program, for error diagnostics - * @param text the SLEIGH source + * @param source the Sleigh source * @return the constructor template */ public static ConstructTpl compileTemplate(Language language, PcodeParser parser, - String sourceName, String text) { - return parser.compilePcode(text, EXPRESSION_SOURCE_NAME, 1); + String sourceName, String source) { + return parser.compilePcode(source, EXPRESSION_SOURCE_NAME, 1); } /** @@ -82,7 +80,7 @@ public class SleighProgramCompiler { * @return the list of p-code ops * @throws UnknownInstructionException in case of crossbuilds, the target instruction is unknown * @throws MemoryAccessException in case of crossbuilds, the target address cannot be accessed - * @throws IOException for errors in during emitting + * @throws IOException for errors in during emitting */ public static List buildOps(Language language, ConstructTpl template) throws UnknownInstructionException, MemoryAccessException, IOException { @@ -164,33 +162,31 @@ public class SleighProgramCompiler { } /** - * Compile the given SLEIGH source into a simple p-code program + * Compile the given Sleigh source into a simple p-code program * *

- * This is suitable for modifying program state using SLEIGH statements. Most likely, in - * scripting, or perhaps in a SLEIGH repl. The library given during compilation must match the + * This is suitable for modifying program state using Sleigh statements. Most likely, in + * scripting, or perhaps in a Sleigh repl. The library given during compilation must match the * library given for execution, at least in its binding of userop IDs to symbols. * * @param language the language of the target p-code machine - * @param sourceName a diagnostic name for the SLEIGH source - * @param lines the lines of SLEIGH source. These are joined with line separators but no - * semicolon! + * @param sourceName a diagnostic name for the Sleigh source + * @param source the Sleigh source * @param library the userop library or stub library for binding userop symbols * @return the compiled p-code program */ public static PcodeProgram compileProgram(SleighLanguage language, String sourceName, - List lines, PcodeUseropLibrary library) { + String source, PcodeUseropLibrary library) { PcodeParser parser = createParser(language); Map symbols = library.getSymbols(language); addParserSymbols(parser, symbols); - ConstructTpl template = - compileTemplate(language, parser, sourceName, StringUtils.join(lines, "\n")); + ConstructTpl template = compileTemplate(language, parser, sourceName, source); return constructProgram(PcodeProgram::new, language, template, symbols); } /** - * Compile the given SLEIGH expression into a p-code program that can evaluate it + * Compile the given Sleigh expression into a p-code program that can evaluate it * *

* TODO: Currently, expressions cannot be compiled for a user-supplied userop library. The @@ -198,7 +194,7 @@ public class SleighProgramCompiler { * userop libraries are easily composed. It should be easy to add that feature if needed. * * @param language the languge of the target p-code machine - * @param expression the SLEIGH expression to be evaluated + * @param expression the Sleigh expression to be evaluated * @return a p-code program whose {@link PcodeExpression#evaluate(PcodeExecutor)} method will * evaluate the expression on the given executor and its state. */ @@ -213,7 +209,7 @@ public class SleighProgramCompiler { } /** - * Generate a SLEIGH symbol for context when compiling a userop definition + * Generate a Sleigh symbol for context when compiling a userop definition * * @param language the language of the target p-code machine * @param sleigh a means of translating address spaces between execution and compilation @@ -221,7 +217,7 @@ public class SleighProgramCompiler { * @param opName a diagnostic name for the userop in which this parameter applies * @param paramName the symbol name for the parameter * @param arg the varnode to bind to the parameter symbol - * @return the named SLEIGH symbol bound to the given varnode + * @return the named Sleigh symbol bound to the given varnode */ public static VarnodeSymbol paramSym(Language language, SleighBase sleigh, String opName, String paramName, Varnode arg) { @@ -232,11 +228,11 @@ public class SleighProgramCompiler { } /** - * Compile the definition of a p-code userop from SLEIGH source into a p-code program + * Compile the definition of a p-code userop from Sleigh source into a p-code program * *

- * TODO: Defining a userop from SLEIGH source is currently a bit of a hack. It would be nice if - * there were a formalization of SLEIGH/p-code subroutines. At the moment, the control flow for + * TODO: Defining a userop from Sleigh source is currently a bit of a hack. It would be nice if + * there were a formalization of Sleigh/p-code subroutines. At the moment, the control flow for * subroutines is handled out of band, which actually works fairly well. However, parameter * passing and returning results is not well defined. The current solution is to alias the * parameters to their arguments, implementing a pass-by-reference scheme. Similarly, the output @@ -256,14 +252,13 @@ public class SleighProgramCompiler { * @param opName the name of the userop (used only for diagnostics here) * @param params the names of parameters in order. Index 0 names the output symbol, probably * {@link SleighPcodeUseropDefinition#OUT_SYMBOL_NAME} - * @param lines the lines of SLEIGH source. These are joined with line separators but no - * semicolon! + * @param source the Sleigh source * @param library the userop library or stub library for binding userop symbols * @param args the varnode arguments in order. Index 0 is the output varnode. * @return a p-code program that implements the userop for the given arguments */ public static PcodeProgram compileUserop(SleighLanguage language, String opName, - List params, List lines, PcodeUseropLibrary library, + List params, String source, PcodeUseropLibrary library, List args) { PcodeParser parser = createParser(language); Map symbols = library.getSymbols(language); @@ -288,7 +283,6 @@ public class SleighProgramCompiler { } } - String source = StringUtils.join(lines, "\n"); try { ConstructTpl template = compileTemplate(language, parser, opName, source); return constructProgram(PcodeProgram::new, language, template, symbols); diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/AbstractStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/AbstractStmt.java index 04bbb86e87..acc8912ff6 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/AbstractStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/AbstractStmt.java @@ -79,7 +79,7 @@ abstract class AbstractStmt implements Stmt { * @param fall the label positioned immediately after this statement in the generated code * @return the generated Sleigh code */ - protected abstract String generate(Label next, Label fall); + protected abstract StringTree generate(Label next, Label fall); /** * Check if the statement is or contains a single branch statement diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/AssignStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/AssignStmt.java index 910f575acc..6dd4153c5f 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/AssignStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/AssignStmt.java @@ -49,8 +49,14 @@ class AssignStmt extends AbstractStmt implements RValInternal, StmtWithVal { } @Override - protected String generate(Label next, Label fall) { - return lhs.generate() + " = " + rhs.generate() + ";\n" + next.genGoto(fall); + protected StringTree generate(Label next, Label fall) { + StringTree st = new StringTree(); + st.append(lhs.generate()); + st.append(" = "); + st.append(rhs.generate()); + st.append(";\n"); + st.append(next.genGoto(fall)); + return st; } @Override diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/BlockStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/BlockStmt.java index b8a87061e8..e4657438d1 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/BlockStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/BlockStmt.java @@ -49,16 +49,16 @@ class BlockStmt extends AbstractStmt { } @Override - protected String generate(Label next, Label fall) { + protected StringTree generate(Label next, Label fall) { if (children.isEmpty()) { return next.genGoto(fall); } - StringBuilder sb = new StringBuilder(); + StringTree st = new StringTree(); for (AbstractStmt c : children.subList(0, children.size() - 1)) { - sb.append(c.generate(ctx.FALL, ctx.FALL)); + st.append(c.generate(ctx.FALL, ctx.FALL)); } - sb.append(children.get(children.size() - 1).generate(next, fall)); - return sb.toString(); + st.append(children.get(children.size() - 1).generate(next, fall)); + return st; } @Override diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/DeclStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/DeclStmt.java index 18ce9c2d84..e962aa3f5d 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/DeclStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/DeclStmt.java @@ -29,8 +29,14 @@ class DeclStmt extends AbstractStmt { } @Override - protected String generate(Label next, Label fall) { - return "local " + name + ":" + type.getLength() + ";\n" + - next.genGoto(fall); + protected StringTree generate(Label next, Label fall) { + StringTree st = new StringTree(); + st.append("local "); + st.append(name); + st.append(":"); + st.append(Integer.toString(type.getLength())); + st.append(";\n"); + st.append(next.genGoto(fall)); + return st; } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ForStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ForStmt.java index e641c6ad63..bbe38438bf 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ForStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ForStmt.java @@ -29,23 +29,26 @@ class ForStmt extends LoopStmt { } @Override - protected String generate(Label next, Label fall) { + protected StringTree generate(Label next, Label fall) { Label lTest = ctx.new FreshLabel(); Label lBegin = ctx.new FreshLabel(); Label lExit = lBreak = next.freshOrBorrow(); Label lStep = lContinue = ctx.new FreshLabel(); - String initGen = init.generate(lTest, lTest); - String testGen = lExit.genGoto(cond.notb(), lBegin); - String stmtGen = stmt.generate(lStep, lStep); - String stepGen = step.generate(lTest, fall); - return initGen + - lTest.genAnchor() + - testGen + - lBegin.genAnchor() + - stmtGen + - lStep.genAnchor() + - stepGen + - lExit.genAnchor(); + StringTree initGen = init.generate(lTest, lTest); + StringTree testGen = lExit.genGoto(cond.notb(), lBegin); + StringTree stmtGen = stmt.generate(lStep, lStep); + StringTree stepGen = step.generate(lTest, fall); + + StringTree st = new StringTree(); + st.append(initGen); + st.append(lTest.genAnchor()); + st.append(testGen); + st.append(lBegin.genAnchor()); + st.append(stmtGen); + st.append(lStep.genAnchor()); + st.append(stepGen); + st.append(lExit.genAnchor()); + return st; } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/IfStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/IfStmt.java index 5a3bdc1a12..0e58ebdf4f 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/IfStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/IfStmt.java @@ -25,7 +25,8 @@ class IfStmt extends ConditionalStmt { } @Override - protected String generate(Label next, Label fall) { + protected StringTree generate(Label next, Label fall) { + StringTree st = new StringTree(); if (elseStmt == null) { if (stmt.isSingleGoto()) { return stmt.getNext().genGoto(cond, fall); @@ -34,28 +35,31 @@ class IfStmt extends ConditionalStmt { Label lTrue = ctx.new FreshLabel(); Label lFalse = next.freshOrBorrow(); - String condGen = lFalse.genGoto(cond.notb(), lTrue); - String stmtGen = stmt.generate(next, fall); - return condGen + - lTrue.genAnchor() + - stmtGen + - lFalse.genAnchor(); + StringTree condGen = lFalse.genGoto(cond.notb(), lTrue); + StringTree stmtGen = stmt.generate(next, fall); + + st.append(condGen); + st.append(lTrue.genAnchor()); + st.append(stmtGen); + st.append(lFalse.genAnchor()); } + else { + Label lFalse = ctx.new FreshLabel(); + Label lTrue = ctx.new FreshLabel(); + Label lExit = next.freshOrBorrow(); - Label lFalse = ctx.new FreshLabel(); - Label lTrue = ctx.new FreshLabel(); - Label lExit = next.freshOrBorrow(); + StringTree condGen = lTrue.genGoto(cond, lFalse); + StringTree elseGen = elseStmt.generate(lExit, lTrue); + StringTree stmtGen = stmt.generate(next, fall); - String condGen = lTrue.genGoto(cond, lFalse); - String elseGen = elseStmt.generate(lExit, lTrue); - String stmtGen = stmt.generate(next, fall); - - return condGen + - lFalse.genAnchor() + - elseGen + - lTrue.genAnchor() + - stmtGen + - lExit.genAnchor(); + st.append(condGen); + st.append(lFalse.genAnchor()); + st.append(elseGen); + st.append(lTrue.genAnchor()); + st.append(stmtGen); + st.append(lExit.genAnchor()); + } + return st; } protected void addElse(Stmt elseStmt) { diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/LoopTruncateStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/LoopTruncateStmt.java index 189c060c37..90c28eb382 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/LoopTruncateStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/LoopTruncateStmt.java @@ -32,7 +32,7 @@ abstract class LoopTruncateStmt extends AbstractStmt { } @Override - protected String generate(Label next, Label fall) { + protected StringTree generate(Label next, Label fall) { return getNext().genGoto(fall); } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/RawStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/RawStmt.java index 9c1adcc3d4..145df6d5ae 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/RawStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/RawStmt.java @@ -26,7 +26,11 @@ class RawStmt extends AbstractStmt { } @Override - protected String generate(Label next, Label fall) { - return stmt + ";\n" + next.genGoto(fall); + protected StringTree generate(Label next, Label fall) { + StringTree st = new StringTree(); + st.append(stmt); + st.append(";\n"); + st.append(next.genGoto(fall)); + return st; } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ResultStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ResultStmt.java index 3a767014fe..30761784b8 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ResultStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ResultStmt.java @@ -30,14 +30,19 @@ class ResultStmt extends AbstractStmt { } @Override - protected String generate(Label next, Label fall) { + protected StringTree generate(Label next, Label fall) { RoutineStmt routine = Objects.requireNonNull(nearest(RoutineStmt.class)); if (!ctx.isAssignable(routine.retType, result.getType())) { ctx.emitResultTypeMismatch(routine, result); } - return SleighPcodeUseropDefinition.OUT_SYMBOL_NAME + " = " + result.generate() + ";\n" + - routine.lReturn.genGoto(fall); + StringTree st = new StringTree(); + st.append(SleighPcodeUseropDefinition.OUT_SYMBOL_NAME); + st.append(" = "); + st.append(result.generate()); + st.append(";\n"); + st.append(routine.lReturn.genGoto(fall)); + return st; } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ReturnStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ReturnStmt.java index e11f288209..aa11c3f41f 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ReturnStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/ReturnStmt.java @@ -27,7 +27,11 @@ class ReturnStmt extends AbstractStmt { } @Override - protected String generate(Label next, Label fall) { - return "return " + target.generate() + ";\n"; + protected StringTree generate(Label next, Label fall) { + StringTree st = new StringTree(); + st.append("return "); + st.append(target.generate()); + st.append(";\n"); + return st; } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/RoutineStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/RoutineStmt.java index 3083d6fc7a..46339bbdc7 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/RoutineStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/RoutineStmt.java @@ -32,14 +32,17 @@ class RoutineStmt extends BlockStmt { } @Override - protected String generate(Label next, Label fall) { + protected StringTree generate(Label next, Label fall) { if (children.isEmpty()) { - return ""; + return StringTree.single(""); } Label lExit = lReturn = next.freshOrBorrow(); // This is an odd case, because it's the root: use lExit instead of fall - String blockGen = super.generate(lReturn, lExit); - return blockGen + - lExit.genAnchor(); + StringTree blockGen = super.generate(lReturn, lExit); + + StringTree st = new StringTree(); + st.append(blockGen); + st.append(lExit.genAnchor()); + return st; } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/StringTree.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/StringTree.java new file mode 100644 index 0000000000..1c2b3bb946 --- /dev/null +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/StringTree.java @@ -0,0 +1,76 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.pcode.struct; + +import java.util.LinkedList; +import java.util.List; + +public class StringTree { + public static StringTree single(CharSequence seq) { + StringTree st = new StringTree(); + st.append(seq); + return st; + } + + interface Node { + void walk(StringBuffer buf); + } + + class Branch implements Node { + List children = new LinkedList<>(); + + void addChild(Node child) { + children.add(child); + } + + @Override + public void walk(StringBuffer buf) { + for (Node child : children) { + child.walk(buf); + } + } + } + + class Leaf implements Node { + final CharSequence seq; + + public Leaf(CharSequence seq) { + this.seq = seq; + } + + @Override + public void walk(StringBuffer buf) { + buf.append(seq); + } + } + + Branch root = new Branch(); + + public void append(CharSequence seq) { + root.addChild(new Leaf(seq)); + } + + public void append(StringTree tree) { + root.addChild(tree.root); + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + root.walk(buf); + return buf.toString(); + } +} diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/StructuredSleigh.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/StructuredSleigh.java index 0ac61819c4..d0c2767156 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/StructuredSleigh.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/StructuredSleigh.java @@ -987,13 +987,14 @@ public class StructuredSleigh { /** * Generate code for this label * + *

* This must be the last method called on the label, because it relies on knowing whether or * not the label is actually used. (The Sleigh compiler rejects code if it contains unused * labels.) * * @return the Sleigh code */ - abstract String genAnchor(); + abstract StringTree genAnchor(); /** * Generate a reference to this label as it should appear in a Sleigh "{@code goto}" @@ -1001,7 +1002,7 @@ public class StructuredSleigh { * * @return the label's expression */ - abstract String ref(); + abstract StringTree ref(); /** * Generate a goto statement that targets this label @@ -1009,7 +1010,7 @@ public class StructuredSleigh { * @param fall the label following the goto * @return the Sleigh code */ - abstract String genGoto(Label fall); + abstract StringTree genGoto(Label fall); /** * Generate a conditional goto statement that targets this label @@ -1018,7 +1019,7 @@ public class StructuredSleigh { * @param fall the label following the goto * @return the Sleigh code */ - abstract String genGoto(RVal cond, Label fall); + abstract StringTree genGoto(RVal cond, Label fall); } /** @@ -1041,32 +1042,49 @@ public class StructuredSleigh { } @Override - public String genAnchor() { + public StringTree genAnchor() { if (name == null) { - return ""; + return StringTree.single(""); } - return "<" + name + ">\n"; + StringTree st = new StringTree(); + st.append("<"); + st.append(name); + st.append(">\n"); + return st; } @Override - public String ref() { - return "<" + getName() + ">"; + public StringTree ref() { + StringTree st = new StringTree(); + st.append("<"); + st.append(getName()); + st.append(">"); + return st; } @Override - public String genGoto(Label fall) { + public StringTree genGoto(Label fall) { if (this == fall) { - return ""; + return StringTree.single(""); } - return "goto " + ref() + ";\n"; + StringTree st = new StringTree(); + st.append("goto "); + st.append(ref()); + st.append(";\n"); + return st; } @Override - public String genGoto(RVal cond, Label fall) { + public StringTree genGoto(RVal cond, Label fall) { if (this == fall) { - return ""; + return StringTree.single(""); } - return "if " + ((RValInternal) cond).generate() + " " + genGoto(fall); + StringTree st = new StringTree(); + st.append("if "); + st.append(((RValInternal) cond).generate()); + st.append(" "); + st.append(genGoto(fall)); + return st; } } @@ -1091,27 +1109,27 @@ public class StructuredSleigh { } @Override - public String genAnchor() { - return ""; + public StringTree genAnchor() { + return StringTree.single(""); } @Override - public String ref() { + public StringTree ref() { return borrowed.ref(); } @Override - public String genGoto(Label fall) { + public StringTree genGoto(Label fall) { if (this == fall) { // placed will also check - return ""; + return StringTree.single(""); } return borrowed.genGoto(fall); } @Override - public String genGoto(RVal cond, Label fall) { + public StringTree genGoto(RVal cond, Label fall) { if (this == fall) { // placed with also check - return ""; + return StringTree.single(""); } return borrowed.genGoto(cond, fall); } @@ -1132,22 +1150,22 @@ public class StructuredSleigh { } @Override - public String genAnchor() { - return ""; + public StringTree genAnchor() { + return StringTree.single(""); } @Override - public String ref() { + public StringTree ref() { throw new AssertionError(); } @Override - public String genGoto(Label fall) { - return ""; + public StringTree genGoto(Label fall) { + return StringTree.single(""); } @Override - public String genGoto(RVal cond, Label fall) { + public StringTree genGoto(RVal cond, Label fall) { throw new AssertionError(); } } @@ -1703,8 +1721,8 @@ public class StructuredSleigh { e); } }); - String source = root.generate(FALL, FALL); - builder.sleigh(source); + StringTree source = root.generate(FALL, FALL); + builder.body(source.toString()); return builder.build(); } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/VoidExprStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/VoidExprStmt.java index 9516b2eec0..dd1dc5cd9a 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/VoidExprStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/VoidExprStmt.java @@ -43,8 +43,12 @@ class VoidExprStmt extends AbstractStmt implements RValInternal, StmtWithVal { } @Override - protected String generate(Label next, Label fall) { - return expr.generate() + ";\n" + next.genGoto(fall); + protected StringTree generate(Label next, Label fall) { + StringTree st = new StringTree(); + st.append(expr.generate()); + st.append(";\n"); + st.append(next.genGoto(fall)); + return st; } @Override diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/WhileStmt.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/WhileStmt.java index 44974d3451..f9e9fc8e3e 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/WhileStmt.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/struct/WhileStmt.java @@ -23,17 +23,21 @@ class WhileStmt extends LoopStmt { } @Override - protected String generate(Label next, Label fall) { + protected StringTree generate(Label next, Label fall) { Label lTest = lContinue = ctx.new FreshLabel(); Label lBegin = ctx.new FreshLabel(); Label lExit = lBreak = next.freshOrBorrow(); - String testGen = lExit.genGoto(cond.notb(), lBegin); - String stmtGen = stmt.generate(lTest, fall); - return lTest.genAnchor() + - testGen + - lBegin.genAnchor() + - stmtGen + - lExit.genAnchor(); + StringTree testGen = lExit.genGoto(cond.notb(), lBegin); + StringTree stmtGen = stmt.generate(lTest, fall); + + StringTree st = new StringTree(); + + st.append(lTest.genAnchor()); + st.append(testGen); + st.append(lBegin.genAnchor()); + st.append(stmtGen); + st.append(lExit.genAnchor()); + return st; } } diff --git a/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/exec/AnnotatedPcodeUseropLibraryTest.java b/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/exec/AnnotatedPcodeUseropLibraryTest.java index f355808804..601b94ee6a 100644 --- a/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/exec/AnnotatedPcodeUseropLibraryTest.java +++ b/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/exec/AnnotatedPcodeUseropLibraryTest.java @@ -20,7 +20,6 @@ import static org.junit.Assert.assertTrue; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; -import java.util.List; import org.junit.Test; @@ -53,15 +52,15 @@ public class AnnotatedPcodeUseropLibraryTest extends AbstractGhidraHeadlessInteg } protected void executeSleigh(PcodeExecutor executor, PcodeUseropLibrary library, - String... lines) { + String source) { PcodeProgram program = SleighProgramCompiler.compileProgram(executor.getLanguage(), "test", - List.of(lines), library); + source, library); executor.execute(program, library); } - protected void executeSleigh(PcodeUseropLibrary library, String... lines) + protected void executeSleigh(PcodeUseropLibrary library, String source) throws Exception { - executeSleigh(createBytesExecutor(), library, lines); + executeSleigh(createBytesExecutor(), library, source); } protected static void assertBytes(long expectedVal, int expectedSize, byte[] actual) { diff --git a/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/exec/PcodeFrameTest.java b/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/exec/PcodeFrameTest.java index df7763cdc4..c54d1dd2b5 100644 --- a/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/exec/PcodeFrameTest.java +++ b/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/exec/PcodeFrameTest.java @@ -17,8 +17,6 @@ package ghidra.pcode.exec; import static org.junit.Assert.assertEquals; -import java.util.List; - import org.junit.Before; import org.junit.Test; @@ -27,26 +25,34 @@ import ghidra.program.model.lang.LanguageID; import ghidra.test.AbstractGhidraHeadlessIntegrationTest; public class PcodeFrameTest extends AbstractGhidraHeadlessIntegrationTest { - static final List SAMPLE_ADD = List.of( - "r0 = r0 + r1;"); - static final List SAMPLE_ADD2 = List.of( - "r0 = r0 + r1 + r2;"); - static final List SAMPLE_IF = List.of( - "if (r0 == r1) goto ;", - "r2 = r2 + 1;", - ""); - static final List SAMPLE_LOOP = List.of( - "", - "r0 = r0 + 1;", - "if (r0 == r1) goto ;"); - static final List SAMPLE_BRANCH = List.of( - "goto 0x1234;"); - static final List SAMPLE_LOAD = List.of( - "r0 = *:8 r1;"); - static final List SAMPLE_LANG_USEROP = List.of( - "pcodeop_one(r0);"); - static final List SAMPLE_LIB_USEROP = List.of( - "__lib_userop(r0);"); + static final String SAMPLE_ADD = """ + r0 = r0 + r1; + """; + static final String SAMPLE_ADD2 = """ + r0 = r0 + r1 + r2; + """; + static final String SAMPLE_IF = """ + if (r0 == r1) goto ; + r2 = r2 + 1; + + """; + static final String SAMPLE_LOOP = """ + + r0 = r0 + 1; + if (r0 == r1) goto ; + """; + static final String SAMPLE_BRANCH = """ + goto 0x1234; + """; + static final String SAMPLE_LOAD = """ + r0 = *:8 r1; + """; + static final String SAMPLE_LANG_USEROP = """ + pcodeop_one(r0); + """; + static final String SAMPLE_LIB_USEROP = """ + __lib_userop(r0); + """; static class MyLib extends AnnotatedPcodeUseropLibrary { @PcodeUserop @@ -63,11 +69,11 @@ public class PcodeFrameTest extends AbstractGhidraHeadlessIntegrationTest { (SleighLanguage) getLanguageService().getLanguage(new LanguageID("Toy:BE:64:default")); } - private PcodeProgram compile(List sample) { + private PcodeProgram compile(String sample) { return SleighProgramCompiler.compileProgram(language, getName(), sample, library); } - private PcodeFrame frame(List sample) { + private PcodeFrame frame(String sample) { PcodeProgram program = compile(sample); return new PcodeFrame(language, program.code, program.useropNames); } @@ -75,172 +81,172 @@ public class PcodeFrameTest extends AbstractGhidraHeadlessIntegrationTest { @Test public void testProgramToStringAdd() throws Exception { PcodeProgram program = compile(SAMPLE_ADD); - assertEquals("" + - "", + assertEquals(""" + """, program.toString()); } @Test public void testProgramToStringAdd2() throws Exception { PcodeProgram program = compile(SAMPLE_ADD2); - assertEquals("" + - "", + assertEquals(""" + """, program.toString()); } @Test public void testProgramToStringIf() throws Exception { PcodeProgram program = compile(SAMPLE_IF); - assertEquals("" + - ", $U2000:1\n" + - " r2 = INT_ADD r2, 1:8\n" + - "<0>\n" + - ">", + assertEquals(""" + , $U2000:1 + r2 = INT_ADD r2, 1:8 + <0> + >""", program.toString()); } @Test public void testProgramToStringLoop() throws Exception { PcodeProgram program = compile(SAMPLE_LOOP); - assertEquals("" + - "\n" + - " r0 = INT_ADD r0, 1:8\n" + - " $U2080:1 = INT_EQUAL r0, r1\n" + - " CBRANCH <0>, $U2080:1\n" + - ">", + assertEquals(""" + + r0 = INT_ADD r0, 1:8 + $U2080:1 = INT_EQUAL r0, r1 + CBRANCH <0>, $U2080:1 + >""", program.toString()); } @Test public void testProgramToStringLoad() throws Exception { PcodeProgram program = compile(SAMPLE_LOAD); - assertEquals("" + - "", + assertEquals(""" + """, program.toString()); } @Test public void testProgramToStringLangUserop() throws Exception { PcodeProgram program = compile(SAMPLE_LANG_USEROP); - assertEquals("" + - "", + assertEquals(""" + """, program.toString()); } @Test public void testProgramToStringLibUserop() throws Exception { PcodeProgram program = compile(SAMPLE_LIB_USEROP); - assertEquals("" + - "", + assertEquals(""" + """, program.toString()); } @Test public void testFrameToStringAdd() throws Exception { PcodeFrame frame = frame(SAMPLE_ADD); - assertEquals("" + - " r0 = INT_ADD r0, r1\n" + - "}>", + assertEquals(""" + r0 = INT_ADD r0, r1 + }>""", frame.toString()); frame.advance(); - assertEquals("" + - " fall-through\n" + - "}>", + assertEquals(""" + fall-through + }>""", frame.toString()); } @Test public void testFrameToStringIf() throws Exception { PcodeFrame frame = frame(SAMPLE_IF); - assertEquals("" + - " $U2000:1 = INT_EQUAL r0, r1\n" + - " CBRANCH <0>, $U2000:1\n" + - " r2 = INT_ADD r2, 1:8\n" + - " <0>\n" + - "}>", + assertEquals(""" + $U2000:1 = INT_EQUAL r0, r1 + CBRANCH <0>, $U2000:1 + r2 = INT_ADD r2, 1:8 + <0> + }>""", frame.toString()); frame.advance(); frame.advance(); frame.advance(); - assertEquals("" + - ", $U2000:1\n" + - " r2 = INT_ADD r2, 1:8\n" + - " <0>\n" + - " *> fall-through\n" + - "}>", + assertEquals(""" + , $U2000:1 + r2 = INT_ADD r2, 1:8 + <0> + *> fall-through + }>""", frame.toString()); } @Test public void testFrameToStringLoop() throws Exception { PcodeFrame frame = frame(SAMPLE_LOOP); - assertEquals("" + - "\n" + - " -> r0 = INT_ADD r0, 1:8\n" + - " $U2080:1 = INT_EQUAL r0, r1\n" + - " CBRANCH <0>, $U2080:1\n" + - "}>", + assertEquals(""" + + -> r0 = INT_ADD r0, 1:8 + $U2080:1 = INT_EQUAL r0, r1 + CBRANCH <0>, $U2080:1 + }>""", frame.toString()); } @Test public void testFrameToStringBranch() throws Exception { PcodeFrame frame = frame(SAMPLE_BRANCH); - assertEquals("" + - " BRANCH *[ram]0x1234:8\n" + - "}>", + assertEquals(""" + BRANCH *[ram]0x1234:8 + }>""", frame.toString()); frame.advance(); frame.finishAsBranch(); - assertEquals("" + - " BRANCH *[ram]0x1234:8\n" + - "}>", + assertEquals(""" + BRANCH *[ram]0x1234:8 + }>""", frame.toString()); } @Test public void testFrameToStringLangUserop() throws Exception { PcodeFrame frame = frame(SAMPLE_LANG_USEROP); - assertEquals("" + - " CALLOTHER \"pcodeop_one\", r0\n" + - "}>", + assertEquals(""" + CALLOTHER \"pcodeop_one\", r0 + }>""", frame.toString()); } @Test public void testFrameToStringLibUserop() throws Exception { PcodeFrame frame = frame(SAMPLE_LIB_USEROP); - assertEquals("" + - " CALLOTHER \"__lib_userop\", r0\n" + - "}>", + assertEquals(""" + CALLOTHER \"__lib_userop\", r0 + }>""", frame.toString()); } } diff --git a/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/struct/sub/StructuredSleighTest.java b/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/struct/sub/StructuredSleighTest.java index a9f1b8f0fc..70c41dae1d 100644 --- a/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/struct/sub/StructuredSleighTest.java +++ b/Ghidra/Debug/ProposedUtils/src/test/java/ghidra/pcode/struct/sub/StructuredSleighTest.java @@ -65,7 +65,7 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest } }; SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); - assertEquals(List.of("__op_output = (param_1 * 0x2:4);\n"), myUserop.getLines()); + assertEquals("__op_output = (param_1 * 0x2:4);\n", myUserop.getBody()); } @Test(expected = SleighException.class) @@ -90,7 +90,7 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest } }; SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); - assertEquals(List.of("__op_output = (r0 * 0x2:4);\n"), myUserop.getLines()); + assertEquals("__op_output = (r0 * 0x2:4);\n", myUserop.getBody()); } @Test @@ -103,10 +103,10 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest } }; SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); - assertEquals(List.of("" + - "local my_var:4;\n" + - "__op_output = (my_var * 0x2:4);\n"), - myUserop.getLines()); + assertEquals(""" + local my_var:4; + __op_output = (my_var * 0x2:4); + """, myUserop.getBody()); // Verify the source compiles myUserop.programFor(new Varnode(r0.getAddress(), r0.getNumBytes()), List.of(), PcodeUseropLibrary.NIL); @@ -121,7 +121,7 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest } }; SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); - assertEquals(List.of(""), myUserop.getLines()); + assertEquals("", myUserop.getBody()); } @Test @@ -137,14 +137,14 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest } }; SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); - assertEquals(List.of("" + - "if 0x1:1 goto ;\n" + - "tmp = 0x2:4;\n" + - "goto ;\n" + - "\n" + - "tmp = 0x1:4;\n" + - "\n"), - myUserop.getLines()); + assertEquals(""" + if 0x1:1 goto ; + tmp = 0x2:4; + goto ; + + tmp = 0x1:4; + + """, myUserop.getBody()); } @Test @@ -158,11 +158,11 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest } }; SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); - assertEquals(List.of("" + - "if (!0x1:1) goto ;\n" + - "tmp = 0x1:4;\n" + - "\n"), - myUserop.getLines()); + assertEquals(""" + if (!0x1:1) goto ; + tmp = 0x1:4; + + """, myUserop.getBody()); } @Test @@ -179,17 +179,18 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest } }; SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); - assertEquals(List.of("" + "local i:4;\n" + - "local sum:4;\n" + - "i = 0x0:4;\n" + - "\n" + - "if (i >= n) goto ;\n" + - "sum = (sum + i);\n" + - "i = (i + 0x1:4);\n" + - "goto ;\n" + - "\n" + - "__op_output = sum;\n"), - myUserop.getLines()); + assertEquals(""" + local i:4; + local sum:4; + i = 0x0:4; + + if (i >= n) goto ; + sum = (sum + i); + i = (i + 0x1:4); + goto ; + + __op_output = sum; + """, myUserop.getBody()); } @Test @@ -209,19 +210,19 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest } }; SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); - assertEquals(List.of("" + - "local i:4;\n" + - "local sum:4;\n" + - "i = 0x0:4;\n" + - "\n" + - "if (i >= n) goto ;\n" + - "sum = (sum + i);\n" + - "if (sum >= 0x3e8:4) goto ;\n" + - "i = (i + 0x1:4);\n" + - "goto ;\n" + - "\n" + - "__op_output = sum;\n"), - myUserop.getLines()); + assertEquals(""" + local i:4; + local sum:4; + i = 0x0:4; + + if (i >= n) goto ; + sum = (sum + i); + if (sum >= 0x3e8:4) goto ; + i = (i + 0x1:4); + goto ; + + __op_output = sum; + """, myUserop.getBody()); } @Test @@ -233,7 +234,7 @@ public class StructuredSleighTest extends AbstractGhidraHeadlessIntegrationTest } }; SleighPcodeUseropDefinition myUserop = ss.generate().get("my_userop"); - assertEquals(List.of("return (* 0xdeadbeef:8);\n"), myUserop.getLines()); + assertEquals("return (* 0xdeadbeef:8);\n", myUserop.getBody()); // TODO: Test that the generated code compiles in a slaspec file. // It's rejected for injects because "return" is not valid there. } diff --git a/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorTest.java b/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorTest.java index e4a8d60916..db4f43cd1e 100644 --- a/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorTest.java +++ b/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorTest.java @@ -18,7 +18,6 @@ package ghidra.pcode.emu.taint.full; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.util.List; import java.util.Set; import org.junit.Before; @@ -105,8 +104,7 @@ public class TaintDebuggerPcodeEmulatorTest extends AbstractGhidraHeadedDebugger new DefaultTraceLocation(tb.trace, null, Range.atLeast(0L), tb.addr(0x55550000)), new ProgramLocation(program, tb.addr(0x00400000)), 0x1000, false); thread = tb.getOrAddThread("Threads[0]", 0); - tb.exec(0, 0, thread, List.of( - "RIP = 0x55550000;")); + tb.exec(0, 0, thread, "RIP = 0x55550000;"); } waitForDomainObject(tb.trace); waitForPass(() -> assertEquals(new ProgramLocation(program, tb.addr(0x00400000)), diff --git a/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/plain/TaintPcodeEmulatorTest.java b/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/plain/TaintPcodeEmulatorTest.java index 597d004a84..07c1afc0e7 100644 --- a/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/plain/TaintPcodeEmulatorTest.java +++ b/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/plain/TaintPcodeEmulatorTest.java @@ -194,7 +194,7 @@ public class TaintPcodeEmulatorTest extends AbstractGhidraHeadlessIntegrationTes public void testTaintViaSleigh() throws Exception { prepareEmulator(); PcodeThread thread = launchThread(start); - thread.getExecutor().executeSleighLine("*:8 0x00400000:8 = taint_arr(*:8 0x004000000:8)"); + thread.getExecutor().executeSleigh("*:8 0x00400000:8 = taint_arr(*:8 0x004000000:8);"); Pair taintVal = emulator.getSharedState().getVar(space, 0x00400000, 8, true); diff --git a/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/trace/TaintTracePcodeEmulatorTest.java b/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/trace/TaintTracePcodeEmulatorTest.java index c230b49ceb..48f235176f 100644 --- a/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/trace/TaintTracePcodeEmulatorTest.java +++ b/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/trace/TaintTracePcodeEmulatorTest.java @@ -63,7 +63,7 @@ public class TaintTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testReadStateMemory() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, List.of(), List.of()); + TraceThread thread = initTrace(tb, "", List.of()); try (UndoableTransaction tid = tb.startTransaction()) { TracePropertyMap taintMap = tb.trace.getAddressPropertyManager() @@ -73,7 +73,7 @@ public class TaintTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest TaintTracePcodeEmulator emu = new TaintTracePcodeEmulator(tb.trace, 0); PcodeThread> emuThread = emu.newThread(thread.getPath()); - emuThread.getExecutor().executeSleighLine("RAX = *0x00400000:8"); + emuThread.getExecutor().executeSleigh("RAX = *0x00400000:8;"); Pair valRAX = emuThread.getState().getVar(tb.language.getRegister("RAX")); @@ -89,7 +89,7 @@ public class TaintTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testReadStateRegister() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, List.of(), List.of()); + TraceThread thread = initTrace(tb, "", List.of()); Register regRAX = tb.language.getRegister("RAX"); Register regEBX = tb.language.getRegister("EBX"); @@ -103,7 +103,7 @@ public class TaintTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest TaintTracePcodeEmulator emu = new TaintTracePcodeEmulator(tb.trace, 0); PcodeThread> emuThread = emu.newThread(thread.getPath()); - emuThread.getExecutor().executeSleighLine("RAX = RBX"); + emuThread.getExecutor().executeSleigh("RAX = RBX;"); Pair valRAX = emuThread.getState().getVar(regRAX); @@ -119,7 +119,7 @@ public class TaintTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testWriteStateMemory() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - initTrace(tb, List.of(), List.of()); + initTrace(tb, "", List.of()); TaintTracePcodeEmulator emu = new TaintTracePcodeEmulator(tb.trace, 0); TaintVec taintVal = TaintVec.empties(8); @@ -146,7 +146,7 @@ public class TaintTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest public void testWriteStateRegister() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { AddressSpace rs = tb.language.getAddressFactory().getRegisterSpace(); - TraceThread thread = initTrace(tb, List.of(), List.of()); + TraceThread thread = initTrace(tb, "", List.of()); TaintTracePcodeEmulator emu = new TaintTracePcodeEmulator(tb.trace, 0); PcodeThread> emuThread = emu.newThread(thread.getPath()); @@ -176,9 +176,9 @@ public class TaintTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest public void testEmptyTaintClears() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { AddressSpace ram = tb.language.getAddressFactory().getDefaultAddressSpace(); - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + """, List.of( "MOV qword ptr [0x00600000], RAX", "MOV qword ptr [0x00600000], RBX")); @@ -214,9 +214,9 @@ public class TaintTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testZeroByXor() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + """, List.of( "XOR RAX, RAX")); @@ -245,9 +245,9 @@ public class TaintTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest @Test public void testZeroByXorVia32() throws Throwable { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) { - TraceThread thread = initTrace(tb, - List.of( - "RIP = 0x00400000;"), + TraceThread thread = initTrace(tb, """ + RIP = 0x00400000; + """, List.of( "XOR EAX, EAX"));