diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProvider.java index dcf589df06..4b4e073b35 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProvider.java @@ -52,6 +52,7 @@ import ghidra.pcode.exec.PcodeExecutorState; import ghidra.pcode.exec.PcodeFrame; import ghidra.program.model.data.DataType; import ghidra.program.model.lang.Language; +import ghidra.program.model.listing.Instruction; import ghidra.program.model.pcode.PcodeOp; import ghidra.program.model.pcode.Varnode; import ghidra.trace.model.Trace; @@ -347,10 +348,11 @@ public class DebuggerPcodeStepperProvider extends ComponentProviderAdapter { GhidraTable uniqueTable; UniqueTableModel uniqueTableModel = new UniqueTableModel(); - private GhidraTableFilterPanel uniqueFilterPanel; + GhidraTableFilterPanel uniqueFilterPanel; GhidraTable pcodeTable; PcodeTableModel pcodeTableModel = new PcodeTableModel(); + JLabel instructionLabel; // No filter panel on p-code DockingAction actionStepBackward; @@ -457,6 +459,8 @@ public class DebuggerPcodeStepperProvider extends ComponentProviderAdapter { JPanel pcodePanel = new JPanel(new BorderLayout()); pcodeTable = new GhidraTable(pcodeTableModel); pcodePanel.add(new JScrollPane(pcodeTable)); + instructionLabel = new JLabel(); + pcodePanel.add(instructionLabel, BorderLayout.NORTH); mainPanel.setLeftComponent(pcodePanel); JPanel uniquePanel = new JPanel(new BorderLayout()); @@ -620,6 +624,9 @@ public class DebuggerPcodeStepperProvider extends ComponentProviderAdapter { } protected void doLoadPcodeFrame() { + if (instructionLabel != null) { + instructionLabel.setText("(no instruction)"); + } if (emulationService == null) { return; } @@ -660,6 +667,13 @@ public class DebuggerPcodeStepperProvider extends ComponentProviderAdapter { populateSingleton(EnumPcodeRow.DECODE); return; } + Instruction instruction = thread.getInstruction(); + if (instruction == null) { + instructionLabel.setText("(no instruction)"); + } + else { + instructionLabel.setText(instruction.toString()); + } PcodeFrame frame = thread.getFrame(); if (frame == null) { /** diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TraceScheduleTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TraceScheduleTest.java index 1bafacd696..1598e8fa57 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TraceScheduleTest.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TraceScheduleTest.java @@ -28,6 +28,7 @@ import ghidra.pcode.emu.*; import ghidra.pcode.exec.*; import ghidra.program.model.address.Address; import ghidra.program.model.lang.*; +import ghidra.program.model.listing.Instruction; import ghidra.test.AbstractGhidraHeadlessIntegrationTest; import ghidra.test.ToyProgramBuilder; import ghidra.trace.database.ToyDBTraceBuilder; @@ -333,6 +334,11 @@ public class TraceScheduleTest extends AbstractGhidraHeadlessIntegrationTest { public PcodeFrame getFrame() { return null; } + + @Override + public Instruction getInstruction() { + return null; + } @Override public void executeInstruction() { 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 62e6195973..74a5c07b2e 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 @@ -284,6 +284,7 @@ public class DefaultPcodeThread implements PcodeThread { } postExecuteInstruction(); frame = null; + instruction = null; } @Override @@ -291,6 +292,11 @@ public class DefaultPcodeThread implements PcodeThread { return frame; } + @Override + public Instruction getInstruction() { + return instruction; + } + protected void assertCompletedInstruction() { if (frame != null) { throw new IllegalStateException("The current instruction or inject has not finished."); 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 760aca1f56..97c53d2158 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 @@ -22,6 +22,7 @@ import ghidra.pcode.emu.DefaultPcodeThread.SleighEmulationLibrary; import ghidra.pcode.exec.*; import ghidra.program.model.address.Address; import ghidra.program.model.lang.RegisterValue; +import ghidra.program.model.listing.Instruction; /** * An emulated thread of execution @@ -157,6 +158,13 @@ public interface PcodeThread { */ PcodeFrame getFrame(); + /** + * Get the current decoded instruction, if applicable + * + * @return the instruction + */ + Instruction getInstruction(); + /** * Execute the next instruction, ignoring injects *