GP-574: Schema implementation for JDI

This commit is contained in:
d-millar 2021-01-13 13:43:37 -05:00 committed by Dan
parent b5070847d1
commit dd041fbe8f
42 changed files with 345 additions and 50 deletions

View file

@ -61,7 +61,7 @@ public class DbgModelTargetAvailableImpl extends DbgModelTargetObjectImpl
this.pid = pid;
this.changeAttributes(List.of(), List.of(), Map.of(//
PID_ATTRIBUTE_NAME, pid, //
PID_ATTRIBUTE_NAME, (long) pid, //
DISPLAY_ATTRIBUTE_NAME, keyAttachable(pid), //
UPDATE_MODE_ATTRIBUTE_NAME, TargetUpdateMode.FIXED //
), "Initialized");

View file

@ -25,6 +25,8 @@ import ghidra.async.AsyncUtils;
import ghidra.dbg.agent.AbstractDebuggerObjectModel;
import ghidra.dbg.jdi.manager.JdiManager;
import ghidra.dbg.target.TargetObject;
import ghidra.dbg.target.schema.AnnotatedSchemaContext;
import ghidra.dbg.target.schema.TargetObjectSchema;
import ghidra.program.model.address.*;
public class JdiModelImpl extends AbstractDebuggerObjectModel {
@ -35,6 +37,10 @@ public class JdiModelImpl extends AbstractDebuggerObjectModel {
public static final long BLOCK_SIZE = 0x1000L;
public static final long DEFAULT_SECTION = 0x0000L;
protected static final AnnotatedSchemaContext SCHEMA_CTX = new AnnotatedSchemaContext();
protected static final TargetObjectSchema ROOT_SCHEMA =
SCHEMA_CTX.getSchemaForClass(JdiModelTargetRoot.class);
protected JdiManager jdi;
protected final AddressSpace ram = new GenericAddressSpace("ram", 64, AddressSpace.TYPE_RAM, 0);
protected Long ramIndex = Long.valueOf(0x1000L);
@ -51,7 +57,9 @@ public class JdiModelImpl extends AbstractDebuggerObjectModel {
public JdiModelImpl() {
this.jdi = JdiManager.newInstance();
this.root = new JdiModelTargetRoot(this);
//System.out.println(XmlSchemaContext.serialize(SCHEMA_CTX));
this.root = new JdiModelTargetRoot(this, ROOT_SCHEMA);
//this.root = new JdiModelTargetRoot(this, EnumerableTargetObjectSchema.OBJECT);
this.completedRoot = CompletableFuture.completedFuture(root);
Address start = ram.getAddress(0L);
@ -106,44 +114,46 @@ public class JdiModelImpl extends AbstractDebuggerObjectModel {
JdiModelTargetVM targetVM = getTargetVM(declaringType);
JdiModelTargetReferenceType classRef =
(JdiModelTargetReferenceType) targetVM.getTargetObject(declaringType);
JdiModelTargetSectionContainer sectionContainer = classRef.sections;
for (Method m : declaringType.methods()) {
if (m.location() != null && targetVM.vm.canGetBytecodes()) {
byte[] bytecodes = m.bytecodes();
int length = bytecodes.length;
if (length > 0) {
synchronized (ramIndex) {
Address start = ram.getAddress(ramIndex);
if (classRef != null) {
JdiModelTargetSectionContainer sectionContainer = classRef.sections;
for (Method m : declaringType.methods()) {
if (m.location() != null && targetVM.vm.canGetBytecodes()) {
byte[] bytecodes = m.bytecodes();
int length = bytecodes.length;
if (length > 0) {
synchronized (ramIndex) {
Address start = ram.getAddress(ramIndex);
AddressRangeImpl range =
new AddressRangeImpl(start, start.add(BLOCK_SIZE - 1));
String key = methodToKey(m);
if (addressRangeByMethod.containsKey(key)) {
System.err.println("non-null location: " + m.location() +
" with " + length + " bytes");
//throw new RuntimeException("non-null location: " +
// m.location() + " with " + length + " bytes");
}
addressRangeByMethod.put(key, range);
if (sectionContainer != null) {
sectionContainer.addSection(m);
}
else {
System.err.println("null sectionContainer");
}
ramIndex += 0x1000; //bytecodes.length;
}
}
else {
Address start = ram.getAddress(DEFAULT_SECTION);
AddressRangeImpl range =
new AddressRangeImpl(start, start.add(BLOCK_SIZE - 1));
String key = methodToKey(m);
if (addressRangeByMethod.containsKey(key)) {
System.err.println("non-null location: " + m.location() +
" with " + length + " bytes");
//throw new RuntimeException("non-null location: " +
// m.location() + " with " + length + " bytes");
throw new RuntimeException("non-null location: " +
m.location() + " with " + length + " bytes");
}
addressRangeByMethod.put(key, range);
if (sectionContainer != null) {
sectionContainer.addSection(m);
}
else {
System.err.println("null sectionContainer");
}
ramIndex += 0x1000; //bytecodes.length;
}
}
else {
Address start = ram.getAddress(DEFAULT_SECTION);
AddressRangeImpl range =
new AddressRangeImpl(start, start.add(BLOCK_SIZE - 1));
String key = methodToKey(m);
if (addressRangeByMethod.containsKey(key)) {
throw new RuntimeException("non-null location: " + m.location() +
" with " + length + " bytes");
}
addressRangeByMethod.put(key, range);
}
}
}
}

View file

@ -20,9 +20,13 @@ import java.util.Map;
import ghidra.dbg.jdi.manager.JdiEventsListenerAdapter;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
// TODO: Should TargetThreadContainer be a thing?
@TargetObjectSchemaInfo(name = "AttributesContainer", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(type = Object.class) //
}, canonicalContainer = true)
public class JdiModelTargetAttributesContainer extends JdiModelTargetObjectImpl
implements JdiEventsListenerAdapter {

View file

@ -27,9 +27,15 @@ import ghidra.dbg.jdi.manager.breakpoint.JdiBreakpointInfo;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.TargetBreakpointContainer;
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
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)
public class JdiModelTargetBreakpointContainer extends JdiModelTargetObjectImpl implements
TargetBreakpointContainer<JdiModelTargetBreakpointContainer>, JdiEventsListenerAdapter {

View file

@ -21,10 +21,22 @@ import java.util.concurrent.CompletableFuture;
import ghidra.dbg.jdi.manager.breakpoint.JdiBreakpointInfo;
import ghidra.dbg.jdi.model.iface1.JdiModelTargetDeletable;
import ghidra.dbg.target.TargetBreakpointContainer.TargetBreakpointKindSet;
import ghidra.dbg.target.TargetBreakpointLocation;
import ghidra.dbg.target.TargetBreakpointSpec;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
import ghidra.dbg.util.CollectionUtils.Delta;
import ghidra.util.datastruct.ListenerSet;
@TargetObjectSchemaInfo(name = "BreakpointSpec", attributes = { //
@TargetAttributeType( //
name = TargetBreakpointSpec.CONTAINER_ATTRIBUTE_NAME, //
type = JdiModelTargetBreakpointContainer.class), //
@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> {

View file

@ -23,8 +23,14 @@ import com.sun.jdi.ReferenceType;
import ghidra.async.AsyncFence;
import ghidra.async.AsyncUtils;
import ghidra.dbg.target.schema.*;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(name = "ClassContainer", elements = { //
@TargetElementType(type = JdiModelTargetReferenceType.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetClassContainer extends JdiModelTargetObjectImpl {
protected final JdiModelTargetVM vm;

View file

@ -27,7 +27,16 @@ import ghidra.dbg.jdi.model.iface1.JdiModelTargetLauncher;
import ghidra.dbg.target.TargetMethod;
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)
public class JdiModelTargetConnector extends JdiModelTargetObjectImpl
implements JdiModelSelectableObject,
// TODO: Make a JidModelTargetLaunchingConnector and JdiModelTargetAttachingConnector
@ -35,7 +44,7 @@ public class JdiModelTargetConnector extends JdiModelTargetObjectImpl
protected final JdiModelTargetConnectorContainer connectors;
protected final Connector cx;
protected final Map<String, ParameterDescription<?>> paramDescs;
protected final TargetParameterMap paramDescs;
public JdiModelTargetConnector(JdiModelTargetConnectorContainer connectors, Connector cx) {
super(connectors, cx.name(), cx);
@ -47,7 +56,8 @@ public class JdiModelTargetConnector extends JdiModelTargetObjectImpl
"Description", cx.description(), //
"Default Arguments", cx.defaultArguments(), //
"Transport", cx.transport(), //
TargetMethod.PARAMETERS_ATTRIBUTE_NAME, paramDescs = computeParameters(), //
TargetMethod.PARAMETERS_ATTRIBUTE_NAME,
paramDescs = TargetParameterMap.copyOf(computeParameters()), //
UPDATE_MODE_ATTRIBUTE_NAME, TargetUpdateMode.FIXED //
), "Initialized");
}

View file

@ -24,8 +24,14 @@ import com.sun.jdi.connect.Connector;
import ghidra.async.AsyncFence;
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)
public class JdiModelTargetConnectorContainer extends JdiModelTargetObjectImpl {
protected final JdiModelTargetRoot root;

View file

@ -21,8 +21,14 @@ import java.util.concurrent.CompletableFuture;
import ghidra.dbg.target.TargetMemoryRegion;
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)
public class JdiModelTargetConstantPool extends JdiModelTargetObjectImpl implements //
//TargetMemory<JdiModelTargetSection>,
TargetMemoryRegion<JdiModelTargetConstantPool>, TargetSection<JdiModelTargetConstantPool> {
@ -40,7 +46,8 @@ public class JdiModelTargetConstantPool extends JdiModelTargetObjectImpl impleme
DISPLAY_ATTRIBUTE_NAME, getDisplay(), //
MODULE_ATTRIBUTE_NAME, parent.getClassType(), //
READABLE_ATTRIBUTE_NAME, true, //
MEMORY_ATTRIBUTE_NAME, parent, TargetMemoryRegion.RANGE_ATTRIBUTE_NAME, range, //
MEMORY_ATTRIBUTE_NAME, parent, //
TargetMemoryRegion.RANGE_ATTRIBUTE_NAME, range, //
UPDATE_MODE_ATTRIBUTE_NAME, TargetUpdateMode.FIXED //
), "Initialized");
}

View file

@ -23,10 +23,15 @@ import com.sun.jdi.ThreadGroupReference;
import ghidra.dbg.jdi.manager.JdiEventsListenerAdapter;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.TargetObject;
import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils;
import ghidra.util.datastruct.WeakValueHashMap;
// TODO: Should TargetThreadContainer be a thing?
@TargetObjectSchemaInfo(name = "ElementsContainer", elements = { //
@TargetElementType(type = JdiModelTargetObject.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetElementsContainer extends JdiModelTargetObjectImpl
implements JdiEventsListenerAdapter {

View file

@ -24,7 +24,15 @@ import com.sun.jdi.request.*;
import ghidra.dbg.jdi.manager.breakpoint.JdiBreakpointInfo;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
@TargetObjectSchemaInfo(name = "Field", elements = { //
//@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class), //
@TargetAttributeType(type = Void.class) //
})
public class JdiModelTargetField extends JdiModelTargetObjectImpl {
protected final Field field;

View file

@ -22,7 +22,13 @@ import java.util.stream.Collectors;
import com.sun.jdi.Field;
import ghidra.async.AsyncFence;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "FieldsContainer", elements = { //
@TargetElementType(type = JdiModelTargetField.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetFieldContainer extends JdiModelTargetObjectImpl {
// NOTE: -file-list-shared-libraries omits the main module and system-supplied DSO.

View file

@ -21,6 +21,17 @@ import java.util.concurrent.CompletableFuture;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.LocalVariable;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "LocalVariable", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class), //
@TargetAttributeType(name = "Generic Signature", type = String.class), //
@TargetAttributeType(name = "Signature", type = String.class), //
@TargetAttributeType(name = "Type", type = String.class, required = true), //
@TargetAttributeType(type = Void.class) //
})
public class JdiModelTargetLocalVariable extends JdiModelTargetObjectImpl {
String IS_ARGUMENT_ATTRIBUTE_NAME = "IsArg";

View file

@ -23,7 +23,13 @@ import com.sun.jdi.LocalVariable;
import ghidra.async.AsyncFence;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "LocalVariableContainer", elements = { //
@TargetElementType(type = JdiModelTargetLocalVariable.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetLocalVariableContainer extends JdiModelTargetObjectImpl {
private List<LocalVariable> vars;

View file

@ -26,9 +26,19 @@ import com.sun.jdi.request.EventRequestManager;
import ghidra.dbg.jdi.manager.breakpoint.JdiBreakpointInfo;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
@TargetObjectSchemaInfo(name = "Location", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Method", type = String.class, required = true, fixed = true), //
@TargetAttributeType(name = "Line", type = Integer.class, required = true, fixed = true), //
@TargetAttributeType(name = "Index", type = Long.class, required = true, fixed = true), //
@TargetAttributeType(name = "Address", type = String.class, required = true, fixed = true), //
@TargetAttributeType(type = Object.class) //
})
public class JdiModelTargetLocation extends JdiModelTargetObjectImpl {
public static String getUniqueId(Location obj) {

View file

@ -23,7 +23,13 @@ import com.sun.jdi.Location;
import ghidra.async.AsyncFence;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "LocationContainer", elements = { //
@TargetElementType(type = JdiModelTargetLocation.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetLocationContainer extends JdiModelTargetObjectImpl {
private List<Location> locations;

View file

@ -21,7 +21,15 @@ import java.util.concurrent.CompletableFuture;
import com.sun.jdi.*;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
@TargetObjectSchemaInfo(name = "Method", elements = { //
//@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class), //
@TargetAttributeType(type = Object.class) //
})
public class JdiModelTargetMethod extends JdiModelTargetObjectImpl {
protected final Method method;

View file

@ -22,7 +22,13 @@ import java.util.stream.Collectors;
import com.sun.jdi.Method;
import ghidra.async.AsyncFence;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "TargetMethodContainer", elements = { //
@TargetElementType(type = JdiModelTargetMethod.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetMethodContainer extends JdiModelTargetObjectImpl {
protected final JdiModelTargetReferenceType reftype;

View file

@ -21,6 +21,13 @@ import java.util.concurrent.CompletableFuture;
import com.sun.jdi.ModuleReference;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "Module", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
})
public class JdiModelTargetModule extends JdiModelTargetObjectReference {
public static String getUniqueId(ModuleReference module) {

View file

@ -26,9 +26,15 @@ import ghidra.async.AsyncUtils;
import ghidra.dbg.error.DebuggerUserException;
import ghidra.dbg.target.TargetModule;
import ghidra.dbg.target.TargetModuleContainer;
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)
public class JdiModelTargetModuleContainer extends JdiModelTargetObjectImpl
implements TargetModuleContainer<JdiModelTargetModuleContainer> {

View file

@ -46,7 +46,7 @@ public class JdiModelTargetObjectImpl extends
private boolean modified;
public JdiModelTargetObjectImpl(JdiModelTargetObject parent, String id) {
super(parent.getModel(), parent, id, "Object", null);
super(parent.getModel(), parent, id, "Object");
this.impl = parent.getModelImpl();
this.mirror = (Mirror) parent.getObject();
this.object = null;

View file

@ -22,7 +22,15 @@ import java.util.concurrent.CompletableFuture;
import com.sun.jdi.*;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
@TargetObjectSchemaInfo(name = "ObjectReference", elements = { //
//@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "UID", type = Long.class, required = true, fixed = true), //
@TargetAttributeType(type = Object.class) //
})
public class JdiModelTargetObjectReference extends JdiModelTargetValue {
private static final long MAX_REFERRERS = 100;

View file

@ -23,7 +23,13 @@ import com.sun.jdi.ObjectReference;
import ghidra.async.AsyncFence;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "TargetObjectReferenceContainer", elements = { //
@TargetElementType(type = JdiModelTargetObjectReference.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetObjectReferenceContainer extends JdiModelTargetObjectImpl {
protected final List<ObjectReference> refs;

View file

@ -26,9 +26,16 @@ import ghidra.dbg.jdi.model.iface1.JdiModelTargetConsole;
import ghidra.dbg.target.TargetConsole;
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
import ghidra.dbg.target.TargetInterpreter.TargetInterpreterListener;
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, //
@ -38,7 +45,7 @@ public class JdiModelTargetProcess extends JdiModelTargetObjectImpl implements /
return Long.toHexString(obj.pid());
}
String STATE_ATTRIBUTE_NAME = PREFIX_INVISIBLE + "state";
static String STATE_ATTRIBUTE_NAME = PREFIX_INVISIBLE + "state";
protected final Process process;

View file

@ -23,9 +23,17 @@ import com.sun.jdi.*;
import ghidra.async.AsyncFence;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.TargetModule;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
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> {

View file

@ -23,9 +23,19 @@ import com.sun.jdi.Location;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.TargetRegister;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
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> {

View file

@ -23,8 +23,14 @@ import com.sun.jdi.Location;
import ghidra.async.AsyncUtils;
import ghidra.dbg.target.TargetRegisterBank;
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)
public class JdiModelTargetRegisterContainer extends JdiModelTargetObjectImpl
implements TargetRegisterBank<JdiModelTargetRegisterContainer>,
TargetRegisterContainer<JdiModelTargetRegisterContainer> {
@ -45,16 +51,18 @@ public class JdiModelTargetRegisterContainer extends JdiModelTargetObjectImpl
registersByName.put(pc.getName(), pc);
registersByName.put(sp.getName(), sp);
registersByName.put(retAddr.getName(), retAddr);
changeAttributes(List.of(), List.of( //
changeElements(List.of(), List.of( //
pc, //
sp, //
retAddr //
), Map.of( //
), "Initialized");
changeAttributes(List.of(), List.of(), Map.of( //
DISPLAY_ATTRIBUTE_NAME, getName(), //
DESCRIPTIONS_ATTRIBUTE_NAME, this //
), "Initialized");
}
/*
@Override
public CompletableFuture<Void> requestAttributes(boolean refresh) {
@ -69,6 +77,7 @@ public class JdiModelTargetRegisterContainer extends JdiModelTargetObjectImpl
return CompletableFuture.completedFuture(null);
}
*/
protected synchronized JdiModelTargetRegister getTargetRegister(String rname) {
return registersByName.computeIfAbsent(rname, n -> new JdiModelTargetRegister(this, rname));

View file

@ -34,6 +34,7 @@ import ghidra.dbg.jdi.model.iface1.*;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.*;
import ghidra.dbg.target.TargetMethod.TargetParameterMap;
import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils;
import ghidra.util.Msg;
@ -47,6 +48,14 @@ 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) //
})
public class JdiModelTargetRoot extends DefaultTargetModelRoot implements //
JdiModelTargetAccessConditioned<JdiModelTargetRoot>, //
//JdiModelTargetAttacher<JdiModelTargetRoot>, //
@ -72,8 +81,8 @@ public class JdiModelTargetRoot extends DefaultTargetModelRoot implements //
protected String debugger = "Jdi"; // Used by JdiModelTargetEnvironment
public JdiModelTargetRoot(JdiModelImpl impl) {
super(impl, "VirtualMachineManager");
public JdiModelTargetRoot(JdiModelImpl impl, TargetObjectSchema schema) {
super(impl, "VirtualMachineManager", schema);
this.impl = impl;
this.vmm = this.impl.getManager().getVirtualMachineManager();

View file

@ -23,8 +23,14 @@ import com.sun.jdi.Method;
import ghidra.dbg.target.TargetMemoryRegion;
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) //
})
public class JdiModelTargetSection extends JdiModelTargetObjectImpl implements //
//TargetMemory<JdiModelTargetSection>,
TargetMemoryRegion<JdiModelTargetSection>, TargetSection<JdiModelTargetSection> {

View file

@ -22,9 +22,15 @@ import com.sun.jdi.Method;
import ghidra.async.AsyncFence;
import ghidra.dbg.target.TargetMemory;
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)
public class JdiModelTargetSectionContainer extends JdiModelTargetObjectImpl
implements TargetMemory<JdiModelTargetSectionContainer> {

View file

@ -22,9 +22,15 @@ import com.sun.jdi.*;
import ghidra.async.AsyncUtils;
import ghidra.dbg.target.TargetStack;
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)
public class JdiModelTargetStack extends JdiModelTargetObjectImpl
implements TargetStack<JdiModelTargetStack> {

View file

@ -30,9 +30,16 @@ import ghidra.dbg.jdi.manager.JdiEventsListenerAdapter;
import ghidra.dbg.jdi.model.iface1.JdiModelSelectableObject;
import ghidra.dbg.jdi.model.iface1.JdiModelTargetFocusScope;
import ghidra.dbg.target.TargetStackFrame;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
import ghidra.program.model.address.Address;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(name = "StackFrame", elements = { //
//@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(type = Object.class) //
})
public class JdiModelTargetStackFrame extends JdiModelTargetObjectImpl
implements TargetStackFrame<JdiModelTargetStackFrame>, //
//TargetRegisterBank<JdiModelTargetStackFrame>, //

View file

@ -30,9 +30,20 @@ import ghidra.dbg.jdi.manager.*;
import ghidra.dbg.jdi.model.iface1.*;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.TargetThread;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
import ghidra.lifecycle.Internal;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(name = "Thread", elements = { //
//@TargetElementType(type = TargetObject.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(type = Object.class) //
}, canonicalContainer = true)
public class JdiModelTargetThread extends JdiModelTargetObjectReference implements //
TargetThread<JdiModelTargetThread>, //
JdiModelTargetAccessConditioned<JdiModelTargetThread>, //

View file

@ -27,8 +27,14 @@ import ghidra.dbg.jdi.manager.*;
import ghidra.dbg.jdi.model.iface1.JdiModelTargetEventScope;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
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 {
@ -42,7 +48,9 @@ public class JdiModelTargetThreadContainer extends JdiModelTargetObjectImpl impl
super(object, name);
this.threads = threads;
impl.getManager().addEventsListener(targetVM.vm, this);
if (targetVM != null) {
impl.getManager().addEventsListener(targetVM.vm, this);
}
}

View file

@ -24,9 +24,15 @@ import com.sun.jdi.ThreadGroupReference;
import ghidra.dbg.jdi.manager.JdiEventsListenerAdapter;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils;
import ghidra.util.datastruct.WeakValueHashMap;
@TargetObjectSchemaInfo(name = "ThreadGroupContainer", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(type = JdiModelTargetThreadGroupContainer.class) //
}, canonicalContainer = true)
public class JdiModelTargetThreadGroupContainer extends JdiModelTargetObjectImpl
implements JdiEventsListenerAdapter {

View file

@ -21,7 +21,15 @@ import java.util.Map;
import com.sun.jdi.Type;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
@TargetObjectSchemaInfo(name = "Type", elements = { //
//@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(name = "Signature", type = String.class), //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetType extends JdiModelTargetObjectImpl {
protected final Type type;

View file

@ -23,7 +23,13 @@ import com.sun.jdi.Type;
import ghidra.async.AsyncFence;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "TargetTypeContainer", elements = { //
@TargetElementType(type = JdiModelTargetType.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetTypeContainer extends JdiModelTargetObjectImpl {
private List<Type> types;

View file

@ -35,6 +35,8 @@ import ghidra.dbg.jdi.model.iface1.*;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.*;
import ghidra.dbg.target.TargetMethod.TargetParameterMap;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
import ghidra.lifecycle.Internal;
/**
@ -43,6 +45,13 @@ 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 = "Threads", type = JdiModelTargetThreadContainer.class, required = true, fixed = true), //
@TargetAttributeType(type = Object.class) //
}, canonicalContainer = true)
public class JdiModelTargetVM extends JdiModelTargetObjectImpl implements //
TargetProcess<JdiModelTargetVM>, //
TargetAggregate, //
@ -57,7 +66,7 @@ public class JdiModelTargetVM extends JdiModelTargetObjectImpl implements //
JdiEventsListenerAdapter, //
JdiModelSelectableObject {
public static final String PID_ATTRIBUTE_NAME = PREFIX_INVISIBLE + "pid";
public static final String ID_ATTRIBUTE_NAME = PREFIX_INVISIBLE + "id";
public static final String EXIT_CODE_ATTRIBUTE_NAME = PREFIX_INVISIBLE + "exit_code";
protected final VirtualMachine vm;
@ -256,7 +265,7 @@ public class JdiModelTargetVM extends JdiModelTargetObjectImpl implements //
if (id != null) {
changeAttributes(List.of(), List.of(), Map.of( //
STATE_ATTRIBUTE_NAME, TargetExecutionState.ALIVE, //
PID_ATTRIBUTE_NAME, id, //
ID_ATTRIBUTE_NAME, id, //
DISPLAY_ATTRIBUTE_NAME, updateDisplay() //
), "Started");
}

View file

@ -28,9 +28,15 @@ import ghidra.dbg.jdi.manager.JdiCause;
import ghidra.dbg.jdi.manager.JdiEventsListenerAdapter;
import ghidra.dbg.target.TargetEventScope.TargetEventScopeListener;
import ghidra.dbg.target.TargetEventScope.TargetEventType;
import ghidra.dbg.target.schema.*;
import ghidra.util.Msg;
import ghidra.util.datastruct.WeakValueHashMap;
@TargetObjectSchemaInfo(name = "VMContainer", elements = { //
@TargetElementType(type = JdiModelTargetVM.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetVMContainer extends JdiModelTargetObjectImpl
implements JdiEventsListenerAdapter {

View file

@ -15,10 +15,17 @@
*/
package ghidra.dbg.jdi.model;
import com.sun.jdi.*;
import com.sun.jdi.Type;
import com.sun.jdi.Value;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "Value", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetValue extends JdiModelTargetObjectImpl {
protected final Value value;

View file

@ -23,7 +23,13 @@ import com.sun.jdi.Value;
import ghidra.async.AsyncFence;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "TargetValueContainer", elements = { //
@TargetElementType(type = JdiModelTargetValue.class) //
}, attributes = { //
@TargetAttributeType(type = Void.class) //
}, canonicalContainer = true)
public class JdiModelTargetValueContainer extends JdiModelTargetObjectImpl {
private List<Value> values;

View file

@ -23,7 +23,13 @@ import com.sun.jdi.Value;
import ghidra.async.AsyncFence;
import ghidra.dbg.jdi.model.iface2.JdiModelTargetObject;
import ghidra.dbg.target.schema.*;
@TargetObjectSchemaInfo(name = "TargetValueMap", elements = { //
@TargetElementType(type = Void.class) //
}, attributes = { //
@TargetAttributeType(type = JdiModelTargetValue.class) //
}, canonicalContainer = true)
public class JdiModelTargetValueMap extends JdiModelTargetObjectImpl {
private Map<LocalVariable, Value> values;