mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-1768A: limits on initial loads; fix for possible id/pid/tid mismatch
GP-1768A: check for symbols; misc fixes GP-1768A: suppress descent for kernel mode GP-1768A: undoing a few things GP-1768A: undoing a few things again GP-1768A: added data offset methods intending to replace pids/tids for kernel lookups GP-1768A: resorting to CLI for state GP-1768A: resorting to CLI for state GP-1768A: add ability to set implicit thread/process GP-1768A: cleanup GP-1768A: default to ALIVE ofr kernel GP-1768A: better setActive implementations GP-1768B: new faster utility methods for model GP-1768B: one more use GP-1768A: NPE fix GP-1768: faster SetCurrentState; minimize calls GP-1768B: better autorecord GP-1768B: reverting a few things GP-1768C: first pass at offset/pid resolution GP-1768C: paired proc/thread logic in place GP-1768C: make only selected items ACTIVE; update only !INACTIVE GP-1768C: activate process/thread on event
This commit is contained in:
parent
b4de95f4f5
commit
6b5d7a6ad6
18 changed files with 684 additions and 288 deletions
|
@ -113,12 +113,15 @@ public interface ModelObject extends UnknownEx {
|
|||
void setIndexer(ModelObject indexer);
|
||||
|
||||
List<ModelObject> getElements();
|
||||
ModelObject getElement(String key);
|
||||
|
||||
ModelObject getChild(DataModelManager1 manager, VARIANT v);
|
||||
|
||||
Map<String, ModelObject> getKeyValueMap();
|
||||
ModelObject getKeyValueByEnum(String key);
|
||||
|
||||
Map<String, ModelObject> getRawValueMap();
|
||||
ModelObject getRawValueByEnum(String key);
|
||||
|
||||
Object getValue();
|
||||
|
||||
|
|
|
@ -130,11 +130,8 @@ 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)) {
|
||||
|
@ -145,30 +142,28 @@ public class HDMAUtil {
|
|||
indexStr = str.substring(str.indexOf("[") + 1, str.indexOf("]"));
|
||||
str = str.substring(0, str.indexOf("["));
|
||||
}
|
||||
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 (!str.equals("")) {
|
||||
ModelObject keyValue = target.getKeyValueByEnum(str);
|
||||
if (keyValue != null) {
|
||||
target = keyValue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (indexStr != null) {
|
||||
List<ModelObject> children = target.getElements();
|
||||
for (ModelObject child : children) {
|
||||
if (indexStr.equals(child.getSearchKey())) {
|
||||
target = child;
|
||||
found = true;
|
||||
else {
|
||||
ModelObject rawValue = target.getRawValueByEnum(str);
|
||||
if (rawValue != null) {
|
||||
target = rawValue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found == false) {
|
||||
return null;
|
||||
if (indexStr != null) {
|
||||
ModelObject element = target.getElement(indexStr);
|
||||
if (element != null) {
|
||||
target = element;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
|
|
@ -723,6 +723,39 @@ public class ModelObjectImpl implements ModelObjectInternal {
|
|||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelObject getElement(String key) {
|
||||
REFIID ref = new REFIID(IIterableConcept.IID_IITERABLE_CONCEPT);
|
||||
IterableConcept concept = (IterableConcept) this.getConcept(ref);
|
||||
if (concept == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ModelIterator iterator = concept.getIterator(this);
|
||||
//long dim = concept.getDefaultIndexDimensionality(this);
|
||||
if (iterator != null) {
|
||||
ModelObject next;
|
||||
int i = 0;
|
||||
while ((next = iterator.getNext(1)) != null) {
|
||||
ModelObject index = iterator.getIndexers();
|
||||
if (index != null) {
|
||||
next.setIndexer(index);
|
||||
if (next.getSearchKey().equals(key)) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
next.setSearchKey(Integer.toHexString(i));
|
||||
if (Integer.toHexString(i).equals(key)) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelObject getChild(DataModelManager1 manager, VARIANT v) {
|
||||
REFIID ref = new REFIID(IIndexableConcept.IID_IINDEXABLE_CONCEPT);
|
||||
|
@ -820,6 +853,22 @@ public class ModelObjectImpl implements ModelObjectInternal {
|
|||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ModelObject getKeyValueByEnum(String key) {
|
||||
String kstr;
|
||||
KeyEnumerator enumerator = this.enumerateKeys();
|
||||
while ((kstr = enumerator.getNext()) != null) {
|
||||
if (kstr.equals(key)) {
|
||||
ModelObject value = this.getKeyValue(kstr);
|
||||
if (value != null) {
|
||||
value.setSearchKey(kstr);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Map<String, ModelObject> getRawValueMap() {
|
||||
TreeMap<String, ModelObject> map = new TreeMap<String, ModelObject>();
|
||||
|
@ -863,6 +912,43 @@ public class ModelObjectImpl implements ModelObjectInternal {
|
|||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ModelObject getRawValueByEnum(String key) {
|
||||
TypeKind typeKind = getTypeKind();
|
||||
if (typeKind == null) {
|
||||
return null;
|
||||
}
|
||||
SymbolKind kind = null;
|
||||
switch (typeKind) {
|
||||
case TYPE_UDT:
|
||||
kind = SymbolKind.SYMBOL_FIELD;
|
||||
break;
|
||||
case TYPE_POINTER:
|
||||
kind = SymbolKind.SYMBOL_BASE_CLASS;
|
||||
try {
|
||||
ModelObject dereference = this.dereference();
|
||||
return dereference.getRawValueByEnum(key);
|
||||
}
|
||||
catch (Exception e) {
|
||||
kind = null;
|
||||
break;
|
||||
}
|
||||
case TYPE_INTRINSIC:
|
||||
case TYPE_ARRAY:
|
||||
break;
|
||||
default:
|
||||
System.err.println(this.getSearchKey() + ":" + typeKind);
|
||||
break;
|
||||
} String kstr;
|
||||
RawEnumerator enumerator = this.enumerateRawValues(kind.ordinal(), 0);
|
||||
while ((kstr = enumerator.getNext()) != null) {
|
||||
ModelObject value = enumerator.getValue();
|
||||
value.setSearchKey(kstr);
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeKind getTypeKind() {
|
||||
ModelObjectKind modelKind = getKind();
|
||||
|
@ -909,14 +995,14 @@ public class ModelObjectImpl implements ModelObjectInternal {
|
|||
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;
|
||||
ModelObject keyValue = getKeyValueByEnum("BaseAddress");
|
||||
if (keyValue != null) {
|
||||
return keyValue.getValueString();
|
||||
}
|
||||
if (map.containsKey("UniqueID") && map.containsKey("Id")) {
|
||||
String valueString = map.get("Id").getValueString();
|
||||
return valueString;
|
||||
keyValue = getKeyValueByEnum("Id");
|
||||
ModelObject keyValue2 = getKeyValueByEnum("UniqueID");
|
||||
if (keyValue != null && keyValue2 != null) {
|
||||
return keyValue.getValueString();
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,14 @@
|
|||
*/
|
||||
package agent.dbgmodel.model.impl;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -24,18 +30,47 @@ import agent.dbgeng.manager.*;
|
|||
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.*;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetBreakpointSpec;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetDebugContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetEventContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetExceptionContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetMemoryContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetModule;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetObject;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetProcess;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetSession;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetStackFrame;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetTTD;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetThread;
|
||||
import agent.dbgeng.model.impl.DbgModelTargetEventContainerImpl;
|
||||
import agent.dbgeng.model.impl.DbgModelTargetExceptionContainerImpl;
|
||||
import agent.dbgeng.model.impl.DbgModelTargetMemoryContainerImpl;
|
||||
import agent.dbgeng.model.impl.DbgModelTargetProcessImpl;
|
||||
import agent.dbgeng.model.impl.DbgModelTargetThreadImpl;
|
||||
import agent.dbgmodel.dbgmodel.main.ModelObject;
|
||||
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.ModelObjectKind;
|
||||
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.TypeKind;
|
||||
import agent.dbgmodel.manager.DbgManager2Impl;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.dbg.agent.DefaultTargetObject;
|
||||
import ghidra.dbg.target.*;
|
||||
import ghidra.dbg.target.TargetAccessConditioned;
|
||||
import ghidra.dbg.target.TargetAttacher;
|
||||
import ghidra.dbg.target.TargetBreakpointSpec;
|
||||
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
|
||||
import ghidra.dbg.target.TargetBreakpointSpecContainer;
|
||||
import ghidra.dbg.target.TargetBreakpointSpecContainer.TargetBreakpointKindSet;
|
||||
import ghidra.dbg.target.TargetEnvironment;
|
||||
import ghidra.dbg.target.TargetExecutionStateful;
|
||||
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
|
||||
import ghidra.dbg.target.TargetInterpreter;
|
||||
import ghidra.dbg.target.TargetModule;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.target.TargetProcess;
|
||||
import ghidra.dbg.target.TargetRegister;
|
||||
import ghidra.dbg.target.TargetRegisterBank;
|
||||
import ghidra.dbg.target.TargetStackFrame;
|
||||
import ghidra.dbg.target.TargetSteppable;
|
||||
import ghidra.dbg.target.TargetThread;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
import ghidra.dbg.util.PathUtils.TargetObjectKeyComparator;
|
||||
|
@ -250,11 +285,6 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||
if (isValid()) {
|
||||
TargetExecutionStateful stateful = (TargetExecutionStateful) proxy;
|
||||
TargetExecutionState state = stateful.getExecutionState();
|
||||
if (getManager().isKernelMode()) {
|
||||
if (state.equals(TargetExecutionState.INACTIVE)) {
|
||||
state = TargetExecutionState.ALIVE;
|
||||
}
|
||||
}
|
||||
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME, state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,24 +15,53 @@
|
|||
*/
|
||||
package agent.dbgmodel.model.impl;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import agent.dbgeng.dbgeng.*;
|
||||
import agent.dbgeng.manager.*;
|
||||
import agent.dbgeng.dbgeng.DebugModuleInfo;
|
||||
import agent.dbgeng.dbgeng.DebugProcessId;
|
||||
import agent.dbgeng.dbgeng.DebugSessionId;
|
||||
import agent.dbgeng.dbgeng.DebugSystemObjects;
|
||||
import agent.dbgeng.dbgeng.DebugThreadId;
|
||||
import agent.dbgeng.manager.DbgCause;
|
||||
import agent.dbgeng.manager.DbgProcess;
|
||||
import agent.dbgeng.manager.DbgReason;
|
||||
import agent.dbgeng.manager.DbgSession;
|
||||
import agent.dbgeng.manager.DbgStackFrame;
|
||||
import agent.dbgeng.manager.DbgState;
|
||||
import agent.dbgeng.manager.DbgThread;
|
||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
||||
import agent.dbgeng.manager.reason.*;
|
||||
import agent.dbgeng.manager.reason.DbgEndSteppingRangeReason;
|
||||
import agent.dbgeng.manager.reason.DbgExitNormallyReason;
|
||||
import agent.dbgeng.manager.reason.DbgExitedReason;
|
||||
import agent.dbgeng.manager.reason.DbgSignalReceivedReason;
|
||||
import agent.dbgeng.model.iface1.DbgModelSelectableObject;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetExecutionStateful;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetBreakpointSpec;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetConnector;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetModule;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetObject;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetProcess;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetProcessContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetRoot;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetThread;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetThreadContainer;
|
||||
import agent.dbgeng.model.impl.DbgModelTargetConnectorContainerImpl;
|
||||
import agent.dbgeng.model.impl.DbgModelTargetProcessImpl;
|
||||
import agent.dbgmodel.dbgmodel.main.ModelObject;
|
||||
import agent.dbgmodel.manager.DbgManager2Impl;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.async.TypeSpec;
|
||||
import ghidra.dbg.target.*;
|
||||
import ghidra.dbg.target.TargetEventScope;
|
||||
import ghidra.dbg.target.TargetExecutionStateful;
|
||||
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
|
||||
import ghidra.dbg.target.TargetFocusScope;
|
||||
import ghidra.dbg.target.TargetMethod;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.target.TargetThread;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
import ghidra.util.Msg;
|
||||
|
@ -135,11 +164,18 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
@Override
|
||||
public void processSelected(DbgProcess process, DbgCause cause) {
|
||||
objectSelected(process);
|
||||
if (getManager().isKernelMode()) {
|
||||
processActivated(process);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadSelected(DbgThread thread, DbgStackFrame frame, DbgCause cause) {
|
||||
objectSelected(thread);
|
||||
if (getManager().isKernelMode() && thread != null) {
|
||||
processActivated(thread.getProcess());
|
||||
threadActivated(thread);
|
||||
}
|
||||
if (frame != null) {
|
||||
objectSelected(frame);
|
||||
}
|
||||
|
@ -151,16 +187,6 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
if (obj instanceof DbgModelSelectableObject) {
|
||||
setFocus((DbgModelSelectableObject) obj);
|
||||
}
|
||||
/*
|
||||
getModel().fetchModelValue(objPath, true).thenAccept(obj -> {
|
||||
if (obj instanceof DbgModelSelectableObject) {
|
||||
setFocus((DbgModelSelectableObject) obj);
|
||||
}
|
||||
}).exceptionally(ex -> {
|
||||
Msg.error("Could not set focus on selected object: " + PathUtils.toString(objPath), ex);
|
||||
return null;
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -190,6 +216,21 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
});
|
||||
}
|
||||
|
||||
public void processActivated(DbgProcess proc) {
|
||||
List<String> objPath = findObject(proc);
|
||||
DbgModelTargetExecutionStateful stateful = (DbgModelTargetExecutionStateful) getModel().getModelObject(objPath);
|
||||
if (stateful == null) {
|
||||
return;
|
||||
}
|
||||
TargetExecutionState state = stateful.getExecutionState();
|
||||
if (state.equals(TargetExecutionState.INACTIVE)) {
|
||||
stateful.changeAttributes(List.of(), Map.of( //
|
||||
TargetExecutionStateful.STATE_ATTRIBUTE_NAME, TargetExecutionState.ALIVE //
|
||||
), "Selected");
|
||||
stateful.fetchAttributes(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadCreated(DbgThread thread, DbgCause cause) {
|
||||
getObject(thread).thenAccept(obj -> {
|
||||
|
@ -211,6 +252,21 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
});
|
||||
}
|
||||
|
||||
public void threadActivated(DbgThread thread) {
|
||||
List<String> objPath = findObject(thread);
|
||||
DbgModelTargetExecutionStateful stateful = (DbgModelTargetExecutionStateful) getModel().getModelObject(objPath);
|
||||
if (stateful == null) {
|
||||
return;
|
||||
}
|
||||
TargetExecutionState state = stateful.getExecutionState();
|
||||
if (state.equals(TargetExecutionState.INACTIVE)) {
|
||||
stateful.changeAttributes(List.of(), Map.of( //
|
||||
TargetExecutionStateful.STATE_ATTRIBUTE_NAME, TargetExecutionState.ALIVE //
|
||||
), "Selected");
|
||||
stateful.fetchAttributes(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moduleLoaded(DbgProcess proc, DebugModuleInfo info, DbgCause cause) {
|
||||
getObjectRevisited(proc, List.of("Modules"), info).thenAccept(obj -> {
|
||||
|
@ -534,6 +590,12 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||
DbgProcess process = thread.getProcess();
|
||||
tkey = PathUtils.makeKey("0x" + Long.toHexString(thread.getTid()));
|
||||
pkey = PathUtils.makeKey("0x" + Long.toHexString(process.getPid()));
|
||||
if (getManager().isKernelMode()) {
|
||||
if (tkey.equals("[0x0]")) {
|
||||
// Weird, but necessary...
|
||||
pkey = "[0x0]";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj instanceof DbgStackFrame) {
|
||||
DbgStackFrame frame = (DbgStackFrame) obj;
|
||||
|
|
|
@ -26,10 +26,13 @@ import java.util.Map;
|
|||
|
||||
import agent.dbgeng.manager.DbgCause;
|
||||
import agent.dbgeng.manager.DbgEventsListener;
|
||||
import agent.dbgeng.manager.DbgProcess;
|
||||
import agent.dbgeng.manager.DbgReason;
|
||||
import agent.dbgeng.manager.DbgState;
|
||||
import agent.dbgeng.manager.DbgStateListener;
|
||||
import agent.dbgeng.manager.DbgThread;
|
||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetAccessConditioned;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetBptHelper;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetExecutionStateful;
|
||||
|
@ -105,92 +108,87 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
}
|
||||
}
|
||||
|
||||
protected static Class<? extends DbgModelTargetObject> lookupWrapperType(String type,
|
||||
String parentName) {
|
||||
protected static Class<? extends DbgModelTargetObject> lookupWrapperType(String type, String parentName) {
|
||||
switch (type) {
|
||||
case "Available":
|
||||
return DbgModelTargetAvailableContainer.class;
|
||||
case "Sessions":
|
||||
return DbgModelTargetSessionContainer.class;
|
||||
case "Processes":
|
||||
return DbgModelTargetProcessContainer.class;
|
||||
case "Threads":
|
||||
return DbgModelTargetThreadContainer.class;
|
||||
case "Modules":
|
||||
return DbgModelTargetModuleContainer.class;
|
||||
case "Frames":
|
||||
return DbgModelTargetStack.class;
|
||||
case "Registers":
|
||||
return DbgModelTargetRegisterContainer.class;
|
||||
case "Attributes":
|
||||
return DbgModelTargetSessionAttributes.class;
|
||||
case "Breakpoints":
|
||||
return DbgModelTargetBreakpointContainer.class;
|
||||
case "cursession":
|
||||
return DbgModelTargetSession.class;
|
||||
case "curprocess":
|
||||
return DbgModelTargetProcess.class;
|
||||
case "curthread":
|
||||
return DbgModelTargetThread.class;
|
||||
case "curframe":
|
||||
return DbgModelTargetStackFrame.class;
|
||||
case "User":
|
||||
return DbgModelTargetRegisterBank.class;
|
||||
case "TTD":
|
||||
return DbgModelTargetTTD.class;
|
||||
case "Debug":
|
||||
return DbgModelTargetDebugContainer.class;
|
||||
case "Available":
|
||||
return DbgModelTargetAvailableContainer.class;
|
||||
case "Sessions":
|
||||
return DbgModelTargetSessionContainer.class;
|
||||
case "Processes":
|
||||
return DbgModelTargetProcessContainer.class;
|
||||
case "Threads":
|
||||
return DbgModelTargetThreadContainer.class;
|
||||
case "Modules":
|
||||
return DbgModelTargetModuleContainer.class;
|
||||
case "Frames":
|
||||
return DbgModelTargetStack.class;
|
||||
case "Registers":
|
||||
return DbgModelTargetRegisterContainer.class;
|
||||
case "Attributes":
|
||||
return DbgModelTargetSessionAttributes.class;
|
||||
case "Breakpoints":
|
||||
return DbgModelTargetBreakpointContainer.class;
|
||||
case "cursession":
|
||||
return DbgModelTargetSession.class;
|
||||
case "curprocess":
|
||||
return DbgModelTargetProcess.class;
|
||||
case "curthread":
|
||||
return DbgModelTargetThread.class;
|
||||
case "curframe":
|
||||
return DbgModelTargetStackFrame.class;
|
||||
case "User":
|
||||
return DbgModelTargetRegisterBank.class;
|
||||
case "TTD":
|
||||
return DbgModelTargetTTD.class;
|
||||
case "Debug":
|
||||
return DbgModelTargetDebugContainer.class;
|
||||
}
|
||||
if (parentName != null) {
|
||||
switch (parentName) {
|
||||
case "Available":
|
||||
return DbgModelTargetAvailable.class;
|
||||
case "Sessions":
|
||||
return DbgModelTargetSession.class;
|
||||
case "Processes":
|
||||
return DbgModelTargetProcess.class;
|
||||
case "Threads":
|
||||
return DbgModelTargetThread.class;
|
||||
case "Modules":
|
||||
return DbgModelTargetModule.class;
|
||||
case "Frames":
|
||||
return DbgModelTargetStackFrame.class;
|
||||
case "Breakpoints":
|
||||
return DbgModelTargetBreakpointSpec.class;
|
||||
//case "Registers":
|
||||
// return DbgModelTargetRegisterBank.class;
|
||||
case "FloatingPoint":
|
||||
case "Kernel":
|
||||
case "SIMD":
|
||||
case "VFP":
|
||||
case "User":
|
||||
return DbgModelTargetRegister.class;
|
||||
case "Available":
|
||||
return DbgModelTargetAvailable.class;
|
||||
case "Sessions":
|
||||
return DbgModelTargetSession.class;
|
||||
case "Processes":
|
||||
return DbgModelTargetProcess.class;
|
||||
case "Threads":
|
||||
return DbgModelTargetThread.class;
|
||||
case "Modules":
|
||||
return DbgModelTargetModule.class;
|
||||
case "Frames":
|
||||
return DbgModelTargetStackFrame.class;
|
||||
case "Breakpoints":
|
||||
return DbgModelTargetBreakpointSpec.class;
|
||||
// case "Registers":
|
||||
// return DbgModelTargetRegisterBank.class;
|
||||
case "FloatingPoint":
|
||||
case "Kernel":
|
||||
case "SIMD":
|
||||
case "VFP":
|
||||
case "User":
|
||||
return DbgModelTargetRegister.class;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DbgModelTargetObject makeProxy(DbgModel2Impl model, DbgModelTargetObject parent,
|
||||
String key, ModelObject object) {
|
||||
public static DbgModelTargetObject makeProxy(DbgModel2Impl model, DbgModelTargetObject parent, String key,
|
||||
ModelObject object) {
|
||||
List<Class<? extends TargetObject>> mixins = new ArrayList<>();
|
||||
String lkey = key;
|
||||
String pname = parent.getName();
|
||||
|
||||
/*
|
||||
if (object.getKind().equals(ModelObjectKind.OBJECT_METHOD) || lkey.contains(")")) {
|
||||
mixins.add(DbgModelTargetMethod.class);
|
||||
// NB: We're passing the parent's mixin model to the method on the assumption
|
||||
// the init methods will need to know that the method's children have various
|
||||
// properties.
|
||||
lkey = pname;
|
||||
pname = "";
|
||||
}
|
||||
*/
|
||||
* if (object.getKind().equals(ModelObjectKind.OBJECT_METHOD) ||
|
||||
* lkey.contains(")")) { mixins.add(DbgModelTargetMethod.class); // NB: We're
|
||||
* passing the parent's mixin model to the method on the assumption // the init
|
||||
* methods will need to know that the method's children have various //
|
||||
* properties. lkey = pname; pname = ""; }
|
||||
*/
|
||||
|
||||
if (object.getKind().equals(ModelObjectKind.OBJECT_METHOD)) {
|
||||
mixins.add(DbgModelTargetMethod.class);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Class<? extends DbgModelTargetObject> mixin = lookupWrapperType(lkey, pname);
|
||||
if (mixin != null) {
|
||||
mixins.add(mixin);
|
||||
|
@ -201,30 +199,32 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
|
||||
protected static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
|
||||
// NOTE: The Cleanable stuff is the replacement for overriding Object.finalize(), which
|
||||
// NOTE: The Cleanable stuff is the replacement for overriding
|
||||
// Object.finalize(), which
|
||||
// is now deprecated.
|
||||
protected final ProxyState state;
|
||||
protected final Cleanable cleanable;
|
||||
|
||||
private boolean breakpointEnabled;
|
||||
private final ListenerSet<TargetBreakpointAction> breakpointActions =
|
||||
new ListenerSet<>(TargetBreakpointAction.class) {
|
||||
// Use strong references on actions
|
||||
protected Map<TargetBreakpointAction, TargetBreakpointAction> createMap() {
|
||||
return Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
};
|
||||
private final ListenerSet<TargetBreakpointAction> breakpointActions = new ListenerSet<>(
|
||||
TargetBreakpointAction.class) {
|
||||
// Use strong references on actions
|
||||
protected Map<TargetBreakpointAction, TargetBreakpointAction> createMap() {
|
||||
return Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
};
|
||||
};
|
||||
|
||||
// Extending DefaultTargetObject may spare you from listeners, elements, and attributes
|
||||
//protected final ListenerSet<TargetObjectListener> listeners =
|
||||
// new ListenerSet<>(TargetObjectListener.class);
|
||||
// Extending DefaultTargetObject may spare you from listeners, elements, and
|
||||
// attributes
|
||||
// protected final ListenerSet<TargetObjectListener> listeners =
|
||||
// new ListenerSet<>(TargetObjectListener.class);
|
||||
|
||||
// any other fields you need to support your impl
|
||||
|
||||
public DelegateDbgModel2TargetObject(DbgModel2Impl model, DbgModelTargetObject parent,
|
||||
String key, ModelObject modelObject, List<Class<? extends TargetObject>> mixins) {
|
||||
public DelegateDbgModel2TargetObject(DbgModel2Impl model, DbgModelTargetObject parent, String key,
|
||||
ModelObject modelObject, List<Class<? extends TargetObject>> mixins) {
|
||||
super(model, mixins, model, parent.getProxy(), key, getHintForObject(modelObject));
|
||||
//System.err.println(this);
|
||||
// System.err.println(this);
|
||||
this.state = new ProxyState(model, modelObject);
|
||||
this.cleanable = CLEANER.register(this, state);
|
||||
|
||||
|
@ -244,8 +244,8 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
if (mixin != null) {
|
||||
mixins.add(mixin);
|
||||
}
|
||||
DelegateDbgModel2TargetObject delegate =
|
||||
new DelegateDbgModel2TargetObject(getModel(), p, key, modelObject, mixins);
|
||||
DelegateDbgModel2TargetObject delegate = new DelegateDbgModel2TargetObject(getModel(), p, key, modelObject,
|
||||
mixins);
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
@ -272,43 +272,45 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
protected void checkExited(DbgState state, DbgCause cause) {
|
||||
TargetExecutionState exec = TargetExecutionState.INACTIVE;
|
||||
switch (state) {
|
||||
case NOT_STARTED: {
|
||||
exec = TargetExecutionState.INACTIVE;
|
||||
break;
|
||||
}
|
||||
case STARTING: {
|
||||
exec = TargetExecutionState.ALIVE;
|
||||
break;
|
||||
}
|
||||
case RUNNING: {
|
||||
exec = TargetExecutionState.RUNNING;
|
||||
resetModified();
|
||||
onRunning();
|
||||
break;
|
||||
}
|
||||
case STOPPED: {
|
||||
exec = TargetExecutionState.STOPPED;
|
||||
onStopped();
|
||||
break;
|
||||
}
|
||||
case EXIT: {
|
||||
exec = TargetExecutionState.TERMINATED;
|
||||
onExit();
|
||||
break;
|
||||
}
|
||||
case SESSION_EXIT: {
|
||||
getModel().close();
|
||||
return;
|
||||
}
|
||||
case NOT_STARTED: {
|
||||
exec = TargetExecutionState.INACTIVE;
|
||||
break;
|
||||
}
|
||||
case STARTING: {
|
||||
exec = TargetExecutionState.ALIVE;
|
||||
break;
|
||||
}
|
||||
case RUNNING: {
|
||||
exec = TargetExecutionState.RUNNING;
|
||||
resetModified();
|
||||
onRunning();
|
||||
break;
|
||||
}
|
||||
case STOPPED: {
|
||||
exec = TargetExecutionState.STOPPED;
|
||||
onStopped();
|
||||
break;
|
||||
}
|
||||
case EXIT: {
|
||||
exec = TargetExecutionState.TERMINATED;
|
||||
onExit();
|
||||
break;
|
||||
}
|
||||
case SESSION_EXIT: {
|
||||
getModel().close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (proxy instanceof TargetExecutionStateful) {
|
||||
if (proxy instanceof DbgModelTargetSession) {
|
||||
if (state != DbgState.EXIT) {
|
||||
setExecutionState(exec, "Refreshed");
|
||||
}
|
||||
}
|
||||
else {
|
||||
setExecutionState(exec, "Refreshed");
|
||||
} else {
|
||||
TargetExecutionState previous = this.getExecutionState();
|
||||
if (!previous.equals(TargetExecutionState.INACTIVE)) {
|
||||
setExecutionState(exec, "Refreshed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +323,7 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
proxy instanceof DbgModelTargetStackFrame || //
|
||||
proxy instanceof DbgModelTargetStack || //
|
||||
proxy instanceof DbgModelTargetTTD) {
|
||||
//listeners.fire.invalidateCacheRequested(proxy);
|
||||
// listeners.fire.invalidateCacheRequested(proxy);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -330,30 +332,37 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
if (PathUtils.isLink(parent.getPath(), proxy.getName(), proxy.getPath())) {
|
||||
return;
|
||||
}
|
||||
DbgManagerImpl manager = getModel().getManager();
|
||||
boolean kernelMode = manager.isKernelMode();
|
||||
if (proxy instanceof DbgModelTargetSession) {
|
||||
DbgModelTargetSession targetSession = (DbgModelTargetSession) proxy;
|
||||
targetSession.getSession(false);
|
||||
}
|
||||
if (proxy instanceof DbgModelTargetProcess) {
|
||||
DbgModelTargetProcess targetProcess = (DbgModelTargetProcess) proxy;
|
||||
targetProcess.getProcess(false);
|
||||
DbgProcess process = targetProcess.getProcess(false);
|
||||
if (kernelMode) {
|
||||
Long offset = process.getOffset();
|
||||
if (offset == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (proxy instanceof DbgModelTargetThread) {
|
||||
DbgModelTargetThread targetThread = (DbgModelTargetThread) proxy;
|
||||
targetThread.getThread(false);
|
||||
}
|
||||
|
||||
boolean kernelMode = getModel().getManager().isKernelMode();
|
||||
if (kernelMode) {
|
||||
if (proxy instanceof DbgModelTargetProcess || //
|
||||
proxy instanceof DbgModelTargetThread) {
|
||||
return;
|
||||
DbgThread thread = targetThread.getThread(false);
|
||||
if (kernelMode) {
|
||||
Long offset = thread.getOffset();
|
||||
if (offset == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getModel().isSuppressDescent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (proxy instanceof DbgModelTargetSession || //
|
||||
proxy instanceof DbgModelTargetProcess || //
|
||||
proxy instanceof DbgModelTargetThread) {
|
||||
|
@ -362,8 +371,7 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
}
|
||||
if (proxy instanceof DbgModelTargetRegisterContainer || //
|
||||
proxy instanceof DbgModelTargetRegisterBank || //
|
||||
proxy.getName().equals("Stack") ||
|
||||
proxy.getName().equals("Debug")) {
|
||||
proxy.getName().equals("Stack") || proxy.getName().equals("Debug")) {
|
||||
requestAttributes(false);
|
||||
return;
|
||||
}
|
||||
|
@ -405,7 +413,7 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
}
|
||||
if (proxy instanceof TargetAccessConditioned) {
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
TargetAccessConditioned.ACCESSIBLE_ATTRIBUTE_NAME, accessible //
|
||||
TargetAccessConditioned.ACCESSIBLE_ATTRIBUTE_NAME, accessible //
|
||||
), "Accessibility changed");
|
||||
}
|
||||
}
|
||||
|
@ -455,21 +463,18 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
}
|
||||
if (proxy instanceof TargetThread) {
|
||||
List<DelegateDbgModel2TargetObject> delegates = new ArrayList<>();
|
||||
TargetObject stack =
|
||||
(TargetObject) getCachedAttribute("Stack");
|
||||
TargetObject stack = (TargetObject) getCachedAttribute("Stack");
|
||||
if (stack != null) {
|
||||
DbgModelTargetStack frames =
|
||||
(DbgModelTargetStack) stack.getCachedAttribute("Frames");
|
||||
DbgModelTargetStack frames = (DbgModelTargetStack) stack.getCachedAttribute("Frames");
|
||||
delegates.add((DelegateDbgModel2TargetObject) frames.getDelegate());
|
||||
}
|
||||
DbgModelTargetRegisterContainer container =
|
||||
(DbgModelTargetRegisterContainer) getCachedAttribute("Registers");
|
||||
DbgModelTargetRegisterContainer container = (DbgModelTargetRegisterContainer) getCachedAttribute(
|
||||
"Registers");
|
||||
if (container == null) {
|
||||
return;
|
||||
}
|
||||
delegates.add((DelegateDbgModel2TargetObject) container.getDelegate());
|
||||
DbgModelTargetRegisterBank bank =
|
||||
(DbgModelTargetRegisterBank) container.getCachedAttribute("User");
|
||||
DbgModelTargetRegisterBank bank = (DbgModelTargetRegisterBank) container.getCachedAttribute("User");
|
||||
if (bank == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -486,7 +491,7 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
}
|
||||
if (proxy instanceof TargetRegisterBank) {
|
||||
TargetRegisterBank bank = (TargetRegisterBank) proxy;
|
||||
//requestElements(false);
|
||||
// requestElements(false);
|
||||
requestAttributes(false).thenAccept(__ -> {
|
||||
bank.readRegistersNamed(getCachedAttributes().keySet());
|
||||
});
|
||||
|
@ -497,8 +502,7 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
|||
for (TargetObject obj : getCachedElements().values()) {
|
||||
if (obj instanceof TargetStackFrame) {
|
||||
DbgModelTargetObject frame = (DbgModelTargetObject) obj;
|
||||
DelegateDbgModel2TargetObject delegate =
|
||||
(DelegateDbgModel2TargetObject) frame.getDelegate();
|
||||
DelegateDbgModel2TargetObject delegate = (DelegateDbgModel2TargetObject) frame.getDelegate();
|
||||
delegate.threadStateChangedSpecific(state, reason);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue