diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java index 7f6d6d4527..3498d7301a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java @@ -580,6 +580,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter { for (WatchRow row : watchTableModel.getModelData()) { AddressSet reads = row.getReads(); if (reads == null || reads.intersects(changed)) { + row.doTargetReads(); row.reevaluate(); } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecutorState.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecutorState.java index 9521114ebd..7be22c72ba 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecutorState.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecutorState.java @@ -21,11 +21,13 @@ import java.util.concurrent.CompletableFuture; import ghidra.app.services.TraceRecorder; import ghidra.pcode.exec.trace.TraceBytesPcodeExecutorState; +import ghidra.pcode.exec.trace.TraceMemoryStatePcodeExecutorStatePiece; import ghidra.pcode.utils.Utils; import ghidra.program.model.address.AddressSet; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.lang.*; import ghidra.trace.model.memory.TraceMemoryRegisterSpace; +import ghidra.trace.model.memory.TraceMemoryState; import ghidra.trace.model.thread.TraceThread; import ghidra.trace.util.TraceRegisterUtils; import ghidra.util.task.TaskMonitor; @@ -34,12 +36,15 @@ public class TraceRecorderAsyncPcodeExecutorState extends AsyncWrappedPcodeExecutorState { private final TraceRecorder recorder; private final TraceBytesPcodeExecutorState traceState; + private final TraceMemoryStatePcodeExecutorStatePiece traceMemState; public TraceRecorderAsyncPcodeExecutorState(TraceRecorder recorder, long snap, TraceThread thread, int frame) { super(new TraceBytesPcodeExecutorState(recorder.getTrace(), snap, thread, frame)); this.recorder = recorder; this.traceState = (TraceBytesPcodeExecutorState) state; + this.traceMemState = + new TraceMemoryStatePcodeExecutorStatePiece(recorder.getTrace(), snap, thread, frame); } protected CompletableFuture doSetTargetVar(AddressSpace space, long offset, int size, @@ -119,6 +124,10 @@ public class TraceRecorderAsyncPcodeExecutorState return super.doGetVar(space, offset, size, truncateAddressableUnit); } return offset.thenCompose(off -> { + TraceMemoryState ms = traceMemState.getVar(space, off, size, truncateAddressableUnit); + if (ms == TraceMemoryState.KNOWN) { + return super.doGetVar(space, offset, size, truncateAddressableUnit); + } return doGetTargetVar(space, traceState.offsetToLong(off), size, truncateAddressableUnit); }); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/TraceMemoryStatePcodeExecutorStatePiece.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/TraceMemoryStatePcodeExecutorStatePiece.java index 9a5a2cee02..8d320d4458 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/TraceMemoryStatePcodeExecutorStatePiece.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/TraceMemoryStatePcodeExecutorStatePiece.java @@ -152,6 +152,11 @@ public class TraceMemoryStatePcodeExecutorStatePiece extends return set.isEmpty() ? TraceMemoryState.KNOWN : TraceMemoryState.UNKNOWN; } + @Override + protected TraceMemoryState getFromNullSpace(int size) { + return TraceMemoryState.UNKNOWN; + } + @Override public MemBuffer getConcreteBuffer(Address address) { throw new AssertionError("Cannot make TraceMemoryState into a concrete buffer"); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java index 02be120bb6..4cee258694 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java @@ -695,11 +695,22 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace return result; } + protected int truncateLen(int len, Address start) { + long maxLen = start.getAddressSpace().getMaxAddress().subtract(start) + 1; + if (maxLen == 0) { + // Only happens when min=0 and max=ffff_ffff_ffff_ffff + return len; + } + return MathUtilities.unsignedMin(len, maxLen); + } + @Override public int getViewBytes(long snap, Address start, ByteBuffer buf) { AddressRange toRead; - int len = MathUtilities.unsignedMin(buf.remaining(), - start.getAddressSpace().getMaxAddress().subtract(start) + 1); + int len = truncateLen(buf.remaining(), start); + if (len == 0) { + return 0; + } try { toRead = new AddressRangeImpl(start, len); } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/AbstractLongOffsetPcodeExecutorStatePiece.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/AbstractLongOffsetPcodeExecutorStatePiece.java index 2094b89618..92a19100c2 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/AbstractLongOffsetPcodeExecutorStatePiece.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/AbstractLongOffsetPcodeExecutorStatePiece.java @@ -52,6 +52,10 @@ public abstract class AbstractLongOffsetPcodeExecutorStatePiece protected abstract T getFromSpace(S space, long offset, int size); + protected T getFromNullSpace(int size) { + return arithmetic.fromConst(0, size); + } + protected abstract long offsetToLong(A offset); @Override @@ -90,7 +94,7 @@ public abstract class AbstractLongOffsetPcodeExecutorStatePiece } S s = getForSpace(space, false); if (s == null) { - return arithmetic.fromConst(0, size); + return getFromNullSpace(size); } offset = truncateOffset(space, offset); return getFromSpace(s, offset, size);