mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-648: Dbgmodel speed-up, and focus issues.
This commit is contained in:
parent
f5ec74f2c3
commit
2ed29f5693
53 changed files with 650 additions and 473 deletions
|
@ -27,8 +27,8 @@ import agent.dbgmodel.dbgmodel.UnknownEx;
|
|||
import agent.dbgmodel.dbgmodel.datamodel.DataModelManager1;
|
||||
import agent.dbgmodel.dbgmodel.debughost.DebugHostContext;
|
||||
import agent.dbgmodel.dbgmodel.debughost.DebugHostType1;
|
||||
import agent.dbgmodel.jna.dbgmodel.IUnknownEx;
|
||||
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.*;
|
||||
import agent.dbgmodel.jna.dbgmodel.IUnknownEx;
|
||||
import agent.dbgmodel.jna.dbgmodel.main.IModelObject;
|
||||
|
||||
/**
|
||||
|
@ -130,6 +130,8 @@ public interface ModelObject extends UnknownEx {
|
|||
|
||||
ModelMethod getMethod(String name);
|
||||
|
||||
String getOriginalKey();
|
||||
|
||||
String getSearchKey();
|
||||
|
||||
void setSearchKey(String key);
|
||||
|
|
|
@ -82,7 +82,7 @@ public class HDMAUtil {
|
|||
public Map<String, ModelObject> getAttributes(List<String> path) {
|
||||
ModelObject target = getTerminalModelObject(path);
|
||||
if (target == null) {
|
||||
System.err.println("(A) Null target for path=" + path);
|
||||
//System.err.println("(A) Null target for path=" + path);
|
||||
return new HashMap<String, ModelObject>();
|
||||
}
|
||||
ModelObjectKind kind = target.getKind();
|
||||
|
@ -102,7 +102,7 @@ public class HDMAUtil {
|
|||
public List<ModelObject> getElements(List<String> path) {
|
||||
ModelObject target = getTerminalModelObject(path);
|
||||
if (target == null) {
|
||||
System.err.println("(C) Null target for path=" + path);
|
||||
//System.err.println("(C) Null target for path=" + path);
|
||||
return new ArrayList<ModelObject>();
|
||||
}
|
||||
ModelObjectKind kind = target.getKind();
|
||||
|
@ -127,9 +127,11 @@ public class HDMAUtil {
|
|||
public ModelObject getTerminalModelObject(List<String> path) {
|
||||
//System.err.println(path);
|
||||
ModelObject target = getRootNamespace();
|
||||
boolean found;
|
||||
for (String str : path) {
|
||||
//System.err.println(":" + str);
|
||||
String indexStr = null;
|
||||
found = false;
|
||||
if (str.endsWith(")")) {
|
||||
target = evaluatePredicate(target, str);
|
||||
if (target.getKind().equals(ModelObjectKind.OBJECT_ERROR)) {
|
||||
|
@ -143,11 +145,13 @@ public class HDMAUtil {
|
|||
Map<String, ModelObject> keyMap = target.getKeyValueMap();
|
||||
if (keyMap.containsKey(str)) {
|
||||
target = keyMap.get(str);
|
||||
found = true;
|
||||
}
|
||||
else {
|
||||
Map<String, ModelObject> rawMap = target.getRawValueMap();
|
||||
if (rawMap.containsKey(str)) {
|
||||
target = rawMap.get(str);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (indexStr != null) {
|
||||
|
@ -155,9 +159,13 @@ public class HDMAUtil {
|
|||
for (ModelObject child : children) {
|
||||
if (indexStr.equals(child.getSearchKey())) {
|
||||
target = child;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found == false) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
|
|
@ -898,6 +898,19 @@ public class ModelObjectImpl implements ModelObjectInternal {
|
|||
|
||||
@Override
|
||||
public String getSearchKey() {
|
||||
if (key == null) {
|
||||
throw new RuntimeException("null key for " + this);
|
||||
}
|
||||
Map<String, ModelObject> map = getKeyValueMap();
|
||||
if (map.containsKey("BaseAddress")) {
|
||||
String valueString = map.get("BaseAddress").getValueString();
|
||||
return valueString;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalKey() {
|
||||
if (key == null) {
|
||||
throw new RuntimeException("null key for " + this);
|
||||
}
|
||||
|
|
|
@ -23,8 +23,7 @@ import agent.dbgeng.model.iface2.DbgModelTargetObject;
|
|||
import agent.dbgmodel.dbgmodel.main.ModelObject;
|
||||
import agent.dbgmodel.gadp.impl.WrappedDbgModel;
|
||||
import agent.dbgmodel.manager.DbgManager2Impl;
|
||||
import agent.dbgmodel.model.impl.DbgModel2TargetObjectImpl;
|
||||
import agent.dbgmodel.model.impl.DelegateDbgModel2TargetObject;
|
||||
import agent.dbgmodel.model.impl.*;
|
||||
import ghidra.dbg.util.PathUtils.TargetObjectKeyComparator;
|
||||
|
||||
public class DbgListAttributesCommand extends AbstractDbgCommand<Map<String, ?>> {
|
||||
|
@ -54,20 +53,19 @@ public class DbgListAttributesCommand extends AbstractDbgCommand<Map<String, ?>>
|
|||
Map<String, ModelObject> map = access.getAttributes(path);
|
||||
Map<String, ?> existingAttributes = targetObject.getCachedAttributes();
|
||||
for (String key : map.keySet()) {
|
||||
DbgModelTargetObject proxyAttribute;
|
||||
DbgModel2TargetProxy proxyAttribute;
|
||||
ModelObject obj = map.get(key);
|
||||
Object object = existingAttributes.get(key);
|
||||
String atKey = obj.getSearchKey();
|
||||
Object object = existingAttributes.get(atKey);
|
||||
if (object != null && (object instanceof DbgModelTargetObject)) {
|
||||
proxyAttribute = (DbgModelTargetObject) object;
|
||||
DelegateDbgModel2TargetObject delegate =
|
||||
DelegateDbgModel2TargetObject.getDelegate(proxyAttribute);
|
||||
proxyAttribute = (DbgModel2TargetProxy) object;
|
||||
DelegateDbgModel2TargetObject delegate = proxyAttribute.getDelegate();
|
||||
delegate.setModelObject(obj);
|
||||
updatedAttributes.put(key, proxyAttribute);
|
||||
}
|
||||
else {
|
||||
String atKey = obj.getSearchKey();
|
||||
proxyAttribute = DelegateDbgModel2TargetObject.makeProxy(targetObject.getModel(),
|
||||
targetObject, atKey, obj);
|
||||
proxyAttribute = (DbgModel2TargetProxy) DelegateDbgModel2TargetObject
|
||||
.makeProxy(targetObject.getModel(), targetObject, atKey, obj);
|
||||
updatedAttributes.put(key, proxyAttribute);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,14 +19,13 @@ import java.util.*;
|
|||
|
||||
import agent.dbgeng.manager.cmd.AbstractDbgCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgPendingCommand;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetObject;
|
||||
import agent.dbgmodel.dbgmodel.main.ModelObject;
|
||||
import agent.dbgmodel.gadp.impl.WrappedDbgModel;
|
||||
import agent.dbgmodel.manager.DbgManager2Impl;
|
||||
import agent.dbgmodel.model.impl.DbgModel2TargetObjectImpl;
|
||||
import agent.dbgmodel.model.impl.DelegateDbgModel2TargetObject;
|
||||
import agent.dbgmodel.model.impl.*;
|
||||
import ghidra.dbg.attributes.TargetObjectRef;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
|
||||
public class DbgListElementsCommand extends AbstractDbgCommand<List<TargetObject>> {
|
||||
|
||||
|
@ -51,23 +50,27 @@ public class DbgListElementsCommand extends AbstractDbgCommand<List<TargetObject
|
|||
|
||||
@Override
|
||||
public void invoke() {
|
||||
updatedElements = new ArrayList<>();
|
||||
List<ModelObject> list = access.getElements(path);
|
||||
Map<String, ? extends TargetObjectRef> existingElements = targetObject.getCachedElements();
|
||||
for (ModelObject obj : list) {
|
||||
DbgModelTargetObject proxyElement;
|
||||
if (existingElements.containsKey(obj.getSearchKey())) {
|
||||
proxyElement = (DbgModelTargetObject) existingElements.get(obj.getSearchKey());
|
||||
DelegateDbgModel2TargetObject delegate =
|
||||
DelegateDbgModel2TargetObject.getDelegate(proxyElement);
|
||||
delegate.setModelObject(obj);
|
||||
synchronized (access) {
|
||||
updatedElements = new ArrayList<>();
|
||||
List<ModelObject> list = access.getElements(path);
|
||||
Map<String, ? extends TargetObjectRef> existingElements =
|
||||
targetObject.getCachedElements();
|
||||
|
||||
for (ModelObject obj : list) {
|
||||
DbgModel2TargetProxy proxyElement;
|
||||
String searchKey = obj.getSearchKey();
|
||||
String elKey = PathUtils.makeKey(searchKey);
|
||||
if (existingElements.containsKey(searchKey)) {
|
||||
proxyElement = (DbgModel2TargetProxy) existingElements.get(searchKey);
|
||||
DelegateDbgModel2TargetObject delegate = proxyElement.getDelegate();
|
||||
delegate.setModelObject(obj);
|
||||
}
|
||||
else {
|
||||
proxyElement = (DbgModel2TargetProxy) DelegateDbgModel2TargetObject
|
||||
.makeProxy(targetObject.getModel(), targetObject, elKey, obj);
|
||||
}
|
||||
updatedElements.add(proxyElement);
|
||||
}
|
||||
else {
|
||||
String elKey = DbgModel2TargetObjectImpl.keyObject(obj);
|
||||
proxyElement = DelegateDbgModel2TargetObject.makeProxy(targetObject.getModel(),
|
||||
targetObject, elKey, obj);
|
||||
}
|
||||
updatedElements.add(proxyElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,11 @@ import java.util.Map;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import agent.dbgeng.dbgeng.*;
|
||||
import agent.dbgeng.dbgeng.DebugClient;
|
||||
import agent.dbgeng.manager.DbgCause.Causes;
|
||||
import agent.dbgeng.manager.DbgState;
|
||||
import agent.dbgeng.manager.impl.*;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgmodel.dbgmodel.DbgModel;
|
||||
import agent.dbgmodel.dbgmodel.main.ModelObject;
|
||||
import agent.dbgmodel.gadp.impl.DbgModelClientThreadExecutor;
|
||||
import agent.dbgmodel.gadp.impl.WrappedDbgModel;
|
||||
import agent.dbgmodel.jna.cmd.*;
|
||||
|
@ -108,6 +107,7 @@ public class DbgManager2Impl extends DbgManagerImpl {
|
|||
return execute(new DbgGetRegisterMapCommand(this, path));
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public DbgSessionImpl getCurrentSession() {
|
||||
ModelObject currentSession = dbgmodel.getUtil().getCurrentSession();
|
||||
|
@ -117,7 +117,7 @@ public class DbgManager2Impl extends DbgManagerImpl {
|
|||
curSession = getSessionComputeIfAbsent(sid);
|
||||
return curSession;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DbgProcessImpl getCurrentProcess() {
|
||||
synchronized (processes) {
|
||||
|
@ -125,7 +125,7 @@ public class DbgManager2Impl extends DbgManagerImpl {
|
|||
return processes.get(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DbgThreadImpl getCurrentThread() {
|
||||
synchronized (threads) {
|
||||
|
@ -133,5 +133,6 @@ public class DbgManager2Impl extends DbgManagerImpl {
|
|||
return threads.get(id);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import agent.dbgmodel.manager.DbgManager2Impl;
|
|||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema;
|
||||
import ghidra.dbg.target.schema.XmlSchemaContext;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.program.model.address.*;
|
||||
|
||||
public class DbgModel2Impl extends AbstractDbgModel {
|
||||
|
|
|
@ -25,7 +25,7 @@ import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
|||
import agent.dbgeng.model.AbstractDbgModel;
|
||||
import agent.dbgeng.model.iface1.DbgModelSelectableObject;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import agent.dbgeng.model.impl.DbgModelTargetMemoryContainerImpl;
|
||||
import agent.dbgeng.model.impl.*;
|
||||
import agent.dbgmodel.dbgmodel.main.ModelObject;
|
||||
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.ModelObjectKind;
|
||||
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.TypeKind;
|
||||
|
@ -37,6 +37,7 @@ import ghidra.dbg.target.TargetBreakpointContainer.TargetBreakpointKindSet;
|
|||
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
|
||||
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema;
|
||||
import ghidra.dbg.util.CollectionUtils.Delta;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
import ghidra.dbg.util.PathUtils.TargetObjectKeyComparator;
|
||||
import ghidra.util.Msg;
|
||||
|
@ -58,6 +59,8 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||
|
||||
protected String DBG_PROMPT = "(kd2)"; // Used by DbgModelTargetEnvironment
|
||||
|
||||
protected boolean fireAttributesChanged = false;
|
||||
|
||||
protected static String indexObject(ModelObject obj) {
|
||||
return obj.getSearchKey();
|
||||
}
|
||||
|
@ -101,51 +104,49 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||
|
||||
@Override
|
||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||
List<TargetObject> nlist = new ArrayList<>();
|
||||
return requestNativeElements().thenCompose(list -> {
|
||||
for (TargetObject element : elements.values()) {
|
||||
if (!list.contains(element)) {
|
||||
if (element instanceof DbgStateListener) {
|
||||
getManager().removeStateListener((DbgStateListener) element);
|
||||
}
|
||||
if (element instanceof DbgEventsListener) {
|
||||
getManager().removeEventsListener((DbgEventsListener) element);
|
||||
synchronized (elements) {
|
||||
List<TargetObject> nlist = new ArrayList<>();
|
||||
return requestNativeElements().thenCompose(list -> {
|
||||
for (TargetObject element : elements.values()) {
|
||||
if (!list.contains(element)) {
|
||||
if (element instanceof DbgStateListener) {
|
||||
getManager().removeStateListener((DbgStateListener) element);
|
||||
}
|
||||
if (element instanceof DbgEventsListener) {
|
||||
getManager().removeEventsListener((DbgEventsListener) element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nlist.addAll(list);
|
||||
int order = 0;
|
||||
for (TargetObject targetObject : nlist) {
|
||||
DbgModelTargetObject to = (DbgModelTargetObject) targetObject;
|
||||
to.changeAttributes(List.of(), Map.of( //
|
||||
ORDER_ATTRIBUTE_NAME, order++ //
|
||||
), "Initialized");
|
||||
}
|
||||
return processModelObjectElements(nlist);
|
||||
}).thenAccept(__ -> {
|
||||
setElements(nlist, Map.of(), "Refreshed");
|
||||
});
|
||||
nlist.addAll(list);
|
||||
return processModelObjectElements(nlist);
|
||||
}).thenAccept(__ -> {
|
||||
setElements(nlist, Map.of(), "Refreshed");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> requestAttributes(boolean refresh) {
|
||||
fireAttributesChanged = true;
|
||||
Map<String, Object> nmap = new HashMap<>();
|
||||
return requestNativeAttributes().thenCompose(map -> {
|
||||
if (map != null) {
|
||||
Collection<?> values = map.values();
|
||||
for (Object attribute : attributes.values()) {
|
||||
if (!values.contains(attribute)) {
|
||||
if (attribute instanceof DbgStateListener) {
|
||||
getManager().removeStateListener((DbgStateListener) attribute);
|
||||
}
|
||||
if (attribute instanceof DbgEventsListener) {
|
||||
getManager().removeEventsListener((DbgEventsListener) attribute);
|
||||
synchronized (attributes) {
|
||||
if (map != null) {
|
||||
Collection<?> values = map.values();
|
||||
for (Object attribute : attributes.values()) {
|
||||
if (!values.contains(attribute)) {
|
||||
if (attribute instanceof DbgStateListener) {
|
||||
getManager().removeStateListener((DbgStateListener) attribute);
|
||||
}
|
||||
if (attribute instanceof DbgEventsListener) {
|
||||
getManager().removeEventsListener((DbgEventsListener) attribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
nmap.putAll(map);
|
||||
}
|
||||
nmap.putAll(map);
|
||||
return addModelObjectAttributes(nmap);
|
||||
}
|
||||
return addModelObjectAttributes(nmap);
|
||||
}).thenAccept(__ -> {
|
||||
setAttributes(List.of(), nmap, "Refreshed");
|
||||
});
|
||||
|
@ -161,9 +162,8 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||
|
||||
private CompletableFuture<Void> processElement(TargetObject targetObject) {
|
||||
if (targetObject instanceof DbgModelTargetObject) {
|
||||
DbgModelTargetObject proxy = (DbgModelTargetObject) targetObject;
|
||||
DelegateDbgModel2TargetObject delegate =
|
||||
DelegateDbgModel2TargetObject.getDelegate(proxy);
|
||||
DbgModel2TargetProxy proxy = (DbgModel2TargetProxy) targetObject;
|
||||
DelegateDbgModel2TargetObject delegate = proxy.getDelegate();
|
||||
if (proxy instanceof TargetStackFrame || //
|
||||
proxy instanceof TargetModule || //
|
||||
proxy instanceof TargetBreakpointSpec) {
|
||||
|
@ -193,10 +193,12 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||
if (value != null && !value.equals("")) {
|
||||
attrs.put(VALUE_ATTRIBUTE_NAME, value);
|
||||
if (!kind.equals(ModelObjectKind.OBJECT_PROPERTY_ACCESSOR)) {
|
||||
String oldval = (String) attributes.get(DISPLAY_ATTRIBUTE_NAME);
|
||||
String newval = getName() + " : " + value;
|
||||
attrs.put(DISPLAY_ATTRIBUTE_NAME, newval);
|
||||
setModified(attrs, !newval.equals(oldval));
|
||||
synchronized (attributes) {
|
||||
String oldval = (String) attributes.get(DISPLAY_ATTRIBUTE_NAME);
|
||||
String newval = getName() + " : " + value;
|
||||
attrs.put(DISPLAY_ATTRIBUTE_NAME, newval);
|
||||
setModified(attrs, !newval.equals(oldval));
|
||||
}
|
||||
}
|
||||
if (tk == null) {
|
||||
Object val = modelObject.getIntrinsicValue();
|
||||
|
@ -208,11 +210,23 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||
if (this instanceof DelegateDbgModel2TargetObject) {
|
||||
DelegateDbgModel2TargetObject delegate = (DelegateDbgModel2TargetObject) this;
|
||||
TargetObject proxy = delegate.getProxy();
|
||||
if (proxy instanceof TargetAccessConditioned) {
|
||||
attrs.put(TargetAccessConditioned.ACCESSIBLE_ATTRIBUTE_NAME,
|
||||
accessibility == TargetAccessibility.ACCESSIBLE);
|
||||
}
|
||||
if (proxy instanceof TargetExecutionStateful) {
|
||||
TargetExecutionStateful<?> stateful = (TargetExecutionStateful<?>) proxy;
|
||||
TargetExecutionState state = stateful.getExecutionState();
|
||||
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME, state);
|
||||
}
|
||||
if (proxy instanceof TargetAttacher) {
|
||||
attrs.put(TargetAttacher.SUPPORTED_ATTACH_KINDS_ATTRIBUTE_NAME,
|
||||
DbgModelTargetProcessImpl.SUPPORTED_KINDS);
|
||||
}
|
||||
if (proxy instanceof TargetSteppable) {
|
||||
attrs.put(TargetSteppable.SUPPORTED_STEP_KINDS_ATTRIBUTE_NAME,
|
||||
DbgModelTargetThreadImpl.SUPPORTED_KINDS);
|
||||
}
|
||||
if (proxy instanceof TargetInterpreter) {
|
||||
attrs.put(TargetInterpreter.PROMPT_ATTRIBUTE_NAME, DBG_PROMPT);
|
||||
}
|
||||
|
@ -230,6 +244,8 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||
attrs.put(TargetEnvironment.OS_ATTRIBUTE_NAME, "Windows");
|
||||
}
|
||||
if (proxy instanceof TargetModule) {
|
||||
//attrs.put(TargetObject.ORDER_ATTRIBUTE_NAME,
|
||||
// Integer.decode(modelObject.getOriginalKey()));
|
||||
DbgModelTargetModule module = (DbgModelTargetModule) proxy;
|
||||
return module.init(attrs);
|
||||
}
|
||||
|
@ -272,28 +288,32 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||
|
||||
@Override
|
||||
public CompletableFuture<?> fetchChild(final String key) {
|
||||
if (key.startsWith("[") && key.endsWith("]")) {
|
||||
String trimKey = key.substring(1, key.length() - 1);
|
||||
if (elements.containsKey(trimKey)) {
|
||||
return CompletableFuture.completedFuture(elements.get(trimKey));
|
||||
synchronized (elements) {
|
||||
if (key.startsWith("[") && key.endsWith("]")) {
|
||||
String trimKey = key.substring(1, key.length() - 1);
|
||||
if (elements.containsKey(trimKey)) {
|
||||
return CompletableFuture.completedFuture(elements.get(trimKey));
|
||||
}
|
||||
return requestElements(true).thenApply(__ -> getCachedElements().get(trimKey));
|
||||
}
|
||||
return requestElements(true).thenApply(__ -> getCachedElements().get(trimKey));
|
||||
}
|
||||
if (attributes.containsKey(key)) {
|
||||
return CompletableFuture.completedFuture(attributes.get(key));
|
||||
synchronized (attributes) {
|
||||
if (attributes.containsKey(key)) {
|
||||
return CompletableFuture.completedFuture(attributes.get(key));
|
||||
}
|
||||
if (key.endsWith(")")) {
|
||||
DbgManager2Impl manager2 = (DbgManager2Impl) getManager();
|
||||
List<String> pathX = PathUtils.extend(List.of("Debugger"), path);
|
||||
pathX = PathUtils.extend(pathX, key);
|
||||
return manager2.applyMethods(pathX, this).thenApply(obj -> {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
key, obj //
|
||||
), "Initialized");
|
||||
return obj;
|
||||
});
|
||||
}
|
||||
return requestAttributes(true).thenApply(__ -> getCachedAttribute(key));
|
||||
}
|
||||
if (key.endsWith(")")) {
|
||||
DbgManager2Impl manager2 = (DbgManager2Impl) getManager();
|
||||
List<String> pathX = PathUtils.extend(List.of("Debugger"), path);
|
||||
pathX = PathUtils.extend(pathX, key);
|
||||
return manager2.applyMethods(pathX, this).thenApply(obj -> {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
key, obj //
|
||||
), "Initialized");
|
||||
return obj;
|
||||
});
|
||||
}
|
||||
return requestAttributes(true).thenApply(__ -> getCachedAttribute(key));
|
||||
}
|
||||
|
||||
//@Override
|
||||
|
@ -378,9 +398,55 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||
|
||||
@Override
|
||||
public void resetModified() {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, false //
|
||||
), "Refreshed");
|
||||
if (getCachedAttribute(MODIFIED_ATTRIBUTE_NAME) != null) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
MODIFIED_ATTRIBUTE_NAME, false //
|
||||
), "Refreshed");
|
||||
}
|
||||
}
|
||||
|
||||
// NB: We're overriding these to prevent events being added as newly added elements
|
||||
// initialize and pull the attributes needed for their display
|
||||
@Override
|
||||
public Delta<?, ?> setAttributes(Map<String, ?> attributes, String reason) {
|
||||
Delta<?, ?> delta;
|
||||
synchronized (this.attributes) {
|
||||
delta = Delta.computeAndSet(this.attributes, attributes, Delta.EQUAL);
|
||||
}
|
||||
TargetObjectSchema schemax = getSchema();
|
||||
if (schemax != null) {
|
||||
schemax.validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
|
||||
}
|
||||
doInvalidateAttributes(delta.removed, reason);
|
||||
if (parent == null && !delta.isEmpty()) {
|
||||
listeners.fire.attributesChanged(getProxy(), delta.getKeysRemoved(), delta.added);
|
||||
return delta;
|
||||
}
|
||||
if (fireAttributesChanged && !delta.isEmpty()) {
|
||||
listeners.fire.attributesChanged(getProxy(), delta.getKeysRemoved(), delta.added);
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Delta<?, ?> changeAttributes(List<String> remove, Map<String, ?> add, String reason) {
|
||||
Delta<?, ?> delta;
|
||||
synchronized (attributes) {
|
||||
delta = Delta.apply(this.attributes, remove, add, Delta.EQUAL);
|
||||
}
|
||||
TargetObjectSchema schemax = getSchema();
|
||||
if (schemax != null) {
|
||||
schemax.validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
|
||||
}
|
||||
doInvalidateAttributes(delta.removed, reason);
|
||||
if (fireAttributesChanged && !delta.isEmpty()) {
|
||||
listeners.fire.attributesChanged(getProxy(), delta.getKeysRemoved(), delta.added);
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean enforcesStrictSchema() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package agent.dbgmodel.model.impl;
|
||||
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetObject;
|
||||
|
||||
public interface DbgModel2TargetProxy extends DbgModelTargetObject {
|
||||
|
||||
public DelegateDbgModel2TargetObject getDelegate();
|
||||
|
||||
}
|
|
@ -26,6 +26,7 @@ import agent.dbgeng.model.iface1.DbgModelSelectableObject;
|
|||
import agent.dbgeng.model.iface1.DbgModelTargetExecutionStateful;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import agent.dbgeng.model.impl.DbgModelTargetConnectorContainerImpl;
|
||||
import agent.dbgmodel.dbgmodel.main.ModelObject;
|
||||
import agent.dbgmodel.manager.DbgManager2Impl;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.async.TypeSpec;
|
||||
|
@ -59,7 +60,9 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
connectors, //
|
||||
systemMarker //
|
||||
), Map.of( //
|
||||
ACCESSIBLE_ATTRIBUTE_NAME, true, //
|
||||
DISPLAY_ATTRIBUTE_NAME, "Debugger", //
|
||||
FOCUS_ATTRIBUTE_NAME, this, //
|
||||
TargetMethod.PARAMETERS_ATTRIBUTE_NAME, defaultConnector.getParameters() //
|
||||
// ARCH_ATTRIBUTE_NAME, "x86_64", //
|
||||
// DEBUGGER_ATTRIBUTE_NAME, "dbgeng", //
|
||||
|
@ -82,7 +85,9 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
connectors, //
|
||||
systemMarker //
|
||||
), Map.of( //
|
||||
ACCESSIBLE_ATTRIBUTE_NAME, true, //
|
||||
DISPLAY_ATTRIBUTE_NAME, "Debugger", //
|
||||
FOCUS_ATTRIBUTE_NAME, this, //
|
||||
TargetMethod.PARAMETERS_ATTRIBUTE_NAME, defaultConnector.getParameters() //
|
||||
// ARCH_ATTRIBUTE_NAME, "x86_64", //
|
||||
// DEBUGGER_ATTRIBUTE_NAME, "dbgeng", //
|
||||
|
@ -99,21 +104,12 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
if (doFire && focus != null) {
|
||||
List<String> focusPath = focus.getPath();
|
||||
List<String> selPath = sel.getPath();
|
||||
for (int i = 0; i < focusPath.size(); i++) {
|
||||
if (i >= selPath.size()) {
|
||||
doFire = false;
|
||||
break;
|
||||
}
|
||||
if (!focusPath.get(i).equals(selPath.get(i))) {
|
||||
doFire = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//doFire = !focusPath.containsAll(selPath);
|
||||
doFire = !PathUtils.isAncestor(selPath, focusPath);
|
||||
}
|
||||
}
|
||||
if (doFire) {
|
||||
this.focus = sel;
|
||||
fireAttributesChanged = true;
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
TargetFocusScope.FOCUS_ATTRIBUTE_NAME, focus //
|
||||
), "Focus changed");
|
||||
|
@ -201,28 +197,28 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
}
|
||||
|
||||
@Override
|
||||
public void moduleLoaded(DbgProcess proc, String name, DbgCause cause) {
|
||||
getObject(proc, List.of("Modules"), name).thenAccept(obj -> {
|
||||
public void moduleLoaded(DbgProcess proc, DebugModuleInfo info, DbgCause cause) {
|
||||
getObjectRevisited(proc, List.of("Modules"), info).thenAccept(obj -> {
|
||||
DbgModelTargetModule mod = (DbgModelTargetModule) obj;
|
||||
if (mod == null) {
|
||||
return;
|
||||
}
|
||||
getListeners().fire(TargetEventScopeListener.class)
|
||||
.event(this, null, TargetEventType.MODULE_LOADED, "Library " + name + " loaded",
|
||||
List.of(mod));
|
||||
.event(this, null, TargetEventType.MODULE_LOADED,
|
||||
"Library " + info.moduleName + " loaded", List.of(mod));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moduleUnloaded(DbgProcess proc, String name, DbgCause cause) {
|
||||
getObject(proc, List.of("Modules"), name).thenAccept(obj -> {
|
||||
public void moduleUnloaded(DbgProcess proc, DebugModuleInfo info, DbgCause cause) {
|
||||
getObjectRevisited(proc, List.of("Modules"), info).thenAccept(obj -> {
|
||||
DbgModelTargetModule mod = (DbgModelTargetModule) obj;
|
||||
if (mod == null) {
|
||||
return;
|
||||
}
|
||||
getListeners().fire(TargetEventScopeListener.class)
|
||||
.event(this, null, TargetEventType.MODULE_UNLOADED,
|
||||
"Library " + name + " unloaded", List.of(mod));
|
||||
"Library " + info.moduleName + " unloaded", List.of(mod));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -241,8 +237,8 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
}).finish();
|
||||
}
|
||||
|
||||
private CompletableFuture<DbgModelTargetObject> getObject(Object object, List<String> ext,
|
||||
String name) {
|
||||
private CompletableFuture<DbgModelTargetObject> getObjectRevisited(Object object,
|
||||
List<String> ext, Object info) {
|
||||
List<String> objPath = findObject(object);
|
||||
if (objPath == null) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
|
@ -257,19 +253,23 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
seq.exit();
|
||||
return;
|
||||
}
|
||||
DbgModelTargetObject proxy = (DbgModelTargetObject) pobj;
|
||||
DelegateDbgModel2TargetObject delegate =
|
||||
DelegateDbgModel2TargetObject.getDelegate(proxy);
|
||||
delegate.requestElements(true).thenAccept(__ -> {
|
||||
Map<String, TargetObject> cachedElements = delegate.getCachedElements();
|
||||
for (TargetObject val : cachedElements.values()) {
|
||||
DbgModelTargetObject obj = (DbgModelTargetObject) val;
|
||||
if (obj.getDisplay().contains(name)) {
|
||||
seq.exit(obj);
|
||||
}
|
||||
DbgModel2TargetProxy proxy = (DbgModel2TargetProxy) pobj;
|
||||
DelegateDbgModel2TargetObject delegate = proxy.getDelegate();
|
||||
|
||||
xpath.add(0, "Debugger");
|
||||
DbgManager2Impl manager = (DbgManager2Impl) getManager();
|
||||
List<ModelObject> list = manager.getAccess().getElements(xpath);
|
||||
for (ModelObject obj : list) {
|
||||
String searchKey = obj.getSearchKey();
|
||||
if (searchKey.equals(info.toString())) {
|
||||
String elKey = PathUtils.makeKey(searchKey);
|
||||
DbgModel2TargetProxy proxyElement =
|
||||
(DbgModel2TargetProxy) DelegateDbgModel2TargetObject
|
||||
.makeProxy(delegate.getModel(), delegate, elKey, obj);
|
||||
delegate.changeElements(List.of(), List.of(proxyElement), "Created");
|
||||
seq.exit(proxyElement);
|
||||
}
|
||||
seq.exit((DbgModelTargetObject) null);
|
||||
});
|
||||
}
|
||||
}).finish();
|
||||
}
|
||||
|
||||
|
@ -350,17 +350,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
public void breakpointCreated(DbgBreakpointInfo info, DbgCause cause) {
|
||||
int id = info.getDebugBreakpoint().getId();
|
||||
bptInfoMap.put(id, info);
|
||||
getObject(info.getProc(), List.of("Debug", "Breakpoints"), Integer.toHexString(id));
|
||||
/*
|
||||
getObject(info).thenAccept(obj -> {
|
||||
DbgModelTargetBreakpointSpec bpt = (DbgModelTargetBreakpointSpec) obj;
|
||||
if (bpt == null) {
|
||||
return;
|
||||
}
|
||||
bpt.setBreakpointInfo(info);
|
||||
bpt.setEnabled(true, "Created");
|
||||
});
|
||||
*/
|
||||
getObjectRevisited(info.getProc(), List.of("Debug", "Breakpoints"), info);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -368,20 +358,19 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
DbgCause cause) {
|
||||
int id = newInfo.getDebugBreakpoint().getId();
|
||||
bptInfoMap.put(id, newInfo);
|
||||
getObject(newInfo.getProc(), List.of("Debug", "Breakpoints"), Integer.toHexString(id));
|
||||
getObjectRevisited(newInfo.getProc(), List.of("Debug", "Breakpoints"), newInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakpointDeleted(DbgBreakpointInfo info, DbgCause cause) {
|
||||
int id = info.getDebugBreakpoint().getId();
|
||||
bptInfoMap.remove(id);
|
||||
getObject(info.getProc(), List.of("Debug", "Breakpoints"), Integer.toHexString(id));
|
||||
getObjectRevisited(info.getProc(), List.of("Debug", "Breakpoints"), info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakpointHit(DbgBreakpointInfo info, DbgCause cause) {
|
||||
int id = info.getDebugBreakpoint().getId();
|
||||
getObject(info.getProc(), List.of("Debug", "Breakpoints"), Integer.toHexString(id))
|
||||
getObjectRevisited(info.getProc(), List.of("Debug", "Breakpoints"), info)
|
||||
.thenAccept(obj -> {
|
||||
DbgModelTargetBreakpointSpec bpt = (DbgModelTargetBreakpointSpec) obj;
|
||||
if (bpt == null) {
|
||||
|
|
|
@ -39,7 +39,7 @@ import utilities.util.ProxyUtilities;
|
|||
public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl implements //
|
||||
DbgModelTargetAccessConditioned<DelegateDbgModel2TargetObject>, //
|
||||
DbgModelTargetExecutionStateful<DelegateDbgModel2TargetObject>, //
|
||||
DbgModelTargetBptHelper {
|
||||
DbgModel2TargetProxy, DbgModelTargetBptHelper {
|
||||
// Probably don-t need any of the handler-map or annotation stuff
|
||||
|
||||
protected final DbgStateListener accessListener = this::checkExited;
|
||||
|
@ -163,12 +163,6 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
return new DelegateDbgModel2TargetObject(model, parent, key, object, mixins).proxy;
|
||||
}
|
||||
|
||||
private static Map<DbgModelTargetObject, DelegateDbgModel2TargetObject> map = new HashMap<>();
|
||||
|
||||
public static DelegateDbgModel2TargetObject getDelegate(DbgModelTargetObject proxy) {
|
||||
return map.get(proxy);
|
||||
}
|
||||
|
||||
protected static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
|
||||
// NOTE: The Cleanable stuff is the replacement for overriding Object.finalize(), which
|
||||
|
@ -201,15 +195,27 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
|
||||
getManager().addStateListener(accessListener);
|
||||
|
||||
mixins.add(DbgModel2TargetProxy.class);
|
||||
this.proxy =
|
||||
ProxyUtilities.composeOnDelegate(DbgModelTargetObject.class, this, mixins, LOOKUP);
|
||||
map.put(proxy, this);
|
||||
if (proxy instanceof DbgEventsListener) {
|
||||
model.getManager().addEventsListener((DbgEventsListener) proxy);
|
||||
}
|
||||
setModelObject(modelObject);
|
||||
}
|
||||
|
||||
public DelegateDbgModel2TargetObject clone(String key, ModelObject modelObject) {
|
||||
DbgModelTargetObject p = (DbgModelTargetObject) getImplParent();
|
||||
List<Class<? extends TargetObject>> mixins = new ArrayList<>();
|
||||
Class<? extends DbgModelTargetObject> mixin = lookupWrapperType(key, p.getName());
|
||||
if (mixin != null) {
|
||||
mixins.add(mixin);
|
||||
}
|
||||
DelegateDbgModel2TargetObject delegate =
|
||||
new DelegateDbgModel2TargetObject(getModel(), p, key, modelObject, mixins);
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends TypedTargetObject<T>> T as(Class<T> iface) {
|
||||
return DebuggerObjectModel.requireIface(iface, proxy, getPath());
|
||||
|
@ -348,6 +354,10 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
}
|
||||
}
|
||||
|
||||
public DelegateDbgModel2TargetObject getDelegate() {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Methods required for DbgModelTargetBreakpointSpec mixin
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_supported_attach_kinds" schema="SET_ATTACH_KIND" required="yes" hidden="yes" />
|
||||
<attribute name="_event_process" schema="STRING" hidden="yes" />
|
||||
<attribute name="_event_thread" schema="STRING" hidden="yes" />
|
||||
<attribute name="_parameters" schema="MAP_PARAMETERS" required="yes" hidden="yes" />
|
||||
|
@ -29,7 +28,7 @@
|
|||
<attribute name="Settings" schema="OBJECT" />
|
||||
<attribute name="State" schema="OBJECT" />
|
||||
<attribute name="Utility" schema="OBJECT" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="VOID" />
|
||||
</schema>
|
||||
<schema name="SessionContainer" canonical="yes">
|
||||
<element schema="Session" />
|
||||
|
@ -41,7 +40,7 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="ConnectorContainer" canonical="yes">
|
||||
<element schema="OBJECT" />
|
||||
|
@ -135,7 +134,7 @@
|
|||
<interface name="Interruptible" />
|
||||
<interface name="Resumable" />
|
||||
<element schema="VOID" />
|
||||
<attribute name="_accessible" schema="BOOL" required="yes" hidden="yes" />
|
||||
<attribute name="_accessible" schema="BOOL" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
|
@ -154,7 +153,7 @@
|
|||
<schema name="Available">
|
||||
<interface name="Attachable" />
|
||||
<element schema="VOID" />
|
||||
<attribute name="_pid" schema="LONG" hidden="yes" />
|
||||
<attribute name="_pid" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
|
@ -182,7 +181,7 @@
|
|||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="Machine" schema="SessionAttributesMachine" fixed="yes" />
|
||||
<attribute name="Target" schema="OBJECT" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="ProcessContainer" canonical="yes">
|
||||
<interface name="EventScope" />
|
||||
|
@ -197,7 +196,7 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="SessionAttributesMachine">
|
||||
<element schema="VOID" />
|
||||
|
@ -213,7 +212,7 @@
|
|||
<attribute name="Debugger" schema="STRING" />
|
||||
<attribute name="OS" schema="STRING" />
|
||||
<attribute name="Mode" schema="STRING" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="Process">
|
||||
<interface name="Aggregate" />
|
||||
|
@ -242,7 +241,6 @@
|
|||
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
|
||||
<attribute name="_accessible" schema="BOOL" required="yes" hidden="yes" />
|
||||
<attribute name="_supported_attach_kinds" schema="SET_ATTACH_KIND" required="yes" hidden="yes" />
|
||||
<attribute name="_parameters" schema="MAP_PARAMETERS" required="yes" fixed="yes" hidden="yes" />
|
||||
<attribute name="_supported_step_kinds" schema="SET_STEP_KIND" required="yes" fixed="yes" hidden="yes" />
|
||||
<attribute name="Debug" schema="DebugContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Memory" schema="Memory" required="yes" fixed="yes" />
|
||||
|
@ -253,8 +251,8 @@
|
|||
<attribute name="Handle" schema="OBJECT" />
|
||||
<attribute name="Id" schema="OBJECT" />
|
||||
<attribute name="Io" schema="OBJECT" />
|
||||
<attribute name="Name" schema="STRING" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute name="Name" schema="OBJECT" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="Memory" canonical="yes">
|
||||
<interface name="Memory" />
|
||||
|
@ -267,7 +265,7 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="ModuleContainer" canonical="yes">
|
||||
<interface name="ModuleContainer" />
|
||||
|
@ -284,7 +282,7 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="DebugContainer" canonical="yes">
|
||||
<element schema="OBJECT" />
|
||||
|
@ -297,7 +295,7 @@
|
|||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="Breakpoints" schema="BreakpointContainer" required="yes" fixed="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="ThreadContainer" canonical="yes">
|
||||
<interface name="EventScope" />
|
||||
|
@ -312,7 +310,7 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="MemoryRegion">
|
||||
<interface name="MemoryRegion" />
|
||||
|
@ -360,11 +358,11 @@
|
|||
<attribute name="_supported_step_kinds" schema="SET_STEP_KIND" required="yes" fixed="yes" hidden="yes" />
|
||||
<attribute name="Registers" schema="RegisterContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Stack" schema="Stack" required="yes" fixed="yes" />
|
||||
<attribute name="Environment" schema="OBJECT" />
|
||||
<attribute name="Environment" schema="OBJECT" />
|
||||
<attribute name="Id" schema="OBJECT" />
|
||||
<attribute name="Name" schema="STRING" />
|
||||
<attribute name="_arch" schema="STRING" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute name="Name" schema="OBJECT" />
|
||||
<attribute name="_arch" schema="STRING" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="Module">
|
||||
<interface name="Module" />
|
||||
|
@ -379,12 +377,13 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="Symbols" schema="SymbolContainer" required="yes" fixed="yes" />
|
||||
<attribute name="BaseAddress" schema="ADDRESS" />
|
||||
<attribute name="ImageName" schema="STRING" />
|
||||
<attribute name="TimeStamp" schema="INT" />
|
||||
<attribute name="Len" schema="STRING" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute name="BaseAddress" schema="OBJECT" />
|
||||
<attribute name="ImageName" schema="OBJECT" />
|
||||
<attribute name="TimeStamp" schema="OBJECT" />
|
||||
<attribute name="Len" schema="OBJECT" />
|
||||
<attribute name="Name" schema="OBJECT" />
|
||||
<attribute name="Size" schema="OBJECT" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="BreakpointContainer" canonical="yes">
|
||||
<interface name="BreakpointContainer" />
|
||||
|
@ -398,7 +397,7 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="SymbolContainer" canonical="yes">
|
||||
<interface name="SymbolNamespace" />
|
||||
|
@ -411,7 +410,7 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="RegisterContainer" canonical="yes">
|
||||
<interface name="RegisterContainer" />
|
||||
|
@ -430,7 +429,7 @@
|
|||
<attribute name="SIMD" schema="OBJECT" />
|
||||
<attribute name="User" schema="RegisterBank" />
|
||||
<attribute name="VFP" schema="OBJECT" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="RegisterBank">
|
||||
<interface name="RegisterBank" />
|
||||
|
@ -447,6 +446,19 @@
|
|||
<attribute schema="OBJECT" />
|
||||
</schema>
|
||||
<schema name="Stack" canonical="yes">
|
||||
<element schema="VOID" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_update_mode" schema="UPDATE_MODE" hidden="yes" />
|
||||
<attribute name="_short_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="Frames" schema="Frames" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="Frames" canonical="yes">
|
||||
<interface name="Stack" />
|
||||
<element schema="StackFrame" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
|
@ -457,7 +469,7 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="BreakpointSpec" canonical="yes">
|
||||
<interface name="BreakpointSpec" />
|
||||
|
@ -480,10 +492,10 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="Type" schema="STRING" />
|
||||
<attribute name="Disposition" schema="STRING" />
|
||||
<attribute name="Pending" schema="STRING" />
|
||||
<attribute name="Times" schema="INT" />
|
||||
<attribute name="Type" schema="OBJECT" />
|
||||
<attribute name="Disposition" schema="OBJECT" />
|
||||
<attribute name="Pending" schema="OBJECT" />
|
||||
<attribute name="Times" schema="OBJECT" />
|
||||
<attribute schema="VOID" />
|
||||
</schema>
|
||||
<schema name="StackFrame">
|
||||
|
@ -499,11 +511,11 @@
|
|||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="Attributes" schema="StackFrameAttributes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="StackFrameAttributes">
|
||||
<element schema="VOID" />
|
||||
<attribute name="_pc" schema="ADDRESS" required="yes" hidden="yes" />
|
||||
<attribute name="_pc" schema="ADDRESS" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
|
@ -512,14 +524,14 @@
|
|||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="FrameNumber" schema="STRING" />
|
||||
<attribute name="FrameOffset" schema="STRING" />
|
||||
<attribute name="FuncTableEntry" schema="STRING" />
|
||||
<attribute name="InstructionOffset" schema="STRING" />
|
||||
<attribute name="ReturnOffset" schema="STRING" />
|
||||
<attribute name="StackOffset" schema="STRING" />
|
||||
<attribute name="Virtual" schema="STRING" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute name="FrameNumber" schema="OBJECT" />
|
||||
<attribute name="FrameOffset" schema="OBJECT" />
|
||||
<attribute name="FuncTableEntry" schema="OBJECT" />
|
||||
<attribute name="InstructionOffset" schema="OBJECT" />
|
||||
<attribute name="ReturnOffset" schema="OBJECT" />
|
||||
<attribute name="StackOffset" schema="OBJECT" />
|
||||
<attribute name="Virtual" schema="OBJECT" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="Symbol">
|
||||
<interface name="Symbol" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue