mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Merge remote-tracking branch 'origin/GP-2834_Dan_hoverVarVals--SQUASHED'
(#4732)
This commit is contained in:
commit
bf5dfa6170
105 changed files with 12279 additions and 478 deletions
|
@ -15,7 +15,10 @@
|
|||
*/
|
||||
package ghidra.pcode.exec.trace;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import generic.ULongSpan.ULongSpanSet;
|
||||
import ghidra.generic.util.datastruct.SemisparseByteArray;
|
||||
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Language;
|
||||
|
@ -38,6 +41,17 @@ public abstract class AbstractCheckedTraceCachedWriteBytesPcodeExecutorStatePiec
|
|||
super(language, space, backing);
|
||||
}
|
||||
|
||||
protected CheckedCachedSpace(Language language, AddressSpace space,
|
||||
PcodeTraceDataAccess backing, SemisparseByteArray bytes, AddressSet written) {
|
||||
super(language, space, backing, bytes, written);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedSpace fork() {
|
||||
return new CheckedCachedSpace(language, space, backing, bytes.fork(),
|
||||
new AddressSet(written));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] read(long offset, int size, Reason reason) {
|
||||
ULongSpanSet uninitialized =
|
||||
|
@ -59,14 +73,34 @@ public abstract class AbstractCheckedTraceCachedWriteBytesPcodeExecutorStatePiec
|
|||
super(data);
|
||||
}
|
||||
|
||||
protected AbstractCheckedTraceCachedWriteBytesPcodeExecutorStatePiece(PcodeTraceDataAccess data,
|
||||
AbstractSpaceMap<CachedSpace> spaceMap) {
|
||||
super(data, spaceMap);
|
||||
}
|
||||
|
||||
protected class CheckedCachedSpaceMap extends TraceBackedSpaceMap {
|
||||
public CheckedCachedSpaceMap() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected CheckedCachedSpaceMap(Map<AddressSpace, CachedSpace> spaces) {
|
||||
super(spaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CachedSpace newSpace(AddressSpace space, PcodeTraceDataAccess backing) {
|
||||
return new CheckedCachedSpace(language, space, backing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckedCachedSpaceMap fork() {
|
||||
return new CheckedCachedSpaceMap(fork(spaces));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractSpaceMap<CachedSpace> newSpaceMap() {
|
||||
return new TraceBackedSpaceMap() {
|
||||
@Override
|
||||
protected CachedSpace newSpace(AddressSpace space, PcodeTraceDataAccess backing) {
|
||||
return new CheckedCachedSpace(language, space, backing);
|
||||
}
|
||||
};
|
||||
return new CheckedCachedSpaceMap();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
package ghidra.pcode.exec.trace;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
|
||||
|
@ -24,6 +23,7 @@ import ghidra.pcode.exec.*;
|
|||
import ghidra.pcode.exec.PcodeArithmetic.Purpose;
|
||||
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,7 @@ public class AddressesReadTracePcodeExecutorStatePiece
|
|||
implements TracePcodeExecutorStatePiece<byte[], AddressSetView> {
|
||||
|
||||
protected final PcodeTraceDataAccess data;
|
||||
private final Map<Long, AddressSetView> unique = new HashMap<>();
|
||||
private final Map<Long, AddressSetView> unique;
|
||||
|
||||
/**
|
||||
* Construct the state piece
|
||||
|
@ -54,6 +54,15 @@ public class AddressesReadTracePcodeExecutorStatePiece
|
|||
super(data.getLanguage(), BytesPcodeArithmetic.forLanguage(data.getLanguage()),
|
||||
AddressesReadPcodeArithmetic.INSTANCE);
|
||||
this.data = data;
|
||||
this.unique = new HashMap<>();
|
||||
}
|
||||
|
||||
protected AddressesReadTracePcodeExecutorStatePiece(PcodeTraceDataAccess data,
|
||||
Map<Long, AddressSetView> unique) {
|
||||
super(data.getLanguage(), BytesPcodeArithmetic.forLanguage(data.getLanguage()),
|
||||
AddressesReadPcodeArithmetic.INSTANCE);
|
||||
this.data = data;
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,11 +75,27 @@ public class AddressesReadTracePcodeExecutorStatePiece
|
|||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddressesReadTracePcodeExecutorStatePiece fork() {
|
||||
return new AddressesReadTracePcodeExecutorStatePiece(data, new HashMap<>(unique));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDown(PcodeTraceDataAccess into) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Register, AddressSetView> getRegisterValuesFromSpace(AddressSpace s,
|
||||
List<Register> registers) {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Register, AddressSetView> getRegisterValues() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AddressSpace getForSpace(AddressSpace space, boolean toWrite) {
|
||||
return space;
|
||||
|
|
|
@ -29,4 +29,13 @@ public class BytesTracePcodeExecutorState extends DefaultTracePcodeExecutorState
|
|||
public BytesTracePcodeExecutorState(PcodeTraceDataAccess data) {
|
||||
super(new BytesTracePcodeExecutorStatePiece(data));
|
||||
}
|
||||
|
||||
protected BytesTracePcodeExecutorState(TracePcodeExecutorStatePiece<byte[], byte[]> piece) {
|
||||
super(piece);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BytesTracePcodeExecutorState fork() {
|
||||
return new BytesTracePcodeExecutorState(piece.fork());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
package ghidra.pcode.exec.trace;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
|
||||
import generic.ULongSpan;
|
||||
import generic.ULongSpan.ULongSpanSet;
|
||||
import ghidra.pcode.exec.AbstractBytesPcodeExecutorStatePiece;
|
||||
import ghidra.pcode.exec.BytesPcodeExecutorStateSpace;
|
||||
import ghidra.generic.util.datastruct.SemisparseByteArray;
|
||||
import ghidra.pcode.exec.*;
|
||||
import ghidra.pcode.exec.trace.BytesTracePcodeExecutorStatePiece.CachedSpace;
|
||||
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
|
||||
import ghidra.program.model.address.*;
|
||||
|
@ -41,11 +42,23 @@ public class BytesTracePcodeExecutorStatePiece
|
|||
|
||||
protected static class CachedSpace
|
||||
extends BytesPcodeExecutorStateSpace<PcodeTraceDataAccess> {
|
||||
protected final AddressSet written = new AddressSet();
|
||||
protected final AddressSet written;
|
||||
|
||||
public CachedSpace(Language language, AddressSpace space, PcodeTraceDataAccess backing) {
|
||||
// Backing could be null, so we need language parameter
|
||||
super(language, space, backing);
|
||||
this.written = new AddressSet();
|
||||
}
|
||||
|
||||
protected CachedSpace(Language language, AddressSpace space, PcodeTraceDataAccess backing,
|
||||
SemisparseByteArray bytes, AddressSet written) {
|
||||
super(language, space, backing, bytes);
|
||||
this.written = written;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedSpace fork() {
|
||||
return new CachedSpace(language, space, backing, bytes.fork(), new AddressSet(written));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -118,11 +131,22 @@ public class BytesTracePcodeExecutorStatePiece
|
|||
this.data = data;
|
||||
}
|
||||
|
||||
protected BytesTracePcodeExecutorStatePiece(PcodeTraceDataAccess data,
|
||||
AbstractSpaceMap<CachedSpace> spaceMap) {
|
||||
super(data.getLanguage(), spaceMap);
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PcodeTraceDataAccess getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BytesTracePcodeExecutorStatePiece fork() {
|
||||
return new BytesTracePcodeExecutorStatePiece(data, spaceMap.fork());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDown(PcodeTraceDataAccess into) {
|
||||
if (into.getLanguage() != language) {
|
||||
|
@ -139,6 +163,14 @@ public class BytesTracePcodeExecutorStatePiece
|
|||
*/
|
||||
protected class TraceBackedSpaceMap
|
||||
extends CacheingSpaceMap<PcodeTraceDataAccess, CachedSpace> {
|
||||
public TraceBackedSpaceMap() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected TraceBackedSpaceMap(Map<AddressSpace, CachedSpace> spaces) {
|
||||
super(spaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PcodeTraceDataAccess getBacking(AddressSpace space) {
|
||||
return data;
|
||||
|
@ -148,6 +180,16 @@ public class BytesTracePcodeExecutorStatePiece
|
|||
protected CachedSpace newSpace(AddressSpace space, PcodeTraceDataAccess backing) {
|
||||
return new CachedSpace(language, space, backing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraceBackedSpaceMap fork() {
|
||||
return new TraceBackedSpaceMap(fork(spaces));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedSpace fork(CachedSpace s) {
|
||||
return s.fork();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -44,6 +44,11 @@ public class DefaultTracePcodeExecutorState<T> extends DefaultPcodeExecutorState
|
|||
return piece.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultTracePcodeExecutorState<T> fork() {
|
||||
return new DefaultTracePcodeExecutorState<>(piece.fork());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDown(PcodeTraceDataAccess into) {
|
||||
piece.writeDown(into);
|
||||
|
|
|
@ -60,6 +60,11 @@ public class DirectBytesTracePcodeExecutorState extends DefaultTracePcodeExecuto
|
|||
super(new DirectBytesTracePcodeExecutorStatePiece(data));
|
||||
}
|
||||
|
||||
protected DirectBytesTracePcodeExecutorState(
|
||||
TracePcodeExecutorStatePiece<byte[], byte[]> piece) {
|
||||
super(piece);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the state
|
||||
*
|
||||
|
@ -83,4 +88,9 @@ public class DirectBytesTracePcodeExecutorState extends DefaultTracePcodeExecuto
|
|||
return new PairedPcodeExecutorState<>(this,
|
||||
new TraceMemoryStatePcodeExecutorStatePiece(getData()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DirectBytesTracePcodeExecutorState fork() {
|
||||
return new DirectBytesTracePcodeExecutorState(piece.fork());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
package ghidra.pcode.exec.trace;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
|
||||
|
@ -27,6 +29,7 @@ import ghidra.pcode.exec.PcodeArithmetic.Purpose;
|
|||
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
|
||||
|
@ -48,7 +51,7 @@ public class DirectBytesTracePcodeExecutorStatePiece
|
|||
|
||||
protected final PcodeTraceDataAccess data;
|
||||
|
||||
protected final SemisparseByteArray unique = new SemisparseByteArray();
|
||||
protected final SemisparseByteArray unique;
|
||||
|
||||
/**
|
||||
* Construct a piece
|
||||
|
@ -57,9 +60,10 @@ public class DirectBytesTracePcodeExecutorStatePiece
|
|||
* @param data the trace-data access shim
|
||||
*/
|
||||
protected DirectBytesTracePcodeExecutorStatePiece(PcodeArithmetic<byte[]> arithmetic,
|
||||
PcodeTraceDataAccess data) {
|
||||
PcodeTraceDataAccess data, SemisparseByteArray unique) {
|
||||
super(data.getLanguage(), arithmetic, arithmetic);
|
||||
this.data = data;
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,7 +72,7 @@ public class DirectBytesTracePcodeExecutorStatePiece
|
|||
* @param data the trace-data access shim
|
||||
*/
|
||||
public DirectBytesTracePcodeExecutorStatePiece(PcodeTraceDataAccess data) {
|
||||
this(BytesPcodeArithmetic.forLanguage(data.getLanguage()), data);
|
||||
this(BytesPcodeArithmetic.forLanguage(data.getLanguage()), data, new SemisparseByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,6 +80,11 @@ public class DirectBytesTracePcodeExecutorStatePiece
|
|||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DirectBytesTracePcodeExecutorStatePiece fork() {
|
||||
return new DirectBytesTracePcodeExecutorStatePiece(arithmetic, data, unique.fork());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a state which computes an expression's {@link TraceMemoryState} as an auxiliary
|
||||
* attribute
|
||||
|
@ -129,6 +138,17 @@ public class DirectBytesTracePcodeExecutorStatePiece
|
|||
return buf.array();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Register, byte[]> getRegisterValuesFromSpace(AddressSpace s,
|
||||
List<Register> registers) {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Register, byte[]> getRegisterValues() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemBuffer getConcreteBuffer(Address address, Purpose purpose) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -30,30 +30,30 @@ import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
|
|||
public class PairedTracePcodeExecutorState<L, R> extends PairedPcodeExecutorState<L, R>
|
||||
implements TracePcodeExecutorState<Pair<L, R>> {
|
||||
|
||||
private final TracePcodeExecutorStatePiece<L, L> left;
|
||||
private final TracePcodeExecutorStatePiece<L, R> right;
|
||||
private final PairedTracePcodeExecutorStatePiece<L, L, R> piece;
|
||||
|
||||
public PairedTracePcodeExecutorState(PairedTracePcodeExecutorStatePiece<L, L, R> piece) {
|
||||
super(piece);
|
||||
this.left = piece.getLeft();
|
||||
this.right = piece.getRight();
|
||||
this.piece = piece;
|
||||
}
|
||||
|
||||
public PairedTracePcodeExecutorState(TracePcodeExecutorState<L> left,
|
||||
TracePcodeExecutorStatePiece<L, R> right) {
|
||||
super(left, right);
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this(new PairedTracePcodeExecutorStatePiece<>(left, right));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PcodeTraceDataAccess getData() {
|
||||
return left.getData();
|
||||
return piece.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PairedTracePcodeExecutorState<L, R> fork() {
|
||||
return new PairedTracePcodeExecutorState<>(piece.fork());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDown(PcodeTraceDataAccess into) {
|
||||
left.writeDown(into);
|
||||
right.writeDown(into);
|
||||
piece.writeDown(into);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,12 @@ public class PairedTracePcodeExecutorStatePiece<A, L, R>
|
|||
return left.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PairedTracePcodeExecutorStatePiece<A, L, R> fork() {
|
||||
return new PairedTracePcodeExecutorStatePiece<>(left.fork(), right.fork(),
|
||||
getAddressArithmetic(), getArithmetic());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDown(PcodeTraceDataAccess into) {
|
||||
left.writeDown(into);
|
||||
|
|
|
@ -31,4 +31,14 @@ public class RequireHasKnownTraceCachedWriteBytesPcodeExecutorState
|
|||
public RequireHasKnownTraceCachedWriteBytesPcodeExecutorState(PcodeTraceDataAccess data) {
|
||||
super(new RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece(data));
|
||||
}
|
||||
|
||||
protected RequireHasKnownTraceCachedWriteBytesPcodeExecutorState(
|
||||
TracePcodeExecutorStatePiece<byte[], byte[]> piece) {
|
||||
super(piece);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequireHasKnownTraceCachedWriteBytesPcodeExecutorState fork() {
|
||||
return new RequireHasKnownTraceCachedWriteBytesPcodeExecutorState(piece.fork());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,17 @@ public class RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece
|
|||
super(data);
|
||||
}
|
||||
|
||||
protected RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece(PcodeTraceDataAccess data,
|
||||
AbstractSpaceMap<CachedSpace> spaceMap) {
|
||||
super(data, spaceMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece fork() {
|
||||
return new RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece(data,
|
||||
spaceMap.fork());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AddressSetView getKnown(PcodeTraceDataAccess backing) {
|
||||
return backing.getKnownBefore();
|
||||
|
|
|
@ -31,4 +31,14 @@ public class RequireIsKnownTraceCachedWriteBytesPcodeExecutorState
|
|||
public RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(PcodeTraceDataAccess data) {
|
||||
super(new RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece(data));
|
||||
}
|
||||
|
||||
protected RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(
|
||||
TracePcodeExecutorStatePiece<byte[], byte[]> piece) {
|
||||
super(piece);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequireIsKnownTraceCachedWriteBytesPcodeExecutorState fork() {
|
||||
return new RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(piece.fork());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.pcode.exec.trace;
|
||||
|
||||
import ghidra.pcode.exec.AccessPcodeExecutionException;
|
||||
import ghidra.pcode.exec.PcodeExecutorStatePiece;
|
||||
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
|
@ -34,6 +35,17 @@ public class RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece
|
|||
super(data);
|
||||
}
|
||||
|
||||
protected RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece(PcodeTraceDataAccess data,
|
||||
AbstractSpaceMap<CachedSpace> spaceMap) {
|
||||
super(data, spaceMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece fork() {
|
||||
return new RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece(data,
|
||||
spaceMap.fork());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a piece
|
||||
*
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.pcode.exec.trace;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import generic.ULongSpan;
|
||||
|
@ -23,6 +25,7 @@ import ghidra.pcode.exec.*;
|
|||
import ghidra.pcode.exec.PcodeArithmetic.Purpose;
|
||||
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
|
@ -42,7 +45,7 @@ import ghidra.trace.model.memory.TraceMemoryState;
|
|||
public class TraceMemoryStatePcodeExecutorStatePiece extends
|
||||
AbstractLongOffsetPcodeExecutorStatePiece<byte[], TraceMemoryState, AddressSpace> {
|
||||
|
||||
protected final MutableULongSpanMap<TraceMemoryState> unique = new DefaultULongSpanMap<>();
|
||||
protected final MutableULongSpanMap<TraceMemoryState> unique;
|
||||
protected final PcodeTraceDataAccess data;
|
||||
|
||||
/**
|
||||
|
@ -55,6 +58,22 @@ public class TraceMemoryStatePcodeExecutorStatePiece extends
|
|||
BytesPcodeArithmetic.forLanguage(data.getLanguage()),
|
||||
TraceMemoryStatePcodeArithmetic.INSTANCE);
|
||||
this.data = data;
|
||||
this.unique = new DefaultULongSpanMap<>();
|
||||
}
|
||||
|
||||
protected TraceMemoryStatePcodeExecutorStatePiece(PcodeTraceDataAccess data,
|
||||
MutableULongSpanMap<TraceMemoryState> unique) {
|
||||
super(data.getLanguage(), BytesPcodeArithmetic.forLanguage(data.getLanguage()),
|
||||
TraceMemoryStatePcodeArithmetic.INSTANCE);
|
||||
this.data = data;
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraceMemoryStatePcodeExecutorStatePiece fork() {
|
||||
MutableULongSpanMap<TraceMemoryState> copyUnique = new DefaultULongSpanMap<>();
|
||||
copyUnique.putAll(unique);
|
||||
return new TraceMemoryStatePcodeExecutorStatePiece(data, copyUnique);
|
||||
}
|
||||
|
||||
protected AddressRange range(AddressSpace space, long offset, int size) {
|
||||
|
@ -107,6 +126,17 @@ public class TraceMemoryStatePcodeExecutorStatePiece extends
|
|||
return TraceMemoryState.UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Register, TraceMemoryState> getRegisterValuesFromSpace(AddressSpace s,
|
||||
List<Register> registers) {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Register, TraceMemoryState> getRegisterValues() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemBuffer getConcreteBuffer(Address address, Purpose purpose) {
|
||||
throw new ConcretionError("Cannot make TraceMemoryState into a concrete buffer", purpose);
|
||||
|
|
|
@ -23,13 +23,14 @@ import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
|
|||
*
|
||||
* <p>
|
||||
* In particular, because this derives from {@link TracePcodeExecutorStatePiece}, such states are
|
||||
* required to implement {@link #writeDown(PcodeTraceDataAccess)}. This interface also
|
||||
* derives from {@link PcodeExecutorState} so that, as the name implies, they can be used where a
|
||||
* state is required.
|
||||
* required to implement {@link #writeDown(PcodeTraceDataAccess)}. This interface also derives from
|
||||
* {@link PcodeExecutorState} so that, as the name implies, they can be used where a state is
|
||||
* required.
|
||||
*
|
||||
* @param <T> the type of values
|
||||
*/
|
||||
public interface TracePcodeExecutorState<T>
|
||||
extends PcodeExecutorState<T>, TracePcodeExecutorStatePiece<T, T> {
|
||||
// Nothing to add. Simply a composition of interfaces.
|
||||
@Override
|
||||
TracePcodeExecutorState<T> fork();
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ public interface TracePcodeExecutorStatePiece<A, T> extends PcodeExecutorStatePi
|
|||
*/
|
||||
PcodeTraceDataAccess getData();
|
||||
|
||||
@Override
|
||||
TracePcodeExecutorStatePiece<A, T> fork();
|
||||
|
||||
/**
|
||||
* Write the accumulated values (cache) into the given trace
|
||||
*
|
||||
|
|
|
@ -256,7 +256,7 @@ public class UndefinedDBTraceData implements DBTraceDataAdapter, DBTraceSpaceKey
|
|||
}
|
||||
|
||||
@Override
|
||||
public Data getComponentContaining(int offset) {
|
||||
public TraceData getComponentContaining(int offset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ public interface DBTraceDelegatingManager<M> {
|
|||
|
||||
default void checkIsInMemory(AddressSpace space) {
|
||||
if (!space.isMemorySpace() && space != Address.NO_ADDRESS.getAddressSpace()) {
|
||||
throw new IllegalArgumentException("Address must be in memory or NO_ADDRESS");
|
||||
throw new IllegalArgumentException(
|
||||
"Address must be in memory or NO_ADDRESS. Got " + space);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@ public interface TraceData extends TraceCodeUnit, Data {
|
|||
@Override
|
||||
TraceData getComponentAt(int offset);
|
||||
|
||||
@Override
|
||||
TraceData getComponentContaining(int offset);
|
||||
|
||||
@Override
|
||||
TraceData getComponent(int[] componentPath);
|
||||
|
||||
|
|
|
@ -333,6 +333,29 @@ public interface TraceMemoryOperations {
|
|||
Collection<Entry<TraceAddressSnapRange, TraceMemoryState>> getStates(long snap,
|
||||
AddressRange range);
|
||||
|
||||
/**
|
||||
* Check if a range addresses are all known
|
||||
*
|
||||
* @param snap the time
|
||||
* @param range the range to examine
|
||||
* @return true if the entire range is {@link TraceMemoryState#KNOWN}
|
||||
*/
|
||||
default boolean isKnown(long snap, AddressRange range) {
|
||||
Collection<Entry<TraceAddressSnapRange, TraceMemoryState>> states = getStates(snap, range);
|
||||
if (states.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (states.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
AddressRange entryRange = states.iterator().next().getKey().getRange();
|
||||
if (!entryRange.contains(range.getMinAddress()) ||
|
||||
!entryRange.contains(range.getMaxAddress())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a range of addresses into smaller ranges each mapped to its most recent state at the
|
||||
* given time
|
||||
|
|
|
@ -118,6 +118,9 @@ public interface Scheduler {
|
|||
TickStep slice = nextSlice(trace);
|
||||
eventThread = slice.getThread(tm, eventThread);
|
||||
emuThread = machine.getThread(eventThread.getPath(), true);
|
||||
if (emuThread.getFrame() != null) {
|
||||
emuThread.finishInstruction();
|
||||
}
|
||||
for (int i = 0; i < slice.tickCount; i++) {
|
||||
monitor.checkCanceled();
|
||||
emuThread.stepInstruction();
|
||||
|
|
|
@ -200,7 +200,7 @@ public enum TraceRegisterUtils {
|
|||
public static void requireByteBound(Register register) {
|
||||
if (!isByteBound(register)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot work with sub-byte registers. Consider a parent, instead.");
|
||||
"Cannot work with sub-byte registers. Consider a parent instead.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue