mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
GP-3857: Port most Debugger components to TraceRmi.
This commit is contained in:
parent
7e4d2bcfaa
commit
fd4380c07a
222 changed files with 7241 additions and 3752 deletions
|
@ -365,6 +365,10 @@ public class DBTraceObjectBreakpointLocation
|
|||
return object;
|
||||
}
|
||||
|
||||
public TraceObjectBreakpointSpec getOrCreateSpecification() {
|
||||
return object.queryOrCreateCanonicalAncestorInterface(TraceObjectBreakpointSpec.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraceObjectBreakpointSpec getSpecification() {
|
||||
try (LockHold hold = object.getTrace().lockRead()) {
|
||||
|
|
|
@ -46,7 +46,7 @@ public class DBTraceObjectBreakpointSpec
|
|||
implements TraceObjectBreakpointSpec, DBTraceObjectInterface {
|
||||
private final DBTraceObject object;
|
||||
|
||||
private TraceBreakpointKindSet kinds;
|
||||
private TraceBreakpointKindSet kinds = TraceBreakpointKindSet.of();
|
||||
|
||||
public DBTraceObjectBreakpointSpec(DBTraceObject object) {
|
||||
this.object = object;
|
||||
|
|
|
@ -312,7 +312,8 @@ public class DBTraceObjectMemoryRegion implements TraceObjectMemoryRegion, DBTra
|
|||
public Set<TraceMemoryFlag> getFlags(long snap) {
|
||||
EnumSet<TraceMemoryFlag> result = EnumSet.noneOf(TraceMemoryFlag.class);
|
||||
for (TraceMemoryFlag flag : TraceMemoryFlag.values()) {
|
||||
if (object.getValue(snap, keyForFlag(flag)) != null) {
|
||||
TraceObjectValue value = object.getValue(snap, keyForFlag(flag));
|
||||
if (value != null && value.getValue() == Boolean.TRUE) {
|
||||
result.add(flag);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -863,6 +863,22 @@ public class DBTraceObject extends DBAnnotatedObject implements TraceObject {
|
|||
.map(p -> p.getSource(this).queryInterface(ifClass));
|
||||
}
|
||||
|
||||
public TraceObject queryOrCreateCanonicalAncestorTargetInterface(
|
||||
Class<? extends TargetObject> targetIf) {
|
||||
PathMatcher matcher = getManager().getRootSchema().searchFor(targetIf, false);
|
||||
return path.streamMatchingAncestry(matcher)
|
||||
.limit(1)
|
||||
.map(kp -> manager.createObject(kp))
|
||||
.findAny()
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
public <I extends TraceObjectInterface> I queryOrCreateCanonicalAncestorInterface(
|
||||
Class<I> ifClass) {
|
||||
return queryOrCreateCanonicalAncestorTargetInterface(
|
||||
TraceObjectInterfaceUtils.toTargetIf(ifClass)).queryInterface(ifClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<? extends TraceObject> queryCanonicalAncestorsTargetInterface(
|
||||
Class<? extends TargetObject> targetIf) {
|
||||
|
|
|
@ -37,6 +37,7 @@ import ghidra.program.model.address.*;
|
|||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.trace.database.DBTrace;
|
||||
import ghidra.trace.database.DBTraceManager;
|
||||
import ghidra.trace.database.breakpoint.DBTraceObjectBreakpointLocation;
|
||||
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMap;
|
||||
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree.TraceAddressSnapRangeQuery;
|
||||
import ghidra.trace.database.module.TraceObjectSection;
|
||||
|
@ -45,8 +46,7 @@ import ghidra.trace.database.target.visitors.SuccessorsRelativeVisitor;
|
|||
import ghidra.trace.database.thread.DBTraceObjectThread;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.Trace.TraceObjectChangeType;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceObjectBreakpointLocation;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.modules.TraceObjectModule;
|
||||
import ghidra.trace.model.stack.TraceObjectStack;
|
||||
|
@ -599,14 +599,17 @@ public class DBTraceObjectManager implements TraceObjectManager, DBTraceManager
|
|||
"breakpoint specification on the given path.");
|
||||
}
|
||||
try (LockHold hold = trace.lockWrite()) {
|
||||
TraceObjectBreakpointLocation loc =
|
||||
doAddWithInterface(path, TraceObjectBreakpointLocation.class);
|
||||
DBTraceObjectBreakpointLocation loc =
|
||||
(DBTraceObjectBreakpointLocation) doAddWithInterface(path,
|
||||
TraceObjectBreakpointLocation.class);
|
||||
loc.setName(lifespan, path);
|
||||
loc.setRange(lifespan, range);
|
||||
// NB. Ignore threads. I'd like to deprecate that field, anyway.
|
||||
loc.setKinds(lifespan, kinds);
|
||||
loc.setEnabled(lifespan, enabled);
|
||||
loc.setComment(lifespan, comment);
|
||||
|
||||
TraceObjectBreakpointSpec spec = loc.getOrCreateSpecification();
|
||||
// NB. Ignore threads. I'd like to deprecate that field, anyway.
|
||||
spec.setKinds(lifespan, kinds);
|
||||
loc.getObject().insert(lifespan, ConflictResolution.DENY);
|
||||
return loc;
|
||||
}
|
||||
|
|
|
@ -89,7 +89,8 @@ public class CanonicalSuccessorsRelativeVisitor implements Visitor {
|
|||
|
||||
Stream<TraceObjectValue> restStream = nextKeys.stream()
|
||||
.filter(k -> !"".equals(k) && !"[]".equals(k))
|
||||
.map(k -> getCanonicalValue(object, k));
|
||||
.map(k -> getCanonicalValue(object, k))
|
||||
.filter(v -> v != null);
|
||||
|
||||
return Stream.concat(Stream.concat(attrStream, elemStream), restStream);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package ghidra.trace.database.target.visitors;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import ghidra.trace.model.Lifespan;
|
||||
|
@ -180,6 +181,7 @@ public enum TreeTraversal {
|
|||
*/
|
||||
public Stream<? extends TraceObjectValPath> walkValue(Visitor visitor,
|
||||
TraceObjectValue value, Lifespan span, TraceObjectValPath path) {
|
||||
Objects.requireNonNull(value);
|
||||
Lifespan compSpan = visitor.composeSpan(span, value);
|
||||
if (compSpan == null) {
|
||||
return Stream.empty();
|
||||
|
|
|
@ -52,7 +52,7 @@ public interface TraceMemoryManager extends TraceMemoryOperations {
|
|||
* <p>
|
||||
* NOTE: We are also moving away from (space, thread, frame) triples to uniquely identify
|
||||
* register storage. Instead, that will be encoded into the address space itself. Register
|
||||
* overlays will overlay register space as be named after the register container object, which
|
||||
* overlays will overlay register space and be named after the register container object, which
|
||||
* subsumes thread and frame when applicable.
|
||||
*
|
||||
* @param name the name of the new address space
|
||||
|
|
|
@ -26,7 +26,6 @@ import ghidra.dbg.util.PathPattern;
|
|||
import ghidra.dbg.util.PathPredicates;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.Lifespan.LifeSet;
|
||||
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
||||
|
||||
/**
|
||||
* The trace record of an observed {@link TargetObject}
|
||||
|
|
|
@ -32,6 +32,7 @@ import db.DBHandle;
|
|||
import db.Transaction;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
||||
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
|
||||
import ghidra.dbg.util.PathPredicates;
|
||||
import ghidra.pcode.exec.*;
|
||||
import ghidra.pcode.exec.trace.TraceSleighUtils;
|
||||
|
@ -49,12 +50,15 @@ import ghidra.trace.database.bookmark.*;
|
|||
import ghidra.trace.database.listing.*;
|
||||
import ghidra.trace.database.memory.DBTraceMemoryManager;
|
||||
import ghidra.trace.database.symbol.DBTraceReference;
|
||||
import ghidra.trace.database.target.DBTraceObjectManager;
|
||||
import ghidra.trace.database.thread.DBTraceThreadManager;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.guest.TraceGuestPlatform;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.symbol.TraceReferenceManager;
|
||||
import ghidra.trace.model.target.*;
|
||||
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.database.DBOpenMode;
|
||||
|
@ -754,6 +758,33 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
|||
return getLanguage(langID).getCompilerSpecByID(new CompilerSpecID(compID));
|
||||
}
|
||||
|
||||
public void createObjectsProcessAndThreads() {
|
||||
DBTraceObjectManager objs = trace.getObjectManager();
|
||||
TraceObjectKeyPath pathProc1 = TraceObjectKeyPath.parse("Processes[1]");
|
||||
TraceObject proc1 = objs.createObject(pathProc1);
|
||||
Lifespan zeroOn = Lifespan.nowOn(0);
|
||||
proc1.insert(zeroOn, ConflictResolution.DENY);
|
||||
TraceObject t1 = objs.createObject(pathProc1.key("Threads").index(1));
|
||||
t1.insert(zeroOn, ConflictResolution.DENY);
|
||||
TraceObject t2 = objs.createObject(pathProc1.key("Threads").index(2));
|
||||
t2.insert(zeroOn, ConflictResolution.DENY);
|
||||
|
||||
proc1.setAttribute(zeroOn, "_state", TargetExecutionState.STOPPED.name());
|
||||
}
|
||||
|
||||
public void createObjectsFramesAndRegs(TraceObjectThread thread, Lifespan lifespan,
|
||||
TracePlatform platform, int n) {
|
||||
DBTraceObjectManager objs = trace.getObjectManager();
|
||||
TraceObjectKeyPath pathThread = thread.getObject().getCanonicalPath();
|
||||
for (int i = 0; i < n; i++) {
|
||||
TraceObjectKeyPath pathContainer = pathThread.key("Stack").index(i).key("Registers");
|
||||
for (Register reg : platform.getLanguage().getRegisters()) {
|
||||
TraceObject regObj = objs.createObject(pathContainer.index(reg.getName()));
|
||||
regObj.insert(lifespan, ConflictResolution.DENY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object by its canonical path
|
||||
*
|
||||
|
@ -765,7 +796,6 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
|||
.getObjectByCanonicalPath(TraceObjectKeyPath.parse(canonicalPath));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an object by its path pattern
|
||||
*
|
||||
|
@ -775,8 +805,10 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
|||
public TraceObject objAny(String pat) {
|
||||
return objAny(pat, Lifespan.at(0));
|
||||
}
|
||||
|
||||
public TraceObject objAny(String path, Lifespan span) {
|
||||
return trace.getObjectManager().getObjectsByPath(span, TraceObjectKeyPath.parse(path))
|
||||
return trace.getObjectManager()
|
||||
.getObjectsByPath(span, TraceObjectKeyPath.parse(path))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
@ -795,7 +827,7 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* List all values matching the given pattern at the given stnap.
|
||||
* List all values matching the given pattern at the given snap.
|
||||
*
|
||||
* @param snap the snap
|
||||
* @param pattern the pattern
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue