Merge remote-tracking branch 'origin/patch'

Conflicts:
	Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java
This commit is contained in:
ghidra1 2022-02-28 12:40:04 -05:00
commit 2d3f68c16d
5 changed files with 67 additions and 24 deletions

View file

@ -44,8 +44,8 @@ import ghidra.trace.model.*;
import ghidra.trace.model.Trace.*;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.DefaultTraceTimeViewport;
import ghidra.trace.util.TraceChangeRecord;
import ghidra.trace.util.TraceViewportSpanIterator;
import ghidra.util.*;
import ghidra.util.AddressIteratorAdapter;
import ghidra.util.database.*;
@ -93,6 +93,8 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace
.build()
.asMap();
protected final DefaultTraceTimeViewport viewport;
public DBTraceMemorySpace(DBTraceMemoryManager manager, DBHandle dbh, AddressSpace space,
DBTraceSpaceEntry ent) throws IOException, VersionException {
this.manager = manager;
@ -127,6 +129,8 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace
true);
this.blocksByOffset =
blockStore.getIndex(OffsetSnap.class, DBTraceMemoryBlockEntry.LOCATION_COLUMN);
this.viewport = new DefaultTraceTimeViewport(trace);
}
private void regionCacheEntryRemoved(
@ -375,9 +379,7 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace
@Override
public Entry<Long, TraceMemoryState> getViewState(long snap, Address address) {
TraceViewportSpanIterator spit = new TraceViewportSpanIterator(trace, snap);
while (spit.hasNext()) {
Range<Long> span = spit.next();
for (Range<Long> span : viewport.getOrderedSpans(snap)) {
TraceMemoryState state = getState(span.upperEndpoint(), address);
switch (state) {
case KNOWN:
@ -403,9 +405,7 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace
@Override
public Entry<TraceAddressSnapRange, TraceMemoryState> getViewMostRecentStateEntry(long snap,
Address address) {
TraceViewportSpanIterator spit = new TraceViewportSpanIterator(trace, snap);
while (spit.hasNext()) {
Range<Long> span = spit.next();
for (Range<Long> span: viewport.getOrderedSpans(snap)) {
Entry<TraceAddressSnapRange, TraceMemoryState> entry =
stateMapSpace.reduce(TraceAddressSnapRangeQuery.mostRecent(address, span))
.firstEntry();
@ -738,9 +738,8 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace
}
Map<AddressRange, Long> sources = new TreeMap<>();
AddressSet remains = new AddressSet(toRead);
TraceViewportSpanIterator spit = new TraceViewportSpanIterator(trace, snap);
spans: while (spit.hasNext()) {
Range<Long> span = spit.next();
spans: for (Range<Long> span : viewport.getOrderedSpans(snap)) {
Iterator<AddressRange> arit =
getAddressesWithState(span, s -> s == TraceMemoryState.KNOWN).iterator(start, true);
while (arit.hasNext()) {
@ -765,7 +764,9 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace
int offset = (int) rng.getMinAddress().subtract(toRead.getMinAddress());
int length = (int) rng.getLength();
buf.limit(pos + offset + length);
buf.position(pos + offset);
while (buf.position() < pos + offset) {
buf.put((byte) 0); // fill gaps with 0
}
int read = getBytes(ent.getValue(), rng.getMinAddress(), buf);
if (read < length) {
break;
@ -773,7 +774,9 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace
}
// We "got it all", even if there were gaps in "KNOWN"
buf.limit(lim);
buf.position(pos + len);
while (buf.position() < pos + len) {
buf.put((byte) 0); // fill final gap with 0
}
return len;
}

View file

@ -100,22 +100,20 @@ public class DefaultTraceTimeViewport implements TraceTimeViewport {
}
protected final Trace trace;
protected final TraceTimeManager timeManager;
/**
* NB: This is the syncing object for the viewport. If there's even a chance an operation may
* need the DB's lock, esp., considering user callbacks, then it must <em>first</em> acquire the
* DB lock.
* NB: This is also the syncing object for the viewport. If there's even a chance an operation
* may need the DB's lock, esp., considering user callbacks, then it must <em>first</em> acquire
* the DB lock.
*/
protected final List<Range<Long>> ordered = new ArrayList<>();
protected final List<Range<Long>> ordered = new ArrayList<>(List.of(Range.singleton(0L)));
protected final RangeSet<Long> spanSet = TreeRangeSet.create();
protected final ForSnapshotsListener listener = new ForSnapshotsListener();
protected final ListenerSet<Runnable> changeListeners = new ListenerSet<>(Runnable.class);
protected long snap;
protected long snap = 0;
public DefaultTraceTimeViewport(Trace trace) {
this.trace = trace;
this.timeManager = trace.getTimeManager();
trace.addCloseListener(listener);
trace.addListener(listener);
}
@ -266,7 +264,7 @@ public class DefaultTraceTimeViewport implements TraceTimeViewport {
RangeSet<Long> spanSet = TreeRangeSet.create();
List<Range<Long>> ordered = new ArrayList<>();
try (LockHold hold = trace.lockRead()) {
collectForkRanges(timeManager, snap, spanSet, ordered);
collectForkRanges(trace.getTimeManager(), snap, spanSet, ordered);
}
synchronized (this.ordered) {
this.spanSet.clear();
@ -279,6 +277,9 @@ public class DefaultTraceTimeViewport implements TraceTimeViewport {
}
public void setSnap(long snap) {
if (this.snap == snap) {
return;
}
this.snap = snap;
refreshSnapRanges();
}
@ -329,6 +330,19 @@ public class DefaultTraceTimeViewport implements TraceTimeViewport {
}
}
public List<Range<Long>> getOrderedSpans() {
synchronized (ordered) {
return List.copyOf(ordered);
}
}
public List<Range<Long>> getOrderedSpans(long snap) {
synchronized (ordered) {
setSnap(snap);
return getOrderedSpans();
}
}
@Override
public List<Long> getOrderedSnaps() {
synchronized (ordered) {