GP-740: Removed TargetObjectRef and cleaned up.

This commit is contained in:
Dan 2021-03-01 15:14:27 -05:00
parent b9f9c69be4
commit 6614b54248
328 changed files with 3177 additions and 4428 deletions

View file

@ -31,13 +31,17 @@ import ghidra.dbg.target.schema.*;
import ghidra.program.model.address.AddressRange;
import ghidra.util.datastruct.WeakValueHashMap;
@TargetObjectSchemaInfo(name = "BreakpointContainer", elements = { //
@TargetElementType(type = JdiModelTargetBreakpointSpec.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(
name = "BreakpointContainer",
elements = { //
@TargetElementType(type = JdiModelTargetBreakpointSpec.class) //
},
attributes = { //
@TargetAttributeType(type = Void.class) //
},
canonicalContainer = true)
public class JdiModelTargetBreakpointContainer extends JdiModelTargetObjectImpl implements
TargetBreakpointContainer<JdiModelTargetBreakpointContainer>, JdiEventsListenerAdapter {
TargetBreakpointContainer, JdiEventsListenerAdapter {
protected static final TargetBreakpointKindSet SUPPORTED_KINDS =
TargetBreakpointKindSet.of(TargetBreakpointKind.values());

View file

@ -28,18 +28,20 @@ import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
import ghidra.dbg.util.CollectionUtils.Delta;
import ghidra.util.datastruct.ListenerSet;
@TargetObjectSchemaInfo(name = "BreakpointSpec", attributes = { //
@TargetAttributeType( //
@TargetObjectSchemaInfo(
name = "BreakpointSpec",
attributes = { //
@TargetAttributeType( //
name = TargetBreakpointSpec.CONTAINER_ATTRIBUTE_NAME, //
type = JdiModelTargetBreakpointContainer.class), //
@TargetAttributeType( //
@TargetAttributeType( //
name = TargetBreakpointLocation.SPEC_ATTRIBUTE_NAME, //
type = JdiModelTargetBreakpointSpec.class), //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetBreakpointSpec extends JdiModelTargetObjectImpl implements //
TargetBreakpointSpec<JdiModelTargetBreakpointSpec>, //
JdiModelTargetDeletable<JdiModelTargetBreakpointSpec> {
@TargetAttributeType(type = Void.class) //
},
canonicalContainer = true)
public class JdiModelTargetBreakpointSpec extends JdiModelTargetObjectImpl
implements TargetBreakpointSpec, JdiModelTargetDeletable {
protected JdiBreakpointInfo info;
protected TargetBreakpointKindSet kinds;

View file

@ -29,18 +29,34 @@ import ghidra.dbg.target.TargetMethod.ParameterDescription;
import ghidra.dbg.target.TargetMethod.TargetParameterMap;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "Connector", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Description", type = String.class, required = true, fixed = true), //
@TargetAttributeType(name = "Default Arguments", type = Object.class, required = true, fixed = true), //
@TargetAttributeType(name = "Transport", type = Object.class, required = true, fixed = true), //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(
name = "Connector",
elements = {
@TargetElementType(type = Void.class)
},
attributes = {
@TargetAttributeType(
name = "Description",
type = String.class,
required = true,
fixed = true),
@TargetAttributeType(
name = "Default Arguments",
type = Object.class,
required = true,
fixed = true),
@TargetAttributeType(
name = "Transport",
type = Object.class,
required = true,
fixed = true),
@TargetAttributeType(type = Void.class)
},
canonicalContainer = true)
public class JdiModelTargetConnector extends JdiModelTargetObjectImpl
implements JdiModelSelectableObject,
// TODO: Make a JidModelTargetLaunchingConnector and JdiModelTargetAttachingConnector
JdiModelTargetLauncher<JdiModelTargetConnector> {
JdiModelTargetLauncher {
protected final JdiModelTargetConnectorContainer connectors;
protected final Connector cx;

View file

@ -27,11 +27,15 @@ import ghidra.async.AsyncUtils;
import ghidra.dbg.target.schema.*;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(name = "ConnectorContainer", elements = { //
@TargetElementType(type = JdiModelTargetConnector.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(
name = "ConnectorContainer",
elements = {
@TargetElementType(type = JdiModelTargetConnector.class)
},
attributes = {
@TargetAttributeType(type = Void.class)
},
canonicalContainer = true)
public class JdiModelTargetConnectorContainer extends JdiModelTargetObjectImpl {
protected final JdiModelTargetRoot root;

View file

@ -24,14 +24,18 @@ import ghidra.dbg.target.TargetSection;
import ghidra.dbg.target.schema.*;
import ghidra.program.model.address.AddressRange;
@TargetObjectSchemaInfo(name = "ConstantPool", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(
name = "ConstantPool",
elements = { //
@TargetElementType(type = Void.class) //
},
attributes = { //
@TargetAttributeType(type = Void.class) //
},
canonicalContainer = true)
public class JdiModelTargetConstantPool extends JdiModelTargetObjectImpl implements //
//TargetMemory<JdiModelTargetSection>,
TargetMemoryRegion<JdiModelTargetConstantPool>, TargetSection<JdiModelTargetConstantPool> {
TargetMemoryRegion, TargetSection {
private AddressRange range;
private byte[] pool;

View file

@ -30,13 +30,17 @@ import ghidra.dbg.target.schema.*;
import ghidra.lifecycle.Internal;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(name = "TargetModuleContainer", elements = { //
@TargetElementType(type = JdiModelTargetModule.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(
name = "TargetModuleContainer",
elements = { //
@TargetElementType(type = JdiModelTargetModule.class) //
},
attributes = { //
@TargetAttributeType(type = Void.class) //
},
canonicalContainer = true)
public class JdiModelTargetModuleContainer extends JdiModelTargetObjectImpl
implements TargetModuleContainer<JdiModelTargetModuleContainer> {
implements TargetModuleContainer {
protected final JdiModelTargetVM vm;
@ -75,7 +79,7 @@ public class JdiModelTargetModuleContainer extends JdiModelTargetObjectImpl
}
@Override
public CompletableFuture<? extends TargetModule<?>> addSyntheticModule(String name) {
public CompletableFuture<? extends TargetModule> addSyntheticModule(String name) {
throw new DebuggerUserException("GDB Does not support synthetic modules");
}

View file

@ -30,16 +30,17 @@ import ghidra.dbg.target.schema.*;
import ghidra.lifecycle.Internal;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(name = "Process", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "state", type = TargetExecutionState.class, hidden = true), //
@TargetAttributeType(type = Void.class) //
})
public class JdiModelTargetProcess extends JdiModelTargetObjectImpl implements //
JdiModelTargetConsole<JdiModelTargetProcess>, //
JdiConsoleOutputListener, //
JdiModelSelectableObject {
@TargetObjectSchemaInfo(
name = "Process",
elements = {
@TargetElementType(type = Void.class)
},
attributes = {
@TargetAttributeType(name = "state", type = TargetExecutionState.class, hidden = true),
@TargetAttributeType(type = Void.class)
})
public class JdiModelTargetProcess extends JdiModelTargetObjectImpl
implements JdiModelTargetConsole, JdiConsoleOutputListener, JdiModelSelectableObject {
public static String getUniqueId(Process obj) {
return Long.toHexString(obj.pid());

View file

@ -27,14 +27,16 @@ import ghidra.dbg.target.schema.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRangeImpl;
@TargetObjectSchemaInfo(name = "ReferenceType", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class), //
@TargetAttributeType(type = Object.class) //
})
public class JdiModelTargetReferenceType extends JdiModelTargetType implements //
TargetModule<JdiModelTargetReferenceType> {
@TargetObjectSchemaInfo(
name = "ReferenceType",
elements = {
@TargetElementType(type = Void.class)
},
attributes = {
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class),
@TargetAttributeType(type = Object.class)
})
public class JdiModelTargetReferenceType extends JdiModelTargetType implements TargetModule {
protected final ReferenceType reftype;
private long maxInstances = 100;

View file

@ -27,16 +27,18 @@ import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.ConversionUtils;
import ghidra.program.model.address.Address;
@TargetObjectSchemaInfo(name = "RegisterDescriptor", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType( //
name = TargetRegister.CONTAINER_ATTRIBUTE_NAME, //
type = JdiModelTargetRegisterContainer.class), //
@TargetAttributeType(type = Void.class) //
})
public class JdiModelTargetRegister extends JdiModelTargetObjectImpl implements //
TargetRegister<JdiModelTargetRegister> {
@TargetObjectSchemaInfo(
name = "RegisterDescriptor",
elements = {
@TargetElementType(type = Void.class)
},
attributes = {
@TargetAttributeType(
name = TargetRegister.CONTAINER_ATTRIBUTE_NAME,
type = JdiModelTargetRegisterContainer.class),
@TargetAttributeType(type = Void.class)
})
public class JdiModelTargetRegister extends JdiModelTargetObjectImpl implements TargetRegister {
protected final String name;
protected Address addr;

View file

@ -26,14 +26,17 @@ import ghidra.dbg.target.TargetRegisterContainer;
import ghidra.dbg.target.schema.*;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(name = "TargetRegisterContainer", elements = { //
@TargetElementType(type = JdiModelTargetRegister.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(
name = "TargetRegisterContainer",
elements = {
@TargetElementType(type = JdiModelTargetRegister.class)
},
attributes = {
@TargetAttributeType(type = Void.class)
},
canonicalContainer = true)
public class JdiModelTargetRegisterContainer extends JdiModelTargetObjectImpl
implements TargetRegisterBank<JdiModelTargetRegisterContainer>,
TargetRegisterContainer<JdiModelTargetRegisterContainer> {
implements TargetRegisterBank, TargetRegisterContainer {
private final Map<String, JdiModelTargetRegister> registersByName = new HashMap<>();

View file

@ -25,17 +25,17 @@ import com.sun.jdi.connect.Connector.Argument;
import ghidra.async.AsyncUtils;
import ghidra.dbg.DebugModelConventions;
import ghidra.dbg.agent.AbstractTargetObject;
import ghidra.dbg.agent.DefaultTargetModelRoot;
import ghidra.dbg.attributes.TargetObjectRef;
import ghidra.dbg.error.DebuggerIllegalArgumentException;
import ghidra.dbg.jdi.manager.*;
import ghidra.dbg.jdi.model.iface1.*;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.*;
import ghidra.dbg.target.TargetAccessConditioned.TargetAccessibilityListener;
import ghidra.dbg.target.TargetFocusScope.TargetFocusScopeListener;
import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher;
import ghidra.dbg.target.TargetMethod.TargetParameterMap;
import ghidra.dbg.target.TargetObject.TargetUpdateMode;
import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils;
import ghidra.util.Msg;
/**
@ -48,23 +48,38 @@ import ghidra.util.Msg;
* {@link DebugModelConventions#findSuitable(Class, TargetObject)} requires a unique answer. That
* would mean neither attach nor launch will be enabled anywhere except on a connector....
*/
@TargetObjectSchemaInfo(name = "Debugger", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class, required = true, fixed = true), //
@TargetAttributeType(name = "Connectors", type = JdiModelTargetConnectorContainer.class, required = true, fixed = true), //
@TargetAttributeType(name = "VirtualMachines", type = JdiModelTargetVMContainer.class, required = true, fixed = true), //
@TargetAttributeType(type = Void.class) //
})
@TargetObjectSchemaInfo(
name = "Debugger",
elements = { //
@TargetElementType(type = Void.class) //
},
attributes = { //
@TargetAttributeType(
name = "Attributes",
type = JdiModelTargetAttributesContainer.class,
required = true,
fixed = true), //
@TargetAttributeType(
name = "Connectors",
type = JdiModelTargetConnectorContainer.class,
required = true,
fixed = true), //
@TargetAttributeType(
name = "VirtualMachines",
type = JdiModelTargetVMContainer.class,
required = true,
fixed = true), //
@TargetAttributeType(type = Void.class) //
})
public class JdiModelTargetRoot extends DefaultTargetModelRoot implements //
JdiModelTargetAccessConditioned<JdiModelTargetRoot>, //
//JdiModelTargetAttacher<JdiModelTargetRoot>, //
JdiModelTargetFocusScope<JdiModelTargetRoot>, //
//TargetFocusScope<JdiModelTargetRoot>, //
//JdiModelTargetInterpreter<JdiModelTargetRoot>, //
JdiModelTargetInterruptible<JdiModelTargetRoot>, //
JdiModelTargetLauncher<JdiModelTargetRoot>, //
JdiModelTargetEventScope<JdiModelTargetRoot>, //
JdiModelTargetAccessConditioned, //
//JdiModelTargetAttacher, //
JdiModelTargetFocusScope, //
//TargetFocusScope, //
//JdiModelTargetInterpreter, //
JdiModelTargetInterruptible, //
JdiModelTargetLauncher, //
JdiModelTargetEventScope, //
JdiEventsListenerAdapter {
protected static final String JDB_PROMPT = ">";
@ -76,7 +91,7 @@ public class JdiModelTargetRoot extends DefaultTargetModelRoot implements //
protected final JdiModelTargetConnectorContainer connectors;
protected JdiModelTargetAttributesContainer addedAttributes;
private TargetAccessibility accessibility = TargetAccessibility.ACCESSIBLE;
private boolean accessible = true;
protected JdiModelSelectableObject focus;
protected String debugger = "Jdi"; // Used by JdiModelTargetEnvironment
@ -96,7 +111,7 @@ public class JdiModelTargetRoot extends DefaultTargetModelRoot implements //
connectors, //
addedAttributes //
), Map.of( //
ACCESSIBLE_ATTRIBUTE_NAME, accessibility == TargetAccessibility.ACCESSIBLE, //
ACCESSIBLE_ATTRIBUTE_NAME, accessible, //
DISPLAY_ATTRIBUTE_NAME, display, //
TargetMethod.PARAMETERS_ATTRIBUTE_NAME, TargetCmdLineLauncher.PARAMETERS, //
UPDATE_MODE_ATTRIBUTE_NAME, TargetUpdateMode.FIXED //
@ -163,22 +178,22 @@ public class JdiModelTargetRoot extends DefaultTargetModelRoot implements //
setFocus(f);
}
public void setAccessibility(TargetAccessibility accessibility) {
public void setAccessible(boolean accessible) {
synchronized (attributes) {
if (this.accessibility == accessibility) {
if (this.accessible == accessible) {
return;
}
this.accessibility = accessibility;
this.accessible = accessible;
changeAttributes(List.of(), List.of(), Map.of( //
ACCESSIBLE_ATTRIBUTE_NAME, accessibility == TargetAccessibility.ACCESSIBLE //
ACCESSIBLE_ATTRIBUTE_NAME, accessible //
), "Accessibility changed");
}
listeners.fire(TargetAccessibilityListener.class).accessibilityChanged(this, accessibility);
listeners.fire(TargetAccessibilityListener.class).accessibilityChanged(this, accessible);
}
@Override
public TargetAccessibility getAccessibility() {
return accessibility;
public boolean isAccessible() {
return accessible;
}
@Override
@ -238,34 +253,6 @@ public class JdiModelTargetRoot extends DefaultTargetModelRoot implements //
return AsyncUtils.NIL;
}
@Override
public CompletableFuture<Void> requestFocus(TargetObjectRef ref) {
impl.assertMine(TargetObjectRef.class, ref);
/**
* Yes, this is pointless, since I'm the root, but do it right (TM), since this may change
* or be used as an example for other implementations.
*/
if (!PathUtils.isAncestor(this.getPath(), ref.getPath())) {
throw new DebuggerIllegalArgumentException("Can only focus a successor of the scope");
}
return ref.fetch().thenCompose(obj -> {
TargetObject cur = obj;
while (cur != null) {
if (cur instanceof JdiModelSelectableObject) {
JdiModelSelectableObject sel = (JdiModelSelectableObject) cur;
return sel.select();
}
if (cur instanceof AbstractTargetObject) {
AbstractTargetObject<?> def = (AbstractTargetObject<?>) cur;
cur = def.getImplParent();
continue;
}
throw new AssertionError();
}
return AsyncUtils.NIL;
});
}
protected void invalidateMemoryAndRegisterCaches() {
vms.invalidateMemoryAndRegisterCaches();
}

View file

@ -26,14 +26,17 @@ import ghidra.dbg.target.TargetSection;
import ghidra.dbg.target.schema.*;
import ghidra.program.model.address.AddressRange;
@TargetObjectSchemaInfo(name = "Section", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
})
@TargetObjectSchemaInfo(
name = "Section",
elements = {
@TargetElementType(type = Void.class)
},
attributes = {
@TargetAttributeType(type = Void.class)
})
public class JdiModelTargetSection extends JdiModelTargetObjectImpl implements //
//TargetMemory<JdiModelTargetSection>,
TargetMemoryRegion<JdiModelTargetSection>, TargetSection<JdiModelTargetSection> {
TargetMemoryRegion, TargetSection {
protected final Method method;
private AddressRange range;

View file

@ -26,13 +26,17 @@ import ghidra.dbg.target.schema.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
@TargetObjectSchemaInfo(name = "TargetSectionContainer", elements = { //
@TargetElementType(type = JdiModelTargetSection.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(
name = "TargetSectionContainer",
elements = {
@TargetElementType(type = JdiModelTargetSection.class)
},
attributes = {
@TargetAttributeType(type = Void.class)
},
canonicalContainer = true)
public class JdiModelTargetSectionContainer extends JdiModelTargetObjectImpl
implements TargetMemory<JdiModelTargetSectionContainer> {
implements TargetMemory {
protected final JdiModelTargetReferenceType reftype;

View file

@ -26,13 +26,17 @@ import ghidra.dbg.target.schema.*;
import ghidra.util.Msg;
import ghidra.util.datastruct.WeakValueHashMap;
@TargetObjectSchemaInfo(name = "Stack", elements = { //
@TargetElementType(type = JdiModelTargetStackFrame.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(
name = "Stack",
elements = {
@TargetElementType(type = JdiModelTargetStackFrame.class)
},
attributes = {
@TargetAttributeType(type = Void.class)
},
canonicalContainer = true)
public class JdiModelTargetStack extends JdiModelTargetObjectImpl
implements TargetStack<JdiModelTargetStack> {
implements TargetStack {
protected final JdiModelTargetThread thread;

View file

@ -34,14 +34,17 @@ import ghidra.dbg.target.schema.*;
import ghidra.program.model.address.Address;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(name = "StackFrame", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(type = Object.class) //
})
@TargetObjectSchemaInfo(
name = "StackFrame",
elements = {
@TargetElementType(type = Void.class)
},
attributes = {
@TargetAttributeType(type = Object.class)
})
public class JdiModelTargetStackFrame extends JdiModelTargetObjectImpl
implements TargetStackFrame<JdiModelTargetStackFrame>, //
//TargetRegisterBank<JdiModelTargetStackFrame>, //
implements TargetStackFrame, //
//TargetRegisterBank, //
JdiEventsListenerAdapter, //
JdiModelSelectableObject {
@ -127,7 +130,7 @@ public class JdiModelTargetStackFrame extends JdiModelTargetObjectImpl
@Override
public void threadSelected(ThreadReference eventThread, StackFrame eventFrame, JdiCause cause) {
if (eventThread.equals(thread.thread) && eventFrame.equals(frame)) {
AtomicReference<JdiModelTargetFocusScope<?>> scope = new AtomicReference<>();
AtomicReference<JdiModelTargetFocusScope> scope = new AtomicReference<>();
AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
DebugModelConventions.findSuitable(JdiModelTargetFocusScope.class, this)
.handle(seq::next);

View file

@ -34,25 +34,37 @@ import ghidra.dbg.target.schema.*;
import ghidra.lifecycle.Internal;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(name = "Thread", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class), //
@TargetAttributeType(name = "Registers", type = JdiModelTargetRegisterContainer.class, required = true, fixed = true), //
@TargetAttributeType(name = "Stack", type = JdiModelTargetStack.class, required = true, fixed = true), //
@TargetAttributeType(name = "Status", type = Integer.class), //
@TargetAttributeType(name = "UID", type = Long.class, fixed = true), //
@TargetAttributeType(type = Object.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(
name = "Thread",
elements = { //
@TargetElementType(type = Void.class)
},
attributes = {
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class),
@TargetAttributeType(
name = "Registers",
type = JdiModelTargetRegisterContainer.class,
required = true,
fixed = true),
@TargetAttributeType(
name = "Stack",
type = JdiModelTargetStack.class,
required = true,
fixed = true),
@TargetAttributeType(name = "Status", type = Integer.class),
@TargetAttributeType(name = "UID", type = Long.class, fixed = true),
@TargetAttributeType(type = Object.class) //
},
canonicalContainer = true)
public class JdiModelTargetThread extends JdiModelTargetObjectReference implements //
TargetThread<JdiModelTargetThread>, //
JdiModelTargetAccessConditioned<JdiModelTargetThread>, //
JdiModelTargetExecutionStateful<JdiModelTargetThread>, //
JdiModelTargetInterruptible<JdiModelTargetThread>, //
JdiModelTargetKillable<JdiModelTargetThread>, //
JdiModelTargetResumable<JdiModelTargetThread>, //
JdiModelTargetSteppable<JdiModelTargetThread>, //
//TargetSuspendable<JdiModelTargetThread>,
TargetThread, //
JdiModelTargetAccessConditioned, //
JdiModelTargetExecutionStateful, //
JdiModelTargetInterruptible, //
JdiModelTargetKillable, //
JdiModelTargetResumable, //
JdiModelTargetSteppable, //
// TargetSuspendable,
JdiEventsListenerAdapter, //
JdiModelSelectableObject {
@ -177,6 +189,7 @@ public class JdiModelTargetThread extends JdiModelTargetObjectReference implemen
return CompletableFuture.completedFuture(null);
}
@Override
public CompletableFuture<Void> init() {
AsyncFence fence = new AsyncFence();
//fence.include(requestAttributes(true));
@ -264,7 +277,7 @@ public class JdiModelTargetThread extends JdiModelTargetObjectReference implemen
@Override
public void threadSelected(ThreadReference eventThread, StackFrame frame, JdiCause cause) {
if (eventThread.equals(thread) && frame == null) {
AtomicReference<JdiModelTargetFocusScope<?>> scope = new AtomicReference<>();
AtomicReference<JdiModelTargetFocusScope> scope = new AtomicReference<>();
AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
DebugModelConventions.findSuitable(JdiModelTargetFocusScope.class, this)
.handle(seq::next);
@ -400,9 +413,7 @@ public class JdiModelTargetThread extends JdiModelTargetObjectReference implemen
}
@Override
public TargetAccessibility getAccessibility() {
return thread.isSuspended() ? TargetAccessibility.ACCESSIBLE
: TargetAccessibility.INACCESSIBLE;
public boolean isAccessible() {
return thread.isSuspended();
}
}

View file

@ -30,14 +30,17 @@ import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
import ghidra.dbg.target.schema.*;
import ghidra.util.datastruct.WeakValueHashMap;
@TargetObjectSchemaInfo(name = "ThreadContainer", elements = { //
@TargetElementType(type = JdiModelTargetThread.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetThreadContainer extends JdiModelTargetObjectImpl implements //
JdiModelTargetEventScope<JdiModelTargetThreadContainer>, //
JdiEventsListenerAdapter {
@TargetObjectSchemaInfo(
name = "ThreadContainer",
elements = {
@TargetElementType(type = JdiModelTargetThread.class)
},
attributes = {
@TargetAttributeType(type = Void.class)
},
canonicalContainer = true)
public class JdiModelTargetThreadContainer extends JdiModelTargetObjectImpl
implements JdiModelTargetEventScope, JdiEventsListenerAdapter {
private List<ThreadReference> threads;

View file

@ -45,28 +45,46 @@ import ghidra.lifecycle.Internal;
* TODO: Implementing {@link TargetLauncher} here doesn't seem right. While it's convenient from a
* UI perspective, it doesn't make sense semantically.
*/
@TargetObjectSchemaInfo(name = "VM", elements = { //
// @TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class), //
@TargetAttributeType(name = "Breakpoints", type = JdiModelTargetBreakpointContainer.class, fixed = true), //
@TargetAttributeType(name = "Classes", type = JdiModelTargetClassContainer.class, fixed = true), //
@TargetAttributeType(name = "Modules", type = JdiModelTargetModuleContainer.class, fixed = true), //
@TargetAttributeType(name = "Threads", type = JdiModelTargetThreadContainer.class, required = true, fixed = true), //
@TargetAttributeType(name = "ThreadGroups", type = JdiModelTargetThreadGroupContainer.class, fixed = true), //
@TargetAttributeType(type = Object.class) //
}, canonicalContainer = true)
@TargetObjectSchemaInfo(name = "VM", elements = {
// @TargetElementType(type = Void.class)
},
attributes = {
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class),
@TargetAttributeType(
name = "Breakpoints",
type = JdiModelTargetBreakpointContainer.class,
fixed = true),
@TargetAttributeType(
name = "Classes",
type = JdiModelTargetClassContainer.class,
fixed = true),
@TargetAttributeType(
name = "Modules",
type = JdiModelTargetModuleContainer.class,
fixed = true),
@TargetAttributeType(
name = "Threads",
type = JdiModelTargetThreadContainer.class,
required = true,
fixed = true),
@TargetAttributeType(
name = "ThreadGroups",
type = JdiModelTargetThreadGroupContainer.class,
fixed = true),
@TargetAttributeType(type = Object.class)
},
canonicalContainer = true)
public class JdiModelTargetVM extends JdiModelTargetObjectImpl implements //
TargetProcess<JdiModelTargetVM>, //
TargetProcess, //
TargetAggregate, //
JdiModelTargetEnvironment<JdiModelTargetVM>, //
JdiModelTargetAccessConditioned<JdiModelTargetVM>, //
JdiModelTargetExecutionStateful<JdiModelTargetVM>, //
JdiModelTargetLauncher<JdiModelTargetVM>, //
JdiModelTargetDeletable<JdiModelTargetVM>, //
JdiModelTargetKillable<JdiModelTargetVM>, //
JdiModelTargetResumable<JdiModelTargetVM>, //
JdiModelTargetInterruptible<JdiModelTargetVM>, //
JdiModelTargetEnvironment, //
JdiModelTargetAccessConditioned, //
JdiModelTargetExecutionStateful, //
JdiModelTargetLauncher, //
JdiModelTargetDeletable, //
JdiModelTargetKillable, //
JdiModelTargetResumable, //
JdiModelTargetInterruptible, //
JdiEventsListenerAdapter, //
JdiModelSelectableObject {
@ -139,7 +157,7 @@ public class JdiModelTargetVM extends JdiModelTargetObjectImpl implements //
threads //
), Map.of( //
STATE_ATTRIBUTE_NAME, TargetExecutionState.ALIVE, //
ACCESSIBLE_ATTRIBUTE_NAME, getAccessibility() == TargetAccessibility.ACCESSIBLE, //
ACCESSIBLE_ATTRIBUTE_NAME, isAccessible(), //
DISPLAY_ATTRIBUTE_NAME, updateDisplay(), //
ARCH_ATTRIBUTE_NAME, vm.name(), //
DEBUGGER_ATTRIBUTE_NAME, vm.description(), //
@ -306,7 +324,7 @@ public class JdiModelTargetVM extends JdiModelTargetObjectImpl implements //
@Override
public void vmSelected(VirtualMachine eventVM, JdiCause cause) {
if (eventVM.equals(vm)) {
AtomicReference<JdiModelTargetFocusScope<?>> scope = new AtomicReference<>();
AtomicReference<JdiModelTargetFocusScope> scope = new AtomicReference<>();
AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
DebugModelConventions.findSuitable(JdiModelTargetFocusScope.class, this)
.handle(seq::next);
@ -435,12 +453,13 @@ public class JdiModelTargetVM extends JdiModelTargetObjectImpl implements //
}
@Override
public TargetAccessibility getAccessibility() {
public boolean isAccessible() {
for (JdiModelTargetThread thread : threads.threadsById.values()) {
if (thread.getAccessibility() == TargetAccessibility.ACCESSIBLE)
return TargetAccessibility.ACCESSIBLE;
if (thread.isAccessible()) {
return true;
}
}
return TargetAccessibility.INACCESSIBLE;
return false;
}
}

View file

@ -25,10 +25,10 @@ import ghidra.dbg.target.TargetAccessConditioned;
*
* @param <T> type for this
*/
public interface JdiModelTargetAccessConditioned<T extends TargetAccessConditioned<T>>
extends JdiModelTargetObject, TargetAccessConditioned<T> {
public interface JdiModelTargetAccessConditioned
extends JdiModelTargetObject, TargetAccessConditioned {
@Override
public TargetAccessibility getAccessibility();
public boolean isAccessible();
}

View file

@ -17,7 +17,6 @@ package ghidra.dbg.jdi.model.iface1;
import java.util.concurrent.CompletableFuture;
import ghidra.dbg.attributes.TypedTargetObjectRef;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.TargetAttachable;
import ghidra.dbg.target.TargetAttacher;
@ -29,12 +28,10 @@ import ghidra.dbg.target.TargetAttacher;
*
* @param <T> type for this
*/
public interface JdiModelTargetAttacher<T extends TargetAttacher<T>>
extends JdiModelTargetObject, TargetAttacher<T> {
public interface JdiModelTargetAttacher extends JdiModelTargetObject, TargetAttacher {
@Override
public CompletableFuture<Void> attach(
TypedTargetObjectRef<? extends TargetAttachable<?>> ref);
public CompletableFuture<Void> attach(TargetAttachable attachable);
@Override
public CompletableFuture<Void> attach(long pid);

View file

@ -25,7 +25,6 @@ import ghidra.dbg.target.TargetConsole;
*
* @param <T> type for this
*/
public interface JdiModelTargetConsole<T extends TargetConsole<T>>
extends JdiModelTargetObject, TargetConsole<T> {
public interface JdiModelTargetConsole extends JdiModelTargetObject, TargetConsole {
}

View file

@ -27,8 +27,7 @@ import ghidra.dbg.target.TargetDeletable;
*
* @param <T> type for this
*/
public interface JdiModelTargetDeletable<T extends TargetDeletable<T>>
extends JdiModelTargetObject, TargetDeletable<T> {
public interface JdiModelTargetDeletable extends JdiModelTargetObject, TargetDeletable {
@Override
public CompletableFuture<Void> delete();

View file

@ -27,8 +27,7 @@ import ghidra.dbg.target.TargetDetachable;
*
* @param <T> type for this
*/
public interface JdiModelTargetDetachable<T extends TargetDetachable<T>>
extends JdiModelTargetObject, TargetDetachable<T> {
public interface JdiModelTargetDetachable extends JdiModelTargetObject, TargetDetachable {
@Override
public CompletableFuture<Void> detach();

View file

@ -18,8 +18,7 @@ package ghidra.dbg.jdi.model.iface1;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.TargetEnvironment;
public interface JdiModelTargetEnvironment<T extends TargetEnvironment<T>>
extends JdiModelTargetObject, TargetEnvironment<T> {
public interface JdiModelTargetEnvironment extends JdiModelTargetObject, TargetEnvironment {
public void refreshInternal();

View file

@ -23,7 +23,6 @@ import ghidra.dbg.target.TargetEventScope;
*
* @param <T> type for this
*/
public interface JdiModelTargetEventScope<T extends TargetEventScope<T>>
extends JdiModelTargetObject, TargetEventScope<T> {
public interface JdiModelTargetEventScope extends JdiModelTargetObject, TargetEventScope {
}

View file

@ -28,8 +28,8 @@ import ghidra.dbg.target.TargetExecutionStateful;
*
* @param <T> type for this
*/
public interface JdiModelTargetExecutionStateful<T extends TargetExecutionStateful<T>>
extends JdiModelTargetObject, TargetExecutionStateful<T> {
public interface JdiModelTargetExecutionStateful
extends JdiModelTargetObject, TargetExecutionStateful {
public default void setExecutionState(TargetExecutionState state, String reason) {
changeAttributes(List.of(), Map.of( //

View file

@ -16,12 +16,8 @@
package ghidra.dbg.jdi.model.iface1;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import ghidra.async.AsyncUtils;
import ghidra.async.TypeSpec;
import ghidra.dbg.DebugModelConventions;
import ghidra.dbg.attributes.TargetObjectRef;
import ghidra.dbg.error.DebuggerIllegalArgumentException;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.TargetFocusScope;
@ -35,8 +31,7 @@ import ghidra.dbg.util.PathUtils;
*
* @param <T> type for this
*/
public interface JdiModelTargetFocusScope<T extends TargetFocusScope<T>>
extends JdiModelTargetObject, TargetFocusScope<T> {
public interface JdiModelTargetFocusScope extends JdiModelTargetObject, TargetFocusScope {
@Override
public JdiModelSelectableObject getFocus();
@ -47,40 +42,23 @@ public interface JdiModelTargetFocusScope<T extends TargetFocusScope<T>>
// NB: requestFocus request change in active object - propagates down to manager
// (but, of course, may then cause change in state)
@Override
public default CompletableFuture<Void> requestFocus(TargetObjectRef ref) {
getModel().assertMine(TargetObjectRef.class, ref);
if (ref.equals(getFocus())) {
public default CompletableFuture<Void> requestFocus(TargetObject obj) {
getModel().assertMine(TargetObject.class, obj);
if (obj.equals(getFocus())) {
return CompletableFuture.completedFuture(null);
}
if (!PathUtils.isAncestor(this.getPath(), ref.getPath())) {
if (!PathUtils.isAncestor(this.getPath(), obj.getPath())) {
throw new DebuggerIllegalArgumentException("Can only focus a successor of the scope");
}
return AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
ref.fetch().handle(seq::next);
}, TypeSpec.cls(TargetObject.class)).then((obj, seq) -> {
TargetObject cur = obj;
while (cur != null) {
if (cur instanceof JdiModelSelectableObject) {
JdiModelSelectableObject sel = (JdiModelSelectableObject) cur;
sel.select().handle(seq::exit);
AtomicReference<JdiModelTargetFocusScope<?>> scope = new AtomicReference<>();
AsyncUtils.sequence(TypeSpec.VOID).then(seqx -> {
DebugModelConventions.findSuitable(JdiModelTargetFocusScope.class, sel)
.handle(seqx::next);
}, scope).then(seqx -> {
scope.get().setFocus(sel);
}).finish();
break;
}
if (cur instanceof JdiModelTargetObject) {
JdiModelTargetObject def = (JdiModelTargetObject) cur;
cur = def.getImplParent();
continue;
}
throw new AssertionError();
TargetObject cur = obj;
while (cur != null) {
if (cur instanceof JdiModelSelectableObject) {
JdiModelSelectableObject sel = (JdiModelSelectableObject) cur;
setFocus(sel);
return sel.select();
}
seq.exit();
}).finish();
cur = cur.getParent();
}
return AsyncUtils.NIL;
}
}

View file

@ -27,8 +27,7 @@ import ghidra.dbg.target.TargetInterruptible;
*
* @param <T> type for this
*/
public interface JdiModelTargetInterruptible<T extends TargetInterruptible<T>>
extends JdiModelTargetObject, TargetInterruptible<T> {
public interface JdiModelTargetInterruptible extends JdiModelTargetObject, TargetInterruptible {
@Override
public CompletableFuture<Void> interrupt();

View file

@ -27,8 +27,7 @@ import ghidra.dbg.target.TargetKillable;
*
* @param <T> type for this
*/
public interface JdiModelTargetKillable<T extends TargetKillable<T>>
extends JdiModelTargetObject, TargetKillable<T> {
public interface JdiModelTargetKillable extends JdiModelTargetObject, TargetKillable {
@Override
public CompletableFuture<Void> kill();

View file

@ -32,8 +32,7 @@ import ghidra.dbg.target.TargetMethod.ParameterDescription;
*
* @param <T> type for this
*/
public interface JdiModelTargetLauncher<T extends TargetLauncher<T>>
extends JdiModelTargetObject, TargetLauncher<T> {
public interface JdiModelTargetLauncher extends JdiModelTargetObject, TargetLauncher {
static ParameterDescription<Boolean> createBooleanParameter(BooleanArgument arg) {
return ParameterDescription.create(Boolean.class, arg.name(), arg.mustSpecify(),

View file

@ -23,7 +23,6 @@ import ghidra.dbg.target.TargetMethod;
*
* @param <T> type for this
*/
public interface JdiModelTargetMethod<T extends TargetMethod<T>>
extends JdiModelTargetObject, TargetMethod<T> {
public interface JdiModelTargetMethod extends JdiModelTargetObject, TargetMethod {
}

View file

@ -27,8 +27,7 @@ import ghidra.dbg.target.TargetResumable;
*
* @param <T> type for this
*/
public interface JdiModelTargetResumable<T extends TargetResumable<T>>
extends JdiModelTargetObject, TargetResumable<T> {
public interface JdiModelTargetResumable extends JdiModelTargetObject, TargetResumable {
@Override
public CompletableFuture<Void> resume();

View file

@ -27,8 +27,7 @@ import ghidra.dbg.target.TargetSteppable;
*
* @param <T> type for this
*/
public interface JdiModelTargetSteppable<T extends TargetSteppable<T>>
extends JdiModelTargetObject, TargetSteppable<T> {
public interface JdiModelTargetSteppable extends JdiModelTargetObject, TargetSteppable {
@Override
CompletableFuture<Void> step(TargetStepKind kind);

View file

@ -23,8 +23,7 @@ import ghidra.dbg.target.TargetAttachable;
* The targets this launcher creates ought to appear in its successors.
*
*/
public interface JdiModelTargetAttachable
extends JdiModelTargetObject, TargetAttachable<JdiModelTargetAttachable> {
public interface JdiModelTargetAttachable extends JdiModelTargetObject, TargetAttachable {
public long getId();

View file

@ -53,8 +53,6 @@ public interface JdiModelTargetObject extends TargetObject, InvalidatableTargetO
@Override
public CompletableFuture<? extends Map<String, ?>> fetchAttributes();
public TargetObject getImplParent();
public Delta<?, ?> changeAttributes(List<String> remove, Map<String, ?> add, String reason);
public ListenerSet<TargetObjectListener> getListeners();

View file

@ -22,7 +22,6 @@ import org.junit.*;
import generic.Unique;
import ghidra.dbg.DebuggerObjectModel;
import ghidra.dbg.attributes.TargetObjectRef;
import ghidra.dbg.jdi.JdiExperimentsTest;
import ghidra.dbg.target.*;
import ghidra.dbg.target.TargetMethod.ParameterDescription;
@ -45,8 +44,8 @@ public class JdiModelTest implements DebuggerModelTestUtils {
@Test
public void testConnectorParameterReflection() throws Throwable {
for (TargetObjectRef connRef : waitOn(model.fetchObjectElements("Connectors")).values()) {
TargetLauncher<?> launcher = waitOn(connRef.as(TargetLauncher.tclass).fetch());
for (TargetObject conn : waitOn(model.fetchObjectElements("Connectors")).values()) {
TargetLauncher launcher = conn.as(TargetLauncher.class);
Msg.info(this, "Launcher: " + launcher);
for (ParameterDescription<?> desc : launcher.getParameters().values()) {
Msg.info(this, " " + desc);
@ -57,7 +56,7 @@ public class JdiModelTest implements DebuggerModelTestUtils {
@Test
@Ignore("TODO") // Not important
public void testCommandLineLauncher() throws Throwable {
TargetLauncher<?> launcher = (TargetLauncher<?>) waitOn(
TargetLauncher launcher = (TargetLauncher) waitOn(
model.fetchModelObject(PathUtils.parse("Connectors[com.sun.jdi.CommandLineLaunch]")));
Map<String, Object> parameters = new HashMap<>();
parameters.put("main", JdiExperimentsTest.HelloWorld.class.getName());
@ -65,9 +64,8 @@ public class JdiModelTest implements DebuggerModelTestUtils {
parameters.put("vmexec", "java");
waitOn(launcher.launch(parameters));
TargetObjectRef vmRef =
TargetObject vm =
Unique.assertOne(waitOn(model.fetchObjectElements("VirtualMachines")).values());
TargetObject vm = waitOn(vmRef.fetch());
waitOn(((TargetKillable<?>) vm).kill());
waitOn(vm.as(TargetKillable.class).kill());
}
}