mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 19:21:14 +08:00
Merge remote-tracking branch 'origin/GP-2752_Dan_removePerTargetObjectListeners--SQUASHED'
This commit is contained in:
-4
@@ -23,11 +23,9 @@ import agent.dbgeng.dbgeng.DebugClient.DebugStatus;
|
|||||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||||
import agent.dbgeng.model.AbstractDbgModel;
|
import agent.dbgeng.model.AbstractDbgModel;
|
||||||
import ghidra.async.AsyncUtils;
|
import ghidra.async.AsyncUtils;
|
||||||
import ghidra.dbg.DebuggerModelListener;
|
|
||||||
import ghidra.dbg.agent.SpiTargetObject;
|
import ghidra.dbg.agent.SpiTargetObject;
|
||||||
import ghidra.dbg.target.TargetObject;
|
import ghidra.dbg.target.TargetObject;
|
||||||
import ghidra.dbg.util.CollectionUtils.Delta;
|
import ghidra.dbg.util.CollectionUtils.Delta;
|
||||||
import ghidra.util.datastruct.ListenerSet;
|
|
||||||
|
|
||||||
public interface DbgModelTargetObject extends SpiTargetObject {
|
public interface DbgModelTargetObject extends SpiTargetObject {
|
||||||
|
|
||||||
@@ -65,8 +63,6 @@ public interface DbgModelTargetObject extends SpiTargetObject {
|
|||||||
|
|
||||||
public CompletableFuture<List<TargetObject>> requestNativeElements();
|
public CompletableFuture<List<TargetObject>> requestNativeElements();
|
||||||
|
|
||||||
public ListenerSet<DebuggerModelListener> getListeners();
|
|
||||||
|
|
||||||
public DbgModelTargetSession getParentSession();
|
public DbgModelTargetSession getParentSession();
|
||||||
|
|
||||||
public DbgModelTargetProcess getParentProcess();
|
public DbgModelTargetProcess getParentProcess();
|
||||||
|
|||||||
+3
-7
@@ -25,12 +25,10 @@ import agent.dbgeng.manager.DbgThread;
|
|||||||
import agent.dbgeng.manager.impl.*;
|
import agent.dbgeng.manager.impl.*;
|
||||||
import ghidra.async.AsyncUtils;
|
import ghidra.async.AsyncUtils;
|
||||||
import ghidra.async.TypeSpec;
|
import ghidra.async.TypeSpec;
|
||||||
import ghidra.dbg.DebuggerModelListener;
|
|
||||||
import ghidra.dbg.error.DebuggerRegisterAccessException;
|
import ghidra.dbg.error.DebuggerRegisterAccessException;
|
||||||
import ghidra.dbg.target.TargetRegisterBank;
|
import ghidra.dbg.target.TargetRegisterBank;
|
||||||
import ghidra.dbg.util.ConversionUtils;
|
import ghidra.dbg.util.ConversionUtils;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.datastruct.ListenerSet;
|
|
||||||
|
|
||||||
public interface DbgModelTargetRegisterBank extends DbgModelTargetObject, TargetRegisterBank {
|
public interface DbgModelTargetRegisterBank extends DbgModelTargetObject, TargetRegisterBank {
|
||||||
|
|
||||||
@@ -91,10 +89,8 @@ public interface DbgModelTargetRegisterBank extends DbgModelTargetObject, Target
|
|||||||
reg.setModified(value.toString(16).equals(oldval));
|
reg.setModified(value.toString(16).equals(oldval));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ListenerSet<DebuggerModelListener> listeners = getListeners();
|
|
||||||
if (listeners != null) {
|
broadcast().registersUpdated(getProxy(), result);
|
||||||
listeners.fire.registersUpdated(getProxy(), result);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -126,7 +122,7 @@ public interface DbgModelTargetRegisterBank extends DbgModelTargetObject, Target
|
|||||||
getParentThread().getThread().writeRegisters(toWrite).handle(seq::next);
|
getParentThread().getThread().writeRegisters(toWrite).handle(seq::next);
|
||||||
// TODO: Should probably filter only effective and normalized writes in the callback
|
// TODO: Should probably filter only effective and normalized writes in the callback
|
||||||
}).then(seq -> {
|
}).then(seq -> {
|
||||||
getListeners().fire.registersUpdated(getProxy(), values);
|
broadcast().registersUpdated(getProxy(), values);
|
||||||
seq.exit();
|
seq.exit();
|
||||||
}).finish();
|
}).finish();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@ public interface DbgModelTargetSession extends //
|
|||||||
if (!isValid()) {
|
if (!isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getListeners().fire.consoleOutput(getProxy(), chan, output);
|
broadcast().consoleOutput(getProxy(), chan, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+1
-1
@@ -95,7 +95,7 @@ public class DbgModelTargetBreakpointContainerImpl extends DbgModelTargetObjectI
|
|||||||
DbgModelTargetThread targetThread =
|
DbgModelTargetThread targetThread =
|
||||||
getParentProcess().getThreads().getTargetThread(getManager().getEventThread());
|
getParentProcess().getThreads().getTargetThread(getManager().getEventThread());
|
||||||
DbgModelTargetBreakpointSpec spec = getTargetBreakpointSpec(info);
|
DbgModelTargetBreakpointSpec spec = getTargetBreakpointSpec(info);
|
||||||
listeners.fire.breakpointHit(getProxy(), targetThread, null, spec, spec);
|
broadcast().breakpointHit(getProxy(), targetThread, null, spec, spec);
|
||||||
spec.breakpointHit();
|
spec.breakpointHit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -121,7 +121,7 @@ public class DbgModelTargetMemoryContainerImpl extends DbgModelTargetObjectImpl
|
|||||||
if (span == null) {
|
if (span == null) {
|
||||||
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
||||||
}
|
}
|
||||||
listeners.fire.memoryUpdated(getProxy(), address, buf.array());
|
broadcast().memoryUpdated(getProxy(), address, buf.array());
|
||||||
return Arrays.copyOf(buf.array(), (int) span.length());
|
return Arrays.copyOf(buf.array(), (int) span.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ public class DbgModelTargetMemoryContainerImpl extends DbgModelTargetObjectImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeAssist(Address address, byte[] data) {
|
private void writeAssist(Address address, byte[] data) {
|
||||||
listeners.fire.memoryUpdated(getProxy(), address, data);
|
broadcast().memoryUpdated(getProxy(), address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+13
-9
@@ -27,13 +27,16 @@ import ghidra.dbg.target.schema.*;
|
|||||||
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
||||||
import ghidra.lifecycle.Internal;
|
import ghidra.lifecycle.Internal;
|
||||||
|
|
||||||
@TargetObjectSchemaInfo(name = "ModuleContainer", elements = { //
|
@TargetObjectSchemaInfo(
|
||||||
@TargetElementType(type = DbgModelTargetModuleImpl.class) //
|
name = "ModuleContainer",
|
||||||
}, //
|
elements = {
|
||||||
elementResync = ResyncMode.ONCE, //
|
@TargetElementType(type = DbgModelTargetModuleImpl.class)
|
||||||
attributes = { //
|
},
|
||||||
@TargetAttributeType(type = Void.class) //
|
elementResync = ResyncMode.ONCE,
|
||||||
}, canonicalContainer = true)
|
attributes = {
|
||||||
|
@TargetAttributeType(type = Void.class)
|
||||||
|
},
|
||||||
|
canonicalContainer = true)
|
||||||
public class DbgModelTargetModuleContainerImpl extends DbgModelTargetObjectImpl
|
public class DbgModelTargetModuleContainerImpl extends DbgModelTargetObjectImpl
|
||||||
implements DbgModelTargetModuleContainer {
|
implements DbgModelTargetModuleContainer {
|
||||||
// NOTE: -file-list-shared-libraries omits the main module and system-supplied DSO.
|
// NOTE: -file-list-shared-libraries omits the main module and system-supplied DSO.
|
||||||
@@ -66,7 +69,7 @@ public class DbgModelTargetModuleContainerImpl extends DbgModelTargetObjectImpl
|
|||||||
TargetThread eventThread =
|
TargetThread eventThread =
|
||||||
(TargetThread) getModel().getModelObject(getManager().getEventThread());
|
(TargetThread) getModel().getModelObject(getManager().getEventThread());
|
||||||
changeElements(List.of(), List.of(module), Map.of(), "Loaded");
|
changeElements(List.of(), List.of(module), Map.of(), "Loaded");
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
||||||
"Library " + name + " loaded", List.of(module));
|
"Library " + name + " loaded", List.of(module));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +80,7 @@ public class DbgModelTargetModuleContainerImpl extends DbgModelTargetObjectImpl
|
|||||||
if (targetModule != null) {
|
if (targetModule != null) {
|
||||||
TargetThread eventThread =
|
TargetThread eventThread =
|
||||||
(TargetThread) getModel().getModelObject(getManager().getEventThread());
|
(TargetThread) getModel().getModelObject(getManager().getEventThread());
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
||||||
"Library " + name + " unloaded", List.of(targetModule));
|
"Library " + name + " unloaded", List.of(targetModule));
|
||||||
DbgModelImpl impl = (DbgModelImpl) model;
|
DbgModelImpl impl = (DbgModelImpl) model;
|
||||||
impl.deleteModelObject(targetModule.getDbgModule());
|
impl.deleteModelObject(targetModule.getDbgModule());
|
||||||
@@ -108,6 +111,7 @@ public class DbgModelTargetModuleContainerImpl extends DbgModelTargetObjectImpl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public DbgModelTargetModule getTargetModule(String name) {
|
public DbgModelTargetModule getTargetModule(String name) {
|
||||||
// Only get here from libraryLoaded or getElements. The known list should be fresh.
|
// Only get here from libraryLoaded or getElements. The known list should be fresh.
|
||||||
DbgModule module = process.getKnownModules().get(name);
|
DbgModule module = process.getKnownModules().get(name);
|
||||||
|
|||||||
+6
-6
@@ -33,12 +33,12 @@ import ghidra.dbg.target.schema.*;
|
|||||||
|
|
||||||
@TargetObjectSchemaInfo(
|
@TargetObjectSchemaInfo(
|
||||||
name = "ProcessContainer",
|
name = "ProcessContainer",
|
||||||
elements = { //
|
elements = {
|
||||||
@TargetElementType(type = DbgModelTargetProcessImpl.class) //
|
@TargetElementType(type = DbgModelTargetProcessImpl.class)
|
||||||
},
|
},
|
||||||
attributes = { //
|
attributes = {
|
||||||
@TargetAttributeType(name = TargetConfigurable.BASE_ATTRIBUTE_NAME, type = Integer.class), //
|
@TargetAttributeType(name = TargetConfigurable.BASE_ATTRIBUTE_NAME, type = Integer.class),
|
||||||
@TargetAttributeType(type = Void.class) //
|
@TargetAttributeType(type = Void.class)
|
||||||
},
|
},
|
||||||
canonicalContainer = true)
|
canonicalContainer = true)
|
||||||
public class DbgModelTargetProcessContainerImpl extends DbgModelTargetObjectImpl
|
public class DbgModelTargetProcessContainerImpl extends DbgModelTargetObjectImpl
|
||||||
@@ -58,7 +58,7 @@ public class DbgModelTargetProcessContainerImpl extends DbgModelTargetObjectImpl
|
|||||||
DbgModelTargetProcess process = getTargetProcess(proc);
|
DbgModelTargetProcess process = getTargetProcess(proc);
|
||||||
changeElements(List.of(), List.of(process), Map.of(), "Added");
|
changeElements(List.of(), List.of(process), Map.of(), "Added");
|
||||||
process.processStarted(proc.getPid());
|
process.processStarted(proc.getPid());
|
||||||
getListeners().fire.event(getProxy(), null, TargetEventType.PROCESS_CREATED,
|
broadcast().event(getProxy(), null, TargetEventType.PROCESS_CREATED,
|
||||||
"Process " + proc.getId() + " started " + process.getName() + "pid=" + proc.getPid(),
|
"Process " + proc.getId() + " started " + process.getName() + "pid=" + proc.getPid(),
|
||||||
List.of(process));
|
List.of(process));
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -139,6 +139,7 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void threadStateChangedSpecific(DbgThread thread, DbgState state) {
|
public void threadStateChangedSpecific(DbgThread thread, DbgState state) {
|
||||||
TargetExecutionState targetState = convertState(state);
|
TargetExecutionState targetState = convertState(state);
|
||||||
setExecutionState(targetState, "ThreadStateChanged");
|
setExecutionState(targetState, "ThreadStateChanged");
|
||||||
@@ -212,7 +213,7 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl
|
|||||||
STATE_ATTRIBUTE_NAME, TargetExecutionState.TERMINATED, //
|
STATE_ATTRIBUTE_NAME, TargetExecutionState.TERMINATED, //
|
||||||
EXIT_CODE_ATTRIBUTE_NAME, proc.getExitCode() //
|
EXIT_CODE_ATTRIBUTE_NAME, proc.getExitCode() //
|
||||||
), "Exited");
|
), "Exited");
|
||||||
getListeners().fire.event(getProxy(), null, TargetEventType.PROCESS_EXITED,
|
broadcast().event(getProxy(), null, TargetEventType.PROCESS_EXITED,
|
||||||
"Process " + proc.getId() + " exited code=" + proc.getExitCode(),
|
"Process " + proc.getId() + " exited code=" + proc.getExitCode(),
|
||||||
List.of(getProxy()));
|
List.of(getProxy()));
|
||||||
}
|
}
|
||||||
@@ -221,7 +222,7 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl
|
|||||||
@Override
|
@Override
|
||||||
public void memoryChanged(DbgProcess proc, long addr, int len, DbgCause cause) {
|
public void memoryChanged(DbgProcess proc, long addr, int len, DbgCause cause) {
|
||||||
if (proc.equals(this.process)) {
|
if (proc.equals(this.process)) {
|
||||||
listeners.fire.invalidateCacheRequested(memory);
|
broadcast().invalidateCacheRequested(memory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -134,7 +134,7 @@ public class DbgModelTargetRegisterContainerImpl extends DbgModelTargetObjectImp
|
|||||||
changeAttrs(reg, value);
|
changeAttrs(reg, value);
|
||||||
}
|
}
|
||||||
this.values = result;
|
this.values = result;
|
||||||
listeners.fire.registersUpdated(getProxy(), result);
|
broadcast().registersUpdated(getProxy(), result);
|
||||||
return result;
|
return result;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -159,7 +159,7 @@ public class DbgModelTargetRegisterContainerImpl extends DbgModelTargetObjectImp
|
|||||||
return thread.writeRegisters(toWrite);
|
return thread.writeRegisters(toWrite);
|
||||||
// TODO: Should probably filter only effective and normalized writes in the callback
|
// TODO: Should probably filter only effective and normalized writes in the callback
|
||||||
}).thenAccept(__ -> {
|
}).thenAccept(__ -> {
|
||||||
listeners.fire.registersUpdated(getProxy(), values);
|
broadcast().registersUpdated(getProxy(), values);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-9
@@ -31,12 +31,16 @@ import ghidra.dbg.target.TargetConfigurable;
|
|||||||
import ghidra.dbg.target.TargetObject;
|
import ghidra.dbg.target.TargetObject;
|
||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
|
|
||||||
@TargetObjectSchemaInfo(name = "ThreadContainer", elements = { //
|
@TargetObjectSchemaInfo(
|
||||||
@TargetElementType(type = DbgModelTargetThreadImpl.class) //
|
name = "ThreadContainer",
|
||||||
}, attributes = { //
|
elements = {
|
||||||
@TargetAttributeType(name = TargetConfigurable.BASE_ATTRIBUTE_NAME, type = Integer.class), //
|
@TargetElementType(type = DbgModelTargetThreadImpl.class)
|
||||||
@TargetAttributeType(type = Void.class) //
|
},
|
||||||
}, canonicalContainer = true)
|
attributes = {
|
||||||
|
@TargetAttributeType(name = TargetConfigurable.BASE_ATTRIBUTE_NAME, type = Integer.class),
|
||||||
|
@TargetAttributeType(type = Void.class)
|
||||||
|
},
|
||||||
|
canonicalContainer = true)
|
||||||
public class DbgModelTargetThreadContainerImpl extends DbgModelTargetObjectImpl
|
public class DbgModelTargetThreadContainerImpl extends DbgModelTargetObjectImpl
|
||||||
implements DbgModelTargetThreadContainer, DbgModelTargetConfigurable {
|
implements DbgModelTargetThreadContainer, DbgModelTargetConfigurable {
|
||||||
|
|
||||||
@@ -59,7 +63,7 @@ public class DbgModelTargetThreadContainerImpl extends DbgModelTargetObjectImpl
|
|||||||
DbgModelTargetThread targetThread = getTargetThread(thread);
|
DbgModelTargetThread targetThread = getTargetThread(thread);
|
||||||
changeElements(List.of(), List.of(targetThread), Map.of(), "Created");
|
changeElements(List.of(), List.of(targetThread), Map.of(), "Created");
|
||||||
targetThread.threadStateChangedSpecific(DbgState.STARTING, DbgReason.getReason(null));
|
targetThread.threadStateChangedSpecific(DbgState.STARTING, DbgReason.getReason(null));
|
||||||
getListeners().fire.event(getProxy(), targetThread, TargetEventType.THREAD_CREATED,
|
broadcast().event(getProxy(), targetThread, TargetEventType.THREAD_CREATED,
|
||||||
"Thread " + thread.getId() + " started", List.of(targetThread));
|
"Thread " + thread.getId() + " started", List.of(targetThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +72,7 @@ public class DbgModelTargetThreadContainerImpl extends DbgModelTargetObjectImpl
|
|||||||
DbgReason reason) {
|
DbgReason reason) {
|
||||||
DbgModelTargetThread targetThread = getTargetThread(thread);
|
DbgModelTargetThread targetThread = getTargetThread(thread);
|
||||||
TargetEventType eventType = getEventType(state, cause, reason);
|
TargetEventType eventType = getEventType(state, cause, reason);
|
||||||
getListeners().fire.event(getProxy(), targetThread, eventType,
|
broadcast().event(getProxy(), targetThread, eventType,
|
||||||
"Thread " + thread.getId() + " state changed", List.of(targetThread));
|
"Thread " + thread.getId() + " state changed", List.of(targetThread));
|
||||||
targetThread.threadStateChangedSpecific(state, reason);
|
targetThread.threadStateChangedSpecific(state, reason);
|
||||||
}
|
}
|
||||||
@@ -78,7 +82,7 @@ public class DbgModelTargetThreadContainerImpl extends DbgModelTargetObjectImpl
|
|||||||
DbgModelImpl impl = (DbgModelImpl) model;
|
DbgModelImpl impl = (DbgModelImpl) model;
|
||||||
DbgModelTargetThread targetThread = (DbgModelTargetThread) impl.getModelObject(threadId);
|
DbgModelTargetThread targetThread = (DbgModelTargetThread) impl.getModelObject(threadId);
|
||||||
if (targetThread != null) {
|
if (targetThread != null) {
|
||||||
getListeners().fire.event(getProxy(), targetThread, TargetEventType.THREAD_EXITED,
|
broadcast().event(getProxy(), targetThread, TargetEventType.THREAD_EXITED,
|
||||||
"Thread " + threadId + " exited", List.of(targetThread));
|
"Thread " + threadId + " exited", List.of(targetThread));
|
||||||
}
|
}
|
||||||
//synchronized (this) {
|
//synchronized (this) {
|
||||||
|
|||||||
+2
-7
@@ -32,7 +32,6 @@ import agent.dbgmodel.jna.dbgmodel.DbgModelNative.ModelObjectKind;
|
|||||||
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.TypeKind;
|
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.TypeKind;
|
||||||
import agent.dbgmodel.manager.DbgManager2Impl;
|
import agent.dbgmodel.manager.DbgManager2Impl;
|
||||||
import ghidra.async.AsyncUtils;
|
import ghidra.async.AsyncUtils;
|
||||||
import ghidra.dbg.DebuggerModelListener;
|
|
||||||
import ghidra.dbg.agent.DefaultTargetObject;
|
import ghidra.dbg.agent.DefaultTargetObject;
|
||||||
import ghidra.dbg.target.*;
|
import ghidra.dbg.target.*;
|
||||||
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
|
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
|
||||||
@@ -254,7 +253,8 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||||||
TargetExecutionStateful stateful = (TargetExecutionStateful) proxy;
|
TargetExecutionStateful stateful = (TargetExecutionStateful) proxy;
|
||||||
TargetExecutionState state = stateful.getExecutionState();
|
TargetExecutionState state = stateful.getExecutionState();
|
||||||
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME, state);
|
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME, state);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME,
|
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME,
|
||||||
TargetExecutionState.INACTIVE);
|
TargetExecutionState.INACTIVE);
|
||||||
}
|
}
|
||||||
@@ -412,11 +412,6 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeListener(DebuggerModelListener l) {
|
|
||||||
listeners.remove(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DbgModelTargetSession getParentSession() {
|
public DbgModelTargetSession getParentSession() {
|
||||||
DbgModelTargetObject test = (DbgModelTargetObject) parent;
|
DbgModelTargetObject test = (DbgModelTargetObject) parent;
|
||||||
|
|||||||
+8
-8
@@ -179,7 +179,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||||||
System.err.println("processAdded - null");
|
System.err.println("processAdded - null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getListeners().fire.event(getProxy(), null, TargetEventType.PROCESS_CREATED,
|
broadcast().event(getProxy(), null, TargetEventType.PROCESS_CREATED,
|
||||||
"Process " + proc.getId() + " started " + "notepad.exe" + " pid=" + proc.getPid(),
|
"Process " + proc.getId() + " started " + "notepad.exe" + " pid=" + proc.getPid(),
|
||||||
List.of(targetProcess));
|
List.of(targetProcess));
|
||||||
});
|
});
|
||||||
@@ -193,7 +193,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||||||
System.err.println("threadCreated - null");
|
System.err.println("threadCreated - null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getListeners().fire.event(getProxy(), targetThread, TargetEventType.THREAD_CREATED,
|
broadcast().event(getProxy(), targetThread, TargetEventType.THREAD_CREATED,
|
||||||
"Thread " + thread.getId() + " started", List.of(targetThread));
|
"Thread " + thread.getId() + " started", List.of(targetThread));
|
||||||
DelegateDbgModel2TargetObject delegate =
|
DelegateDbgModel2TargetObject delegate =
|
||||||
(DelegateDbgModel2TargetObject) targetThread.getDelegate();
|
(DelegateDbgModel2TargetObject) targetThread.getDelegate();
|
||||||
@@ -210,7 +210,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||||||
}
|
}
|
||||||
getObject(getManager().getEventThread()).thenAccept(t -> {
|
getObject(getManager().getEventThread()).thenAccept(t -> {
|
||||||
TargetThread eventThread = (TargetThread) t;
|
TargetThread eventThread = (TargetThread) t;
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
||||||
"Library " + info.getModuleName() + " loaded", List.of(mod));
|
"Library " + info.getModuleName() + " loaded", List.of(mod));
|
||||||
});
|
});
|
||||||
getObject(getManager().getEventProcess()).thenAccept(p -> {
|
getObject(getManager().getEventProcess()).thenAccept(p -> {
|
||||||
@@ -231,7 +231,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||||||
}
|
}
|
||||||
getObject(getManager().getEventThread()).thenAccept(t -> {
|
getObject(getManager().getEventThread()).thenAccept(t -> {
|
||||||
TargetThread eventThread = (TargetThread) t;
|
TargetThread eventThread = (TargetThread) t;
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
||||||
"Library " + info.getModuleName() + " unloaded", List.of(mod));
|
"Library " + info.getModuleName() + " unloaded", List.of(mod));
|
||||||
});
|
});
|
||||||
getObject(getManager().getEventProcess()).thenAccept(p -> {
|
getObject(getManager().getEventProcess()).thenAccept(p -> {
|
||||||
@@ -369,7 +369,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||||||
DbgModelTargetProcessImpl.EXIT_CODE_ATTRIBUTE_NAME, proc.getExitCode() //
|
DbgModelTargetProcessImpl.EXIT_CODE_ATTRIBUTE_NAME, proc.getExitCode() //
|
||||||
), "Exited");
|
), "Exited");
|
||||||
}
|
}
|
||||||
getListeners().fire.event(targetProcess.getProxy(), null,
|
broadcast().event(targetProcess.getProxy(), null,
|
||||||
TargetEventType.PROCESS_EXITED,
|
TargetEventType.PROCESS_EXITED,
|
||||||
"Process " + proc.getId() + " exited code=" + proc.getExitCode(),
|
"Process " + proc.getId() + " exited code=" + proc.getExitCode(),
|
||||||
List.of(getProxy()));
|
List.of(getProxy()));
|
||||||
@@ -383,7 +383,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DbgModelTargetThread targetThread = (DbgModelTargetThread) thread.getProxy();
|
DbgModelTargetThread targetThread = (DbgModelTargetThread) thread.getProxy();
|
||||||
getListeners().fire.event(getProxy(), targetThread, TargetEventType.THREAD_EXITED,
|
broadcast().event(getProxy(), targetThread, TargetEventType.THREAD_EXITED,
|
||||||
"Thread " + threadId + " exited", List.of(targetThread));
|
"Thread " + threadId + " exited", List.of(targetThread));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -401,7 +401,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||||||
), reason.desc());
|
), reason.desc());
|
||||||
intrinsics.put(TargetEventScope.EVENT_OBJECT_ATTRIBUTE_NAME, targetThread);
|
intrinsics.put(TargetEventScope.EVENT_OBJECT_ATTRIBUTE_NAME, targetThread);
|
||||||
TargetEventType eventType = getEventType(state, cause, reason);
|
TargetEventType eventType = getEventType(state, cause, reason);
|
||||||
getListeners().fire.event(getProxy(), targetThread, eventType,
|
broadcast().event(getProxy(), targetThread, eventType,
|
||||||
"Thread " + thread.getId() + " state changed", List.of(targetThread));
|
"Thread " + thread.getId() + " state changed", List.of(targetThread));
|
||||||
DelegateDbgModel2TargetObject delegate =
|
DelegateDbgModel2TargetObject delegate =
|
||||||
(DelegateDbgModel2TargetObject) targetThread.getDelegate();
|
(DelegateDbgModel2TargetObject) targetThread.getDelegate();
|
||||||
@@ -472,7 +472,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
|||||||
|
|
||||||
DbgThread thread = info.getEventThread();
|
DbgThread thread = info.getEventThread();
|
||||||
TargetObject targetThread = getModel().getModelObject(thread);
|
TargetObject targetThread = getModel().getModelObject(thread);
|
||||||
listeners.fire.breakpointHit(bpt.getParent(), targetThread, null, bpt, bpt);
|
broadcast().breakpointHit(bpt.getParent(), targetThread, null, bpt, bpt);
|
||||||
bpt.breakpointHit();
|
bpt.breakpointHit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
-4
@@ -22,11 +22,9 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import agent.frida.manager.impl.FridaManagerImpl;
|
import agent.frida.manager.impl.FridaManagerImpl;
|
||||||
import agent.frida.model.AbstractFridaModel;
|
import agent.frida.model.AbstractFridaModel;
|
||||||
import ghidra.async.AsyncUtils;
|
import ghidra.async.AsyncUtils;
|
||||||
import ghidra.dbg.DebuggerModelListener;
|
|
||||||
import ghidra.dbg.agent.SpiTargetObject;
|
import ghidra.dbg.agent.SpiTargetObject;
|
||||||
import ghidra.dbg.target.TargetObject;
|
import ghidra.dbg.target.TargetObject;
|
||||||
import ghidra.dbg.util.CollectionUtils.Delta;
|
import ghidra.dbg.util.CollectionUtils.Delta;
|
||||||
import ghidra.util.datastruct.ListenerSet;
|
|
||||||
|
|
||||||
public interface FridaModelTargetObject extends SpiTargetObject {
|
public interface FridaModelTargetObject extends SpiTargetObject {
|
||||||
|
|
||||||
@@ -59,8 +57,6 @@ public interface FridaModelTargetObject extends SpiTargetObject {
|
|||||||
|
|
||||||
public CompletableFuture<List<TargetObject>> requestNativeElements();
|
public CompletableFuture<List<TargetObject>> requestNativeElements();
|
||||||
|
|
||||||
public ListenerSet<DebuggerModelListener> getListeners();
|
|
||||||
|
|
||||||
public FridaModelTargetSession getParentSession();
|
public FridaModelTargetSession getParentSession();
|
||||||
|
|
||||||
public FridaModelTargetProcess getParentProcess();
|
public FridaModelTargetProcess getParentProcess();
|
||||||
|
|||||||
+1
-1
@@ -50,7 +50,7 @@ public interface FridaModelTargetSession extends //
|
|||||||
== DebugOutputFlags.DEBUG_OUTPUT_WARNING.getValue())) {
|
== DebugOutputFlags.DEBUG_OUTPUT_WARNING.getValue())) {
|
||||||
chan = TargetConsole.Channel.STDERR;
|
chan = TargetConsole.Channel.STDERR;
|
||||||
}
|
}
|
||||||
getListeners().fire.consoleOutput(getProxy(), chan, output);
|
broadcast().consoleOutput(getProxy(), chan, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
-3
@@ -80,7 +80,7 @@ public class FridaModelTargetKernelMemoryContainerImpl extends FridaModelTargetO
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
listeners.fire.invalidateCacheRequested(this);
|
broadcast().invalidateCacheRequested(this);
|
||||||
}
|
}
|
||||||
return getManager().listKernelMemory();
|
return getManager().listKernelMemory();
|
||||||
}
|
}
|
||||||
@@ -104,12 +104,12 @@ public class FridaModelTargetKernelMemoryContainerImpl extends FridaModelTargetO
|
|||||||
if (range == null) {
|
if (range == null) {
|
||||||
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
||||||
}
|
}
|
||||||
listeners.fire.memoryUpdated(getProxy(), address, buf.array());
|
broadcast().memoryUpdated(getProxy(), address, buf.array());
|
||||||
return Arrays.copyOf(buf.array(), (int) range.getLength());
|
return Arrays.copyOf(buf.array(), (int) range.getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeAssist(Address address, byte[] data) {
|
private void writeAssist(Address address, byte[] data) {
|
||||||
listeners.fire.memoryUpdated(getProxy(), address, data);
|
broadcast().memoryUpdated(getProxy(), address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+11
-8
@@ -72,12 +72,13 @@ public class FridaModelTargetKernelModuleContainerImpl extends FridaModelTargetO
|
|||||||
TargetThread eventThread =
|
TargetThread eventThread =
|
||||||
(TargetThread) getModel().getModelObject(thread);
|
(TargetThread) getModel().getModelObject(thread);
|
||||||
changeElements(List.of(), List.of(targetModule), Map.of(), "Loaded");
|
changeElements(List.of(), List.of(targetModule), Map.of(), "Loaded");
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
||||||
"Library " + info.getModuleName(index) + " loaded", List.of(targetModule));
|
"Library " + info.getModuleName(index) + " loaded", List.of(targetModule));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moduleReplaced(FridaProcess proc, FridaModuleInfo info, int index, FridaCause cause) {
|
public void moduleReplaced(FridaProcess proc, FridaModuleInfo info, int index,
|
||||||
|
FridaCause cause) {
|
||||||
FridaModule module = info.getModule(index);
|
FridaModule module = info.getModule(index);
|
||||||
changeElements(List.of(), List.of(getTargetModule(module)), Map.of(), "Replaced");
|
changeElements(List.of(), List.of(getTargetModule(module)), Map.of(), "Replaced");
|
||||||
FridaModelTargetModule targetModule = getTargetModule(module);
|
FridaModelTargetModule targetModule = getTargetModule(module);
|
||||||
@@ -85,14 +86,15 @@ public class FridaModelTargetKernelModuleContainerImpl extends FridaModelTargetO
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moduleUnloaded(FridaProcess proc, FridaModuleInfo info, int index, FridaCause cause) {
|
public void moduleUnloaded(FridaProcess proc, FridaModuleInfo info, int index,
|
||||||
|
FridaCause cause) {
|
||||||
FridaModelTargetModule targetModule = getTargetModule(info.getModule(index));
|
FridaModelTargetModule targetModule = getTargetModule(info.getModule(index));
|
||||||
if (targetModule != null) {
|
if (targetModule != null) {
|
||||||
FridaThread thread = getManager().getCurrentThread();
|
FridaThread thread = getManager().getCurrentThread();
|
||||||
TargetThread eventThread =
|
TargetThread eventThread =
|
||||||
(TargetThread) getModel().getModelObject(thread);
|
(TargetThread) getModel().getModelObject(thread);
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
||||||
"Library " + info.getModuleName(index) + " unloaded", List.of(targetModule));
|
"Library " + info.getModuleName(index) + " unloaded", List.of(targetModule));
|
||||||
FridaModelImpl impl = (FridaModelImpl) model;
|
FridaModelImpl impl = (FridaModelImpl) model;
|
||||||
impl.deleteModelObject(targetModule.getModule());
|
impl.deleteModelObject(targetModule.getModule());
|
||||||
}
|
}
|
||||||
@@ -112,7 +114,7 @@ public class FridaModelTargetKernelModuleContainerImpl extends FridaModelTargetO
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
listeners.fire.invalidateCacheRequested(this);
|
broadcast().invalidateCacheRequested(this);
|
||||||
}
|
}
|
||||||
return getManager().listKernelModules();
|
return getManager().listKernelModules();
|
||||||
}
|
}
|
||||||
@@ -121,7 +123,8 @@ public class FridaModelTargetKernelModuleContainerImpl extends FridaModelTargetO
|
|||||||
public FridaModelTargetKernelModuleImpl getTargetModule(FridaModule module) {
|
public FridaModelTargetKernelModuleImpl getTargetModule(FridaModule module) {
|
||||||
TargetObject targetObject = getMapObject(module);
|
TargetObject targetObject = getMapObject(module);
|
||||||
if (targetObject != null) {
|
if (targetObject != null) {
|
||||||
FridaModelTargetKernelModuleImpl targetModule = (FridaModelTargetKernelModuleImpl) targetObject;
|
FridaModelTargetKernelModuleImpl targetModule =
|
||||||
|
(FridaModelTargetKernelModuleImpl) targetObject;
|
||||||
targetModule.setModelObject(module);
|
targetModule.setModelObject(module);
|
||||||
return targetModule;
|
return targetModule;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -102,7 +102,7 @@ public class FridaModelTargetMemoryContainerImpl extends FridaModelTargetObjectI
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
listeners.fire.invalidateCacheRequested(this);
|
broadcast().invalidateCacheRequested(this);
|
||||||
}
|
}
|
||||||
return getManager().listMemory(process.getProcess());
|
return getManager().listMemory(process.getProcess());
|
||||||
}
|
}
|
||||||
@@ -126,12 +126,12 @@ public class FridaModelTargetMemoryContainerImpl extends FridaModelTargetObjectI
|
|||||||
if (range == null) {
|
if (range == null) {
|
||||||
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
||||||
}
|
}
|
||||||
listeners.fire.memoryUpdated(getProxy(), address, buf.array());
|
broadcast().memoryUpdated(getProxy(), address, buf.array());
|
||||||
return Arrays.copyOf(buf.array(), (int) range.getLength());
|
return Arrays.copyOf(buf.array(), (int) range.getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeAssist(Address address, byte[] data) {
|
private void writeAssist(Address address, byte[] data) {
|
||||||
listeners.fire.memoryUpdated(getProxy(), address, data);
|
broadcast().memoryUpdated(getProxy(), address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+14
-25
@@ -20,25 +20,12 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import agent.frida.frida.FridaModuleInfo;
|
import agent.frida.frida.FridaModuleInfo;
|
||||||
import agent.frida.manager.FridaCause;
|
import agent.frida.manager.*;
|
||||||
import agent.frida.manager.FridaModule;
|
import agent.frida.model.iface2.*;
|
||||||
import agent.frida.manager.FridaProcess;
|
import agent.frida.model.methods.*;
|
||||||
import agent.frida.manager.FridaSession;
|
import ghidra.dbg.target.*;
|
||||||
import agent.frida.manager.FridaThread;
|
import ghidra.dbg.target.schema.*;
|
||||||
import agent.frida.model.iface2.FridaModelTargetModule;
|
|
||||||
import agent.frida.model.iface2.FridaModelTargetModuleContainer;
|
|
||||||
import agent.frida.model.iface2.FridaModelTargetSession;
|
|
||||||
import agent.frida.model.methods.FridaModelTargetModuleInitImpl;
|
|
||||||
import agent.frida.model.methods.FridaModelTargetModuleInterceptorImpl;
|
|
||||||
import agent.frida.model.methods.FridaModelTargetModuleLoadImpl;
|
|
||||||
import agent.frida.model.methods.FridaModelTargetUnloadScriptImpl;
|
|
||||||
import ghidra.dbg.target.TargetModule;
|
|
||||||
import ghidra.dbg.target.TargetObject;
|
|
||||||
import ghidra.dbg.target.TargetThread;
|
|
||||||
import ghidra.dbg.target.schema.TargetAttributeType;
|
|
||||||
import ghidra.dbg.target.schema.TargetElementType;
|
|
||||||
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
||||||
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
@TargetObjectSchemaInfo(
|
@TargetObjectSchemaInfo(
|
||||||
@@ -103,12 +90,13 @@ public class FridaModelTargetModuleContainerImpl extends FridaModelTargetObjectI
|
|||||||
TargetThread eventThread =
|
TargetThread eventThread =
|
||||||
(TargetThread) getModel().getModelObject(thread);
|
(TargetThread) getModel().getModelObject(thread);
|
||||||
changeElements(List.of(), List.of(targetModule), Map.of(), "Loaded");
|
changeElements(List.of(), List.of(targetModule), Map.of(), "Loaded");
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
||||||
"Library " + info.getModuleName(index) + " loaded", List.of(targetModule));
|
"Library " + info.getModuleName(index) + " loaded", List.of(targetModule));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moduleReplaced(FridaProcess proc, FridaModuleInfo info, int index, FridaCause cause) {
|
public void moduleReplaced(FridaProcess proc, FridaModuleInfo info, int index,
|
||||||
|
FridaCause cause) {
|
||||||
FridaModule module = info.getModule(index);
|
FridaModule module = info.getModule(index);
|
||||||
changeElements(List.of(), List.of(getTargetModule(module)), Map.of(), "Replaced");
|
changeElements(List.of(), List.of(getTargetModule(module)), Map.of(), "Replaced");
|
||||||
FridaModelTargetModule targetModule = getTargetModule(module);
|
FridaModelTargetModule targetModule = getTargetModule(module);
|
||||||
@@ -116,14 +104,15 @@ public class FridaModelTargetModuleContainerImpl extends FridaModelTargetObjectI
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moduleUnloaded(FridaProcess proc, FridaModuleInfo info, int index, FridaCause cause) {
|
public void moduleUnloaded(FridaProcess proc, FridaModuleInfo info, int index,
|
||||||
|
FridaCause cause) {
|
||||||
FridaModelTargetModule targetModule = getTargetModule(info.getModule(index));
|
FridaModelTargetModule targetModule = getTargetModule(info.getModule(index));
|
||||||
if (targetModule != null) {
|
if (targetModule != null) {
|
||||||
FridaThread thread = getManager().getCurrentThread();
|
FridaThread thread = getManager().getCurrentThread();
|
||||||
TargetThread eventThread =
|
TargetThread eventThread =
|
||||||
(TargetThread) getModel().getModelObject(thread);
|
(TargetThread) getModel().getModelObject(thread);
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
||||||
"Library " + info.getModuleName(index) + " unloaded", List.of(targetModule));
|
"Library " + info.getModuleName(index) + " unloaded", List.of(targetModule));
|
||||||
FridaModelImpl impl = (FridaModelImpl) model;
|
FridaModelImpl impl = (FridaModelImpl) model;
|
||||||
impl.deleteModelObject(targetModule.getModule());
|
impl.deleteModelObject(targetModule.getModule());
|
||||||
}
|
}
|
||||||
@@ -143,7 +132,7 @@ public class FridaModelTargetModuleContainerImpl extends FridaModelTargetObjectI
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
listeners.fire.invalidateCacheRequested(this);
|
broadcast().invalidateCacheRequested(this);
|
||||||
}
|
}
|
||||||
return getManager().listModules(session.getProcess());
|
return getManager().listModules(session.getProcess());
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -64,7 +64,7 @@ public class FridaModelTargetProcessContainerImpl extends FridaModelTargetObject
|
|||||||
FridaModelTargetProcess process = getTargetProcess(proc);
|
FridaModelTargetProcess process = getTargetProcess(proc);
|
||||||
changeElements(List.of(), List.of(process), Map.of(), "Added");
|
changeElements(List.of(), List.of(process), Map.of(), "Added");
|
||||||
process.processStarted(proc);
|
process.processStarted(proc);
|
||||||
getListeners().fire.event(getProxy(), null, TargetEventType.PROCESS_CREATED,
|
broadcast().event(getProxy(), null, TargetEventType.PROCESS_CREATED,
|
||||||
"Process " + FridaClient.getId(proc) + " started " + process.getName(),
|
"Process " + FridaClient.getId(proc) + " started " + process.getName(),
|
||||||
List.of(process));
|
List.of(process));
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -236,7 +236,7 @@ public class FridaModelTargetProcessImpl extends FridaModelTargetObjectImpl
|
|||||||
STATE_ATTRIBUTE_NAME, TargetExecutionState.TERMINATED, //
|
STATE_ATTRIBUTE_NAME, TargetExecutionState.TERMINATED, //
|
||||||
EXIT_CODE_ATTRIBUTE_NAME, exitDesc //
|
EXIT_CODE_ATTRIBUTE_NAME, exitDesc //
|
||||||
), "Exited");
|
), "Exited");
|
||||||
getListeners().fire.event(getProxy(), null, TargetEventType.PROCESS_EXITED,
|
broadcast().event(getProxy(), null, TargetEventType.PROCESS_EXITED,
|
||||||
"Process " + FridaClient.getId(getProcess()) + " exited code=" + exitDesc,
|
"Process " + FridaClient.getId(getProcess()) + " exited code=" + exitDesc,
|
||||||
List.of(getProxy()));
|
List.of(getProxy()));
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-31
@@ -16,42 +16,31 @@
|
|||||||
package agent.frida.model.impl;
|
package agent.frida.model.impl;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import agent.frida.manager.FridaReason;
|
import agent.frida.manager.*;
|
||||||
import agent.frida.manager.FridaState;
|
import agent.frida.model.iface2.*;
|
||||||
import agent.frida.manager.FridaValue;
|
|
||||||
import agent.frida.model.iface2.FridaModelTargetRegister;
|
|
||||||
import agent.frida.model.iface2.FridaModelTargetRegisterBank;
|
|
||||||
import agent.frida.model.iface2.FridaModelTargetRegisterContainerAndBank;
|
|
||||||
import ghidra.async.AsyncUtils;
|
import ghidra.async.AsyncUtils;
|
||||||
import ghidra.dbg.DebuggerModelListener;
|
|
||||||
import ghidra.dbg.error.DebuggerRegisterAccessException;
|
import ghidra.dbg.error.DebuggerRegisterAccessException;
|
||||||
import ghidra.dbg.target.TargetObject;
|
import ghidra.dbg.target.TargetObject;
|
||||||
import ghidra.dbg.target.TargetRegisterBank;
|
import ghidra.dbg.target.TargetRegisterBank;
|
||||||
import ghidra.dbg.target.schema.TargetAttributeType;
|
import ghidra.dbg.target.schema.*;
|
||||||
import ghidra.dbg.target.schema.TargetElementType;
|
|
||||||
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
||||||
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
|
|
||||||
import ghidra.util.datastruct.ListenerSet;
|
|
||||||
|
|
||||||
@TargetObjectSchemaInfo(
|
@TargetObjectSchemaInfo(
|
||||||
name = "RegisterContainer",
|
name = "RegisterContainer",
|
||||||
attributeResync = ResyncMode.ALWAYS,
|
attributeResync = ResyncMode.ALWAYS,
|
||||||
elements = { //
|
elements = { //
|
||||||
@TargetElementType(type = FridaModelTargetRegisterImpl.class) //
|
@TargetElementType(type = FridaModelTargetRegisterImpl.class) //
|
||||||
},
|
},
|
||||||
attributes = {
|
attributes = {
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = TargetRegisterBank.DESCRIPTIONS_ATTRIBUTE_NAME,
|
name = TargetRegisterBank.DESCRIPTIONS_ATTRIBUTE_NAME,
|
||||||
type = FridaModelTargetRegisterContainerImpl.class),
|
type = FridaModelTargetRegisterContainerImpl.class),
|
||||||
@TargetAttributeType(type = Void.class)
|
@TargetAttributeType(type = Void.class)
|
||||||
},
|
},
|
||||||
canonicalContainer = true)
|
canonicalContainer = true)
|
||||||
public class FridaModelTargetRegisterContainerImpl
|
public class FridaModelTargetRegisterContainerImpl
|
||||||
@@ -66,8 +55,8 @@ public class FridaModelTargetRegisterContainerImpl
|
|||||||
this.thread = thread;
|
this.thread = thread;
|
||||||
|
|
||||||
changeAttributes(List.of(), List.of(), Map.of(
|
changeAttributes(List.of(), List.of(), Map.of(
|
||||||
DISPLAY_ATTRIBUTE_NAME, getName(),
|
DISPLAY_ATTRIBUTE_NAME, getName(),
|
||||||
DESCRIPTIONS_ATTRIBUTE_NAME, this), "Initialized");
|
DESCRIPTIONS_ATTRIBUTE_NAME, this), "Initialized");
|
||||||
|
|
||||||
requestElements(false);
|
requestElements(false);
|
||||||
}
|
}
|
||||||
@@ -78,7 +67,7 @@ public class FridaModelTargetRegisterContainerImpl
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
listeners.fire.invalidateCacheRequested(this);
|
broadcast().invalidateCacheRequested(this);
|
||||||
}
|
}
|
||||||
return getManager().listRegisters(thread.getThread()).thenAccept(registers -> {
|
return getManager().listRegisters(thread.getThread()).thenAccept(registers -> {
|
||||||
List<TargetObject> targetRegisters;
|
List<TargetObject> targetRegisters;
|
||||||
@@ -114,7 +103,8 @@ public class FridaModelTargetRegisterContainerImpl
|
|||||||
requestAttributes(false).thenAccept(__ -> {
|
requestAttributes(false).thenAccept(__ -> {
|
||||||
for (Object attribute : getCachedAttributes().values()) {
|
for (Object attribute : getCachedAttributes().values()) {
|
||||||
if (attribute instanceof FridaModelTargetRegisterBank) {
|
if (attribute instanceof FridaModelTargetRegisterBank) {
|
||||||
FridaModelTargetRegisterBank bank = (FridaModelTargetRegisterBank) attribute;
|
FridaModelTargetRegisterBank bank =
|
||||||
|
(FridaModelTargetRegisterBank) attribute;
|
||||||
bank.threadStateChangedSpecific(state, reason);
|
bank.threadStateChangedSpecific(state, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,12 +126,9 @@ public class FridaModelTargetRegisterContainerImpl
|
|||||||
byte[] bytes = register.getBytes();
|
byte[] bytes = register.getBytes();
|
||||||
result.put(regname, bytes);
|
result.put(regname, bytes);
|
||||||
}
|
}
|
||||||
ListenerSet<DebuggerModelListener> ls = getListeners();
|
//if (getName().contains("General")) {
|
||||||
if (ls != null) {
|
broadcast().registersUpdated(this, result);
|
||||||
//if (getName().contains("General")) {
|
//}
|
||||||
ls.fire.registersUpdated(this, result);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
return CompletableFuture.completedFuture(result);
|
return CompletableFuture.completedFuture(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +145,7 @@ public class FridaModelTargetRegisterContainerImpl
|
|||||||
BigInteger val = new BigInteger(1, ent.getValue());
|
BigInteger val = new BigInteger(1, ent.getValue());
|
||||||
reg.getRegister().setValue(val.toString());
|
reg.getRegister().setValue(val.toString());
|
||||||
}
|
}
|
||||||
getListeners().fire.registersUpdated(getProxy(), values);
|
broadcast().registersUpdated(getProxy(), values);
|
||||||
return AsyncUtils.NIL;
|
return AsyncUtils.NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -76,7 +76,7 @@ public class FridaModelTargetThreadContainerImpl extends FridaModelTargetObjectI
|
|||||||
changeElements(List.of(), List.of(targetThread), Map.of(), "Created");
|
changeElements(List.of(), List.of(targetThread), Map.of(), "Created");
|
||||||
targetThread.threadStateChangedSpecific(FridaState.FRIDA_THREAD_UNINTERRUPTIBLE,
|
targetThread.threadStateChangedSpecific(FridaState.FRIDA_THREAD_UNINTERRUPTIBLE,
|
||||||
FridaReason.getReason(null));
|
FridaReason.getReason(null));
|
||||||
getListeners().fire.event(getProxy(), targetThread, TargetEventType.THREAD_CREATED,
|
broadcast().event(getProxy(), targetThread, TargetEventType.THREAD_CREATED,
|
||||||
"Thread " + FridaClient.getId(thread) + " started", List.of(targetThread));
|
"Thread " + FridaClient.getId(thread) + " started", List.of(targetThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ public class FridaModelTargetThreadContainerImpl extends FridaModelTargetObjectI
|
|||||||
String threadId = FridaModelTargetThreadImpl.indexThread(thread);
|
String threadId = FridaModelTargetThreadImpl.indexThread(thread);
|
||||||
FridaModelTargetThread targetThread = (FridaModelTargetThread) getMapObject(thread);
|
FridaModelTargetThread targetThread = (FridaModelTargetThread) getMapObject(thread);
|
||||||
if (targetThread != null) {
|
if (targetThread != null) {
|
||||||
getListeners().fire.event(getProxy(), targetThread, TargetEventType.THREAD_EXITED,
|
broadcast().event(getProxy(), targetThread, TargetEventType.THREAD_EXITED,
|
||||||
"Thread " + threadId + " exited", List.of(targetThread));
|
"Thread " + threadId + " exited", List.of(targetThread));
|
||||||
}
|
}
|
||||||
changeElements(List.of( //
|
changeElements(List.of( //
|
||||||
@@ -108,7 +108,7 @@ public class FridaModelTargetThreadContainerImpl extends FridaModelTargetObjectI
|
|||||||
FridaReason reason) {
|
FridaReason reason) {
|
||||||
FridaModelTargetThread targetThread = getTargetThread(thread);
|
FridaModelTargetThread targetThread = getTargetThread(thread);
|
||||||
TargetEventType eventType = getEventType(state, cause, reason);
|
TargetEventType eventType = getEventType(state, cause, reason);
|
||||||
getListeners().fire.event(getProxy(), targetThread, eventType,
|
broadcast().event(getProxy(), targetThread, eventType,
|
||||||
"Thread " + FridaClient.getId(thread) + " state changed", List.of(targetThread));
|
"Thread " + FridaClient.getId(thread) + " state changed", List.of(targetThread));
|
||||||
targetThread.threadStateChangedSpecific(state, reason);
|
targetThread.threadStateChangedSpecific(state, reason);
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ public class FridaModelTargetThreadContainerImpl extends FridaModelTargetObjectI
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
listeners.fire.invalidateCacheRequested(this);
|
broadcast().invalidateCacheRequested(this);
|
||||||
}
|
}
|
||||||
return getManager().listThreads(process);
|
return getManager().listThreads(process);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ public class GdbModelTargetBreakpointContainer
|
|||||||
spec + " (pc=" + frame.getProgramCounter() + ")");
|
spec + " (pc=" + frame.getProgramCounter() + ")");
|
||||||
//return; // Not ideal, but eb == null should be fine, since the spec holds the actions
|
//return; // Not ideal, but eb == null should be fine, since the spec holds the actions
|
||||||
}
|
}
|
||||||
listeners.fire.breakpointHit(this, frame.thread, frame, spec, loc);
|
broadcast().breakpointHit(this, frame.thread, frame, spec, loc);
|
||||||
spec.breakpointHit(frame, loc);
|
spec.breakpointHit(frame, loc);
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-12
@@ -186,7 +186,6 @@ public class GdbModelTargetInferior
|
|||||||
return impl.gateFuture(inferior.cont());
|
return impl.gateFuture(inferior.cont());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> step(TargetStepKind kind) {
|
public CompletableFuture<Void> step(TargetStepKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
@@ -233,7 +232,7 @@ public class GdbModelTargetInferior
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected CompletableFuture<Void> inferiorStarted(Long pid) {
|
protected CompletableFuture<Void> inferiorStarted(Long pid) {
|
||||||
parent.getListeners().fire.event(parent, null, TargetEventType.PROCESS_CREATED,
|
broadcast().event(parent, null, TargetEventType.PROCESS_CREATED,
|
||||||
"Inferior " + inferior.getId() + " started " + inferior.getExecutable() + " pid=" + pid,
|
"Inferior " + inferior.getId() + " started " + inferior.getExecutable() + " pid=" + pid,
|
||||||
List.of(this));
|
List.of(this));
|
||||||
/*System.err.println("inferiorStarted: realState = " + realState);
|
/*System.err.println("inferiorStarted: realState = " + realState);
|
||||||
@@ -315,28 +314,28 @@ public class GdbModelTargetInferior
|
|||||||
params.add(loc);
|
params.add(loc);
|
||||||
}
|
}
|
||||||
gatherThreads(params, sco.getAffectedThreads());
|
gatherThreads(params, sco.getAffectedThreads());
|
||||||
impl.session.getListeners().fire.event(impl.session, targetEventThread,
|
broadcast().event(impl.session, targetEventThread, TargetEventType.BREAKPOINT_HIT,
|
||||||
TargetEventType.BREAKPOINT_HIT, bpHit.desc(), params);
|
bpHit.desc(), params);
|
||||||
}
|
}
|
||||||
else if (reason instanceof GdbEndSteppingRangeReason) {
|
else if (reason instanceof GdbEndSteppingRangeReason) {
|
||||||
List<Object> params = new ArrayList<>();
|
List<Object> params = new ArrayList<>();
|
||||||
gatherThreads(params, sco.getAffectedThreads());
|
gatherThreads(params, sco.getAffectedThreads());
|
||||||
impl.session.getListeners().fire.event(impl.session, targetEventThread,
|
broadcast().event(impl.session, targetEventThread, TargetEventType.STEP_COMPLETED,
|
||||||
TargetEventType.STEP_COMPLETED, reason.desc(), params);
|
reason.desc(), params);
|
||||||
}
|
}
|
||||||
else if (reason instanceof GdbSignalReceivedReason) {
|
else if (reason instanceof GdbSignalReceivedReason) {
|
||||||
GdbSignalReceivedReason signal = (GdbSignalReceivedReason) reason;
|
GdbSignalReceivedReason signal = (GdbSignalReceivedReason) reason;
|
||||||
List<Object> params = new ArrayList<>();
|
List<Object> params = new ArrayList<>();
|
||||||
params.add(signal.getSignalName());
|
params.add(signal.getSignalName());
|
||||||
gatherThreads(params, sco.getAffectedThreads());
|
gatherThreads(params, sco.getAffectedThreads());
|
||||||
impl.session.getListeners().fire.event(impl.session, targetEventThread,
|
broadcast().event(impl.session, targetEventThread, TargetEventType.SIGNAL,
|
||||||
TargetEventType.SIGNAL, reason.desc(), params);
|
reason.desc(), params);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
List<Object> params = new ArrayList<>();
|
List<Object> params = new ArrayList<>();
|
||||||
gatherThreads(params, sco.getAffectedThreads());
|
gatherThreads(params, sco.getAffectedThreads());
|
||||||
impl.session.getListeners().fire.event(impl.session, targetEventThread,
|
broadcast().event(impl.session, targetEventThread, TargetEventType.STOPPED,
|
||||||
TargetEventType.STOPPED, reason.desc(), params);
|
reason.desc(), params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,8 +444,8 @@ public class GdbModelTargetInferior
|
|||||||
threads.getTargetThread(sco.getAffectedThreads().iterator().next());
|
threads.getTargetThread(sco.getAffectedThreads().iterator().next());
|
||||||
}
|
}
|
||||||
if (targetEventThread != null) {
|
if (targetEventThread != null) {
|
||||||
impl.session.getListeners().fire.event(impl.session, targetEventThread,
|
broadcast().event(impl.session, targetEventThread, TargetEventType.RUNNING,
|
||||||
TargetEventType.RUNNING, "Running", params);
|
"Running", params);
|
||||||
invalidateMemoryAndRegisterCaches();
|
invalidateMemoryAndRegisterCaches();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -71,7 +71,7 @@ public class GdbModelTargetInferiorContainer
|
|||||||
@Override
|
@Override
|
||||||
public void inferiorExited(GdbInferior inf, GdbCause cause) {
|
public void inferiorExited(GdbInferior inf, GdbCause cause) {
|
||||||
GdbModelTargetInferior inferior = getTargetInferior(inf);
|
GdbModelTargetInferior inferior = getTargetInferior(inf);
|
||||||
parent.getListeners().fire.event(parent, null, TargetEventType.PROCESS_EXITED,
|
broadcast().event(parent, null, TargetEventType.PROCESS_EXITED,
|
||||||
"Inferior " + inf.getId() + " exited code=" + inf.getExitCode(), List.of(inferior));
|
"Inferior " + inf.getId() + " exited code=" + inf.getExitCode(), List.of(inferior));
|
||||||
inferior.inferiorExited(inf.getExitCode());
|
inferior.inferiorExited(inf.getExitCode());
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ public class GdbModelTargetInferiorContainer
|
|||||||
public void threadCreated(GdbThread thread, GdbCause cause) {
|
public void threadCreated(GdbThread thread, GdbCause cause) {
|
||||||
GdbModelTargetInferior inferior = getTargetInferior(thread.getInferior());
|
GdbModelTargetInferior inferior = getTargetInferior(thread.getInferior());
|
||||||
GdbModelTargetThread targetThread = inferior.threads.threadCreated(thread);
|
GdbModelTargetThread targetThread = inferior.threads.threadCreated(thread);
|
||||||
parent.getListeners().fire.event(parent, targetThread, TargetEventType.THREAD_CREATED,
|
broadcast().event(parent, targetThread, TargetEventType.THREAD_CREATED,
|
||||||
"Thread " + thread.getId() + " started", List.of(targetThread));
|
"Thread " + thread.getId() + " started", List.of(targetThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ public class GdbModelTargetInferiorContainer
|
|||||||
GdbModelTargetInferior inferior = getTargetInferior(inf);
|
GdbModelTargetInferior inferior = getTargetInferior(inf);
|
||||||
GdbModelTargetThread targetThread =
|
GdbModelTargetThread targetThread =
|
||||||
inferior.threads.getCachedElements().get(GdbModelTargetThread.indexThread(threadId));
|
inferior.threads.getCachedElements().get(GdbModelTargetThread.indexThread(threadId));
|
||||||
parent.getListeners().fire.event(parent, targetThread, TargetEventType.THREAD_EXITED,
|
broadcast().event(parent, targetThread, TargetEventType.THREAD_EXITED,
|
||||||
"Thread " + threadId + " exited", List.of(targetThread));
|
"Thread " + threadId + " exited", List.of(targetThread));
|
||||||
inferior.threads.threadExited(threadId);
|
inferior.threads.threadExited(threadId);
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ public class GdbModelTargetInferiorContainer
|
|||||||
public void libraryLoaded(GdbInferior inf, String name, GdbCause cause) {
|
public void libraryLoaded(GdbInferior inf, String name, GdbCause cause) {
|
||||||
GdbModelTargetInferior inferior = getTargetInferior(inf);
|
GdbModelTargetInferior inferior = getTargetInferior(inf);
|
||||||
GdbModelTargetModule module = inferior.modules.libraryLoaded(name);
|
GdbModelTargetModule module = inferior.modules.libraryLoaded(name);
|
||||||
parent.getListeners().fire.event(parent, null, TargetEventType.MODULE_LOADED,
|
broadcast().event(parent, null, TargetEventType.MODULE_LOADED,
|
||||||
"Library " + name + " loaded", List.of(module));
|
"Library " + name + " loaded", List.of(module));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ public class GdbModelTargetInferiorContainer
|
|||||||
public void libraryUnloaded(GdbInferior inf, String name, GdbCause cause) {
|
public void libraryUnloaded(GdbInferior inf, String name, GdbCause cause) {
|
||||||
GdbModelTargetInferior inferior = getTargetInferior(inf);
|
GdbModelTargetInferior inferior = getTargetInferior(inf);
|
||||||
GdbModelTargetModule module = inferior.modules.getTargetModuleIfPresent(name);
|
GdbModelTargetModule module = inferior.modules.getTargetModuleIfPresent(name);
|
||||||
parent.getListeners().fire.event(parent, null, TargetEventType.MODULE_UNLOADED,
|
broadcast().event(parent, null, TargetEventType.MODULE_UNLOADED,
|
||||||
"Library " + name + " unloaded", List.of(module));
|
"Library " + name + " unloaded", List.of(module));
|
||||||
inferior.modules.libraryUnloaded(name);
|
inferior.modules.libraryUnloaded(name);
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -159,7 +159,7 @@ public class GdbModelTargetProcessMemory
|
|||||||
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
||||||
}
|
}
|
||||||
byte[] content = Arrays.copyOf(buf.array(), (int) s.length());
|
byte[] content = Arrays.copyOf(buf.array(), (int) s.length());
|
||||||
listeners.fire.memoryUpdated(this, address, content);
|
broadcast().memoryUpdated(this, address, content);
|
||||||
return content;
|
return content;
|
||||||
}).exceptionally(e -> {
|
}).exceptionally(e -> {
|
||||||
e = AsyncUtils.unwrapThrowable(e);
|
e = AsyncUtils.unwrapThrowable(e);
|
||||||
@@ -167,10 +167,10 @@ public class GdbModelTargetProcessMemory
|
|||||||
GdbCommandError gce = (GdbCommandError) e;
|
GdbCommandError gce = (GdbCommandError) e;
|
||||||
e = new DebuggerMemoryAccessException(
|
e = new DebuggerMemoryAccessException(
|
||||||
"Cannot read at " + address + ": " + gce.getInfo().getString("msg"));
|
"Cannot read at " + address + ": " + gce.getInfo().getString("msg"));
|
||||||
listeners.fire.memoryReadError(this, range, (DebuggerMemoryAccessException) e);
|
broadcast().memoryReadError(this, range, (DebuggerMemoryAccessException) e);
|
||||||
}
|
}
|
||||||
if (e instanceof DebuggerMemoryAccessException) {
|
if (e instanceof DebuggerMemoryAccessException) {
|
||||||
listeners.fire.memoryReadError(this, range, (DebuggerMemoryAccessException) e);
|
broadcast().memoryReadError(this, range, (DebuggerMemoryAccessException) e);
|
||||||
}
|
}
|
||||||
return ExceptionUtils.rethrow(e);
|
return ExceptionUtils.rethrow(e);
|
||||||
});
|
});
|
||||||
@@ -186,12 +186,12 @@ public class GdbModelTargetProcessMemory
|
|||||||
CompletableFuture<Void> future =
|
CompletableFuture<Void> future =
|
||||||
inferior.writeMemory(address.getOffset(), ByteBuffer.wrap(data));
|
inferior.writeMemory(address.getOffset(), ByteBuffer.wrap(data));
|
||||||
return impl.gateFuture(future.thenAccept(__ -> {
|
return impl.gateFuture(future.thenAccept(__ -> {
|
||||||
listeners.fire.memoryUpdated(this, address, data);
|
broadcast().memoryUpdated(this, address, data);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void invalidateMemoryCaches() {
|
protected void invalidateMemoryCaches() {
|
||||||
listeners.fire.invalidateCacheRequested(this);
|
broadcast().invalidateCacheRequested(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void memoryChanged(long offset, int len) {
|
public void memoryChanged(long offset, int len) {
|
||||||
|
|||||||
+1
-1
@@ -147,7 +147,7 @@ public class GdbModelTargetSession extends DefaultTargetModelRoot
|
|||||||
default:
|
default:
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
listeners.fire.consoleOutput(this, dbgChannel, out);
|
broadcast().consoleOutput(this, dbgChannel, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+1
-1
@@ -110,7 +110,7 @@ public class GdbModelTargetStackFrame
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void invalidateRegisterCaches() {
|
protected void invalidateRegisterCaches() {
|
||||||
listeners.fire.invalidateCacheRequested(this);
|
broadcast().invalidateCacheRequested(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+1
-1
@@ -117,7 +117,7 @@ public class GdbModelTargetStackFrameRegisterContainer
|
|||||||
elements.get(regName).stateChanged(bytes);
|
elements.get(regName).stateChanged(bytes);
|
||||||
}
|
}
|
||||||
this.regValues = result;
|
this.regValues = result;
|
||||||
listeners.fire.registersUpdated(this, result);
|
broadcast().registersUpdated(this, result);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
-4
@@ -22,11 +22,9 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import agent.lldb.manager.impl.LldbManagerImpl;
|
import agent.lldb.manager.impl.LldbManagerImpl;
|
||||||
import agent.lldb.model.AbstractLldbModel;
|
import agent.lldb.model.AbstractLldbModel;
|
||||||
import ghidra.async.AsyncUtils;
|
import ghidra.async.AsyncUtils;
|
||||||
import ghidra.dbg.DebuggerModelListener;
|
|
||||||
import ghidra.dbg.agent.SpiTargetObject;
|
import ghidra.dbg.agent.SpiTargetObject;
|
||||||
import ghidra.dbg.target.TargetObject;
|
import ghidra.dbg.target.TargetObject;
|
||||||
import ghidra.dbg.util.CollectionUtils.Delta;
|
import ghidra.dbg.util.CollectionUtils.Delta;
|
||||||
import ghidra.util.datastruct.ListenerSet;
|
|
||||||
|
|
||||||
public interface LldbModelTargetObject extends SpiTargetObject {
|
public interface LldbModelTargetObject extends SpiTargetObject {
|
||||||
|
|
||||||
@@ -59,8 +57,6 @@ public interface LldbModelTargetObject extends SpiTargetObject {
|
|||||||
|
|
||||||
public CompletableFuture<List<TargetObject>> requestNativeElements();
|
public CompletableFuture<List<TargetObject>> requestNativeElements();
|
||||||
|
|
||||||
public ListenerSet<DebuggerModelListener> getListeners();
|
|
||||||
|
|
||||||
public LldbModelTargetSession getParentSession();
|
public LldbModelTargetSession getParentSession();
|
||||||
|
|
||||||
public LldbModelTargetProcess getParentProcess();
|
public LldbModelTargetProcess getParentProcess();
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ public interface LldbModelTargetSession extends //
|
|||||||
if (output.contains("loaded *kernel* extension dll for usermode")) {
|
if (output.contains("loaded *kernel* extension dll for usermode")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getListeners().fire.consoleOutput(getProxy(), chan, output);
|
broadcast().consoleOutput(getProxy(), chan, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+11
-8
@@ -47,8 +47,7 @@ public class LldbModelTargetBreakpointContainerImpl extends LldbModelTargetObjec
|
|||||||
TargetBreakpointKind.SW_EXECUTE,
|
TargetBreakpointKind.SW_EXECUTE,
|
||||||
//TargetBreakpointKind.HW_EXECUTE,
|
//TargetBreakpointKind.HW_EXECUTE,
|
||||||
TargetBreakpointKind.READ,
|
TargetBreakpointKind.READ,
|
||||||
TargetBreakpointKind.WRITE
|
TargetBreakpointKind.WRITE);
|
||||||
);
|
|
||||||
|
|
||||||
private final SBTarget session;
|
private final SBTarget session;
|
||||||
|
|
||||||
@@ -98,22 +97,25 @@ public class LldbModelTargetBreakpointContainerImpl extends LldbModelTargetObjec
|
|||||||
BigInteger bptId = t.GetStopReasonDataAtIndex(0);
|
BigInteger bptId = t.GetStopReasonDataAtIndex(0);
|
||||||
BigInteger locId = t.GetStopReasonDataAtIndex(1);
|
BigInteger locId = t.GetStopReasonDataAtIndex(1);
|
||||||
if (bpt.GetID() == bptId.intValue()) {
|
if (bpt.GetID() == bptId.intValue()) {
|
||||||
LldbModelTargetProcess targetProcess = (LldbModelTargetProcess) getModel().getModelObject(eventProcess);
|
LldbModelTargetProcess targetProcess =
|
||||||
|
(LldbModelTargetProcess) getModel().getModelObject(eventProcess);
|
||||||
LldbModelTargetThread targetThread =
|
LldbModelTargetThread targetThread =
|
||||||
targetProcess.getThreads().getTargetThread(t);
|
targetProcess.getThreads().getTargetThread(t);
|
||||||
LldbModelTargetBreakpointSpec spec = getTargetBreakpointSpec(bpt);
|
LldbModelTargetBreakpointSpec spec = getTargetBreakpointSpec(bpt);
|
||||||
if (spec == null) {
|
if (spec == null) {
|
||||||
Msg.error(this, "Stopped for breakpoint unknown to the agent: " + bpt + " (pc=" +
|
Msg.error(this,
|
||||||
targetThread + ")");
|
"Stopped for breakpoint unknown to the agent: " + bpt + " (pc=" +
|
||||||
|
targetThread + ")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LldbModelTargetBreakpointLocation loc = spec.findLocation(locId);
|
LldbModelTargetBreakpointLocation loc = spec.findLocation(locId);
|
||||||
if (loc == null) {
|
if (loc == null) {
|
||||||
Msg.warn(this,
|
Msg.warn(this,
|
||||||
"Stopped for a breakpoint whose location is unknown to the agent: " + spec);
|
"Stopped for a breakpoint whose location is unknown to the agent: " +
|
||||||
|
spec);
|
||||||
}
|
}
|
||||||
listeners.fire.breakpointHit(this, targetThread, null, spec, loc);
|
broadcast().breakpointHit(this, targetThread, null, spec, loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,6 +150,7 @@ public class LldbModelTargetBreakpointContainerImpl extends LldbModelTargetObjec
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public SBTarget getSession() {
|
public SBTarget getSession() {
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -87,12 +87,12 @@ public class LldbModelTargetMemoryContainerImpl extends LldbModelTargetObjectImp
|
|||||||
if (range == null) {
|
if (range == null) {
|
||||||
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
throw new DebuggerMemoryAccessException("Cannot read at " + address);
|
||||||
}
|
}
|
||||||
listeners.fire.memoryUpdated(getProxy(), address, buf.array());
|
broadcast().memoryUpdated(getProxy(), address, buf.array());
|
||||||
return Arrays.copyOf(buf.array(), (int) range.getLength());
|
return Arrays.copyOf(buf.array(), (int) range.getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeAssist(Address address, byte[] data) {
|
private void writeAssist(Address address, byte[] data) {
|
||||||
listeners.fire.memoryUpdated(getProxy(), address, data);
|
broadcast().memoryUpdated(getProxy(), address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+4
-4
@@ -72,8 +72,8 @@ public class LldbModelTargetModuleContainerImpl extends LldbModelTargetObjectImp
|
|||||||
TargetThread eventThread =
|
TargetThread eventThread =
|
||||||
(TargetThread) getModel().getModelObject(thread);
|
(TargetThread) getModel().getModelObject(thread);
|
||||||
changeElements(List.of(), List.of(targetModule), Map.of(), "Loaded");
|
changeElements(List.of(), List.of(targetModule), Map.of(), "Loaded");
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_LOADED,
|
||||||
"Library " + info.getModuleName(index) + " loaded", List.of(targetModule));
|
"Library " + info.getModuleName(index) + " loaded", List.of(targetModule));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -84,8 +84,8 @@ public class LldbModelTargetModuleContainerImpl extends LldbModelTargetObjectImp
|
|||||||
SBThread thread = getManager().getEventThread();
|
SBThread thread = getManager().getEventThread();
|
||||||
TargetThread eventThread =
|
TargetThread eventThread =
|
||||||
(TargetThread) getModel().getModelObject(thread);
|
(TargetThread) getModel().getModelObject(thread);
|
||||||
getListeners().fire.event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
broadcast().event(getProxy(), eventThread, TargetEventType.MODULE_UNLOADED,
|
||||||
"Library " + info.getModuleName(index) + " unloaded", List.of(targetModule));
|
"Library " + info.getModuleName(index) + " unloaded", List.of(targetModule));
|
||||||
LldbModelImpl impl = (LldbModelImpl) model;
|
LldbModelImpl impl = (LldbModelImpl) model;
|
||||||
impl.deleteModelObject(targetModule.getModule());
|
impl.deleteModelObject(targetModule.getModule());
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -70,7 +70,7 @@ public class LldbModelTargetProcessContainerImpl extends LldbModelTargetObjectIm
|
|||||||
LldbModelTargetProcess process = getTargetProcess(proc);
|
LldbModelTargetProcess process = getTargetProcess(proc);
|
||||||
changeElements(List.of(), List.of(process), Map.of(), "Added");
|
changeElements(List.of(), List.of(process), Map.of(), "Added");
|
||||||
process.processStarted(proc);
|
process.processStarted(proc);
|
||||||
getListeners().fire.event(getProxy(), null, TargetEventType.PROCESS_CREATED,
|
broadcast().event(getProxy(), null, TargetEventType.PROCESS_CREATED,
|
||||||
"Process " + DebugClient.getId(proc) + " started " + process.getName(),
|
"Process " + DebugClient.getId(proc) + " started " + process.getName(),
|
||||||
List.of(process));
|
List.of(process));
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -245,7 +245,7 @@ public class LldbModelTargetProcessImpl extends LldbModelTargetObjectImpl
|
|||||||
STATE_ATTRIBUTE_NAME, TargetExecutionState.TERMINATED, //
|
STATE_ATTRIBUTE_NAME, TargetExecutionState.TERMINATED, //
|
||||||
EXIT_CODE_ATTRIBUTE_NAME, exitDesc //
|
EXIT_CODE_ATTRIBUTE_NAME, exitDesc //
|
||||||
), "Exited");
|
), "Exited");
|
||||||
getListeners().fire.event(getProxy(), null, TargetEventType.PROCESS_EXITED,
|
broadcast().event(getProxy(), null, TargetEventType.PROCESS_EXITED,
|
||||||
"Process " + DebugClient.getId(getProcess()) + " exited code=" + exitDesc,
|
"Process " + DebugClient.getId(getProcess()) + " exited code=" + exitDesc,
|
||||||
List.of(getProxy()));
|
List.of(getProxy()));
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-9
@@ -25,13 +25,11 @@ import agent.lldb.manager.LldbReason;
|
|||||||
import agent.lldb.model.iface2.LldbModelTargetRegister;
|
import agent.lldb.model.iface2.LldbModelTargetRegister;
|
||||||
import agent.lldb.model.iface2.LldbModelTargetStackFrameRegisterBank;
|
import agent.lldb.model.iface2.LldbModelTargetStackFrameRegisterBank;
|
||||||
import ghidra.async.AsyncUtils;
|
import ghidra.async.AsyncUtils;
|
||||||
import ghidra.dbg.DebuggerModelListener;
|
|
||||||
import ghidra.dbg.error.DebuggerRegisterAccessException;
|
import ghidra.dbg.error.DebuggerRegisterAccessException;
|
||||||
import ghidra.dbg.target.TargetObject;
|
import ghidra.dbg.target.TargetObject;
|
||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
||||||
import ghidra.dbg.util.PathUtils;
|
import ghidra.dbg.util.PathUtils;
|
||||||
import ghidra.util.datastruct.ListenerSet;
|
|
||||||
|
|
||||||
@TargetObjectSchemaInfo(
|
@TargetObjectSchemaInfo(
|
||||||
name = "RegisterValueBank",
|
name = "RegisterValueBank",
|
||||||
@@ -66,6 +64,7 @@ public class LldbModelTargetStackFrameRegisterBankImpl
|
|||||||
requestElements(false);
|
requestElements(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDescription(int level) {
|
public String getDescription(int level) {
|
||||||
SBStream stream = new SBStream();
|
SBStream stream = new SBStream();
|
||||||
SBValue val = (SBValue) getModelObject();
|
SBValue val = (SBValue) getModelObject();
|
||||||
@@ -105,6 +104,7 @@ public class LldbModelTargetStackFrameRegisterBankImpl
|
|||||||
return new LldbModelTargetStackFrameRegisterImpl(this, register);
|
return new LldbModelTargetStackFrameRegisterImpl(this, register);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void threadStateChangedSpecific(StateType state, LldbReason reason) {
|
public void threadStateChangedSpecific(StateType state, LldbReason reason) {
|
||||||
if (state.equals(StateType.eStateStopped)) {
|
if (state.equals(StateType.eStateStopped)) {
|
||||||
requestElements(false).thenAccept(__ -> {
|
requestElements(false).thenAccept(__ -> {
|
||||||
@@ -127,12 +127,9 @@ public class LldbModelTargetStackFrameRegisterBankImpl
|
|||||||
byte[] bytes = register.getBytes();
|
byte[] bytes = register.getBytes();
|
||||||
result.put(regname, bytes);
|
result.put(regname, bytes);
|
||||||
}
|
}
|
||||||
ListenerSet<DebuggerModelListener> listeners = getListeners();
|
//if (getName().contains("General")) {
|
||||||
if (listeners != null) {
|
broadcast().registersUpdated(this, result);
|
||||||
//if (getName().contains("General")) {
|
//}
|
||||||
listeners.fire.registersUpdated(this, result);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
return CompletableFuture.completedFuture(result);
|
return CompletableFuture.completedFuture(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +146,7 @@ public class LldbModelTargetStackFrameRegisterBankImpl
|
|||||||
BigInteger val = new BigInteger(1, ent.getValue());
|
BigInteger val = new BigInteger(1, ent.getValue());
|
||||||
reg.getRegister().SetValueFromCString(val.toString());
|
reg.getRegister().SetValueFromCString(val.toString());
|
||||||
}
|
}
|
||||||
getListeners().fire.registersUpdated(getProxy(), values);
|
broadcast().registersUpdated(getProxy(), values);
|
||||||
return AsyncUtils.NIL;
|
return AsyncUtils.NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -65,7 +65,7 @@ public class LldbModelTargetThreadContainerImpl extends LldbModelTargetObjectImp
|
|||||||
changeElements(List.of(), List.of(targetThread), Map.of(), "Created");
|
changeElements(List.of(), List.of(targetThread), Map.of(), "Created");
|
||||||
targetThread.threadStateChangedSpecific(StateType.eStateConnected,
|
targetThread.threadStateChangedSpecific(StateType.eStateConnected,
|
||||||
LldbReason.getReason(null));
|
LldbReason.getReason(null));
|
||||||
getListeners().fire.event(getProxy(), targetThread, TargetEventType.THREAD_CREATED,
|
broadcast().event(getProxy(), targetThread, TargetEventType.THREAD_CREATED,
|
||||||
"Thread " + DebugClient.getId(thread) + " started", List.of(targetThread));
|
"Thread " + DebugClient.getId(thread) + " started", List.of(targetThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ public class LldbModelTargetThreadContainerImpl extends LldbModelTargetObjectImp
|
|||||||
LldbReason reason) {
|
LldbReason reason) {
|
||||||
LldbModelTargetThread targetThread = getTargetThread(thread);
|
LldbModelTargetThread targetThread = getTargetThread(thread);
|
||||||
TargetEventType eventType = getEventType(state, cause, reason);
|
TargetEventType eventType = getEventType(state, cause, reason);
|
||||||
getListeners().fire.event(getProxy(), targetThread, eventType,
|
broadcast().event(getProxy(), targetThread, eventType,
|
||||||
"Thread " + DebugClient.getId(thread) + " state changed", List.of(targetThread));
|
"Thread " + DebugClient.getId(thread) + " state changed", List.of(targetThread));
|
||||||
targetThread.threadStateChangedSpecific(state, reason);
|
targetThread.threadStateChangedSpecific(state, reason);
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ public class LldbModelTargetThreadContainerImpl extends LldbModelTargetObjectImp
|
|||||||
String threadId = LldbModelTargetThreadImpl.indexThread(thread);
|
String threadId = LldbModelTargetThreadImpl.indexThread(thread);
|
||||||
LldbModelTargetThread targetThread = (LldbModelTargetThread) getMapObject(thread);
|
LldbModelTargetThread targetThread = (LldbModelTargetThread) getMapObject(thread);
|
||||||
if (targetThread != null) {
|
if (targetThread != null) {
|
||||||
getListeners().fire.event(getProxy(), targetThread, TargetEventType.THREAD_EXITED,
|
broadcast().event(getProxy(), targetThread, TargetEventType.THREAD_EXITED,
|
||||||
"Thread " + threadId + " exited", List.of(targetThread));
|
"Thread " + threadId + " exited", List.of(targetThread));
|
||||||
}
|
}
|
||||||
changeElements(List.of( //
|
changeElements(List.of( //
|
||||||
|
|||||||
+1
-1
@@ -71,7 +71,7 @@ public interface GadpClientTargetBreakpointSpecContainer
|
|||||||
Path bptPath = evt.getEffective();
|
Path bptPath = evt.getEffective();
|
||||||
TargetBreakpointLocation breakpoint = bptPath == null ? null
|
TargetBreakpointLocation breakpoint = bptPath == null ? null
|
||||||
: getModel().getProxy(bptPath.getEList(), true).as(TargetBreakpointLocation.class);
|
: getModel().getProxy(bptPath.getEList(), true).as(TargetBreakpointLocation.class);
|
||||||
getDelegate().getListeners().fire.breakpointHit(this, trapped, frame, spec, breakpoint);
|
broadcast().breakpointHit(this, trapped, frame, spec, breakpoint);
|
||||||
if (spec instanceof GadpClientTargetBreakpointSpec) {
|
if (spec instanceof GadpClientTargetBreakpointSpec) {
|
||||||
// If I don't have a cached proxy, then I don't have any listeners
|
// If I don't have a cached proxy, then I don't have any listeners
|
||||||
GadpClientTargetBreakpointSpec specObj = (GadpClientTargetBreakpointSpec) spec;
|
GadpClientTargetBreakpointSpec specObj = (GadpClientTargetBreakpointSpec) spec;
|
||||||
|
|||||||
+1
-1
@@ -33,6 +33,6 @@ public interface GadpClientTargetEventScope extends GadpClientTargetObject, Targ
|
|||||||
String description = evt.getDescription();
|
String description = evt.getDescription();
|
||||||
List<Object> parameters =
|
List<Object> parameters =
|
||||||
GadpValueUtils.getValues(getModel(), evt.getParametersList());
|
GadpValueUtils.getValues(getModel(), evt.getParametersList());
|
||||||
getDelegate().getListeners().fire.event(this, thread, type, description, parameters);
|
broadcast().event(this, thread, type, description, parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -89,7 +89,7 @@ public interface GadpClientTargetMemory extends GadpClientTargetObject, TargetMe
|
|||||||
byte[] data = evt.getContent().toByteArray();
|
byte[] data = evt.getContent().toByteArray();
|
||||||
DelegateGadpClientTargetObject delegate = getDelegate();
|
DelegateGadpClientTargetObject delegate = getDelegate();
|
||||||
delegate.getMemoryCache(address.getAddressSpace()).updateMemory(address.getOffset(), data);
|
delegate.getMemoryCache(address.getAddressSpace()).updateMemory(address.getOffset(), data);
|
||||||
delegate.getListeners().fire.memoryUpdated(this, address, data);
|
broadcast().memoryUpdated(this, address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GadpEventHandler(Gadp.EventNotification.EvtCase.MEMORY_ERROR_EVENT)
|
@GadpEventHandler(Gadp.EventNotification.EvtCase.MEMORY_ERROR_EVENT)
|
||||||
@@ -98,7 +98,6 @@ public interface GadpClientTargetMemory extends GadpClientTargetObject, TargetMe
|
|||||||
AddressRange range = GadpValueUtils.getAddressRange(getModel(), evt.getRange());
|
AddressRange range = GadpValueUtils.getAddressRange(getModel(), evt.getRange());
|
||||||
String message = evt.getMessage();
|
String message = evt.getMessage();
|
||||||
// Errors are not cached, but recorded in trace
|
// Errors are not cached, but recorded in trace
|
||||||
getDelegate().getListeners().fire.memoryReadError(this, range,
|
broadcast().memoryReadError(this, range, new DebuggerMemoryAccessException(message));
|
||||||
new DebuggerMemoryAccessException(message));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -56,8 +56,7 @@ public interface GadpClientTargetObject extends SpiTargetObject {
|
|||||||
int channelIndex = evt.getChannel();
|
int channelIndex = evt.getChannel();
|
||||||
Channel[] allChannels = Channel.values();
|
Channel[] allChannels = Channel.values();
|
||||||
if (0 <= channelIndex && channelIndex < allChannels.length) {
|
if (0 <= channelIndex && channelIndex < allChannels.length) {
|
||||||
getDelegate().getListeners().fire.consoleOutput(this, allChannels[channelIndex],
|
broadcast().consoleOutput(this, allChannels[channelIndex], evt.getData().toByteArray());
|
||||||
evt.getData().toByteArray());
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Msg.error(this, "Received output for unknown channel " + channelIndex + ": " +
|
Msg.error(this, "Received output for unknown channel " + channelIndex + ": " +
|
||||||
|
|||||||
+1
-1
@@ -82,6 +82,6 @@ public interface GadpClientTargetRegisterBank extends GadpClientTargetObject, Ta
|
|||||||
Map<String, byte[]> updates = GadpValueUtils.getRegisterValueMap(evt.getValueList());
|
Map<String, byte[]> updates = GadpValueUtils.getRegisterValueMap(evt.getValueList());
|
||||||
DelegateGadpClientTargetObject delegate = getDelegate();
|
DelegateGadpClientTargetObject delegate = getDelegate();
|
||||||
delegate.getRegisterCache().putAll(updates);
|
delegate.getRegisterCache().putAll(updates);
|
||||||
delegate.getListeners().fire.registersUpdated(this, updates);
|
broadcast().registersUpdated(this, updates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+51
-19
@@ -926,6 +926,9 @@ public class GadpClientServerTest implements AsyncTestUtils {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAvailableWithObjectGettingListener() throws Throwable {
|
public void testGetAvailableWithObjectGettingListener() throws Throwable {
|
||||||
|
var l = new Object() {
|
||||||
|
TargetObject avail;
|
||||||
|
};
|
||||||
List<ElementsChangedInvocation> invocations = new ArrayList<>();
|
List<ElementsChangedInvocation> invocations = new ArrayList<>();
|
||||||
// Any listener which calls .get on a child ref would do....
|
// Any listener which calls .get on a child ref would do....
|
||||||
// This object-getting listener is the pattern that revealed this problem, though.
|
// This object-getting listener is the pattern that revealed this problem, though.
|
||||||
@@ -933,18 +936,21 @@ public class GadpClientServerTest implements AsyncTestUtils {
|
|||||||
@Override
|
@Override
|
||||||
public void elementsChanged(TargetObject parent, Collection<String> removed,
|
public void elementsChanged(TargetObject parent, Collection<String> removed,
|
||||||
Map<String, ? extends TargetObject> added) {
|
Map<String, ? extends TargetObject> added) {
|
||||||
|
if (parent != l.avail) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
invocations.add(new ElementsChangedInvocation(parent, removed, added));
|
invocations.add(new ElementsChangedInvocation(parent, removed, added));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
AsynchronousSocketChannel socket = socketChannel();
|
AsynchronousSocketChannel socket = socketChannel();
|
||||||
try (ServerRunner runner = new ServerRunner()) {
|
try (ServerRunner runner = new ServerRunner()) {
|
||||||
GadpClient client = new GadpClient("Test", socket);
|
GadpClient client = new GadpClient("Test", socket);
|
||||||
|
client.addModelListener(listener);
|
||||||
waitOn(AsyncUtils.completable(TypeSpec.VOID, socket::connect,
|
waitOn(AsyncUtils.completable(TypeSpec.VOID, socket::connect,
|
||||||
runner.server.getLocalAddress()));
|
runner.server.getLocalAddress()));
|
||||||
waitOn(client.connect());
|
waitOn(client.connect());
|
||||||
TargetObject avail = waitOn(client.fetchModelObject(List.of("Available")));
|
l.avail = waitOn(client.fetchModelObject(List.of("Available")));
|
||||||
avail.addListener(listener);
|
Map<String, ? extends TargetObject> elements = waitOn(l.avail.fetchElements());
|
||||||
Map<String, ? extends TargetObject> elements = waitOn(avail.fetchElements());
|
|
||||||
Msg.debug(this, "Elements: " + elements);
|
Msg.debug(this, "Elements: " + elements);
|
||||||
waitOn(client.close());
|
waitOn(client.close());
|
||||||
}
|
}
|
||||||
@@ -957,13 +963,18 @@ public class GadpClientServerTest implements AsyncTestUtils {
|
|||||||
public void testFocus() throws Throwable {
|
public void testFocus() throws Throwable {
|
||||||
// Interesting because it involves a non-object-valued attribute (link)
|
// Interesting because it involves a non-object-valued attribute (link)
|
||||||
// Need to check callback as well as getAttributes
|
// Need to check callback as well as getAttributes
|
||||||
|
var l = new Object() {
|
||||||
|
TargetObject session;
|
||||||
|
};
|
||||||
CompletableFuture<List<String>> focusPath = new CompletableFuture<>();
|
CompletableFuture<List<String>> focusPath = new CompletableFuture<>();
|
||||||
AtomicBoolean failed = new AtomicBoolean();
|
AtomicBoolean failed = new AtomicBoolean();
|
||||||
DebuggerModelListener focusListener =
|
DebuggerModelListener focusListener =
|
||||||
new AnnotatedDebuggerAttributeListener(MethodHandles.lookup()) {
|
new AnnotatedDebuggerAttributeListener(MethodHandles.lookup()) {
|
||||||
@AttributeCallback(TargetFocusScope.FOCUS_ATTRIBUTE_NAME)
|
@AttributeCallback(TargetFocusScope.FOCUS_ATTRIBUTE_NAME)
|
||||||
public void focusChanged(TargetObject object, TargetObject focused) {
|
public void focusChanged(TargetObject object, TargetObject focused) {
|
||||||
|
if (object != l.session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Msg.info(this, "Focus changed to " + focused);
|
Msg.info(this, "Focus changed to " + focused);
|
||||||
if (!focusPath.complete(focused.getPath())) {
|
if (!focusPath.complete(focused.getPath())) {
|
||||||
failed.set(true);
|
failed.set(true);
|
||||||
@@ -976,8 +987,7 @@ public class GadpClientServerTest implements AsyncTestUtils {
|
|||||||
waitOn(AsyncUtils.completable(TypeSpec.VOID, socket::connect,
|
waitOn(AsyncUtils.completable(TypeSpec.VOID, socket::connect,
|
||||||
runner.server.getLocalAddress()));
|
runner.server.getLocalAddress()));
|
||||||
waitOn(client.connect());
|
waitOn(client.connect());
|
||||||
TargetObject session = waitOn(client.fetchModelObject(List.of()));
|
l.session = waitOn(client.fetchModelObject(List.of()));
|
||||||
session.addListener(focusListener);
|
|
||||||
TargetObject procCont = waitOn(client.fetchModelObject(List.of("Processes")));
|
TargetObject procCont = waitOn(client.fetchModelObject(List.of("Processes")));
|
||||||
assertTrue(procCont.getInterfaceNames().contains("Launcher"));
|
assertTrue(procCont.getInterfaceNames().contains("Launcher"));
|
||||||
TargetLauncher launcher = procCont.as(TargetLauncher.class);
|
TargetLauncher launcher = procCont.as(TargetLauncher.class);
|
||||||
@@ -1017,7 +1027,19 @@ public class GadpClientServerTest implements AsyncTestUtils {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSubscribeLaunchForChildrenChanged() throws Throwable {
|
public void testSubscribeLaunchForChildrenChanged() throws Throwable {
|
||||||
ElementsChangedListener elemL = new ElementsChangedListener();
|
var l = new Object() {
|
||||||
|
TargetObject procContainer;
|
||||||
|
};
|
||||||
|
ElementsChangedListener elemL = new ElementsChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void elementsChanged(TargetObject parent, Collection<String> removed,
|
||||||
|
Map<String, ? extends TargetObject> added) {
|
||||||
|
if (parent != l.procContainer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.elementsChanged(parent, removed, added);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
AsynchronousSocketChannel socket = socketChannel();
|
AsynchronousSocketChannel socket = socketChannel();
|
||||||
try (ServerRunner runner = new ServerRunner()) {
|
try (ServerRunner runner = new ServerRunner()) {
|
||||||
@@ -1026,10 +1048,9 @@ public class GadpClientServerTest implements AsyncTestUtils {
|
|||||||
waitOn(AsyncUtils.completable(TypeSpec.VOID, socket::connect,
|
waitOn(AsyncUtils.completable(TypeSpec.VOID, socket::connect,
|
||||||
runner.server.getLocalAddress()));
|
runner.server.getLocalAddress()));
|
||||||
waitOn(client.connect());
|
waitOn(client.connect());
|
||||||
TargetObject procContainer = waitOn(client.fetchModelObject(List.of("Processes")));
|
l.procContainer = waitOn(client.fetchModelObject(List.of("Processes")));
|
||||||
assertTrue(procContainer.getInterfaceNames().contains("Launcher"));
|
assertTrue(l.procContainer.getInterfaceNames().contains("Launcher"));
|
||||||
procContainer.addListener(elemL);
|
TargetLauncher launcher = l.procContainer.as(TargetLauncher.class);
|
||||||
TargetLauncher launcher = procContainer.as(TargetLauncher.class);
|
|
||||||
waitOn(launcher.launch(
|
waitOn(launcher.launch(
|
||||||
Map.of(TargetCmdLineLauncher.CMDLINE_ARGS_NAME, "/bin/echo Hello, World!")));
|
Map.of(TargetCmdLineLauncher.CMDLINE_ARGS_NAME, "/bin/echo Hello, World!")));
|
||||||
waitOn(elemL.count.waitValue(1));
|
waitOn(elemL.count.waitValue(1));
|
||||||
@@ -1038,7 +1059,7 @@ public class GadpClientServerTest implements AsyncTestUtils {
|
|||||||
|
|
||||||
assertEquals(1, elemL.invocations.size());
|
assertEquals(1, elemL.invocations.size());
|
||||||
ElementsChangedInvocation eci = elemL.invocations.get(0);
|
ElementsChangedInvocation eci = elemL.invocations.get(0);
|
||||||
assertEquals(procContainer, eci.parent);
|
assertEquals(l.procContainer, eci.parent);
|
||||||
assertEquals(List.of(), List.copyOf(eci.removed));
|
assertEquals(List.of(), List.copyOf(eci.removed));
|
||||||
assertEquals(1, eci.added.size());
|
assertEquals(1, eci.added.size());
|
||||||
Entry<String, ? extends TargetObject> ent = eci.added.entrySet().iterator().next();
|
Entry<String, ? extends TargetObject> ent = eci.added.entrySet().iterator().next();
|
||||||
@@ -1107,20 +1128,31 @@ public class GadpClientServerTest implements AsyncTestUtils {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReplaceAttribute() throws Throwable {
|
public void testReplaceAttribute() throws Throwable {
|
||||||
AttributesChangedListener attrL = new AttributesChangedListener();
|
var l = new Object() {
|
||||||
|
TargetObject echoAvail;
|
||||||
|
};
|
||||||
|
AttributesChangedListener attrL = new AttributesChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void attributesChanged(TargetObject parent, Collection<String> removed,
|
||||||
|
Map<String, ?> added) {
|
||||||
|
if (parent != l.echoAvail) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.attributesChanged(parent, removed, added);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
try (AsynchronousSocketChannel socket = socketChannel();
|
try (AsynchronousSocketChannel socket = socketChannel();
|
||||||
ServerRunner runner = new ServerRunner()) {
|
ServerRunner runner = new ServerRunner()) {
|
||||||
GadpClient client = new GadpClient("Test", socket);
|
GadpClient client = new GadpClient("Test", socket);
|
||||||
|
client.addModelListener(attrL);
|
||||||
waitOn(AsyncUtils.completable(TypeSpec.VOID, socket::connect,
|
waitOn(AsyncUtils.completable(TypeSpec.VOID, socket::connect,
|
||||||
runner.server.getLocalAddress()));
|
runner.server.getLocalAddress()));
|
||||||
waitOn(client.connect());
|
waitOn(client.connect());
|
||||||
|
|
||||||
TargetObject echoAvail =
|
l.echoAvail = waitOn(client.fetchModelObject(PathUtils.parse("Available[1]")));
|
||||||
waitOn(client.fetchModelObject(PathUtils.parse("Available[1]")));
|
|
||||||
echoAvail.addListener(attrL);
|
|
||||||
assertEquals(Map.ofEntries(Map.entry("pid", 1), Map.entry("cmd", "echo"),
|
assertEquals(Map.ofEntries(Map.entry("pid", 1), Map.entry("cmd", "echo"),
|
||||||
Map.entry("_display", "[1]")), waitOn(echoAvail.fetchAttributes()));
|
Map.entry("_display", "[1]")), waitOn(l.echoAvail.fetchAttributes()));
|
||||||
|
|
||||||
TestGadpTargetAvailable ssEchoAvail =
|
TestGadpTargetAvailable ssEchoAvail =
|
||||||
runner.server.model.session.available.getCachedElements().get("1");
|
runner.server.model.session.available.getCachedElements().get("1");
|
||||||
@@ -1132,10 +1164,10 @@ public class GadpClientServerTest implements AsyncTestUtils {
|
|||||||
waitOn(attrL.count.waitValue(1));
|
waitOn(attrL.count.waitValue(1));
|
||||||
|
|
||||||
assertEquals(Map.ofEntries(Map.entry("cmd", "echo"), Map.entry("args", "Hello, World!"),
|
assertEquals(Map.ofEntries(Map.entry("cmd", "echo"), Map.entry("args", "Hello, World!"),
|
||||||
Map.entry("_display", "[1]")), echoAvail.getCachedAttributes());
|
Map.entry("_display", "[1]")), l.echoAvail.getCachedAttributes());
|
||||||
|
|
||||||
AttributesChangedInvocation changed = Unique.assertOne(attrL.invocations);
|
AttributesChangedInvocation changed = Unique.assertOne(attrL.invocations);
|
||||||
assertSame(echoAvail, changed.parent);
|
assertSame(l.echoAvail, changed.parent);
|
||||||
assertEquals(Set.of("pid"), Set.copyOf(changed.removed));
|
assertEquals(Set.of("pid"), Set.copyOf(changed.removed));
|
||||||
assertEquals(Map.ofEntries(Map.entry("args", "Hello, World!")), changed.added);
|
assertEquals(Map.ofEntries(Map.entry("args", "Hello, World!")), changed.added);
|
||||||
}
|
}
|
||||||
|
|||||||
-4
@@ -22,7 +22,6 @@ import java.util.stream.Collectors;
|
|||||||
import com.sun.jdi.ReferenceType;
|
import com.sun.jdi.ReferenceType;
|
||||||
|
|
||||||
import ghidra.async.AsyncFence;
|
import ghidra.async.AsyncFence;
|
||||||
import ghidra.async.AsyncUtils;
|
|
||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
@@ -90,9 +89,6 @@ public class JdiModelTargetClassContainer extends JdiModelTargetObjectImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<?> refreshInternal() {
|
public CompletableFuture<?> refreshInternal() {
|
||||||
if (!isObserved()) {
|
|
||||||
return AsyncUtils.NIL;
|
|
||||||
}
|
|
||||||
return doRefresh().exceptionally(ex -> {
|
return doRefresh().exceptionally(ex -> {
|
||||||
Msg.error(this, "Problem refreshing vm's classes", ex);
|
Msg.error(this, "Problem refreshing vm's classes", ex);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
-4
@@ -23,7 +23,6 @@ import com.sun.jdi.VirtualMachineManager;
|
|||||||
import com.sun.jdi.connect.Connector;
|
import com.sun.jdi.connect.Connector;
|
||||||
|
|
||||||
import ghidra.async.AsyncFence;
|
import ghidra.async.AsyncFence;
|
||||||
import ghidra.async.AsyncUtils;
|
|
||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
@@ -96,9 +95,6 @@ public class JdiModelTargetConnectorContainer extends JdiModelTargetObjectImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<?> refreshInternal() {
|
public CompletableFuture<?> refreshInternal() {
|
||||||
if (!isObserved()) {
|
|
||||||
return AsyncUtils.NIL;
|
|
||||||
}
|
|
||||||
return doRefresh().exceptionally(ex -> {
|
return doRefresh().exceptionally(ex -> {
|
||||||
Msg.error(this, "Problem refreshing inferior's modules", ex);
|
Msg.error(this, "Problem refreshing inferior's modules", ex);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
-4
@@ -22,7 +22,6 @@ import java.util.stream.Collectors;
|
|||||||
import com.sun.jdi.ModuleReference;
|
import com.sun.jdi.ModuleReference;
|
||||||
|
|
||||||
import ghidra.async.AsyncFence;
|
import ghidra.async.AsyncFence;
|
||||||
import ghidra.async.AsyncUtils;
|
|
||||||
import ghidra.dbg.error.DebuggerUserException;
|
import ghidra.dbg.error.DebuggerUserException;
|
||||||
import ghidra.dbg.target.TargetModule;
|
import ghidra.dbg.target.TargetModule;
|
||||||
import ghidra.dbg.target.TargetModuleContainer;
|
import ghidra.dbg.target.TargetModuleContainer;
|
||||||
@@ -136,9 +135,6 @@ public class JdiModelTargetModuleContainer extends JdiModelTargetObjectImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<?> refreshInternal() {
|
public CompletableFuture<?> refreshInternal() {
|
||||||
if (!isObserved()) {
|
|
||||||
return AsyncUtils.NIL;
|
|
||||||
}
|
|
||||||
return doRefresh().exceptionally(ex -> {
|
return doRefresh().exceptionally(ex -> {
|
||||||
Msg.error(this, "Problem refreshing inferior's modules", ex);
|
Msg.error(this, "Problem refreshing inferior's modules", ex);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+1
-1
@@ -106,7 +106,7 @@ public class JdiModelTargetProcess extends JdiModelTargetObjectImpl
|
|||||||
default:
|
default:
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
listeners.fire.consoleOutput(this, channel, out);
|
broadcast().consoleOutput(this, channel, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readStream(InputStream in, TargetConsole.Channel channel) {
|
private void readStream(InputStream in, TargetConsole.Channel channel) {
|
||||||
|
|||||||
+2
-6
@@ -20,7 +20,6 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
|
|
||||||
import com.sun.jdi.Location;
|
import com.sun.jdi.Location;
|
||||||
|
|
||||||
import ghidra.async.AsyncUtils;
|
|
||||||
import ghidra.dbg.target.TargetRegisterBank;
|
import ghidra.dbg.target.TargetRegisterBank;
|
||||||
import ghidra.dbg.target.TargetRegisterContainer;
|
import ghidra.dbg.target.TargetRegisterContainer;
|
||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
@@ -121,7 +120,7 @@ public class JdiModelTargetRegisterContainer extends JdiModelTargetObjectImpl
|
|||||||
map.put(retAddr.getIndex(), bytes);
|
map.put(retAddr.getIndex(), bytes);
|
||||||
}
|
}
|
||||||
if (!map.isEmpty()) {
|
if (!map.isEmpty()) {
|
||||||
listeners.fire.registersUpdated(this, map);
|
broadcast().registersUpdated(this, map);
|
||||||
}
|
}
|
||||||
return CompletableFuture.completedFuture(map);
|
return CompletableFuture.completedFuture(map);
|
||||||
}
|
}
|
||||||
@@ -133,13 +132,10 @@ public class JdiModelTargetRegisterContainer extends JdiModelTargetObjectImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void invalidateRegisterCaches() {
|
public void invalidateRegisterCaches() {
|
||||||
listeners.fire.invalidateCacheRequested(this);
|
broadcast().invalidateCacheRequested(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CompletableFuture<?> update() {
|
protected CompletableFuture<?> update() {
|
||||||
if (!isObserved()) {
|
|
||||||
return AsyncUtils.NIL;
|
|
||||||
}
|
|
||||||
return fetchElements(true).exceptionally(e -> {
|
return fetchElements(true).exceptionally(e -> {
|
||||||
Msg.error(this, "Could not update registers " + this + " on STOPPED");
|
Msg.error(this, "Could not update registers " + this + " on STOPPED");
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+2
-2
@@ -125,12 +125,12 @@ public class JdiModelTargetSectionContainer extends JdiModelTargetObjectImpl
|
|||||||
bytes[i] = (byte) 0xFF;
|
bytes[i] = (byte) 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
listeners.fire.memoryUpdated(this, address, bytes);
|
broadcast().memoryUpdated(this, address, bytes);
|
||||||
return CompletableFuture.completedFuture(bytes);
|
return CompletableFuture.completedFuture(bytes);
|
||||||
}
|
}
|
||||||
if (addressSpace.equals(impl.getAddressSpace("constantPool"))) {
|
if (addressSpace.equals(impl.getAddressSpace("constantPool"))) {
|
||||||
byte[] bytes = constantPool.getPool();
|
byte[] bytes = constantPool.getPool();
|
||||||
listeners.fire.memoryUpdated(this, address, bytes);
|
broadcast().memoryUpdated(this, address, bytes);
|
||||||
return CompletableFuture.completedFuture(bytes);
|
return CompletableFuture.completedFuture(bytes);
|
||||||
}
|
}
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user