mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-2189: Add FlatDebuggerAPI interface
This commit is contained in:
parent
58066601fc
commit
c7b464a0be
46 changed files with 4619 additions and 129 deletions
|
@ -25,12 +25,24 @@ import java.util.*;
|
|||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
/**
|
||||
* A model listener that permits {@link AttributeCallback} annotations for convenient callbacks when
|
||||
* the named attribute changes
|
||||
*/
|
||||
public abstract class AnnotatedDebuggerAttributeListener implements DebuggerModelListener {
|
||||
private static final String ATTR_METHODS =
|
||||
"@" + AttributeCallback.class.getSimpleName() + "-annotated methods";
|
||||
private static final String PARAMS_ERR =
|
||||
ATTR_METHODS + " must accept 2 parameters: (TargetObject, T)";
|
||||
|
||||
/**
|
||||
* Annotation for a method receiving an attribute change callback
|
||||
*
|
||||
* <p>
|
||||
* The annotated method must accept parameters {@code (TargetObject, T)}, where {@code T} is the
|
||||
* type of the attribute. Currently, very little checks are applied during construction.
|
||||
* Incorrect use will result in errors during callback invocation.
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
protected @interface AttributeCallback {
|
||||
|
|
|
@ -374,4 +374,8 @@ public class DebuggerCallbackReorderer implements DebuggerModelListener {
|
|||
rec.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> flushEvents() {
|
||||
return lastEvent.thenApply(v -> v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,12 +40,16 @@ public class TestDebuggerModelBuilder {
|
|||
public TestTargetRegister testRegisterPC;
|
||||
public TestTargetRegister testRegisterSP;
|
||||
|
||||
protected TestDebuggerObjectModel newModel(String typeHint) {
|
||||
return new TestDebuggerObjectModel(typeHint);
|
||||
}
|
||||
|
||||
public void createTestModel() {
|
||||
createTestModel("Session");
|
||||
}
|
||||
|
||||
public void createTestModel(String typeHint) {
|
||||
testModel = new TestDebuggerObjectModel(typeHint);
|
||||
testModel = newModel(typeHint);
|
||||
}
|
||||
|
||||
public Address addr(long offset) {
|
||||
|
|
|
@ -16,15 +16,19 @@
|
|||
package ghidra.dbg.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import org.jdom.JDOMException;
|
||||
|
||||
import ghidra.dbg.DebuggerModelListener;
|
||||
import ghidra.dbg.attributes.TargetDataType;
|
||||
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema;
|
||||
import ghidra.dbg.target.schema.XmlSchemaContext;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
|
||||
// TODO: Refactor with other Fake and Test model stuff.
|
||||
public class TestDebuggerObjectModel extends EmptyDebuggerObjectModel {
|
||||
|
@ -60,13 +64,145 @@ public class TestDebuggerObjectModel extends EmptyDebuggerObjectModel {
|
|||
this("Session");
|
||||
}
|
||||
|
||||
public Executor getClientExecutor() {
|
||||
return clientExecutor;
|
||||
public TestDebuggerObjectModel(String rootHint) {
|
||||
this.session = newTestTargetSession(rootHint);
|
||||
addModelRoot(session);
|
||||
}
|
||||
|
||||
public TestDebuggerObjectModel(String rootHint) {
|
||||
this.session = new TestTargetSession(this, rootHint, ROOT_SCHEMA);
|
||||
addModelRoot(session);
|
||||
protected TestTargetSession newTestTargetSession(String rootHint) {
|
||||
return new TestTargetSession(this, rootHint, ROOT_SCHEMA);
|
||||
}
|
||||
|
||||
protected TestTargetEnvironment newTestTargetEnvironment(TestTargetSession session) {
|
||||
return new TestTargetEnvironment(session);
|
||||
}
|
||||
|
||||
protected TestTargetProcessContainer newTestTargetProcessContainer(TestTargetSession session) {
|
||||
return new TestTargetProcessContainer(session);
|
||||
}
|
||||
|
||||
protected TestTargetProcess newTestTargetProcess(TestTargetProcessContainer container, int pid,
|
||||
AddressSpace space) {
|
||||
return new TestTargetProcess(container, pid, space);
|
||||
}
|
||||
|
||||
protected TestTargetBreakpointContainer newTestTargetBreakpointContainer(
|
||||
TestTargetProcess process) {
|
||||
return new TestTargetBreakpointContainer(process);
|
||||
}
|
||||
|
||||
protected TestTargetBreakpoint newTestTargetBreakpoint(TestTargetBreakpointContainer container,
|
||||
int num, Address address, int length, Set<TargetBreakpointKind> kinds) {
|
||||
return new TestTargetBreakpoint(container, num, address, length, kinds);
|
||||
}
|
||||
|
||||
protected TestTargetMemory newTestTargetMemory(TestTargetProcess process, AddressSpace space) {
|
||||
return new TestTargetMemory(process, space);
|
||||
}
|
||||
|
||||
protected TestTargetMemoryRegion newTestTargetMemoryRegion(TestTargetMemory memory, String name,
|
||||
AddressRange range, String flags) {
|
||||
return new TestTargetMemoryRegion(memory, name, range, flags);
|
||||
}
|
||||
|
||||
protected TestTargetModuleContainer newTestTargetModuleContainer(TestTargetProcess process) {
|
||||
return new TestTargetModuleContainer(process);
|
||||
}
|
||||
|
||||
protected TestTargetModule newTestTargetModule(TestTargetModuleContainer container, String name,
|
||||
AddressRange range) {
|
||||
return new TestTargetModule(container, name, range);
|
||||
}
|
||||
|
||||
protected TestTargetSectionContainer newTestTargetSectionContainer(TestTargetModule module) {
|
||||
return new TestTargetSectionContainer(module);
|
||||
}
|
||||
|
||||
protected TestTargetSection newTestTargetSection(TestTargetSectionContainer container,
|
||||
String name, AddressRange range) {
|
||||
return new TestTargetSection(container, name, range);
|
||||
}
|
||||
|
||||
protected TestTargetSymbolNamespace newTestTargetSymbolNamespace(TestTargetModule module) {
|
||||
return new TestTargetSymbolNamespace(module);
|
||||
}
|
||||
|
||||
protected TestTargetSymbol newTestTargetSymbol(TestTargetSymbolNamespace namespace, String name,
|
||||
Address address, long size, TargetDataType dataType) {
|
||||
return new TestTargetSymbol(namespace, name, address, size, dataType);
|
||||
}
|
||||
|
||||
protected TestTargetDataTypeNamespace newTestTargetDataTypeNamespace(TestTargetModule module) {
|
||||
return new TestTargetDataTypeNamespace(module);
|
||||
}
|
||||
|
||||
protected TestTargetTypedefDataType newTestTargetTypedefDataType(
|
||||
TestTargetDataTypeNamespace namespace, String name, TargetDataType defDataType) {
|
||||
return new TestTargetTypedefDataType(namespace, name, defDataType);
|
||||
}
|
||||
|
||||
protected TestTargetTypedefDef newTestTargetTypedefDef(TestTargetTypedefDataType typedef,
|
||||
TargetDataType dataType) {
|
||||
return new TestTargetTypedefDef(typedef, dataType);
|
||||
}
|
||||
|
||||
protected TestTargetRegisterContainer newTestTargetRegisterContainer(
|
||||
TestTargetProcess process) {
|
||||
return new TestTargetRegisterContainer(process);
|
||||
}
|
||||
|
||||
protected TestTargetRegister newTestTargetRegister(TestTargetRegisterContainer container,
|
||||
Register register) {
|
||||
return TestTargetRegister.fromLanguageRegister(container, register);
|
||||
}
|
||||
|
||||
protected TestTargetThreadContainer newTestTargetThreadContainer(TestTargetProcess process) {
|
||||
return new TestTargetThreadContainer(process);
|
||||
}
|
||||
|
||||
protected TestTargetThread newTestTargetThread(TestTargetThreadContainer container, int tid) {
|
||||
return new TestTargetThread(container, tid);
|
||||
}
|
||||
|
||||
protected TestTargetRegisterBankInThread newTestTargetRegisterBankInThread(
|
||||
TestTargetThread thread) {
|
||||
return new TestTargetRegisterBankInThread(thread);
|
||||
}
|
||||
|
||||
protected TestTargetStack newTestTargetStack(TestTargetThread thread) {
|
||||
return new TestTargetStack(thread);
|
||||
}
|
||||
|
||||
protected TestTargetStackFrameNoRegisterBank newTestTargetStackFrameNoRegisterBank(
|
||||
TestTargetStack stack, int level, Address pc) {
|
||||
return new TestTargetStackFrameNoRegisterBank(stack, level, pc);
|
||||
}
|
||||
|
||||
protected TestTargetStackFrameHasRegisterBank newTestTargetStackFrameHasRegisterBank(
|
||||
TestTargetStack stack, int level, Address pc) {
|
||||
return new TestTargetStackFrameHasRegisterBank(stack, level, pc);
|
||||
}
|
||||
|
||||
protected TestTargetRegisterBankInFrame newTestTargetRegisterBankInFrame(
|
||||
TestTargetStackFrameHasRegisterBank frame) {
|
||||
return new TestTargetRegisterBankInFrame(frame);
|
||||
}
|
||||
|
||||
protected TestTargetStackFrameIsRegisterBank newTestTargetStackFrameIsRegisterBank(
|
||||
TestTargetStack stack, int level, Address pc) {
|
||||
return new TestTargetStackFrameIsRegisterBank(stack, level, pc);
|
||||
}
|
||||
|
||||
protected TestTargetInterpreter newTestTargetInterpreter(TestTargetSession session) {
|
||||
return new TestTargetInterpreter(session);
|
||||
}
|
||||
|
||||
protected TestMimickJavaLauncher newTestMimickJavaLauncher(TestTargetSession session) {
|
||||
return new TestMimickJavaLauncher(session);
|
||||
}
|
||||
|
||||
public Executor getClientExecutor() {
|
||||
return clientExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -56,8 +56,9 @@ public class TestTargetBreakpointContainer
|
|||
@Override
|
||||
public CompletableFuture<Void> placeBreakpoint(AddressRange range,
|
||||
Set<TargetBreakpointKind> kinds) {
|
||||
TestTargetBreakpoint bpt = new TestTargetBreakpoint(this, counter.getAndIncrement(),
|
||||
range.getMinAddress(), (int) range.getLength(), kinds);
|
||||
TestTargetBreakpoint bpt =
|
||||
getModel().newTestTargetBreakpoint(this, counter.getAndIncrement(),
|
||||
range.getMinAddress(), (int) range.getLength(), kinds);
|
||||
changeElements(List.of(), List.of(bpt), "Breakpoint Added");
|
||||
return getModel().future(null);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ public class TestTargetDataTypeNamespace
|
|||
|
||||
public TestTargetTypedefDataType addTypedefDataType(String name,
|
||||
TargetDataType defDataType) {
|
||||
TestTargetTypedefDataType dataType = new TestTargetTypedefDataType(this, name, defDataType);
|
||||
TestTargetTypedefDataType dataType =
|
||||
getModel().newTestTargetTypedefDataType(this, name, defDataType);
|
||||
changeElements(List.of(), List.of(dataType), "Added typedef " + name);
|
||||
return dataType;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,8 @@ public class TestTargetMemory
|
|||
}
|
||||
|
||||
public TestTargetMemoryRegion addRegion(String name, AddressRange range, String flags) {
|
||||
TestTargetMemoryRegion region = new TestTargetMemoryRegion(this, name, range, flags);
|
||||
TestTargetMemoryRegion region =
|
||||
getModel().newTestTargetMemoryRegion(this, name, range, flags);
|
||||
changeElements(List.of(), List.of(region), "Add test region: " + range);
|
||||
return region;
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ public class TestTargetModule
|
|||
|
||||
public TestTargetModule(TestTargetModuleContainer parent, String name, AddressRange range) {
|
||||
super(parent, PathUtils.makeKey(name), "Module");
|
||||
sections = new TestTargetSectionContainer(this);
|
||||
symbols = new TestTargetSymbolNamespace(this);
|
||||
types = new TestTargetDataTypeNamespace(this);
|
||||
sections = getModel().newTestTargetSectionContainer(this);
|
||||
symbols = getModel().newTestTargetSymbolNamespace(this);
|
||||
types = getModel().newTestTargetDataTypeNamespace(this);
|
||||
|
||||
changeAttributes(List.of(), Map.of(
|
||||
RANGE_ATTRIBUTE_NAME, range,
|
||||
|
|
|
@ -29,7 +29,7 @@ public class TestTargetModuleContainer
|
|||
}
|
||||
|
||||
public TestTargetModule addModule(String name, AddressRange range) {
|
||||
TestTargetModule module = new TestTargetModule(this, name, range);
|
||||
TestTargetModule module = getModel().newTestTargetModule(this, name, range);
|
||||
changeElements(List.of(), List.of(module), "Add test module: " + name);
|
||||
return module;
|
||||
}
|
||||
|
|
|
@ -35,11 +35,11 @@ public class TestTargetProcess extends
|
|||
|
||||
public TestTargetProcess(DefaultTestTargetObject<?, ?> parent, int pid, AddressSpace space) {
|
||||
super(parent, PathUtils.makeKey(PathUtils.makeIndex(pid)), "Process");
|
||||
breaks = new TestTargetBreakpointContainer(this);
|
||||
memory = new TestTargetMemory(this, space);
|
||||
modules = new TestTargetModuleContainer(this);
|
||||
regs = new TestTargetRegisterContainer(this);
|
||||
threads = new TestTargetThreadContainer(this);
|
||||
breaks = getModel().newTestTargetBreakpointContainer(this);
|
||||
memory = getModel().newTestTargetMemory(this, space);
|
||||
modules = getModel().newTestTargetModuleContainer(this);
|
||||
regs = getModel().newTestTargetRegisterContainer(this);
|
||||
threads = getModel().newTestTargetThreadContainer(this);
|
||||
|
||||
changeAttributes(List.of(), List.of(
|
||||
breaks,
|
||||
|
|
|
@ -27,7 +27,7 @@ public class TestTargetProcessContainer
|
|||
}
|
||||
|
||||
public TestTargetProcess addProcess(int pid, AddressSpace space) {
|
||||
TestTargetProcess proc = new TestTargetProcess(this, pid, space);
|
||||
TestTargetProcess proc = getModel().newTestTargetProcess(this, pid, space);
|
||||
changeElements(List.of(), List.of(proc), Map.of(), "Test Process Added");
|
||||
return proc;
|
||||
}
|
||||
|
|
|
@ -41,14 +41,14 @@ public class TestTargetRegisterContainer
|
|||
if (!predicate.test(register)) {
|
||||
continue;
|
||||
}
|
||||
add.add(TestTargetRegister.fromLanguageRegister(this, register));
|
||||
add.add(getModel().newTestTargetRegister(this, register));
|
||||
}
|
||||
changeElements(List.of(), add, "Added registers from Ghidra language: " + language);
|
||||
return add;
|
||||
}
|
||||
|
||||
public TestTargetRegister addRegister(Register register) {
|
||||
TestTargetRegister tr = TestTargetRegister.fromLanguageRegister(this, register);
|
||||
TestTargetRegister tr = getModel().newTestTargetRegister(this, register);
|
||||
changeElements(List.of(), List.of(tr), "Added " + register + " from Ghidra language");
|
||||
return tr;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public class TestTargetSectionContainer
|
|||
}
|
||||
|
||||
public TestTargetSection addSection(String name, AddressRange range) {
|
||||
TestTargetSection section = new TestTargetSection(this, name, range);
|
||||
TestTargetSection section = getModel().newTestTargetSection(this, name, range);
|
||||
changeElements(List.of(), List.of(section), "Add test section: " + name);
|
||||
return section;
|
||||
}
|
||||
|
|
|
@ -42,10 +42,10 @@ public class TestTargetSession extends DefaultTargetModelRoot
|
|||
public TestTargetSession(TestDebuggerObjectModel model, String rootHint,
|
||||
TargetObjectSchema schema) {
|
||||
super(model, rootHint, schema);
|
||||
environment = new TestTargetEnvironment(this);
|
||||
processes = new TestTargetProcessContainer(this);
|
||||
interpreter = new TestTargetInterpreter(this);
|
||||
mimickJavaLauncher = new TestMimickJavaLauncher(this);
|
||||
environment = model.newTestTargetEnvironment(this);
|
||||
processes = model.newTestTargetProcessContainer(this);
|
||||
interpreter = model.newTestTargetInterpreter(this);
|
||||
mimickJavaLauncher = model.newTestMimickJavaLauncher(this);
|
||||
|
||||
changeAttributes(List.of(),
|
||||
List.of(environment, processes, interpreter, mimickJavaLauncher), Map.of(),
|
||||
|
|
|
@ -39,7 +39,8 @@ public class TestTargetStack extends DefaultTestTargetObject<TestTargetStackFram
|
|||
}
|
||||
|
||||
public TestTargetStackFrameNoRegisterBank pushFrameNoBank(Address pc) {
|
||||
return pushFrame(new TestTargetStackFrameNoRegisterBank(this, elements.size(), pc));
|
||||
return pushFrame(
|
||||
getModel().newTestTargetStackFrameNoRegisterBank(this, elements.size(), pc));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,7 +49,8 @@ public class TestTargetStack extends DefaultTestTargetObject<TestTargetStackFram
|
|||
* @return the "new" highest-indexed frame, into which old data was pushed
|
||||
*/
|
||||
public TestTargetStackFrameHasRegisterBank pushFrameHasBank(Address pc) {
|
||||
return pushFrame(new TestTargetStackFrameHasRegisterBank(this, elements.size(), pc));
|
||||
return pushFrame(
|
||||
getModel().newTestTargetStackFrameHasRegisterBank(this, elements.size(), pc));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,6 +59,7 @@ public class TestTargetStack extends DefaultTestTargetObject<TestTargetStackFram
|
|||
* @return the "new" highest-indexed frame, into which old data was pushed
|
||||
*/
|
||||
public TestTargetStackFrameIsRegisterBank pushFrameIsBank(Address pc) {
|
||||
return pushFrame(new TestTargetStackFrameIsRegisterBank(this, elements.size(), pc));
|
||||
return pushFrame(
|
||||
getModel().newTestTargetStackFrameIsRegisterBank(this, elements.size(), pc));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public class TestTargetStackFrameHasRegisterBank
|
|||
|
||||
public TestTargetStackFrameHasRegisterBank(TestTargetStack parent, int level, Address pc) {
|
||||
super(parent, PathUtils.makeKey(PathUtils.makeIndex(level)), "Frame");
|
||||
bank = new TestTargetRegisterBankInFrame(this);
|
||||
bank = getModel().newTestTargetRegisterBankInFrame(this);
|
||||
|
||||
changeAttributes(List.of(), Map.of(
|
||||
bank.getName(), bank, //
|
||||
|
|
|
@ -31,7 +31,8 @@ public class TestTargetSymbolNamespace
|
|||
|
||||
public TestTargetSymbol addSymbol(String name, Address address, long size,
|
||||
TargetDataType dataType) {
|
||||
TestTargetSymbol symbol = new TestTargetSymbol(this, name, address, size, dataType);
|
||||
TestTargetSymbol symbol =
|
||||
getModel().newTestTargetSymbol(this, name, address, size, dataType);
|
||||
changeElements(List.of(), List.of(symbol), "Added symbol " + name);
|
||||
return symbol;
|
||||
}
|
||||
|
|
|
@ -17,20 +17,26 @@ package ghidra.dbg.model;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ghidra.dbg.target.TargetExecutionStateful;
|
||||
import ghidra.dbg.target.TargetThread;
|
||||
import ghidra.dbg.util.CollectionUtils.Delta;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.dbg.target.*;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
|
||||
public class TestTargetThread
|
||||
extends DefaultTestTargetObject<TestTargetObject, TestTargetThreadContainer>
|
||||
implements TargetThread, TargetExecutionStateful {
|
||||
implements TargetThread, TargetExecutionStateful, TargetSteppable, TargetResumable,
|
||||
TargetInterruptible, TargetKillable {
|
||||
|
||||
public static final TargetStepKindSet SUPPORTED_KINDS =
|
||||
TargetStepKindSet.of(TargetStepKind.values());
|
||||
|
||||
public TestTargetThread(TestTargetThreadContainer parent, int tid) {
|
||||
super(parent, PathUtils.makeKey(PathUtils.makeIndex(tid)), "Thread");
|
||||
changeAttributes(List.of(), List.of(), Map.of(
|
||||
STATE_ATTRIBUTE_NAME, TargetExecutionState.STOPPED //
|
||||
), "Initialized");
|
||||
STATE_ATTRIBUTE_NAME, TargetExecutionState.STOPPED,
|
||||
SUPPORTED_STEP_KINDS_ATTRIBUTE_NAME, SUPPORTED_KINDS),
|
||||
"Initialized");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,7 +45,7 @@ public class TestTargetThread
|
|||
* @return the created register bank
|
||||
*/
|
||||
public TestTargetRegisterBankInThread addRegisterBank() {
|
||||
TestTargetRegisterBankInThread regs = new TestTargetRegisterBankInThread(this);
|
||||
TestTargetRegisterBankInThread regs = getModel().newTestTargetRegisterBankInThread(this);
|
||||
changeAttributes(List.of(), List.of(
|
||||
regs),
|
||||
Map.of(), "Add Test Register Bank");
|
||||
|
@ -47,7 +53,7 @@ public class TestTargetThread
|
|||
}
|
||||
|
||||
public TestTargetStack addStack() {
|
||||
TestTargetStack stack = new TestTargetStack(this);
|
||||
TestTargetStack stack = getModel().newTestTargetStack(this);
|
||||
changeAttributes(List.of(), List.of(
|
||||
stack),
|
||||
Map.of(), "Add Test Stack");
|
||||
|
@ -55,8 +61,28 @@ public class TestTargetThread
|
|||
}
|
||||
|
||||
public void setState(TargetExecutionState state) {
|
||||
Delta<?, ?> delta = changeAttributes(List.of(), List.of(), Map.of(
|
||||
STATE_ATTRIBUTE_NAME, state //
|
||||
), "Changed state");
|
||||
changeAttributes(List.of(), List.of(), Map.of(
|
||||
STATE_ATTRIBUTE_NAME, state),
|
||||
"Changed state");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> step(TargetStepKind kind) {
|
||||
return AsyncUtils.NIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> resume() {
|
||||
return AsyncUtils.NIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> interrupt() {
|
||||
return AsyncUtils.NIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> kill() {
|
||||
return AsyncUtils.NIL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,13 @@ import ghidra.dbg.target.TargetObject;
|
|||
|
||||
public class TestTargetThreadContainer
|
||||
extends DefaultTestTargetObject<TestTargetThread, TestTargetProcess> {
|
||||
|
||||
public TestTargetThreadContainer(TestTargetProcess parent) {
|
||||
super(parent, "Threads", "Threads");
|
||||
}
|
||||
|
||||
public TestTargetThread addThread(int tid) {
|
||||
TestTargetThread thread = new TestTargetThread(this, tid);
|
||||
TestTargetThread thread = getModel().newTestTargetThread(this, tid);
|
||||
changeElements(List.of(), List.of(thread), Map.of(), "Test Thread Added");
|
||||
return thread;
|
||||
}
|
||||
|
|
|
@ -21,9 +21,11 @@ import ghidra.dbg.attributes.TargetDataType;
|
|||
|
||||
public class TestTargetTypedefDataType
|
||||
extends TestTargetNamedDataType<TestTargetTypedefDef> {
|
||||
|
||||
public TestTargetTypedefDataType(TestTargetDataTypeNamespace parent, String name,
|
||||
TargetDataType dataType) {
|
||||
super(parent, name, NamedDataTypeKind.TYPEDEF, "TypedefType");
|
||||
changeElements(List.of(), List.of(new TestTargetTypedefDef(this, dataType)), "Initialized");
|
||||
changeElements(List.of(), List.of(getModel().newTestTargetTypedefDef(this, dataType)),
|
||||
"Initialized");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,7 +172,10 @@
|
|||
<schema name="Thread" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Thread" />
|
||||
<interface name="ExecutionStateful" />
|
||||
<!--interface name="Steppable" / -->
|
||||
<interface name="Steppable" />
|
||||
<interface name="Resumable" />
|
||||
<interface name="Interruptible" />
|
||||
<interface name="Killable" />
|
||||
<element schema="VOID" />
|
||||
<attribute name="_tid" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue