From 2fb29027217a8d1699c3a1c454c2cb845897acf9 Mon Sep 17 00:00:00 2001 From: Dan <46821332+nsadeveloper789@users.noreply.github.com> Date: Fri, 31 Mar 2023 10:10:00 -0400 Subject: [PATCH] GP-0: Fixes post GP-1529 --- .../BytesTracePcodeExecutorStatePiece.java | 6 ++- ...chedWriteBytesPcodeExecutorStatePiece.java | 4 +- ...chedWriteBytesPcodeExecutorStatePiece.java | 6 +-- .../data/AbstractPcodeTraceDataAccess.java | 41 ++++++++----------- .../data/DefaultPcodeTraceThreadAccess.java | 15 ++----- .../exec/trace/data/PcodeTraceDataAccess.java | 32 +-------------- .../database/memory/DBTraceMemoryManager.java | 7 +++- .../database/memory/DBTraceMemorySpace.java | 13 +++--- .../model/memory/TraceMemoryOperations.java | 16 +++++++- .../ghidra/trace/util/TraceRegisterUtils.java | 28 +++++++++++++ .../trace/BytesTracePcodeEmulatorTest.java | 17 ++++++++ .../full/TaintDebuggerPcodeEmulatorTest.java | 25 +++++++---- .../exec/BytesPcodeExecutorStateSpace.java | 10 ++++- .../exec/DecodePcodeExecutionException.java | 2 +- 14 files changed, 129 insertions(+), 93 deletions(-) diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/BytesTracePcodeExecutorStatePiece.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/BytesTracePcodeExecutorStatePiece.java index 1d1710bd72..c4e08694c5 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/BytesTracePcodeExecutorStatePiece.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/BytesTracePcodeExecutorStatePiece.java @@ -76,6 +76,10 @@ public class BytesTracePcodeExecutorStatePiece } } + protected AddressSetView intersectViewKnown(AddressSetView set) { + return backing.intersectViewKnown(set, true); + } + @Override protected ULongSpanSet readUninitializedFromBacking(ULongSpanSet uninitialized) { if (uninitialized.isEmpty()) { @@ -84,7 +88,7 @@ public class BytesTracePcodeExecutorStatePiece // TODO: Warn or bail when reading UNKNOWN bytes // NOTE: Read without regard to gaps // NOTE: Cannot write those gaps, though!!! - AddressSetView knownButUninit = backing.intersectViewKnown(addrSet(uninitialized)); + AddressSetView knownButUninit = intersectViewKnown(addrSet(uninitialized)); if (knownButUninit.isEmpty()) { return uninitialized; } diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece.java index 990ebbb2f2..46e7ee3474 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece.java @@ -52,8 +52,8 @@ public class RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece } @Override - protected AddressSetView getKnown(PcodeTraceDataAccess backing) { - return backing.getKnownBefore(); + protected AddressSetView getKnown(PcodeTraceDataAccess backing, AddressSetView set) { + return backing.intersectViewKnown(set, true); } @Override diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece.java index e487911a18..e33df8cc8b 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece.java @@ -50,8 +50,8 @@ public class RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece spaceMap.fork()); } - protected AddressSetView getKnown(PcodeTraceDataAccess backing) { - return backing.getKnownNow(); + protected AddressSetView getKnown(PcodeTraceDataAccess backing, AddressSetView set) { + return backing.intersectViewKnown(set, false); } protected AccessPcodeExecutionException excFor(AddressSetView unknown) { @@ -68,7 +68,7 @@ public class RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece throw excFor(uninitialized); } // TODO: Could find first instead? - AddressSetView unknown = uninitialized.subtract(getKnown(backing)); + AddressSetView unknown = uninitialized.subtract(getKnown(backing, uninitialized)); if (unknown.isEmpty()) { return size; } diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/AbstractPcodeTraceDataAccess.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/AbstractPcodeTraceDataAccess.java index ff0c8a9452..532ea340e5 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/AbstractPcodeTraceDataAccess.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/AbstractPcodeTraceDataAccess.java @@ -23,6 +23,7 @@ import ghidra.trace.model.Lifespan; import ghidra.trace.model.TraceTimeViewport; import ghidra.trace.model.guest.TracePlatform; import ghidra.trace.model.memory.*; +import ghidra.trace.util.TraceRegisterUtils; /** * An abstract data-access shim, for either memory or registers @@ -130,27 +131,8 @@ public abstract class AbstractPcodeTraceDataAccess implements InternalPcodeTrace return hostSet.isEmpty() ? TraceMemoryState.KNOWN : TraceMemoryState.UNKNOWN; } - protected AddressSetView doGetKnown(Lifespan span) { - TraceMemoryOperations ops = getMemoryOps(false); - if (ops == null) { - return new AddressSet(); - } - return platform.mapHostToGuest(ops.getAddressesWithState(span, - s -> s == TraceMemoryState.KNOWN)); - } - @Override - public AddressSetView getKnownNow() { - return doGetKnown(Lifespan.at(snap)); - } - - @Override - public AddressSetView getKnownBefore() { - return doGetKnown(Lifespan.since(snap)); - } - - @Override - public AddressSetView intersectViewKnown(AddressSetView guestView) { + public AddressSetView intersectViewKnown(AddressSetView guestView, boolean useFullSpans) { TraceMemoryOperations ops = getMemoryOps(false); if (ops == null) { return new AddressSet(); @@ -158,11 +140,20 @@ public abstract class AbstractPcodeTraceDataAccess implements InternalPcodeTrace AddressSetView hostView = toOverlay(platform.mapGuestToHost(guestView)); AddressSet hostKnown = new AddressSet(); - for (long sn : viewport.getOrderedSnaps()) { - hostKnown.add(ops.getAddressesWithState(sn, hostView, - st -> st != null && st != TraceMemoryState.UNKNOWN)); + if (useFullSpans) { + for (Lifespan span : viewport.getOrderedSpans()) { + hostKnown.add(ops.getAddressesWithState(span, hostView, + st -> st != null && st != TraceMemoryState.UNKNOWN)); + } } - AddressSetView hostResult = hostView.intersect(hostKnown); + else { + for (long snap : viewport.getOrderedSnaps()) { + hostKnown.add(ops.getAddressesWithState(snap, hostView, + st -> st != null && st != TraceMemoryState.UNKNOWN)); + } + } + AddressSetView hostResult = + TraceRegisterUtils.getPhysicalSet(hostView.intersect(hostKnown)); return platform.mapHostToGuest(hostResult); } @@ -176,7 +167,7 @@ public abstract class AbstractPcodeTraceDataAccess implements InternalPcodeTrace AddressSetView hostView = toOverlay(platform.mapGuestToHost(guestView)); AddressSetView hostKnown = ops.getAddressesWithState(snap, hostView, s -> s != null && s != TraceMemoryState.UNKNOWN); - AddressSetView hostResult = hostView.subtract(hostKnown); + AddressSetView hostResult = TraceRegisterUtils.getPhysicalSet(hostView.subtract(hostKnown)); return platform.mapHostToGuest(hostResult); } diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/DefaultPcodeTraceThreadAccess.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/DefaultPcodeTraceThreadAccess.java index 2456b8027f..d6eaf8bb51 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/DefaultPcodeTraceThreadAccess.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/DefaultPcodeTraceThreadAccess.java @@ -71,18 +71,9 @@ public class DefaultPcodeTraceThreadAccess } @Override - public AddressSetView getKnownNow() { - return memory.getKnownNow().union(registers.getKnownNow()); - } - - @Override - public AddressSetView getKnownBefore() { - return memory.getKnownBefore().union(registers.getKnownBefore()); - } - - @Override - public AddressSetView intersectViewKnown(AddressSetView view) { - return memory.intersectViewKnown(view).union(registers.intersectViewKnown(view)); + public AddressSetView intersectViewKnown(AddressSetView view, boolean useFullSpans) { + return memory.intersectViewKnown(view, useFullSpans) + .union(registers.intersectViewKnown(view, useFullSpans)); } @Override diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/PcodeTraceDataAccess.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/PcodeTraceDataAccess.java index 71f68a4d49..3d4e6d66f4 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/PcodeTraceDataAccess.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/data/PcodeTraceDataAccess.java @@ -63,43 +63,15 @@ public interface PcodeTraceDataAccess { */ TraceMemoryState getViewportState(AddressRange range); - /** - * Get the address set of {@link TraceMemoryState#KNOWN} memory in the source snapshot - * - *
- * Note, this does not consider the snapshot's viewport. - * - * @implNote This can be an expensive operation when the platform is a guest, since what would - * ordinarily be a lazy address set must be computed and translated to the guest - * address spaces. - * - * @return the address set - */ - AddressSetView getKnownNow(); - - /** - * Get the address set of {@link TraceMemoryState#KNOWN} memory among all snapshots from 0 to - * the source snapshot - * - *
- * Note, this does not consider the snapshot's viewport.
- *
- * @implNote This can be an expensive operation when the platform is a guest, since what would
- * ordinarily be a lazy address set must be computed and translated to the guest
- * address spaces.
- *
- * @return the address set
- */
- AddressSetView getKnownBefore();
-
/**
* Compute the intersection of the given address set and the set of
* {@link TraceMemoryState#KNOWN} or (@link {@link TraceMemoryState#ERROR} memory
*
* @param view the address set
+ * @param useFullSpans how to treat the viewport; true for ever known, false for known now.
* @return the intersection
*/
- AddressSetView intersectViewKnown(AddressSetView view);
+ AddressSetView intersectViewKnown(AddressSetView view, boolean useFullSpans);
/**
* Compute the intersection of the given address set and the set of
diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemoryManager.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemoryManager.java
index 94e7483997..59599946b3 100644
--- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemoryManager.java
+++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemoryManager.java
@@ -290,7 +290,7 @@ public class DBTraceMemoryManager extends AbstractDBTraceSpaceBasedManager