mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-0: Fix tests. Add "requireCanonical" parameter
This commit is contained in:
parent
c198419b7e
commit
ab97c34205
13 changed files with 43 additions and 33 deletions
|
@ -470,7 +470,7 @@ public class ObjectBasedTraceRecorder implements TraceRecorder {
|
|||
public Set<TargetThread> getLiveTargetThreads() {
|
||||
return trace.getObjectManager()
|
||||
.getRootObject()
|
||||
.querySuccessorsInterface(Lifespan.at(getSnap()), TraceObjectThread.class)
|
||||
.querySuccessorsInterface(Lifespan.at(getSnap()), TraceObjectThread.class, true)
|
||||
.map(t -> objectRecorder.getTargetInterface(t.getObject(), TargetThread.class))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
@ -673,9 +673,10 @@ public class ObjectBasedTraceRecorder implements TraceRecorder {
|
|||
public List<TargetBreakpointSpecContainer> collectBreakpointContainers(TargetThread thread) {
|
||||
if (thread == null) {
|
||||
return objectRecorder.collectTargetSuccessors(target,
|
||||
TargetBreakpointSpecContainer.class);
|
||||
TargetBreakpointSpecContainer.class, false);
|
||||
}
|
||||
return objectRecorder.collectTargetSuccessors(thread, TargetBreakpointSpecContainer.class);
|
||||
return objectRecorder.collectTargetSuccessors(thread, TargetBreakpointSpecContainer.class,
|
||||
false);
|
||||
}
|
||||
|
||||
private class BreakpointConvention {
|
||||
|
@ -711,7 +712,8 @@ public class ObjectBasedTraceRecorder implements TraceRecorder {
|
|||
@Override
|
||||
public List<TargetBreakpointLocation> collectBreakpoints(TargetThread thread) {
|
||||
if (thread == null) {
|
||||
return objectRecorder.collectTargetSuccessors(target, TargetBreakpointLocation.class);
|
||||
return objectRecorder.collectTargetSuccessors(target, TargetBreakpointLocation.class,
|
||||
true);
|
||||
}
|
||||
BreakpointConvention convention = new BreakpointConvention(
|
||||
objectRecorder.getTraceInterface(thread, TraceObjectThread.class));
|
||||
|
@ -725,7 +727,8 @@ public class ObjectBasedTraceRecorder implements TraceRecorder {
|
|||
|
||||
@Override
|
||||
public Set<TraceBreakpointKind> getSupportedBreakpointKinds() {
|
||||
return objectRecorder.collectTargetSuccessors(target, TargetBreakpointSpecContainer.class)
|
||||
return objectRecorder
|
||||
.collectTargetSuccessors(target, TargetBreakpointSpecContainer.class, false)
|
||||
.stream()
|
||||
.flatMap(c -> c.getSupportedBreakpointKinds().stream())
|
||||
.map(k -> TraceRecorder.targetToTraceBreakpointKind(k))
|
||||
|
@ -750,7 +753,7 @@ public class ObjectBasedTraceRecorder implements TraceRecorder {
|
|||
@Override
|
||||
public CompletableFuture<Boolean> requestFocus(TargetObject focus) {
|
||||
for (TargetFocusScope scope : objectRecorder.collectTargetSuccessors(target,
|
||||
TargetFocusScope.class)) {
|
||||
TargetFocusScope.class, false)) {
|
||||
if (PathUtils.isAncestor(scope.getPath(), focus.getPath())) {
|
||||
return scope.requestFocus(focus).thenApply(__ -> true).exceptionally(ex -> {
|
||||
ex = AsyncUtils.unwrapThrowable(ex);
|
||||
|
@ -772,7 +775,7 @@ public class ObjectBasedTraceRecorder implements TraceRecorder {
|
|||
@Override
|
||||
public CompletableFuture<Boolean> requestActivation(TargetObject active) {
|
||||
for (TargetActiveScope scope : objectRecorder.collectTargetSuccessors(target,
|
||||
TargetActiveScope.class)) {
|
||||
TargetActiveScope.class, false)) {
|
||||
if (PathUtils.isAncestor(scope.getPath(), active.getPath())) {
|
||||
return scope.requestActivation(active).thenApply(__ -> true).exceptionally(ex -> {
|
||||
ex = AsyncUtils.unwrapThrowable(ex);
|
||||
|
|
|
@ -314,13 +314,14 @@ class ObjectRecorder {
|
|||
}
|
||||
|
||||
protected <T extends TargetObject> List<T> collectTargetSuccessors(TargetObject targetSeed,
|
||||
Class<T> targetIf) {
|
||||
Class<T> targetIf, boolean requireCanonical) {
|
||||
// TODO: Should this really go through the database?
|
||||
TraceObject seed = toTrace(targetSeed);
|
||||
if (seed == null) {
|
||||
return List.of();
|
||||
}
|
||||
return seed.querySuccessorsTargetInterface(Lifespan.at(recorder.getSnap()), targetIf)
|
||||
return seed.querySuccessorsTargetInterface(Lifespan.at(recorder.getSnap()), targetIf,
|
||||
requireCanonical)
|
||||
.map(p -> toTarget(p.getDestination(seed)).as(targetIf))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
|
|
@ -47,10 +47,9 @@ import ghidra.framework.plugintool.annotation.AutoConfigStateField;
|
|||
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
import ghidra.lifecycle.Internal;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.Trace.TraceObjectChangeType;
|
||||
import ghidra.trace.model.Trace.TraceThreadChangeType;
|
||||
import ghidra.trace.model.TraceDomainObjectListener;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.model.program.TraceVariableSnapProgramView;
|
||||
|
@ -641,7 +640,13 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
|||
inactive = curForTrace.snapNoResolve(snap);
|
||||
lastCoordsByTrace.put(trace, inactive);
|
||||
}
|
||||
trace.getProgramView().setSnap(snap);
|
||||
try {
|
||||
trace.getProgramView().setSnap(snap);
|
||||
}
|
||||
catch (TraceClosedException e) {
|
||||
// Whatever. Presumably, a closed event is already queued....
|
||||
Msg.warn(this, "Ignoring snapshot advance for closed trace: " + e);
|
||||
}
|
||||
firePluginEvent(new TraceInactiveCoordinatesPluginEvent(getName(), inactive));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -186,13 +186,13 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
|||
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||
TraceObject root = om.getRootObject();
|
||||
for (TraceObject module : (Iterable<TraceObject>) () -> root
|
||||
.querySuccessorsTargetInterface(Lifespan.at(0), TargetModule.class)
|
||||
.querySuccessorsTargetInterface(Lifespan.at(0), TargetModule.class, true)
|
||||
.map(p -> p.getDestination(root))
|
||||
.iterator()) {
|
||||
String moduleName = module.getCanonicalPath().index();
|
||||
Lifespan span = module.getLife().bound();
|
||||
for (TraceObject section : (Iterable<TraceObject>) () -> module
|
||||
.querySuccessorsTargetInterface(Lifespan.at(0), TargetSection.class)
|
||||
.querySuccessorsTargetInterface(Lifespan.at(0), TargetSection.class, true)
|
||||
.map(p -> p.getDestination(root))
|
||||
.iterator()) {
|
||||
String sectionName = section.getCanonicalPath().index();
|
||||
|
|
|
@ -517,7 +517,7 @@ public class ObjectBasedTraceRecorderTest extends AbstractGhidraHeadedDebuggerGU
|
|||
|
||||
TraceObject traceBank = thread.getObject()
|
||||
.querySuccessorsTargetInterface(Lifespan.at(recorder.getSnap()),
|
||||
TargetRegisterBank.class)
|
||||
TargetRegisterBank.class, false)
|
||||
.map(p -> p.getDestination(thread.getObject()))
|
||||
.findAny()
|
||||
.orElseThrow();
|
||||
|
|
|
@ -618,6 +618,7 @@ public interface TargetObjectSchema {
|
|||
}
|
||||
if (sch.getInterfaces().contains(type) && (parentIsCanonical || !requireCanonical)) {
|
||||
result.addPattern(prefix);
|
||||
return;
|
||||
}
|
||||
if (!visited.add(sch)) {
|
||||
return;
|
||||
|
|
|
@ -283,7 +283,7 @@ public class DBTraceObjectBreakpointLocation
|
|||
return object.getAncestorsRoot(getLifespan(), procMatcher)
|
||||
.flatMap(proc -> proc.getSource(object)
|
||||
.querySuccessorsInterface(getLifespan(),
|
||||
TraceObjectThread.class))
|
||||
TraceObjectThread.class, true))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,9 +226,8 @@ public class DBTraceObjectBreakpointSpec
|
|||
@Override
|
||||
public Collection<? extends TraceObjectBreakpointLocation> getLocations() {
|
||||
try (LockHold hold = object.getTrace().lockRead()) {
|
||||
return object
|
||||
.querySuccessorsInterface(getLifespan(), TraceObjectBreakpointLocation.class)
|
||||
.collect(Collectors.toSet());
|
||||
return object.querySuccessorsInterface(getLifespan(),
|
||||
TraceObjectBreakpointLocation.class, true).collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -242,7 +242,8 @@ public enum DBTraceObjectRegisterSupport {
|
|||
protected void onSpaceAddedCheckTransferToPlatformRegisters(TracePlatform platform,
|
||||
TraceObject regContainer, TraceMemorySpace mem) {
|
||||
for (TraceObjectValPath path : it(
|
||||
regContainer.querySuccessorsTargetInterface(Lifespan.ALL, TargetRegister.class))) {
|
||||
regContainer.querySuccessorsTargetInterface(Lifespan.ALL, TargetRegister.class,
|
||||
true))) {
|
||||
TraceObject registerObject =
|
||||
path.getDestination(platform.getTrace().getObjectManager().getRootObject());
|
||||
onSpaceAddedCheckTransferObjectToPlatformRegister(registerObject, platform, mem);
|
||||
|
@ -437,7 +438,7 @@ public enum DBTraceObjectRegisterSupport {
|
|||
public void onMappingAddedCheckTransferMemoryMapped(TraceObject root,
|
||||
TraceGuestPlatformMappedRange mapped) {
|
||||
for (TraceObjectValPath path : it(
|
||||
root.querySuccessorsTargetInterface(Lifespan.ALL, TargetRegister.class))) {
|
||||
root.querySuccessorsTargetInterface(Lifespan.ALL, TargetRegister.class, true))) {
|
||||
TraceObject registerObject = path.getDestination(root);
|
||||
onMappingAddedCheckTransferRegisterObjectMemoryMapped(registerObject, mapped);
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ public class DBTraceObjectModule implements TraceObjectModule, DBTraceObjectInte
|
|||
@Override
|
||||
public Collection<? extends TraceObjectSection> getSections() {
|
||||
try (LockHold hold = object.getTrace().lockRead()) {
|
||||
return object.querySuccessorsInterface(getLifespan(), TraceObjectSection.class)
|
||||
return object.querySuccessorsInterface(getLifespan(), TraceObjectSection.class, true)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,8 +93,7 @@ public class DBTraceObjectStack implements TraceObjectStack, DBTraceObjectInterf
|
|||
@Override
|
||||
public int getDepth() {
|
||||
try (LockHold hold = object.getTrace().lockRead()) {
|
||||
return object
|
||||
.querySuccessorsInterface(computeSpan(), TraceObjectStackFrame.class)
|
||||
return object.querySuccessorsInterface(computeSpan(), TraceObjectStackFrame.class, true)
|
||||
.map(f -> f.getLevel())
|
||||
.reduce(Integer::max)
|
||||
.map(m -> m + 1)
|
||||
|
@ -210,8 +209,7 @@ public class DBTraceObjectStack implements TraceObjectStack, DBTraceObjectInterf
|
|||
}
|
||||
|
||||
protected Stream<TraceObjectStackFrame> doGetFrames(long snap) {
|
||||
return object
|
||||
.querySuccessorsInterface(Lifespan.at(snap), TraceObjectStackFrame.class)
|
||||
return object.querySuccessorsInterface(Lifespan.at(snap), TraceObjectStackFrame.class, true)
|
||||
.sorted(Comparator.comparing(f -> f.getLevel()));
|
||||
}
|
||||
|
||||
|
|
|
@ -876,16 +876,16 @@ public class DBTraceObject extends DBAnnotatedObject implements TraceObject {
|
|||
|
||||
@Override
|
||||
public Stream<? extends TraceObjectValPath> querySuccessorsTargetInterface(Lifespan span,
|
||||
Class<? extends TargetObject> targetIf) {
|
||||
PathMatcher matcher = getTargetSchema().searchFor(targetIf, true);
|
||||
Class<? extends TargetObject> targetIf, boolean requireCanonical) {
|
||||
PathMatcher matcher = getTargetSchema().searchFor(targetIf, requireCanonical);
|
||||
return getSuccessors(span, matcher).filter(p -> isActuallyInterface(p, targetIf));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I extends TraceObjectInterface> Stream<I> querySuccessorsInterface(Lifespan span,
|
||||
Class<I> ifClass) {
|
||||
return querySuccessorsTargetInterface(span, TraceObjectInterfaceUtils.toTargetIf(ifClass))
|
||||
.map(p -> p.getDestination(this).queryInterface(ifClass));
|
||||
Class<I> ifClass, boolean requireCanonical) {
|
||||
return querySuccessorsTargetInterface(span, TraceObjectInterfaceUtils.toTargetIf(ifClass),
|
||||
requireCanonical).map(p -> p.getDestination(this).queryInterface(ifClass));
|
||||
}
|
||||
|
||||
protected void doDelete() {
|
||||
|
|
|
@ -466,10 +466,11 @@ public interface TraceObject extends TraceUniqueObject {
|
|||
*
|
||||
* @param span the span which the found paths must intersect
|
||||
* @param targetIf the target interface class
|
||||
* @param requireCanonical if the objects must be found within their canonical container
|
||||
* @return the stream of found paths to values
|
||||
*/
|
||||
Stream<? extends TraceObjectValPath> querySuccessorsTargetInterface(Lifespan span,
|
||||
Class<? extends TargetObject> targetIf);
|
||||
Class<? extends TargetObject> targetIf, boolean requireCanonical);
|
||||
|
||||
/**
|
||||
* Search for successors providing the given interface and retrieve those interfaces
|
||||
|
@ -477,10 +478,11 @@ public interface TraceObject extends TraceUniqueObject {
|
|||
* @param <I> the interface type
|
||||
* @param span the span which the found objects must intersect
|
||||
* @param ifClass the interface class
|
||||
* @param requireCanonical if the objects must be found within their canonical container
|
||||
* @return the stream of interfaces
|
||||
*/
|
||||
<I extends TraceObjectInterface> Stream<I> querySuccessorsInterface(Lifespan span,
|
||||
Class<I> ifClass);
|
||||
Class<I> ifClass, boolean requireCanonical);
|
||||
|
||||
/**
|
||||
* Delete this object along with parent and child value entries referring to it
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue