mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-595: Fixing path and schema issues in JPDA/JDI
This commit is contained in:
parent
aa18341dca
commit
9c6cbcbc81
36 changed files with 149 additions and 114 deletions
|
@ -83,7 +83,7 @@ public class JdiModelTargetBreakpointContainer extends JdiModelTargetObjectImpl
|
|||
JdiModelTargetLocation targetLocation =
|
||||
(JdiModelTargetLocation) getTargetObject(location);
|
||||
if (targetLocation == null) {
|
||||
targetLocation = new JdiModelTargetLocation(this, location);
|
||||
targetLocation = new JdiModelTargetLocation(this, location, true);
|
||||
}
|
||||
JdiBreakpointInfo info = targetLocation.addBreakpoint();
|
||||
breakpointCreated(info, JdiCause.Causes.UNCLAIMED);
|
||||
|
@ -122,7 +122,8 @@ public class JdiModelTargetBreakpointContainer extends JdiModelTargetObjectImpl
|
|||
|
||||
public synchronized JdiModelTargetBreakpointSpec getTargetBreakpointSpec(
|
||||
JdiBreakpointInfo info) {
|
||||
return specsByInfo.computeIfAbsent(info, i -> new JdiModelTargetBreakpointSpec(this, info));
|
||||
return specsByInfo.computeIfAbsent(info,
|
||||
i -> new JdiModelTargetBreakpointSpec(this, info, true));
|
||||
}
|
||||
|
||||
protected void updateUsingBreakpoints(Map<Long, JdiBreakpointInfo> byNumber) {
|
||||
|
|
|
@ -53,8 +53,8 @@ public class JdiModelTargetBreakpointSpec extends JdiModelTargetObjectImpl imple
|
|||
};
|
||||
|
||||
public JdiModelTargetBreakpointSpec(JdiModelTargetBreakpointContainer breakpoints,
|
||||
JdiBreakpointInfo info) {
|
||||
super(breakpoints, info.toString(), info);
|
||||
JdiBreakpointInfo info, boolean isElement) {
|
||||
super(breakpoints, info.toString(), info, isElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -46,8 +46,9 @@ public class JdiModelTargetConnector extends JdiModelTargetObjectImpl
|
|||
protected final Connector cx;
|
||||
protected final TargetParameterMap paramDescs;
|
||||
|
||||
public JdiModelTargetConnector(JdiModelTargetConnectorContainer connectors, Connector cx) {
|
||||
super(connectors, cx.name(), cx);
|
||||
public JdiModelTargetConnector(JdiModelTargetConnectorContainer connectors, Connector cx,
|
||||
boolean isElement) {
|
||||
super(connectors, cx.name(), cx, isElement);
|
||||
this.connectors = connectors;
|
||||
this.cx = cx;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public class JdiModelTargetConnectorContainer extends JdiModelTargetObjectImpl {
|
|||
|
||||
protected synchronized JdiModelTargetConnector getTargetConnector(Connector cx) {
|
||||
return connectorsByName.computeIfAbsent(cx.name(),
|
||||
n -> new JdiModelTargetConnector(this, cx));
|
||||
n -> new JdiModelTargetConnector(this, cx, true));
|
||||
}
|
||||
|
||||
public synchronized JdiModelTargetConnector getTargetConnectorIfPresent(String name) {
|
||||
|
|
|
@ -36,8 +36,9 @@ public class JdiModelTargetConstantPool extends JdiModelTargetObjectImpl impleme
|
|||
private AddressRange range;
|
||||
private byte[] pool;
|
||||
|
||||
public JdiModelTargetConstantPool(JdiModelTargetSectionContainer parent, byte[] pool) {
|
||||
super(parent, "Constant Pool", pool);
|
||||
public JdiModelTargetConstantPool(JdiModelTargetSectionContainer parent, byte[] pool,
|
||||
boolean isElement) {
|
||||
super(parent, "Constant Pool", pool, isElement);
|
||||
this.pool = pool;
|
||||
|
||||
this.range = impl.getAddressRange(getClassType(), pool.length);
|
||||
|
|
|
@ -24,11 +24,10 @@ 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;
|
||||
import ghidra.dbg.target.schema.*;
|
||||
|
||||
@TargetObjectSchemaInfo(name = "Field", elements = { //
|
||||
//@TargetElementType(type = Void.class) //
|
||||
@TargetElementType(type = Void.class) //
|
||||
}, attributes = { //
|
||||
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class), //
|
||||
@TargetAttributeType(type = Void.class) //
|
||||
|
@ -41,8 +40,8 @@ public class JdiModelTargetField extends JdiModelTargetObjectImpl {
|
|||
private JdiModelTargetReferenceType declaringType;
|
||||
private JdiModelTargetAttributesContainer addedAttributes;
|
||||
|
||||
public JdiModelTargetField(JdiModelTargetObject fields, Field field) {
|
||||
super(fields, field.toString(), field);
|
||||
public JdiModelTargetField(JdiModelTargetObject fields, Field field, boolean isElement) {
|
||||
super(fields, field.toString(), field, isElement);
|
||||
this.field = field;
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
|
|
|
@ -41,8 +41,8 @@ public class JdiModelTargetLocalVariable extends JdiModelTargetObjectImpl {
|
|||
private JdiModelTargetAttributesContainer addedAttributes;
|
||||
|
||||
public JdiModelTargetLocalVariable(JdiModelTargetLocalVariableContainer variables,
|
||||
LocalVariable var) {
|
||||
super(variables, var.name(), var);
|
||||
LocalVariable var, boolean isElement) {
|
||||
super(variables, var.name(), var, isElement);
|
||||
this.var = var;
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
|
|
|
@ -75,7 +75,7 @@ public class JdiModelTargetLocalVariableContainer extends JdiModelTargetObjectIm
|
|||
|
||||
protected synchronized JdiModelTargetLocalVariable getTargetVariable(LocalVariable var) {
|
||||
return variablesByName.computeIfAbsent(var.name(),
|
||||
n -> new JdiModelTargetLocalVariable(this, var));
|
||||
n -> new JdiModelTargetLocalVariable(this, var, true));
|
||||
}
|
||||
|
||||
public synchronized JdiModelTargetLocalVariable getTargetVariableIfPresent(String name) {
|
||||
|
|
|
@ -49,8 +49,9 @@ public class JdiModelTargetLocation extends JdiModelTargetObjectImpl {
|
|||
private JdiModelTargetReferenceType declaringType;
|
||||
private Address address;
|
||||
|
||||
public JdiModelTargetLocation(JdiModelTargetObject parent, Location location) {
|
||||
super(parent, getUniqueId(location), location);
|
||||
public JdiModelTargetLocation(JdiModelTargetObject parent, Location location,
|
||||
boolean isElement) {
|
||||
super(parent, getUniqueId(location), location, isElement);
|
||||
this.location = location;
|
||||
|
||||
impl.registerMethod(location.method());
|
||||
|
@ -105,13 +106,17 @@ public class JdiModelTargetLocation extends JdiModelTargetObjectImpl {
|
|||
if (address != null) {
|
||||
return address;
|
||||
}
|
||||
getInstance(location.method());
|
||||
return getAddressFromLocation(impl, location);
|
||||
}
|
||||
|
||||
public static Address getAddressFromLocation(JdiModelImpl impl, Location location) {
|
||||
AddressRange addressRange = impl.getAddressRange(location.method());
|
||||
if (addressRange == null) {
|
||||
return impl.getAddressSpace("ram").getAddress(-1L);
|
||||
}
|
||||
long codeIndex = location.codeIndex();
|
||||
return addressRange.getMinAddress().add(codeIndex < 0 ? 0 : codeIndex);
|
||||
|
||||
}
|
||||
|
||||
public JdiBreakpointInfo addBreakpoint() {
|
||||
|
|
|
@ -72,7 +72,7 @@ public class JdiModelTargetLocationContainer extends JdiModelTargetObjectImpl {
|
|||
|
||||
protected synchronized JdiModelTargetLocation getTargetLocation(Location loc) {
|
||||
return locationsByName.computeIfAbsent(loc.toString(),
|
||||
n -> new JdiModelTargetLocation(this, loc));
|
||||
n -> new JdiModelTargetLocation(this, loc, true));
|
||||
}
|
||||
|
||||
public synchronized JdiModelTargetLocation getTargetLocationsIfPresent(String name) {
|
||||
|
|
|
@ -21,11 +21,10 @@ 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;
|
||||
import ghidra.dbg.target.schema.*;
|
||||
|
||||
@TargetObjectSchemaInfo(name = "Method", elements = { //
|
||||
//@TargetElementType(type = Void.class) //
|
||||
@TargetElementType(type = Void.class) //
|
||||
}, attributes = { //
|
||||
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class), //
|
||||
@TargetAttributeType(type = Object.class) //
|
||||
|
@ -42,8 +41,8 @@ public class JdiModelTargetMethod extends JdiModelTargetObjectImpl {
|
|||
private JdiModelTargetLocalVariableContainer variables;
|
||||
private JdiModelTargetType returnType;
|
||||
|
||||
public JdiModelTargetMethod(JdiModelTargetObject parent, Method method) {
|
||||
super(parent, method.toString(), method);
|
||||
public JdiModelTargetMethod(JdiModelTargetObject parent, Method method, boolean isElement) {
|
||||
super(parent, method.toString(), method, isElement);
|
||||
this.method = method;
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
|
@ -94,7 +93,7 @@ public class JdiModelTargetMethod extends JdiModelTargetObjectImpl {
|
|||
), "Initialized");
|
||||
|
||||
this.location = method.location() == null ? null
|
||||
: new JdiModelTargetLocation(parent, method.location());
|
||||
: new JdiModelTargetLocation(parent, method.location(), false);
|
||||
if (location != null) {
|
||||
changeAttributes(List.of(), List.of( //
|
||||
location //
|
||||
|
|
|
@ -26,7 +26,8 @@ import ghidra.dbg.target.schema.*;
|
|||
@TargetObjectSchemaInfo(name = "Module", elements = { //
|
||||
@TargetElementType(type = Void.class) //
|
||||
}, attributes = { //
|
||||
@TargetAttributeType(type = Void.class) //
|
||||
@TargetAttributeType(name = "UID", type = Long.class, fixed = true), //
|
||||
@TargetAttributeType(type = Object.class) //
|
||||
})
|
||||
public class JdiModelTargetModule extends JdiModelTargetObjectReference {
|
||||
|
||||
|
@ -38,8 +39,9 @@ public class JdiModelTargetModule extends JdiModelTargetObjectReference {
|
|||
|
||||
///protected final JdiModelTargetSymbolContainer symbols;
|
||||
|
||||
public JdiModelTargetModule(JdiModelTargetModuleContainer modules, ModuleReference module) {
|
||||
super(modules, module);
|
||||
public JdiModelTargetModule(JdiModelTargetModuleContainer modules, ModuleReference module,
|
||||
boolean isElement) {
|
||||
super(modules, module, isElement);
|
||||
this.module = module;
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
|
|
|
@ -111,7 +111,7 @@ public class JdiModelTargetModuleContainer extends JdiModelTargetObjectImpl
|
|||
|
||||
protected synchronized JdiModelTargetModule getTargetModule(ModuleReference module) {
|
||||
return modulesByName.computeIfAbsent(JdiModelTargetModule.getUniqueId(module),
|
||||
n -> new JdiModelTargetModule(this, module));
|
||||
n -> new JdiModelTargetModule(this, module, true));
|
||||
}
|
||||
|
||||
public synchronized JdiModelTargetModule getTargetModuleIfPresent(String name) {
|
||||
|
|
|
@ -63,8 +63,9 @@ public class JdiModelTargetObjectImpl extends
|
|||
), "Initialized");
|
||||
}
|
||||
|
||||
public JdiModelTargetObjectImpl(JdiModelTargetObject parent, String id, Object object) {
|
||||
super(parent.getModel(), parent, keyObject(id), "Object");
|
||||
public JdiModelTargetObjectImpl(JdiModelTargetObject parent, String id, Object object,
|
||||
boolean isElement) {
|
||||
super(parent.getModel(), parent, isElement ? keyObject(id) : id, "Object");
|
||||
this.impl = parent.getModelImpl();
|
||||
this.mirror = object instanceof Mirror ? (Mirror) object : null;
|
||||
this.object = object;
|
||||
|
@ -118,7 +119,7 @@ public class JdiModelTargetObjectImpl extends
|
|||
if (targetVM != null) {
|
||||
return targetVM.getTargetObject(obj);
|
||||
}
|
||||
System.err.println("Attempt to getTargetObject from class without Mirror " + this);
|
||||
//System.err.println("Attempt to getTargetObject from class without Mirror " + this);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,10 @@ 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;
|
||||
import ghidra.dbg.target.schema.*;
|
||||
|
||||
@TargetObjectSchemaInfo(name = "ObjectReference", elements = { //
|
||||
//@TargetElementType(type = Void.class) //
|
||||
@TargetElementType(type = Void.class) //
|
||||
}, attributes = { //
|
||||
@TargetAttributeType(name = "UID", type = Long.class, required = true, fixed = true), //
|
||||
@TargetAttributeType(type = Object.class) //
|
||||
|
@ -40,13 +39,14 @@ public class JdiModelTargetObjectReference extends JdiModelTargetValue {
|
|||
protected JdiModelTargetThread owner;
|
||||
private JdiModelTargetReferenceType referenceType;
|
||||
|
||||
public JdiModelTargetObjectReference(JdiModelTargetObject object, ObjectReference objref) {
|
||||
this(object, Long.toHexString(objref.uniqueID()), objref);
|
||||
public JdiModelTargetObjectReference(JdiModelTargetObject object, ObjectReference objref,
|
||||
boolean isElement) {
|
||||
this(object, Long.toString(objref.uniqueID()), objref, isElement);
|
||||
}
|
||||
|
||||
public JdiModelTargetObjectReference(JdiModelTargetObject object, String id,
|
||||
ObjectReference objref) {
|
||||
super(object, id, objref);
|
||||
ObjectReference objref, boolean isElement) {
|
||||
super(object, id, objref, isElement);
|
||||
this.objref = objref;
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
|
|
|
@ -44,17 +44,18 @@ public class JdiModelTargetObjectReferenceContainer extends JdiModelTargetObject
|
|||
}
|
||||
|
||||
protected CompletableFuture<Void> updateUsingReferences(Map<String, ObjectReference> byName) {
|
||||
List<JdiModelTargetObjectReference> objects;
|
||||
Map<String, JdiModelTargetObjectReference> objects;
|
||||
synchronized (this) {
|
||||
objects =
|
||||
byName.values().stream().map(this::getTargetObject).collect(Collectors.toList());
|
||||
objects = byName.entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(e -> e.getKey(), e -> getTargetObject(e.getValue())));
|
||||
}
|
||||
AsyncFence fence = new AsyncFence();
|
||||
for (JdiModelTargetObjectReference m : objects) {
|
||||
for (JdiModelTargetObjectReference m : objects.values()) {
|
||||
fence.include(m.init());
|
||||
}
|
||||
return fence.ready().thenAccept(__ -> {
|
||||
changeElements(List.of(), objects, Map.of(), "Refreshed");
|
||||
changeElements(List.of(), List.of(), objects, "Refreshed");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,8 @@ public class JdiModelTargetProcess extends JdiModelTargetObjectImpl implements /
|
|||
private Thread input;
|
||||
private Thread error;
|
||||
|
||||
public JdiModelTargetProcess(JdiModelTargetVM vm, Process process) {
|
||||
super(vm, getUniqueId(process), process);
|
||||
public JdiModelTargetProcess(JdiModelTargetVM vm, Process process, boolean isElement) {
|
||||
super(vm, getUniqueId(process), process, isElement);
|
||||
this.process = process;
|
||||
|
||||
//writer = new PrintWriter(process.getOutputStream());
|
||||
|
|
|
@ -23,13 +23,12 @@ 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.dbg.target.schema.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRangeImpl;
|
||||
|
||||
@TargetObjectSchemaInfo(name = "ReferenceType", elements = { //
|
||||
//@TargetElementType(type = Void.class) //
|
||||
@TargetElementType(type = Void.class) //
|
||||
}, attributes = { //
|
||||
@TargetAttributeType(name = "Attributes", type = JdiModelTargetAttributesContainer.class), //
|
||||
@TargetAttributeType(type = Object.class) //
|
||||
|
@ -52,13 +51,14 @@ public class JdiModelTargetReferenceType extends JdiModelTargetType implements /
|
|||
private JdiModelTargetAttributesContainer addedAttributes;
|
||||
protected JdiModelTargetSectionContainer sections;
|
||||
|
||||
public JdiModelTargetReferenceType(JdiModelTargetObject parent, ReferenceType reftype) {
|
||||
this(parent, reftype.name(), reftype);
|
||||
public JdiModelTargetReferenceType(JdiModelTargetObject parent, ReferenceType reftype,
|
||||
boolean isElement) {
|
||||
this(parent, reftype.name(), reftype, isElement);
|
||||
}
|
||||
|
||||
public JdiModelTargetReferenceType(JdiModelTargetObject parent, String id,
|
||||
ReferenceType reftype) {
|
||||
super(parent, id, reftype);
|
||||
ReferenceType reftype, boolean isElement) {
|
||||
super(parent, id, reftype, isElement);
|
||||
this.reftype = reftype;
|
||||
|
||||
if (reftype instanceof ClassType) {
|
||||
|
@ -120,7 +120,7 @@ public class JdiModelTargetReferenceType extends JdiModelTargetType implements /
|
|||
this.instances = new JdiModelTargetObjectReferenceContainer(this, "Objects",
|
||||
reftype.instances(maxInstances));
|
||||
this.classLoader = reftype.classLoader() == null ? null
|
||||
: new JdiModelTargetObjectReference(this, reftype.classLoader());
|
||||
: new JdiModelTargetObjectReference(this, reftype.classLoader(), false);
|
||||
this.classObject = (JdiModelTargetObjectReference) getInstance(reftype.classObject());
|
||||
|
||||
populateAttributes();
|
||||
|
|
|
@ -23,13 +23,12 @@ 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.target.schema.*;
|
||||
import ghidra.dbg.util.ConversionUtils;
|
||||
import ghidra.program.model.address.Address;
|
||||
|
||||
@TargetObjectSchemaInfo(name = "RegisterDescriptor", elements = { //
|
||||
//@TargetElementType(type = Void.class) //
|
||||
@TargetElementType(type = Void.class) //
|
||||
}, attributes = { //
|
||||
@TargetAttributeType( //
|
||||
name = TargetRegister.CONTAINER_ATTRIBUTE_NAME, //
|
||||
|
@ -42,8 +41,8 @@ public class JdiModelTargetRegister extends JdiModelTargetObjectImpl implements
|
|||
protected final String name;
|
||||
protected Address addr;
|
||||
|
||||
public JdiModelTargetRegister(JdiModelTargetObject parent, String name) {
|
||||
super(parent, name, name);
|
||||
public JdiModelTargetRegister(JdiModelTargetObject parent, String name, boolean isElement) {
|
||||
super(parent, name, name, isElement);
|
||||
this.name = name;
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
|
@ -77,9 +76,8 @@ public class JdiModelTargetRegister extends JdiModelTargetObjectImpl implements
|
|||
}
|
||||
|
||||
public byte[] readRegister(Location location) {
|
||||
JdiModelTargetLocation targetLocation = new JdiModelTargetLocation(this, location);
|
||||
Address oldval = (Address) getCachedAttribute(VALUE_ATTRIBUTE_NAME);
|
||||
addr = targetLocation.getAddress();
|
||||
addr = JdiModelTargetLocation.getAddressFromLocation(impl, location);
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
DISPLAY_ATTRIBUTE_NAME, getDisplay(), //
|
||||
|
|
|
@ -45,9 +45,9 @@ public class JdiModelTargetRegisterContainer extends JdiModelTargetObjectImpl
|
|||
public JdiModelTargetRegisterContainer(JdiModelTargetThread thread) {
|
||||
super(thread, "Registers");
|
||||
this.thread = thread;
|
||||
this.pc = new JdiModelTargetRegister(this, "PC");
|
||||
this.sp = new JdiModelTargetRegister(this, "SP");
|
||||
this.retAddr = new JdiModelTargetRegister(this, "return_address");
|
||||
this.pc = new JdiModelTargetRegister(this, "PC", true);
|
||||
this.sp = new JdiModelTargetRegister(this, "SP", true);
|
||||
this.retAddr = new JdiModelTargetRegister(this, "return_address", true);
|
||||
registersByName.put(pc.getName(), pc);
|
||||
registersByName.put(sp.getName(), sp);
|
||||
registersByName.put(retAddr.getName(), retAddr);
|
||||
|
@ -80,7 +80,8 @@ public class JdiModelTargetRegisterContainer extends JdiModelTargetObjectImpl
|
|||
*/
|
||||
|
||||
protected synchronized JdiModelTargetRegister getTargetRegister(String rname) {
|
||||
return registersByName.computeIfAbsent(rname, n -> new JdiModelTargetRegister(this, rname));
|
||||
return registersByName.computeIfAbsent(rname,
|
||||
n -> new JdiModelTargetRegister(this, rname, true));
|
||||
}
|
||||
|
||||
public synchronized JdiModelTargetRegister getTargetMethodIfPresent(String rname) {
|
||||
|
|
|
@ -38,8 +38,9 @@ public class JdiModelTargetSection extends JdiModelTargetObjectImpl implements /
|
|||
protected final Method method;
|
||||
private AddressRange range;
|
||||
|
||||
public JdiModelTargetSection(JdiModelTargetSectionContainer parent, Method method) {
|
||||
super(parent, method.toString(), method);
|
||||
public JdiModelTargetSection(JdiModelTargetSectionContainer parent, Method method,
|
||||
boolean isElement) {
|
||||
super(parent, method.toString(), method, isElement);
|
||||
this.method = method;
|
||||
|
||||
this.range = impl.getAddressRange(method);
|
||||
|
|
|
@ -54,7 +54,7 @@ public class JdiModelTargetSectionContainer extends JdiModelTargetObjectImpl
|
|||
@Override
|
||||
protected CompletableFuture<Void> requestAttributes(boolean refresh) {
|
||||
|
||||
constantPool = new JdiModelTargetConstantPool(this, reftype.reftype.constantPool());
|
||||
constantPool = new JdiModelTargetConstantPool(this, reftype.reftype.constantPool(), false);
|
||||
changeAttributes(List.of(), List.of( //
|
||||
constantPool //
|
||||
), Map.of(), "Initialized");
|
||||
|
@ -70,7 +70,7 @@ public class JdiModelTargetSectionContainer extends JdiModelTargetObjectImpl
|
|||
|
||||
protected synchronized JdiModelTargetSection getTargetSection(Method method) {
|
||||
return sectionsByName.computeIfAbsent(JdiModelImpl.methodToKey(method),
|
||||
n -> new JdiModelTargetSection(this, method));
|
||||
n -> new JdiModelTargetSection(this, method, true));
|
||||
}
|
||||
|
||||
public synchronized JdiModelTargetSection getTargetSectionIfPresent(String name) {
|
||||
|
|
|
@ -68,7 +68,7 @@ public class JdiModelTargetStack extends JdiModelTargetObjectImpl
|
|||
return framesByLocation.compute(frame.location(), (l, f) -> {
|
||||
if (f == null || f.getFrameLevel() != level) {
|
||||
JdiModelTargetStackFrame tf =
|
||||
new JdiModelTargetStackFrame(this, thread, level, frame);
|
||||
new JdiModelTargetStackFrame(this, thread, level, frame, true);
|
||||
framesByLevel.put(level, tf);
|
||||
return tf;
|
||||
}
|
||||
|
|
|
@ -30,13 +30,12 @@ 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.dbg.target.schema.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
@TargetObjectSchemaInfo(name = "StackFrame", elements = { //
|
||||
//@TargetElementType(type = Void.class) //
|
||||
@TargetElementType(type = Void.class) //
|
||||
}, attributes = { //
|
||||
@TargetAttributeType(type = Object.class) //
|
||||
})
|
||||
|
@ -65,13 +64,13 @@ public class JdiModelTargetStackFrame extends JdiModelTargetObjectImpl
|
|||
protected long level;
|
||||
|
||||
public JdiModelTargetStackFrame(JdiModelTargetStack stack, JdiModelTargetThread thread,
|
||||
int level, StackFrame frame) {
|
||||
super(stack, getUniqueId(level), frame);
|
||||
int level, StackFrame frame, boolean isElement) {
|
||||
super(stack, getUniqueId(level), frame, isElement);
|
||||
this.thread = thread;
|
||||
this.level = level;
|
||||
this.frame = frame;
|
||||
|
||||
this.location = new JdiModelTargetLocation(this, frame.location());
|
||||
this.location = new JdiModelTargetLocation(this, frame.location(), false);
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
DISPLAY_ATTRIBUTE_NAME, getDisplay(), //
|
||||
|
|
|
@ -30,18 +30,18 @@ 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.dbg.target.schema.*;
|
||||
import ghidra.lifecycle.Internal;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
@TargetObjectSchemaInfo(name = "Thread", elements = { //
|
||||
//@TargetElementType(type = TargetObject.class) //
|
||||
@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 //
|
||||
|
@ -72,8 +72,9 @@ public class JdiModelTargetThread extends JdiModelTargetObjectReference implemen
|
|||
protected JdiModelTargetObjectReferenceContainer ownedMonitors;
|
||||
protected JdiModelTargetAttributesContainer addedAttributes;
|
||||
|
||||
public JdiModelTargetThread(JdiModelTargetObject parent, ThreadReference thread) {
|
||||
super(parent, thread.name(), thread);
|
||||
public JdiModelTargetThread(JdiModelTargetObject parent, ThreadReference thread,
|
||||
boolean isElement) {
|
||||
super(parent, thread.name(), thread, isElement);
|
||||
this.thread = thread;
|
||||
this.eventManager = thread.virtualMachine().eventRequestManager();
|
||||
|
||||
|
@ -160,7 +161,8 @@ public class JdiModelTargetThread extends JdiModelTargetObjectReference implemen
|
|||
}
|
||||
}
|
||||
ThreadGroupReference tg = thread.threadGroup();
|
||||
this.threadGroup = tg == null ? null : new JdiModelTargetThreadGroupContainer(this, tg);
|
||||
this.threadGroup =
|
||||
tg == null ? null : new JdiModelTargetThreadGroupContainer(this, tg, false);
|
||||
if (threadGroup != null) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
"Thread Group", thread.threadGroup() //
|
||||
|
@ -381,7 +383,7 @@ public class JdiModelTargetThread extends JdiModelTargetObjectReference implemen
|
|||
}
|
||||
|
||||
public void setLocation(Location location) {
|
||||
this.location = new JdiModelTargetLocation(this, location);
|
||||
this.location = new JdiModelTargetLocation(this, location, false);
|
||||
Method method = location.method();
|
||||
impl.registerMethod(method);
|
||||
}
|
||||
|
|
|
@ -51,8 +51,8 @@ public class JdiModelTargetThreadGroupContainer extends JdiModelTargetObjectImpl
|
|||
}
|
||||
|
||||
public JdiModelTargetThreadGroupContainer(JdiModelTargetObject parent,
|
||||
ThreadGroupReference group) {
|
||||
super(parent, keyGroup(group));
|
||||
ThreadGroupReference group, boolean isElement) {
|
||||
super(parent, isElement ? keyGroup(group) : group.name());
|
||||
this.baseGroup = group;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ public class JdiModelTargetThreadGroupContainer extends JdiModelTargetObjectImpl
|
|||
public synchronized JdiModelTargetThreadGroupContainer getTargetThreadGroup(
|
||||
ThreadGroupReference group) {
|
||||
return threadGroupsById.computeIfAbsent(group.name(),
|
||||
i -> new JdiModelTargetThreadGroupContainer(this, group));
|
||||
i -> new JdiModelTargetThreadGroupContainer(this, group, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,11 +21,10 @@ 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;
|
||||
import ghidra.dbg.target.schema.*;
|
||||
|
||||
@TargetObjectSchemaInfo(name = "Type", elements = { //
|
||||
//@TargetElementType(type = Void.class) //
|
||||
@TargetElementType(type = Void.class) //
|
||||
}, attributes = { //
|
||||
@TargetAttributeType(name = "Signature", type = String.class), //
|
||||
@TargetAttributeType(type = Void.class) //
|
||||
|
@ -34,12 +33,13 @@ public class JdiModelTargetType extends JdiModelTargetObjectImpl {
|
|||
|
||||
protected final Type type;
|
||||
|
||||
public JdiModelTargetType(JdiModelTargetObject object, Type type) {
|
||||
this(object, type.toString(), type);
|
||||
public JdiModelTargetType(JdiModelTargetObject object, Type type, boolean isElement) {
|
||||
this(object, type.toString(), type, isElement);
|
||||
}
|
||||
|
||||
public JdiModelTargetType(JdiModelTargetObject object, String id, Type type) {
|
||||
super(object, id, type);
|
||||
public JdiModelTargetType(JdiModelTargetObject object, String id, Type type,
|
||||
boolean isElement) {
|
||||
super(object, id, type, isElement);
|
||||
this.type = type;
|
||||
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
|
|
|
@ -49,7 +49,11 @@ import ghidra.lifecycle.Internal;
|
|||
// @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 //
|
||||
|
@ -91,8 +95,8 @@ public class JdiModelTargetVM extends JdiModelTargetObjectImpl implements //
|
|||
private final MonitorContendedEnterRequest monitorEnterRequest;
|
||||
private final MonitorContendedEnteredRequest monitorEnteredRequest;
|
||||
|
||||
public JdiModelTargetVM(JdiModelTargetVMContainer vms, VirtualMachine vm) {
|
||||
super(vms, vm.name(), vm);
|
||||
public JdiModelTargetVM(JdiModelTargetVMContainer vms, VirtualMachine vm, boolean isElement) {
|
||||
super(vms, vm.name(), vm, isElement);
|
||||
vms.vmsById.put(vm.name(), this);
|
||||
this.vm = vm;
|
||||
this.eventManager = vm.eventRequestManager();
|
||||
|
@ -124,7 +128,7 @@ public class JdiModelTargetVM extends JdiModelTargetObjectImpl implements //
|
|||
|
||||
Process proc = vm.process();
|
||||
if (proc != null) {
|
||||
this.process = new JdiModelTargetProcess(this, proc);
|
||||
this.process = new JdiModelTargetProcess(this, proc, false);
|
||||
}
|
||||
else {
|
||||
this.process = null;
|
||||
|
|
|
@ -170,12 +170,12 @@ public class JdiModelTargetVMContainer extends JdiModelTargetObjectImpl
|
|||
|
||||
public synchronized JdiModelTargetVM getTargetVM(VirtualMachine vm) {
|
||||
return vmsById.computeIfAbsent(vm.name(),
|
||||
i -> new JdiModelTargetVM(this, impl.getManager().getKnownVMs().get(i)));
|
||||
i -> new JdiModelTargetVM(this, impl.getManager().getKnownVMs().get(i), true));
|
||||
}
|
||||
|
||||
public synchronized JdiModelTargetVM getTargetVMByName(String name) {
|
||||
return vmsById.computeIfAbsent(name,
|
||||
i -> new JdiModelTargetVM(this, impl.getManager().getKnownVMs().get(i)));
|
||||
i -> new JdiModelTargetVM(this, impl.getManager().getKnownVMs().get(i), true));
|
||||
}
|
||||
|
||||
protected void invalidateMemoryAndRegisterCaches() {
|
||||
|
|
|
@ -31,12 +31,13 @@ public class JdiModelTargetValue extends JdiModelTargetObjectImpl {
|
|||
protected final Value value;
|
||||
protected final Type type;
|
||||
|
||||
public JdiModelTargetValue(JdiModelTargetObject object, Value value) {
|
||||
this(object, value.toString(), value);
|
||||
public JdiModelTargetValue(JdiModelTargetObject object, Value value, boolean isElement) {
|
||||
this(object, value.toString(), value, isElement);
|
||||
}
|
||||
|
||||
public JdiModelTargetValue(JdiModelTargetObject object, String id, Value value) {
|
||||
super(object, id, value);
|
||||
public JdiModelTargetValue(JdiModelTargetObject object, String id, Value value,
|
||||
boolean isElement) {
|
||||
super(object, id, value, isElement);
|
||||
this.value = value;
|
||||
this.type = value.type();
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public class JdiModelTargetValueContainer extends JdiModelTargetObjectImpl {
|
|||
|
||||
protected synchronized JdiModelTargetValue getTargetValue(Value val) {
|
||||
return valuesByName.computeIfAbsent(val.toString(),
|
||||
n -> new JdiModelTargetValue(this, val));
|
||||
n -> new JdiModelTargetValue(this, val, true));
|
||||
}
|
||||
|
||||
public synchronized JdiModelTargetValue getTargetValueIfPresent(String name) {
|
||||
|
|
|
@ -68,7 +68,8 @@ public class JdiModelTargetValueMap extends JdiModelTargetObjectImpl {
|
|||
}
|
||||
|
||||
protected synchronized JdiModelTargetValue getTargetValue(LocalVariable var, Value val) {
|
||||
return valuesByVariable.computeIfAbsent(var, n -> new JdiModelTargetValue(this, val));
|
||||
return valuesByVariable.computeIfAbsent(var,
|
||||
n -> new JdiModelTargetValue(this, val, false));
|
||||
}
|
||||
|
||||
public synchronized JdiModelTargetValue getTargetValueIfPresent(LocalVariable var) {
|
||||
|
|
|
@ -25,6 +25,9 @@ import ghidra.dbg.agent.InvalidatableTargetObjectIf;
|
|||
import ghidra.dbg.jdi.manager.JdiManager;
|
||||
import ghidra.dbg.jdi.model.*;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.target.schema.EnumerableTargetObjectSchema;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName;
|
||||
import ghidra.dbg.util.CollectionUtils.Delta;
|
||||
import ghidra.util.datastruct.ListenerSet;
|
||||
|
||||
|
@ -61,27 +64,29 @@ public interface JdiModelTargetObject extends TargetObject, InvalidatableTargetO
|
|||
if (targetObject == null) {
|
||||
if (object instanceof ThreadReference) {
|
||||
ThreadReference thread = (ThreadReference) object;
|
||||
targetObject = new JdiModelTargetThread(this, thread);
|
||||
targetObject = new JdiModelTargetThread(this, thread, acceptsElement("Thread"));
|
||||
}
|
||||
else if (object instanceof ObjectReference) {
|
||||
ObjectReference ref = (ObjectReference) object;
|
||||
targetObject = new JdiModelTargetObjectReference(this, ref);
|
||||
targetObject =
|
||||
new JdiModelTargetObjectReference(this, ref, acceptsElement("ObjectReference"));
|
||||
}
|
||||
else if (object instanceof ReferenceType) {
|
||||
ReferenceType reftype = (ReferenceType) object;
|
||||
targetObject = new JdiModelTargetReferenceType(this, reftype);
|
||||
targetObject =
|
||||
new JdiModelTargetReferenceType(this, reftype, acceptsElement("ReferenceType"));
|
||||
}
|
||||
else if (object instanceof Field) {
|
||||
Field field = (Field) object;
|
||||
targetObject = new JdiModelTargetField(this, field);
|
||||
targetObject = new JdiModelTargetField(this, field, acceptsElement("Field"));
|
||||
}
|
||||
else if (object instanceof Method) {
|
||||
Method method = (Method) object;
|
||||
targetObject = new JdiModelTargetMethod(this, method);
|
||||
targetObject = new JdiModelTargetMethod(this, method, acceptsElement("Method"));
|
||||
}
|
||||
else if (object instanceof Type) {
|
||||
Type type = (Type) object;
|
||||
targetObject = new JdiModelTargetType(this, type);
|
||||
targetObject = new JdiModelTargetType(this, type, acceptsElement("Type"));
|
||||
}
|
||||
else {
|
||||
throw new RuntimeException();
|
||||
|
@ -90,6 +95,15 @@ public interface JdiModelTargetObject extends TargetObject, InvalidatableTargetO
|
|||
return targetObject;
|
||||
}
|
||||
|
||||
public default boolean acceptsElement(String schemaName) {
|
||||
TargetObjectSchema schema = this.getSchema();
|
||||
if (schema.equals(EnumerableTargetObjectSchema.ANY)) {
|
||||
return true;
|
||||
}
|
||||
SchemaName s = schema.getElementSchema(schemaName);
|
||||
return s.toString().equals(schemaName);
|
||||
}
|
||||
|
||||
public JdiModelTargetObject getTargetObject(Object object);
|
||||
|
||||
public Object getObject();
|
||||
|
|
|
@ -588,11 +588,12 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter implements
|
|||
else {
|
||||
addToPanel(buildTableFromAttributes(oc));
|
||||
}
|
||||
seq.exit();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).finish();
|
||||
}).finish().completeExceptionally(new RuntimeException("Unable to add table"));
|
||||
}
|
||||
|
||||
private ObjectTable<ObjectAttributeRow> buildTableFromAttributes(ObjectContainer container) {
|
||||
|
|
|
@ -27,6 +27,7 @@ import ghidra.app.plugin.core.debug.gui.objects.DebuggerObjectsProvider;
|
|||
import ghidra.app.plugin.core.debug.gui.objects.ObjectContainer;
|
||||
import ghidra.dbg.target.*;
|
||||
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import resources.ResourceManager;
|
||||
|
@ -90,6 +91,8 @@ public class ObjectNode extends GTreeSlowLoadingNode { //extends GTreeNode
|
|||
}
|
||||
catch (InterruptedException | ExecutionException e) {
|
||||
// Ignore
|
||||
Msg.warn(this, e);
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
|
|
|
@ -193,7 +193,7 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
|
|||
Map<String, E> asMap = new LinkedHashMap<>();
|
||||
for (E e : canonical) {
|
||||
if (!PathUtils.parent(e.getPath()).equals(getPath())) {
|
||||
Msg.error(this, "Link found in canonical elements: " + e);
|
||||
Msg.error(this, "Link found in canonical elements of " + parent + ": " + e);
|
||||
}
|
||||
asMap.put(e.getIndex(), e);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue