diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java
index 4366551c06..54dcabbd05 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java
@@ -17,9 +17,9 @@ package ghidra.app.plugin.core.debug.disassemble;
import static org.junit.Assert.*;
-import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
+import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.function.Supplier;
@@ -44,8 +44,7 @@ import ghidra.dbg.target.schema.XmlSchemaContext;
import ghidra.debug.api.control.ControlMode;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSet;
-import ghidra.program.model.lang.LanguageID;
-import ghidra.program.model.lang.RegisterValue;
+import ghidra.program.model.lang.*;
import ghidra.program.model.listing.Instruction;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
@@ -115,10 +114,20 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
+
+
+
+
+
+
+
+
+
+
""");
@@ -148,7 +157,12 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
}
protected TraceObjectThread createPolyglotTrace(String arch, long offset,
- Supplier byteSupplier) throws IOException {
+ Supplier byteSupplier) throws Exception {
+ return createPolyglotTrace(arch, offset, byteSupplier, true);
+ }
+
+ protected TraceObjectThread createPolyglotTrace(String arch, long offset,
+ Supplier byteSupplier, boolean pcInStack) throws Exception {
createAndOpenTrace("DATA:BE:64:default");
DBTraceObjectManager objects = tb.trace.getObjectManager();
@@ -171,13 +185,31 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
// TODO: Why doesn't setRange work after insert?
objBinText.insert(zeroOn, ConflictResolution.DENY);
- DBTraceObject objFrame =
- objects.createObject(TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0]"));
- objFrame.insert(zeroOn, ConflictResolution.DENY);
- TraceObjectStackFrame frame = objFrame.queryInterface(TraceObjectStackFrame.class);
- frame.setProgramCounter(zeroOn, tb.addr(offset));
-
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
+ if (pcInStack) {
+ DBTraceObject objFrame =
+ objects.createObject(
+ TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0]"));
+ objFrame.insert(zeroOn, ConflictResolution.DENY);
+ TraceObjectStackFrame frame = objFrame.queryInterface(TraceObjectStackFrame.class);
+ frame.setProgramCounter(zeroOn, tb.addr(offset));
+ }
+ else {
+ objects.createObject(
+ TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0].Registers"))
+ .insert(zeroOn, ConflictResolution.DENY);
+ TraceObjectThread thread = objects.getObjectByCanonicalPath(
+ TraceObjectKeyPath.parse("Targets[0].Threads[0]"))
+ .queryInterface(TraceObjectThread.class);
+ traceManager.activateThread(thread);
+ DBTraceMemorySpace regs =
+ Objects.requireNonNull(memory.getMemoryRegisterSpace(thread, true));
+ TraceGuestPlatform platform =
+ Unique.assertOne(tb.trace.getPlatformManager().getGuestPlatforms());
+ Register regPc = platform.getLanguage().getProgramCounter();
+ regs.setValue(platform, 0, new RegisterValue(regPc, BigInteger.valueOf(offset)));
+ }
+
ByteBuffer bytes = byteSupplier.get();
assertEquals(bytes.remaining(), memory.putBytes(0, tb.addr(offset), bytes));
}
@@ -260,6 +292,21 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
});
}
+ @Test
+ public void testAutoDisassembleGuestX8664WithPcInRegs() throws Throwable {
+ enableAutoDisassembly();
+ getSLEIGH_X86_64_LANGUAGE(); // So that the platform is mapped promptly
+ createPolyglotTrace("x86-64", 0x00400000, () -> tb.buf(0x90, 0x90, 0x90), false);
+
+ waitForPass(() -> {
+ DBTraceInstructionsMemoryView instructions = tb.trace.getCodeManager().instructions();
+ assertMnemonic("NOP", instructions.getAt(0, tb.addr(0x00400000)));
+ assertMnemonic("NOP", instructions.getAt(0, tb.addr(0x00400001)));
+ assertMnemonic("NOP", instructions.getAt(0, tb.addr(0x00400002)));
+ assertNull(instructions.getAt(0, tb.addr(0x00400003)));
+ });
+ }
+
@Test
public void testCurrentDisassembleActionHostArm() throws Throwable {
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x1e, 0xff, 0x2f, 0xe1));
@@ -352,7 +399,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
TraceObjectThread thread =
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x70, 0x47));
- // Set up registers to injects will select THUMB
+ // Set up registers so injects will select THUMB
// TODO
Address start = tb.addr(0x00400000);
diff --git a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/schema/TargetObjectSchema.java b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/schema/TargetObjectSchema.java
index e91e2dc13e..755e85e060 100644
--- a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/schema/TargetObjectSchema.java
+++ b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/schema/TargetObjectSchema.java
@@ -1164,7 +1164,7 @@ public interface TargetObjectSchema {
* {@link TargetStackFrame}, and the frame level (index) must precede it.
*
* @param frameLevel the frame level. May be ignored if not applicable
- * @path the path of the seed object relative to the root
+ * @param path the path of the seed object relative to the root
* @return the predicates where the register container should be found, possibly empty
*/
default PathPredicates searchForRegisterContainer(int frameLevel, List path) {