diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/DBTraceUtils.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/DBTraceUtils.java index d69cd0492e..f6c398c70e 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/DBTraceUtils.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/DBTraceUtils.java @@ -19,7 +19,8 @@ import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URL; import java.nio.ByteBuffer; -import java.util.*; +import java.util.Iterator; +import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Consumer; 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 82242b3f10..1159102161 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 @@ -295,7 +295,9 @@ public class DBTraceMemorySpace if (state == null) { throw new NullPointerException(); } - + var l = new Object() { + boolean changed; + }; new AddressRangeMapSetter, TraceMemoryState>() { @Override protected AddressRange getRange(Entry entry) { @@ -324,6 +326,8 @@ public class DBTraceMemorySpace @Override protected Entry put(AddressRange range, TraceMemoryState value) { + // This should not get called if the range is already the desired state + l.changed = true; if (value != TraceMemoryState.UNKNOWN) { stateMapSpace.put(new ImmutableTraceAddressSnapRange(range, snap), value); } @@ -331,8 +335,10 @@ public class DBTraceMemorySpace } }.set(start, end, state); - trace.setChanged(new TraceChangeRecord<>(TraceMemoryStateChangeType.CHANGED, this, - new ImmutableTraceAddressSnapRange(start, end, snap, snap), state)); + if (l.changed) { + trace.setChanged(new TraceChangeRecord<>(TraceMemoryStateChangeType.CHANGED, this, + new ImmutableTraceAddressSnapRange(start, end, snap, snap), state)); + } } protected void checkState(TraceMemoryState state) { diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/generic/RangeMapSetter.java b/Ghidra/Debug/ProposedUtils/src/main/java/generic/RangeMapSetter.java index 558c131bd8..5017e282b6 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/generic/RangeMapSetter.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/generic/RangeMapSetter.java @@ -188,26 +188,30 @@ public abstract class RangeMapSetter { Map toPut = new HashMap<>(); for (E entry : getIntersecting(prev, next)) { R r = getRange(entry); - boolean precedesMin = compare(getLower(r), lower) < 0; - boolean succeedsMax = compare(getUpper(r), upper) > 0; + int cmpMin = compare(getLower(r), lower); + int cmpMax = compare(getUpper(r), upper); boolean sameVal = Objects.equals(getValue(entry), value); - if (precedesMin && succeedsMax && sameVal) { + if (cmpMin <= 0 && cmpMax >= 0 && sameVal) { return entry; // The value in this range is already set as specified } toRemove.add(entry); - if (precedesMin) { + if (cmpMin < 0) { if (sameVal) { + // Expand the new entry to cover the one we just removed lower = getLower(r); } else { + // Create a truncated entry to replace the one we just removed toPut.put(toSpan(getLower(r), prev), getValue(entry)); } } - if (succeedsMax) { + if (cmpMax > 0) { if (sameVal) { + // Expand the new entry to cover the one we just removed upper = getUpper(r); } else { + // Create a truncated entry to replace the one we just removed toPut.put(toSpan(next, getUpper(r)), getValue(entry)); } }