GP-2479: Remove register-specific space interfaces from Trace API

This commit is contained in:
Dan
2022-08-23 11:15:21 -04:00
parent 1eb2e71734
commit 0459d93508
146 changed files with 2030 additions and 1949 deletions
@@ -300,7 +300,7 @@ public class PopulateTraceLocal extends GhidraScript {
Collection<? extends TraceThread> liveThreads = threads.getLiveThreads(snap);
for (TraceThread thread : liveThreads) {
TraceMemoryRegisterSpace regspace = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regspace = memory.getMemoryRegisterSpace(thread, true);
ModelObject modelThread = modelThreadMap.get("0x" + thread.getName());
if (modelThread != null) {
Map<String, ModelObject> registers =
@@ -34,7 +34,7 @@ import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.program.util.DefaultLanguageService;
import ghidra.trace.database.DBTrace;
import ghidra.trace.model.Trace;
import ghidra.trace.model.listing.TraceCodeRegisterSpace;
import ghidra.trace.model.listing.TraceCodeSpace;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.symbol.TraceLabelSymbol;
import ghidra.trace.model.symbol.TraceNamespaceSymbol;
@@ -149,13 +149,13 @@ public class PopulateDemoTrace extends GhidraScript {
* Fields to store the handle to the first (main) thread and its registers
*/
private TraceThread thread1;
private TraceMemoryRegisterSpace regs1;
private TraceMemorySpace regs1;
/**
* Fields to store the handle to the second (cloned) thread and its registers
*/
private TraceThread thread2;
private TraceMemoryRegisterSpace regs2;
private TraceMemorySpace regs2;
/**
* Create an address in the processor's (x86_64) default space.
@@ -195,7 +195,7 @@ public class PopulateDemoTrace extends GhidraScript {
* @param regs the register space for a given thread
* @param ins the instructions
*/
protected void putRIP(long tick, TraceMemoryRegisterSpace regs, Instruction ins) {
protected void putRIP(long tick, TraceMemorySpace regs, Instruction ins) {
regs.setValue(tick,
new RegisterValue(reg("RIP"), ins.getAddress().getOffsetAsBigInteger()));
}
@@ -224,7 +224,7 @@ public class PopulateDemoTrace extends GhidraScript {
// NOTE: This is compensating for a TODO in the memory and code managers
// TODO: Consider convenience methods TraceThread#getMemorySpace(boolean), etc
TraceMemoryRegisterSpace mem =
TraceMemorySpace mem =
thread.getTrace().getMemoryManager().getMemoryRegisterSpace(thread, true);
// First check if the value was set at all
if (mem.getState(tick, reg) != TraceMemoryState.KNOWN) {
@@ -237,7 +237,7 @@ public class PopulateDemoTrace extends GhidraScript {
return;
}
TraceCodeRegisterSpace code =
TraceCodeSpace code =
thread.getTrace().getCodeManager().getCodeRegisterSpace(thread, true);
code.definedUnits().clear(Range.atLeast(tick), reg, TaskMonitor.DUMMY);
code.definedData().create(Range.atLeast(tick), reg, PointerDataType.dataType);
@@ -22,7 +22,7 @@ import ghidra.program.model.lang.Register;
import ghidra.program.model.lang.RegisterValue;
import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.thread.TraceThread;
@@ -58,7 +58,7 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec {
if (!thread.getLifespan().contains(snap)) {
return null;
}
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
trace.getMemoryManager().getMemoryRegisterSpace(thread, frame, false);
if (regs == null) {
return null;
@@ -71,7 +71,7 @@ import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.trace.model.*;
import ghidra.trace.model.Trace.*;
import ghidra.trace.model.listing.*;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.model.thread.TraceThread;
@@ -281,7 +281,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
}
private void refreshRange(AddressRange range) {
TraceMemoryRegisterSpace space = getRegisterMemorySpace(false);
TraceMemorySpace space = getRegisterMemorySpace(false);
// ... If I got an event for it, it ought to exist.
assert space != null;
@@ -857,7 +857,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
}
BigInteger getRegisterValue(Register register) {
TraceMemoryRegisterSpace regs = getRegisterMemorySpace(false);
TraceMemorySpace regs = getRegisterMemorySpace(false);
if (regs == null) {
return BigInteger.ZERO;
}
@@ -901,7 +901,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
}
private RegisterValue combineWithTraceBaseRegisterValue(RegisterValue rv) {
TraceMemoryRegisterSpace regs = getRegisterMemorySpace(false);
TraceMemorySpace regs = getRegisterMemorySpace(false);
long snap = current.getViewSnap();
return TraceRegisterUtils.combineWithTraceBaseRegisterValue(rv, snap, regs, true);
}
@@ -914,7 +914,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
void writeRegisterDataType(Register register, DataType dataType) {
try (UndoableTransaction tid =
UndoableTransaction.start(current.getTrace(), "Edit Register Type")) {
TraceCodeRegisterSpace space = getRegisterMemorySpace(true).getCodeSpace(true);
TraceCodeSpace space = getRegisterMemorySpace(true).getCodeSpace(true);
long snap = current.getViewSnap();
space.definedUnits().clear(Range.closed(snap, snap), register, TaskMonitor.DUMMY);
if (dataType != null) {
@@ -927,7 +927,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
}
TraceData getRegisterData(Register register) {
TraceCodeRegisterSpace space = getRegisterCodeSpace(false);
TraceCodeSpace space = getRegisterCodeSpace(false);
if (space == null) {
return null;
}
@@ -985,7 +985,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
viewKnown = null;
return;
}
TraceMemoryRegisterSpace regs = getRegisterMemorySpace(false);
TraceMemorySpace regs = getRegisterMemorySpace(false);
TraceProgramView view = current.getView();
if (regs == null || view == null) {
viewKnown = null;
@@ -1014,8 +1014,8 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
if (!isRegisterKnown(register)) {
return false;
}
TraceMemoryRegisterSpace curSpace = getRegisterMemorySpace(current, false);
TraceMemoryRegisterSpace prevSpace = getRegisterMemorySpace(previous, false);
TraceMemorySpace curSpace = getRegisterMemorySpace(current, false);
TraceMemorySpace prevSpace = getRegisterMemorySpace(previous, false);
if (prevSpace == null) {
return false;
}
@@ -1104,7 +1104,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
return viewKnown;
}
protected static TraceMemoryRegisterSpace getRegisterMemorySpace(DebuggerCoordinates coords,
protected static TraceMemorySpace getRegisterMemorySpace(DebuggerCoordinates coords,
boolean createIfAbsent) {
TraceThread thread = coords.getThread();
if (thread == null) {
@@ -1115,11 +1115,11 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
.getMemoryRegisterSpace(thread, coords.getFrame(), createIfAbsent);
}
protected TraceMemoryRegisterSpace getRegisterMemorySpace(boolean createIfAbsent) {
protected TraceMemorySpace getRegisterMemorySpace(boolean createIfAbsent) {
return getRegisterMemorySpace(current, createIfAbsent);
}
protected TraceCodeRegisterSpace getRegisterCodeSpace(boolean createIfAbsent) {
protected TraceCodeSpace getRegisterCodeSpace(boolean createIfAbsent) {
TraceThread curThread = current.getThread();
if (curThread == null) {
return null;
@@ -1132,7 +1132,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
protected Set<Register> collectBaseRegistersWithKnownValues(TraceThread thread) {
// TODO: Other registers may acquire known values.
// TODO: How to best alert the user? Just add to view?
TraceMemoryRegisterSpace mem =
TraceMemorySpace mem =
thread.getTrace().getMemoryManager().getMemoryRegisterSpace(thread, false);
Set<Register> result = new LinkedHashSet<>();
if (mem == null) {
@@ -45,7 +45,7 @@ import ghidra.program.model.listing.Program;
import ghidra.trace.model.*;
import ghidra.trace.model.Trace.TraceMemoryBytesChangeType;
import ghidra.trace.model.Trace.TraceStackChangeType;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.thread.TraceThread;
@@ -194,7 +194,7 @@ public class DebuggerStackProvider extends ComponentProviderAdapter {
if (!TraceRegisterUtils.rangeForRegister(pc).intersects(range.getRange())) {
return;
}
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
trace.getMemoryManager().getMemoryRegisterSpace(curThread, false);
RegisterValue value = regs.getViewValue(current.getViewSnap(), pc);
Address address = trace.getBaseLanguage()
@@ -427,7 +427,7 @@ public class DebuggerStackProvider extends ComponentProviderAdapter {
currentStack = null;
Trace curTrace = current.getTrace();
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
curTrace.getMemoryManager().getMemoryRegisterSpace(current.getThread(), false);
if (regs == null) {
contextChanged();
@@ -24,7 +24,7 @@ import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.lang.*;
import ghidra.trace.model.Trace;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.Msg;
@@ -78,8 +78,7 @@ public class ArmDisassemblyInject implements DisassemblyInject {
return;
}
TraceMemoryRegisterSpace regs =
trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
TraceMemorySpace regs = trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
/**
* Some variants (particularly Cortex-M) are missing cpsr. This seems to indicate it only
* supports THUMB. There is an epsr (xpsr in gdb), but we don't have it in our models, and
@@ -216,7 +216,7 @@ public enum ProgramEmulationUtils {
*/
public static void initializeRegisters(Trace trace, long snap, TraceThread thread,
Program program, Address tracePc, Address programPc, TraceMemoryRegion stack) {
TraceMemoryRegisterSpace space =
TraceMemorySpace space =
trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
if (program != null) {
ProgramContext ctx = program.getProgramContext();
@@ -266,11 +266,11 @@ public class DefaultThreadRecorder implements ManagedThreadRecorder {
TimedMsg.debug(this, "Reg values changed: " + updates.keySet());
recorder.parTx.execute("Registers " + path + " changed", () -> {
TraceCodeManager codeManager = trace.getCodeManager();
TraceCodeRegisterSpace codeRegisterSpace =
TraceCodeSpace codeRegisterSpace =
codeManager.getCodeRegisterSpace(traceThread, false);
TraceDefinedDataRegisterView definedData =
TraceDefinedDataView definedData =
codeRegisterSpace == null ? null : codeRegisterSpace.definedData();
TraceMemoryRegisterSpace regSpace =
TraceMemorySpace regSpace =
memoryManager.getMemoryRegisterSpace(traceThread, frameLevel, true);
for (Entry<String, byte[]> ent : updates.entrySet()) {
RegisterValue rv = regMapper.targetToTrace(ent.getKey(), ent.getValue());
@@ -304,11 +304,11 @@ public class DefaultThreadRecorder implements ManagedThreadRecorder {
//TimedMsg.info(this, "Register value changed: " + targetRegister);
recorder.parTx.execute("Register " + path + " changed", () -> {
TraceCodeManager codeManager = trace.getCodeManager();
TraceCodeRegisterSpace codeRegisterSpace =
TraceCodeSpace codeRegisterSpace =
codeManager.getCodeRegisterSpace(traceThread, false);
TraceDefinedDataRegisterView definedData =
TraceDefinedDataView definedData =
codeRegisterSpace == null ? null : codeRegisterSpace.definedData();
TraceMemoryRegisterSpace regSpace =
TraceMemorySpace regSpace =
memoryManager.getMemoryRegisterSpace(traceThread, frameLevel, true);
String key = targetRegister.getName();
if (PathUtils.isIndex(key)) {
@@ -337,7 +337,7 @@ public class DefaultThreadRecorder implements ManagedThreadRecorder {
String path = bank.getJoinedPath(".");
recorder.parTx.execute("Registers invalidated: " + path, () -> {
TraceMemoryRegisterSpace regSpace =
TraceMemorySpace regSpace =
memoryManager.getMemoryRegisterSpace(traceThread, frameLevel, false);
if (regSpace == null) {
return;
@@ -227,8 +227,7 @@ public class DisassembleAtPcDebuggerBot implements DebuggerBot {
TraceData pcUnit = null;
try (UndoableTransaction tid =
UndoableTransaction.start(trace, "Disassemble: PC is code pointer")) {
TraceCodeRegisterSpace regCode =
codeManager.getCodeRegisterSpace(thread, frameLevel, true);
TraceCodeSpace regCode = codeManager.getCodeRegisterSpace(thread, frameLevel, true);
try {
pcUnit = regCode.definedData()
.create(Range.atLeast(pcSnap), pc, PointerDataType.dataType);
@@ -32,7 +32,7 @@ import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.modules.TraceModule;
import ghidra.trace.model.modules.TraceSection;
import ghidra.trace.model.stack.TraceStackFrame;
@@ -365,7 +365,7 @@ public interface TraceRecorder {
RegisterValue rv = new RegisterValue(register,
Utils.bytesToBigInteger(data, data.length, lang.isBigEndian(), false));
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
getTrace().getMemoryManager().getMemoryRegisterSpace(thread, frameLevel, false);
rv = TraceRegisterUtils.combineWithTraceBaseRegisterValue(rv, getSnap(), regs, true);
return writeThreadRegisters(thread, frameLevel, Map.of(rv.getRegister(), rv));
@@ -48,7 +48,7 @@ import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceLocation;
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
import ghidra.trace.model.memory.TraceMemoryOperations;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.schedule.TraceSchedule;
@@ -947,7 +947,7 @@ public interface FlatDebuggerAPI {
catch (InterruptedException | ExecutionException | TimeoutException e) {
return null;
}
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
thread.getTrace().getMemoryManager().getMemoryRegisterSpace(thread, frame, false);
if (regs == null) {
return registers.stream().map(RegisterValue::new).collect(Collectors.toList());
@@ -31,7 +31,7 @@ import ghidra.program.model.symbol.SourceType;
import ghidra.test.ToyProgramBuilder;
import ghidra.trace.database.ToyDBTraceBuilder;
import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.symbol.*;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.database.UndoableTransaction;
@@ -110,7 +110,7 @@ public class DebuggerListingPluginScreenShots extends GhidraScreenShotGenerator
TraceThread thread = tb.getOrAddThread("[1]", snap);
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regs.setValue(snap, new RegisterValue(tb.language.getProgramCounter(),
childLabel.getAddress().getOffsetAsBigInteger()));
@@ -31,7 +31,7 @@ import ghidra.program.model.symbol.SourceType;
import ghidra.test.ToyProgramBuilder;
import ghidra.trace.database.ToyDBTraceBuilder;
import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.symbol.*;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.database.UndoableTransaction;
@@ -114,7 +114,7 @@ public class DebuggerMemoryBytesPluginScreenShots extends GhidraScreenShotGenera
TraceThread thread = tb.getOrAddThread("[1]", snap);
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regs.setValue(snap, new RegisterValue(tb.language.getProgramCounter(),
childLabel.getAddress().getOffsetAsBigInteger()));
@@ -28,7 +28,7 @@ import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.RegisterValue;
import ghidra.test.ToyProgramBuilder;
import ghidra.trace.database.ToyDBTraceBuilder;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.database.UndoableTransaction;
import help.screenshot.GhidraScreenShotGenerator;
@@ -62,7 +62,7 @@ public class DebuggerRegistersPluginScreenShots extends GhidraScreenShotGenerato
long snap1 = tb.trace.getTimeManager().createSnapshot("Second").getKey();
TraceThread thread = tb.getOrAddThread("[1]", snap0);
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
Language lang = tb.trace.getBaseLanguage();
regs.setValue(snap0,
@@ -56,7 +56,7 @@ import ghidra.program.util.ProgramSelection;
import ghidra.trace.database.listing.DBTraceInstruction;
import ghidra.trace.database.listing.DBTraceInstructionsMemoryView;
import ghidra.trace.database.memory.DBTraceMemoryManager;
import ghidra.trace.database.memory.DBTraceMemoryRegisterSpace;
import ghidra.trace.database.memory.DBTraceMemorySpace;
import ghidra.trace.database.program.DBTraceVariableSnapProgramView;
import ghidra.trace.database.target.DBTraceObject;
import ghidra.trace.database.target.DBTraceObjectManager;
@@ -225,7 +225,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
TraceThread thread;
try (UndoableTransaction tid = tb.startTransaction()) {
thread = tb.getOrAddThread("Threads[0]", 0);
DBTraceMemoryRegisterSpace regs =
DBTraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(tb.language.getRegister("cpsr"), BigInteger.ZERO));
}
@@ -259,7 +259,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
TraceThread thread;
try (UndoableTransaction tid = tb.startTransaction()) {
thread = tb.getOrAddThread("Threads[0]", 0);
DBTraceMemoryRegisterSpace regs =
DBTraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regs.setValue(0,
new RegisterValue(tb.language.getRegister("cpsr"), BigInteger.ONE.shiftLeft(5)));
@@ -68,7 +68,7 @@ import ghidra.test.TestEnv;
import ghidra.trace.database.ToyDBTraceBuilder;
import ghidra.trace.model.*;
import ghidra.trace.model.Trace.TraceMemoryBytesChangeType;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.TraceAddressSpace;
import ghidra.util.InvalidNameException;
@@ -750,7 +750,7 @@ public abstract class AbstractGhidraHeadedDebuggerGUITest
if (space.getThread() != traceThread) {
return;
}
TraceMemoryRegisterSpace regSpace =
TraceMemorySpace regSpace =
trace.getMemoryManager().getMemoryRegisterSpace(traceThread, false);
assertNotNull(regSpace);
for (Map.Entry<String, byte[]> ent : values.entrySet()) {
@@ -182,7 +182,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
// NOTE: PC-tracking should be the default for the main dynamic listing
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(tb.trace);
@@ -208,7 +208,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
// NOTE: PC-tracking should be the default for the main dynamic listing
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
regs.setValue(1, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(tb.trace);
@@ -237,9 +237,9 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
// NOTE: PC-tracking should be the default for the main dynamic listing
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
TraceMemorySpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
regs1.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
TraceMemoryRegisterSpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
TraceMemorySpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
regs2.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(tb.trace);
@@ -282,9 +282,9 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
// NOTE: PC-tracking should be the default for the main dynamic listing
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
TraceMemorySpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
regs1.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
TraceMemoryRegisterSpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
TraceMemorySpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
regs2.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(tb.trace);
@@ -322,7 +322,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
assertEquals(tb.trace.getProgramView(), listingProvider.getProgram());
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
Register sp = tb.trace.getBaseCompilerSpec().getStackPointer();
regs.setValue(0, new RegisterValue(sp, BigInteger.valueOf(0x01fff800)));
}
@@ -356,7 +356,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
t1 = b1.getOrAddThread("Thread1", 0);
Register pc = b1.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(t1, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t1, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(b1.trace);
@@ -368,7 +368,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
t2 = b2.getOrAddThread("Thread2", 0);
Register pc = b2.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(t2, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t2, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(b1.trace);
@@ -412,7 +412,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
t1 = b1.getOrAddThread("Thread1", 0);
Register pc = b1.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(t1, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t1, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(b1.trace);
@@ -424,7 +424,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
t2 = b2.getOrAddThread("Thread2", 0);
Register pc = b2.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(t2, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t2, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(b1.trace);
@@ -505,7 +505,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
thread = tb.getOrAddThread("Thread1", 0);
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
regs.setValue(1, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForProgram(program);
@@ -582,7 +582,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
thread = tb.getOrAddThread("Thread1", 0);
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(tb.trace);
@@ -618,7 +618,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
thread = tb.getOrAddThread("Thread1", 0);
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
regs.setValue(1, new RegisterValue(pc, BigInteger.valueOf(0x00408765)));
}
@@ -823,7 +823,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
mm.addRegion("exe:.text", Range.atLeast(0L), tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
Register r0 = tb.language.getRegister("r0");
regs.setValue(0, new RegisterValue(r0, new BigInteger("00401234", 16)));
mm.putBytes(0, tb.addr(0x00401234), tb.buf(0x00, 0x40, 0x43, 0x21));
@@ -863,7 +863,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
mm.addRegion("[stack]", Range.atLeast(0L), tb.range(0x1f000000, 0x1fffffff),
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
Register pc = tb.language.getProgramCounter();
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
Register sp = tb.trace.getBaseCompilerSpec().getStackPointer();
@@ -1009,9 +1009,9 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
// NOTE: PC-tracking should be the default for the main dynamic listing
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
TraceMemorySpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
regs1.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
TraceMemoryRegisterSpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
TraceMemorySpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
regs2.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(tb.trace);
@@ -1309,9 +1309,9 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread1 = tb.getOrAddThread("Thread 1", 0);
thread2 = tb.getOrAddThread("Thread 2", 0);
TraceMemoryRegisterSpace regs1 = mm.getMemoryRegisterSpace(thread1, true);
TraceMemorySpace regs1 = mm.getMemoryRegisterSpace(thread1, true);
regs1.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
TraceMemoryRegisterSpace regs2 = mm.getMemoryRegisterSpace(thread2, true);
TraceMemorySpace regs2 = mm.getMemoryRegisterSpace(thread2, true);
regs2.setValue(0, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
waitForDomainObject(tb.trace);
@@ -1338,7 +1338,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
mm.addRegion("exe:.text", Range.atLeast(0L), tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
regs.setValue(1, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
@@ -1394,7 +1394,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
mm.addRegion("exe:.text", Range.atLeast(0L), tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
}
waitForDomainObject(tb.trace);
@@ -1404,7 +1404,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
assertEquals(tb.addr(0x00401234), listingProvider.getLocation().getAddress());
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
waitForDomainObject(tb.trace);
@@ -1424,7 +1424,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
mm.addRegion("exe:.text", Range.atLeast(0L), tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
DBTraceStackManager sm = tb.trace.getStackManager();
@@ -1438,7 +1438,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
assertEquals(tb.addr(0x00401234), listingProvider.getLocation().getAddress());
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
waitForDomainObject(tb.trace);
@@ -158,7 +158,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
// NOTE: PC-tracking should be the default for the main bytes viewer
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(tb.trace);
@@ -184,7 +184,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
// NOTE: PC-tracking should be the default for the main bytes viewer
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
regs.setValue(1, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(tb.trace);
@@ -214,9 +214,9 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
// NOTE: PC-tracking should be the default for the main bytes viewer
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
TraceMemorySpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
regs1.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
TraceMemoryRegisterSpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
TraceMemorySpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
regs2.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(tb.trace);
@@ -259,9 +259,9 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
// NOTE: PC-tracking should be the default for the main bytes viewer
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
TraceMemorySpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
regs1.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
TraceMemoryRegisterSpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
TraceMemorySpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
regs2.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(tb.trace);
@@ -299,7 +299,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
assertEquals(tb.trace.getProgramView(), memBytesProvider.getProgram());
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
Register sp = tb.trace.getBaseCompilerSpec().getStackPointer();
regs.setValue(0, new RegisterValue(sp, BigInteger.valueOf(0x01fff800)));
}
@@ -332,7 +332,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
t1 = b1.getOrAddThread("Thread1", 0);
Register pc = b1.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(t1, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t1, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(b1.trace);
@@ -344,7 +344,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
t2 = b2.getOrAddThread("Thread2", 0);
Register pc = b2.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(t2, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t2, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(b1.trace);
@@ -383,7 +383,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
t1 = b1.getOrAddThread("Thread1", 0);
Register pc = b1.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(t1, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t1, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(b1.trace);
@@ -395,7 +395,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
t2 = b2.getOrAddThread("Thread2", 0);
Register pc = b2.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(t2, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t2, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(b1.trace);
@@ -456,7 +456,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
thread = tb.getOrAddThread("Thread1", 0);
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs = memory.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
}
waitForDomainObject(tb.trace);
@@ -616,7 +616,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
mm.addRegion("exe:.text", Range.atLeast(0L), tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
Register r0 = tb.language.getRegister("r0");
regs.setValue(0, new RegisterValue(r0, new BigInteger("00401234", 16)));
mm.putBytes(0, tb.addr(0x00401234), tb.buf(0x00, 0x40, 0x43, 0x21));
@@ -656,7 +656,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
mm.addRegion("[stack]", Range.atLeast(0L), tb.range(0x1f000000, 0x1fffffff),
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
Register pc = tb.language.getProgramCounter();
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
Register sp = tb.trace.getBaseCompilerSpec().getStackPointer();
@@ -708,9 +708,9 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
// NOTE: PC-tracking should be the default for the main dynamic listing
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
TraceMemoryRegisterSpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
TraceMemorySpace regs1 = memory.getMemoryRegisterSpace(thread1, true);
regs1.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
TraceMemoryRegisterSpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
TraceMemorySpace regs2 = memory.getMemoryRegisterSpace(thread2, true);
regs2.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00405678)));
}
waitForDomainObject(tb.trace);
@@ -911,9 +911,9 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread1 = tb.getOrAddThread("Thread 1", 0);
thread2 = tb.getOrAddThread("Thread 2", 0);
TraceMemoryRegisterSpace regs1 = mm.getMemoryRegisterSpace(thread1, true);
TraceMemorySpace regs1 = mm.getMemoryRegisterSpace(thread1, true);
regs1.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
TraceMemoryRegisterSpace regs2 = mm.getMemoryRegisterSpace(thread2, true);
TraceMemorySpace regs2 = mm.getMemoryRegisterSpace(thread2, true);
regs2.setValue(0, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
waitForDomainObject(tb.trace);
@@ -940,7 +940,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
mm.addRegion("exe:.text", Range.atLeast(0L), tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
regs.setValue(1, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
@@ -996,7 +996,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
mm.addRegion("exe:.text", Range.atLeast(0L), tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
}
waitForDomainObject(tb.trace);
@@ -1006,7 +1006,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
assertEquals(tb.addr(0x00401234), memBytesProvider.getLocation().getAddress());
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
waitForDomainObject(tb.trace);
@@ -1026,7 +1026,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
mm.addRegion("exe:.text", Range.atLeast(0L), tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread = tb.getOrAddThread("Thread 1", 0);
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
DBTraceStackManager sm = tb.trace.getStackManager();
@@ -1040,7 +1040,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
assertEquals(tb.addr(0x00401234), memBytesProvider.getLocation().getAddress());
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regs = mm.getMemoryRegisterSpace(thread, true);
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
waitForDomainObject(tb.trace);
@@ -46,10 +46,10 @@ import ghidra.program.model.lang.Register;
import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.trace.database.DBTraceUtils;
import ghidra.trace.database.ToyDBTraceBuilder;
import ghidra.trace.database.listing.DBTraceCodeRegisterSpace;
import ghidra.trace.database.listing.DBTraceCodeSpace;
import ghidra.trace.model.listing.*;
import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.database.UndoableTransaction;
import ghidra.util.exception.DuplicateNameException;
@@ -122,7 +122,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
}
protected void addRegisterValues(TraceThread thread, UndoableTransaction tid) {
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regVals.putBytes(0, pc, tb.buf(0, 0, 0, 0, 0, 0x40, 0, 0));
regVals.putBytes(0, sp, tb.buf(0x1f, 0, 0, 0, 0, 0, 0, 0));
@@ -131,7 +131,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
protected void addRegisterTypes(TraceThread thread, UndoableTransaction tid)
throws CodeUnitInsertionException {
TraceCodeRegisterSpace regCode =
TraceCodeSpace regCode =
tb.trace.getCodeManager().getCodeRegisterSpace(thread, true);
regCode.definedData().create(Range.atLeast(0L), pc, PointerDataType.dataType);
// TODO: Pointer needs to be to ram, not register space
@@ -384,7 +384,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
addRegisterValues(thread);
waitForDomainObject(tb.trace);
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
RegisterRow row = findRegisterRow(r0);
@@ -422,7 +422,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
addRegisterValues(thread);
waitForDomainObject(tb.trace);
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
RegisterRow row = findRegisterRow(r0);
@@ -456,7 +456,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
row.setDataType(PointerDataType.dataType);
waitForSwing();
DBTraceCodeRegisterSpace regCode =
DBTraceCodeSpace regCode =
tb.trace.getCodeManager().getCodeRegisterSpace(thread, false);
assertNotNull(regCode);
TraceData data = regCode.data().getForRegister(0L, pc);
@@ -478,7 +478,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
row.setDataType(LongLongDataType.dataType);
waitForSwing();
DBTraceCodeRegisterSpace regCode =
DBTraceCodeSpace regCode =
tb.trace.getCodeManager().getCodeRegisterSpace(thread, false);
assertNotNull(regCode);
TraceData data = regCode.data().getForRegister(0L, pc);
@@ -514,7 +514,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
rowH.setDataType(SignedDWordDataType.dataType);
waitForSwing();
DBTraceCodeRegisterSpace regCode =
DBTraceCodeSpace regCode =
tb.trace.getCodeManager().getCodeRegisterSpace(thread, false);
assertNotNull(regCode);
// It's two units, not a struct with two components
@@ -621,9 +621,9 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
assertR0RowValuePopulated();
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
TraceCodeRegisterSpace regCode =
TraceCodeSpace regCode =
tb.trace.getCodeManager().getCodeRegisterSpace(thread, true);
regVals.putBytes(1, r0, tb.buf(1, 1, 2, 2, 3, 3, 4, 4));
regCode.definedData().create(Range.atLeast(1L), r0, r0Struct);
@@ -649,7 +649,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
assertR0RowTypePopulated();
try (UndoableTransaction tid = tb.startTransaction()) {
TraceCodeRegisterSpace regCode =
TraceCodeSpace regCode =
tb.trace.getCodeManager().getCodeRegisterSpace(thread, true);
TraceCodeUnit code = regCode.codeUnits().getContaining(1, r0);
code.setEndSnap(0);
@@ -679,7 +679,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
assertR0RowTypePopulated();
try (UndoableTransaction tid = tb.startTransaction()) {
TraceCodeRegisterSpace regCode =
TraceCodeSpace regCode =
tb.trace.getCodeManager().getCodeRegisterSpace(thread, true);
TraceCodeUnit code = regCode.codeUnits().getContaining(1, r0);
code.delete();
@@ -890,9 +890,9 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
assertR0RowTypePopulated();
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
TraceCodeRegisterSpace regCode =
TraceCodeSpace regCode =
tb.trace.getCodeManager().getCodeRegisterSpace(thread, true);
regVals.putBytes(10, r0, tb.buf(0, 0, 0, 0, 0, 0, 0, 0));
// NB. the manager should have split the data unit at the value change
@@ -932,11 +932,11 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
assertR0RowTypePopulated();
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, 1, true);
regVals.putBytes(0, pc, tb.buf(0, 0, 0, 0, 0, 0x50, 0, 0));
TraceCodeRegisterSpace regCode =
TraceCodeSpace regCode =
tb.trace.getCodeManager().getCodeRegisterSpace(thread, 1, true);
regCode.definedData().create(Range.atLeast(0L), pc, QWordDataType.dataType);
}
@@ -40,7 +40,7 @@ import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.DefaultTraceLocation;
import ghidra.trace.model.TraceLocation;
import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.thread.TraceThread;
@@ -73,7 +73,7 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerGUITe
protected void addRegVals(TraceThread thread) {
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(pc, new BigInteger("00400123", 16)));
}
@@ -119,7 +119,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
private void setRegisterValues(TraceThread thread) {
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regVals.setValue(0, new RegisterValue(r0, BigInteger.valueOf(0x00400000)));
}
@@ -318,7 +318,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
waitForSwing();
// Verify no target read has occurred yet
TraceMemoryRegisterSpace regs =
TraceMemorySpace regs =
trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
if (regs != null) {
assertEquals(BigInteger.ZERO, regs.getValue(0, r0).getUnsignedValue());
@@ -402,7 +402,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
@Test
public void testEditRegisterEmu() {
WatchRow row = prepareTestEditEmu("r0");
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
row.setRawValueString("0x1234");
@@ -433,7 +433,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
waitForSwing();
assertTrue(row.isValueEditable());
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
row.setValueString("1234");
@@ -748,7 +748,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
.createLabel(tb.addr(0x00601234), "my_symbol", SourceType.USER_DEFINED);
}
try (UndoableTransaction tid = tb.startTransaction()) {
TraceMemoryRegisterSpace regVals =
TraceMemorySpace regVals =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regVals.setValue(0, new RegisterValue(r0, BigInteger.valueOf(0x55751234)));
}
@@ -37,7 +37,7 @@ import ghidra.pcode.exec.DebuggerPcodeUtils;
import ghidra.program.model.lang.*;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.trace.database.DBTraceUtils;
import ghidra.trace.database.memory.DBTraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.schedule.TraceSchedule;
import ghidra.util.database.UndoableTransaction;
@@ -366,8 +366,8 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
StateEditor editor = editingService.createStateEditor(tb.trace);
waitOn(editor.setRegister(rv1234));
waitForPass(() -> {
DBTraceMemoryRegisterSpace regs = tb.trace.getMemoryManager()
.getMemoryRegisterSpace(thread, false);
TraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
assertNotNull(regs);
RegisterValue value = regs.getValue(traceManager.getCurrentSnap(), r0);
assertEquals(rv1234, value);
@@ -36,7 +36,7 @@ import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.Trace;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.schedule.TraceSchedule;
import ghidra.util.database.UndoableTransaction;
@@ -89,8 +89,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerGU
assertNotNull(trace);
TraceThread thread = Unique.assertOne(trace.getThreadManager().getAllThreads());
TraceMemoryRegisterSpace regs =
trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
TraceMemorySpace regs = trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
assertEquals(new BigInteger("00400000", 16),
regs.getViewValue(0, regPC).getUnsignedValue());
assertEquals(new BigInteger("0000", 16), regs.getViewValue(0, regR0).getUnsignedValue());
@@ -146,8 +145,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerGU
assertNotNull(trace);
TraceThread thread = Unique.assertOne(trace.getThreadManager().getAllThreads());
TraceMemoryRegisterSpace regs =
trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
TraceMemorySpace regs = trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
assertEquals(new BigInteger("00000400", 16),
regs.getViewValue(0, regPC).getUnsignedValue());
assertEquals(new BigInteger("0000", 16), regs.getViewValue(0, regR0).getUnsignedValue());
@@ -205,8 +203,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerGU
assertNotNull(trace);
TraceThread thread = Unique.assertOne(trace.getThreadManager().getAllThreads());
TraceMemoryRegisterSpace regs =
trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
TraceMemorySpace regs = trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
assertEquals(new BigInteger("000100", 16),
regs.getViewValue(0, regPC).getUnsignedValue());
assertEquals(new BigInteger("0000", 16), regs.getViewValue(0, regW0).getUnsignedValue());
@@ -36,7 +36,7 @@ import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.Register;
import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.listing.TraceCodeRegisterSpace;
import ghidra.trace.model.listing.TraceCodeSpace;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.database.UndoableTransaction;
@@ -75,7 +75,7 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
});
}
protected TraceMemoryRegisterSpace createRegSpace(TraceThread thread) {
protected TraceMemorySpace createRegSpace(TraceThread thread) {
try (UndoableTransaction tid =
UndoableTransaction.start(thread.getTrace(), "Create register space")) {
return thread.getTrace().getMemoryManager().getMemoryRegisterSpace(thread, true);
@@ -105,7 +105,7 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
Register r1 = lang.getRegister("r1");
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
//TraceThread thread = recorder.getTraceThread(mb.testThread1);
TraceMemoryRegisterSpace rs = createRegSpace(thread);
TraceMemorySpace rs = createRegSpace(thread);
mb.testProcess1.regs.addRegistersFromLanguage(getToyBE64Language(),
Register::isBaseRegister);
TestTargetRegisterBankInThread regs = mb.testThread1.addRegisterBank();
@@ -138,13 +138,13 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
Register pc = lang.getRegister("pc");
Register sp = lang.getRegister("sp");
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
TraceMemoryRegisterSpace rs = createRegSpace(thread);
TraceMemorySpace rs = createRegSpace(thread);
mb.testProcess1.addRegion("bin:.text", mb.rng(0x55550000, 0x5555ffff), "rx");
mb.testProcess1.regs.addRegistersFromLanguage(getToyBE64Language(),
r -> r.isBaseRegister() && r != pc && r != sp);
TestTargetRegisterBankInThread regs = mb.testThread1.addRegisterBank();
try (UndoableTransaction tid = UndoableTransaction.start(trace, "Add PC type")) {
TraceCodeRegisterSpace code = trace.getCodeManager().getCodeRegisterSpace(thread, true);
TraceCodeSpace code = trace.getCodeManager().getCodeRegisterSpace(thread, true);
code.definedData().create(Range.atLeast(0L), pc, PointerDataType.dataType);
}
@@ -187,13 +187,13 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
Register pc = lang.getRegister("pc");
Register sp = lang.getRegister("sp");
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
TraceMemoryRegisterSpace rs = createRegSpace(thread);
TraceMemorySpace rs = createRegSpace(thread);
mb.testProcess1.addRegion("[stack]", mb.rng(0x22220000, 0x2222ffff), "rw");
mb.testProcess1.regs.addRegistersFromLanguage(getToyBE64Language(),
r -> r.isBaseRegister() && r != pc && r != sp);
TestTargetRegisterBankInThread regs = mb.testThread1.addRegisterBank();
try (UndoableTransaction tid = UndoableTransaction.start(trace, "Add SP type")) {
TraceCodeRegisterSpace code = trace.getCodeManager().getCodeRegisterSpace(thread, true);
TraceCodeSpace code = trace.getCodeManager().getCodeRegisterSpace(thread, true);
code.definedData().create(Range.atLeast(0L), sp, PointerDataType.dataType);
}
@@ -242,7 +242,7 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
//waitForCondition(() -> registerMapped(recorder, thread, pc));
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
try (UndoableTransaction tid = UndoableTransaction.start(trace, "Add PC type")) {
TraceCodeRegisterSpace code = trace.getCodeManager().getCodeRegisterSpace(thread, true);
TraceCodeSpace code = trace.getCodeManager().getCodeRegisterSpace(thread, true);
code.definedData().create(Range.atLeast(0L), pc, PointerDataType.dataType);
}
regs.writeRegister("pc", tb.arr(0x55, 0x55, 0x02, 0x22));
@@ -59,7 +59,7 @@ import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.*;
import ghidra.program.model.listing.Program;
import ghidra.trace.database.memory.DBTraceMemoryManager;
import ghidra.trace.database.memory.DBTraceMemoryRegisterSpace;
import ghidra.trace.database.memory.DBTraceMemorySpace;
import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
@@ -718,7 +718,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
waitForSwing();
assertTrue(flat.writeRegister(thread, 0, 0, "r0", BigInteger.valueOf(0x0102030405060708L)));
DBTraceMemoryRegisterSpace regs =
DBTraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
assertNotNull(regs);
Register r0 = tb.language.getRegister("r0");
@@ -734,7 +734,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
waitForSwing();
assertTrue(flat.writeRegister("r0", BigInteger.valueOf(0x0102030405060708L)));
DBTraceMemoryRegisterSpace regs =
DBTraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
assertNotNull(regs);
Register r0 = tb.language.getRegister("r0");
@@ -21,7 +21,7 @@ import ghidra.pcode.emu.PcodeThread;
import ghidra.program.model.lang.Register;
import ghidra.program.model.lang.RegisterValue;
import ghidra.trace.model.Trace;
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.thread.TraceThreadManager;
@@ -88,7 +88,7 @@ public interface TracePcodeMachine<T> extends PcodeMachine<T> {
long snap = getSnap();
TraceThread traceThread =
trace.getThreadManager().getLiveThreadByPath(snap, thread.getName());
TraceMemoryRegisterSpace space =
TraceMemorySpace space =
trace.getMemoryManager().getMemoryRegisterSpace(traceThread, false);
if (space == null) {
return false;
@@ -44,8 +44,7 @@ import ghidra.util.database.DBOpenMode;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
public class DBTraceBookmarkManager
extends AbstractDBTraceSpaceBasedManager<DBTraceBookmarkSpace, DBTraceBookmarkRegisterSpace>
public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBTraceBookmarkSpace>
implements TraceBookmarkManager, DBTraceDelegatingManager<DBTraceBookmarkSpace> {
public static final String NAME = "Bookmark";
@@ -180,13 +179,13 @@ public class DBTraceBookmarkManager
@Override
protected DBTraceBookmarkSpace createSpace(AddressSpace space, DBTraceSpaceEntry ent)
throws VersionException, IOException {
return new DBTraceBookmarkSpace(this, space);
return new DBTraceBookmarkSpace(this, space, null, 0);
}
@Override
protected DBTraceBookmarkRegisterSpace createRegisterSpace(AddressSpace space,
protected DBTraceBookmarkSpace createRegisterSpace(AddressSpace space,
TraceThread thread, DBTraceSpaceEntry ent) throws VersionException, IOException {
return new DBTraceBookmarkRegisterSpace(this, space, thread, ent.getFrameLevel());
return new DBTraceBookmarkSpace(this, space, thread, ent.getFrameLevel());
}
@Override
@@ -195,13 +194,13 @@ public class DBTraceBookmarkManager
}
@Override
public DBTraceBookmarkRegisterSpace getBookmarkRegisterSpace(TraceThread thread,
public DBTraceBookmarkSpace getBookmarkRegisterSpace(TraceThread thread,
boolean createIfAbsent) {
return getForRegisterSpace(thread, 0, createIfAbsent);
}
@Override
public DBTraceBookmarkRegisterSpace getBookmarkRegisterSpace(TraceStackFrame frame,
public DBTraceBookmarkSpace getBookmarkRegisterSpace(TraceStackFrame frame,
boolean createIfAbsent) {
return getForRegisterSpace(frame, createIfAbsent);
}
@@ -1,46 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.trace.database.bookmark;
import java.io.IOException;
import ghidra.program.model.address.AddressSpace;
import ghidra.trace.model.bookmark.TraceBookmarkRegisterSpace;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.exception.VersionException;
public class DBTraceBookmarkRegisterSpace extends DBTraceBookmarkSpace
implements TraceBookmarkRegisterSpace {
private final TraceThread thread;
private final int frameLevel;
public DBTraceBookmarkRegisterSpace(DBTraceBookmarkManager manager, AddressSpace space,
TraceThread thread, int frameLevel) throws VersionException, IOException {
super(manager, space);
this.thread = thread;
this.frameLevel = frameLevel;
}
@Override
public TraceThread getThread() {
return thread;
}
@Override
public int getFrameLevel() {
return frameLevel;
}
}
@@ -39,20 +39,27 @@ public class DBTraceBookmarkSpace implements TraceBookmarkSpace, DBTraceSpaceBas
protected final DBTraceBookmarkManager manager;
protected final ReadWriteLock lock;
protected final DBTrace trace;
protected final AddressSpace space;
protected final TraceThread thread;
protected final int frameLevel;
protected final DBTraceAddressSnapRangePropertyMapSpace<DBTraceBookmark, DBTraceBookmark> bookmarkMapSpace;
protected final DBCachedObjectIndex<String, DBTraceBookmark> bookmarksByTypeName;
protected final Collection<DBTraceBookmark> bookmarkView;
public DBTraceBookmarkSpace(DBTraceBookmarkManager manager, AddressSpace space)
public DBTraceBookmarkSpace(DBTraceBookmarkManager manager, AddressSpace space,
TraceThread thread, int frameLevel)
throws VersionException, IOException {
this.manager = manager;
this.lock = manager.getLock();
this.trace = manager.getTrace();
this.space = space;
this.thread = thread;
this.frameLevel = frameLevel;
this.bookmarkMapSpace =
new DBTraceAddressSnapRangePropertyMapSpace<>(DBTraceBookmark.tableName(space, -1, 0),
trace.getStoreFactory(), lock, space, DBTraceBookmark.class,
trace.getStoreFactory(), lock, space, null, 0, DBTraceBookmark.class,
(t, s, r) -> new DBTraceBookmark(this, t, s, r));
this.bookmarksByTypeName =
bookmarkMapSpace.getUserIndex(String.class, DBTraceBookmark.TYPE_COLUMN);
@@ -61,17 +68,17 @@ public class DBTraceBookmarkSpace implements TraceBookmarkSpace, DBTraceSpaceBas
@Override
public AddressSpace getAddressSpace() {
return bookmarkMapSpace.getAddressSpace();
return space;
}
@Override
public TraceThread getThread() {
return null;
return thread;
}
@Override
public int getFrameLevel() {
return 0;
return frameLevel;
}
protected DBTraceBookmarkType assertInTrace(TraceBookmarkType type) {
@@ -40,7 +40,7 @@ import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
public class DBTraceBreakpointManager
extends AbstractDBTraceSpaceBasedManager<DBTraceBreakpointSpace, DBTraceBreakpointSpace>
extends AbstractDBTraceSpaceBasedManager<DBTraceBreakpointSpace>
implements TraceBreakpointManager, DBTraceDelegatingManager<DBTraceBreakpointSpace> {
protected static final String NAME = "Breakpoint";
@@ -67,7 +67,7 @@ public class DBTraceBreakpointSpace implements DBTraceSpaceBased {
assert threadKey == -1; // No breakpoints on registers
breakpointMapSpace =
new DBTraceAddressSnapRangePropertyMapSpace<DBTraceBreakpoint, DBTraceBreakpoint>(
DBTraceBreakpoint.tableName(space, threadKey), factory, lock, space,
DBTraceBreakpoint.tableName(space, threadKey), factory, lock, space, null, 0,
DBTraceBreakpoint.class, (t, s, r) -> new DBTraceBreakpoint(this, t, s, r));
breakpointsByPath =
breakpointMapSpace.getUserIndex(String.class, DBTraceBreakpoint.PATH_COLUMN);
@@ -45,8 +45,8 @@ import ghidra.util.database.annot.*;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
public class DBTraceRegisterContextManager extends
AbstractDBTraceSpaceBasedManager<DBTraceRegisterContextSpace, DBTraceRegisterContextRegisterSpace>
public class DBTraceRegisterContextManager
extends AbstractDBTraceSpaceBasedManager<DBTraceRegisterContextSpace>
implements TraceRegisterContextManager,
DBTraceDelegatingManager<DBTraceRegisterContextSpace> {
public static final String NAME = "RegisterContext";
@@ -100,14 +100,14 @@ public class DBTraceRegisterContextManager extends
@Override
protected DBTraceRegisterContextSpace createSpace(AddressSpace space, DBTraceSpaceEntry ent)
throws VersionException, IOException {
return new DBTraceRegisterContextSpace(this, dbh, space, ent);
return new DBTraceRegisterContextSpace(this, dbh, space, ent, null);
}
@Override
protected DBTraceRegisterContextRegisterSpace createRegisterSpace(AddressSpace space,
protected DBTraceRegisterContextSpace createRegisterSpace(AddressSpace space,
TraceThread thread, DBTraceSpaceEntry ent) throws VersionException, IOException {
// TODO: Should I just forbid this? It doesn't seem sane. Then again, what do I know?
return new DBTraceRegisterContextRegisterSpace(this, dbh, space, ent, thread);
return new DBTraceRegisterContextSpace(this, dbh, space, ent, thread);
}
@Override
@@ -132,7 +132,7 @@ public class DBTraceRegisterContextManager extends
}
@Override
public DBTraceRegisterContextRegisterSpace getRegisterContextRegisterSpace(TraceThread thread,
public DBTraceRegisterContextSpace getRegisterContextRegisterSpace(TraceThread thread,
boolean createIfAbsent) {
return getForRegisterSpace(thread, 0, createIfAbsent);
}
@@ -1,49 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.trace.database.context;
import java.io.IOException;
import db.DBHandle;
import ghidra.program.model.address.AddressSpace;
import ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager.DBTraceSpaceEntry;
import ghidra.trace.model.context.TraceRegisterContextRegisterSpace;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.exception.VersionException;
public class DBTraceRegisterContextRegisterSpace extends DBTraceRegisterContextSpace
implements TraceRegisterContextRegisterSpace {
private final TraceThread thread;
private final int frameLevel;
public DBTraceRegisterContextRegisterSpace(DBTraceRegisterContextManager manager, DBHandle dbh,
AddressSpace space, DBTraceSpaceEntry ent, TraceThread thread)
throws VersionException, IOException {
super(manager, dbh, space, ent);
this.thread = thread;
this.frameLevel = ent.getFrameLevel();
}
@Override
public TraceThread getThread() {
return thread;
}
@Override
public int getFrameLevel() {
return frameLevel;
}
}
@@ -81,6 +81,8 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
protected final DBTraceRegisterContextManager manager;
protected final DBHandle dbh;
protected final AddressSpace space;
protected final TraceThread thread;
protected final int frameLevel;
protected final ReadWriteLock lock;
protected final Language baseLanguage;
protected final DBTrace trace;
@@ -91,10 +93,13 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
new HashMap<>();
public DBTraceRegisterContextSpace(DBTraceRegisterContextManager manager, DBHandle dbh,
AddressSpace space, DBTraceSpaceEntry ent) throws VersionException, IOException {
AddressSpace space, DBTraceSpaceEntry ent, TraceThread thread)
throws VersionException, IOException {
this.manager = manager;
this.dbh = dbh;
this.space = space;
this.thread = thread;
this.frameLevel = ent.getFrameLevel();
this.lock = manager.getLock();
this.baseLanguage = manager.getBaseLanguage();
this.trace = manager.getTrace();
@@ -129,7 +134,7 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
@Override
public TraceThread getThread() {
return null;
return thread;
}
protected long getThreadKey() {
@@ -139,7 +144,7 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
@Override
public int getFrameLevel() {
return 0;
return frameLevel;
}
protected String tableName(Language language, Register register) {
@@ -152,7 +157,8 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
String name = tableName(lr.getLeft(), lr.getRight());
try {
return new DBTraceAddressSnapRangePropertyMapSpace<>(name, trace.getStoreFactory(),
lock, space, DBTraceRegisterContextEntry.class, DBTraceRegisterContextEntry::new);
lock, space, thread, frameLevel, DBTraceRegisterContextEntry.class,
DBTraceRegisterContextEntry::new);
}
catch (IOException e) {
manager.dbError(e);
@@ -159,29 +159,8 @@ public class DBTraceDataSettingsAdapter
DBTraceAddressSnapRangePropertyMapSpace<DBTraceSettingsEntry, DBTraceSettingsEntry>
implements DBTraceDataSettingsOperations {
public DBTraceDataSettingsSpace(String tableName, DBCachedObjectStoreFactory storeFactory,
ReadWriteLock lock, AddressSpace space, Class<DBTraceSettingsEntry> dataType,
DBTraceAddressSnapRangePropertyMapDataFactory<DBTraceSettingsEntry, DBTraceSettingsEntry> dataFactory)
throws VersionException, IOException {
super(tableName, storeFactory, lock, space, dataType, dataFactory);
}
@Override
public void makeWay(DBTraceSettingsEntry entry, Range<Long> span) {
DBTraceUtils.makeWay(entry, span, (e, s) -> e.setLifespan(s), e -> deleteData(e));
}
@Override
public ReadWriteLock getLock() {
return lock;
}
}
public class DBTraceDataSettingsRegisterSpace extends
DBTraceAddressSnapRangePropertyMapRegisterSpace<DBTraceSettingsEntry, DBTraceSettingsEntry>
implements DBTraceDataSettingsOperations {
public DBTraceDataSettingsRegisterSpace(String tableName,
DBCachedObjectStoreFactory storeFactory, ReadWriteLock lock, AddressSpace space,
TraceThread thread, int frameLevel, Class<DBTraceSettingsEntry> dataType,
ReadWriteLock lock, AddressSpace space, TraceThread thread, int frameLevel,
Class<DBTraceSettingsEntry> dataType,
DBTraceAddressSnapRangePropertyMapDataFactory<DBTraceSettingsEntry, DBTraceSettingsEntry> dataFactory)
throws VersionException, IOException {
super(tableName, storeFactory, lock, space, thread, frameLevel, dataType, dataFactory);
@@ -206,20 +185,20 @@ public class DBTraceDataSettingsAdapter
}
@Override
protected DBTraceDataSettingsSpace createSpace(AddressSpace space, DBTraceSpaceEntry ent)
throws VersionException, IOException {
protected DBTraceDataSettingsSpace createSpace(
AddressSpace space, DBTraceSpaceEntry ent) throws VersionException, IOException {
return new DBTraceDataSettingsSpace(
tableName(space, ent.getThreadKey(), ent.getFrameLevel()),
trace.getStoreFactory(), lock, space, dataType, dataFactory);
tableName(space, ent.getThreadKey(), ent.getFrameLevel()), trace.getStoreFactory(),
lock, space, null, 0, dataType, dataFactory);
}
@Override
protected DBTraceDataSettingsRegisterSpace createRegisterSpace(AddressSpace space,
TraceThread thread, DBTraceSpaceEntry ent) throws VersionException, IOException {
return new DBTraceDataSettingsRegisterSpace(
tableName(space, ent.getThreadKey(), ent.getFrameLevel()),
trace.getStoreFactory(), lock, space, thread, ent.getFrameLevel(), dataType,
dataFactory);
protected DBTraceDataSettingsSpace createRegisterSpace(
AddressSpace space, TraceThread thread, DBTraceSpaceEntry ent)
throws VersionException, IOException {
return new DBTraceDataSettingsSpace(
tableName(space, ent.getThreadKey(), ent.getFrameLevel()), trace.getStoreFactory(),
lock, space, thread, ent.getFrameLevel(), dataType, dataFactory);
}
@Override
@@ -228,9 +207,9 @@ public class DBTraceDataSettingsAdapter
}
@Override
public DBTraceDataSettingsRegisterSpace getRegisterSpace(TraceThread thread,
public DBTraceDataSettingsSpace getRegisterSpace(TraceThread thread,
boolean createIfAbsent) {
return (DBTraceDataSettingsRegisterSpace) super.getRegisterSpace(thread, createIfAbsent);
return (DBTraceDataSettingsSpace) super.getRegisterSpace(thread, createIfAbsent);
}
@Override
@@ -28,42 +28,126 @@ import ghidra.trace.database.DBTraceUtils;
import ghidra.trace.database.space.DBTraceDelegatingManager;
import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.listing.TraceBaseCodeUnitsView;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.LockHold;
/**
* An abstract implementation of {@link TraceBaseCodeUnitsView} for composing views of many address
* spaces
*
* @param <T> the implementation type of the units contained in the view
* @param <M> the implementation type of the views being composed
*/
public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCodeUnitAdapter, M extends AbstractBaseDBTraceCodeUnitsView<T>>
implements DBTraceDelegatingManager<M> {
protected final DBTraceCodeManager manager;
protected final Collection<M> activeSpacesView;
/**
* Construct a composite view
*
* @param manager the code manager, from which individual views are retrieved
*/
public AbstractBaseDBTraceCodeUnitsMemoryView(DBTraceCodeManager manager) {
this.manager = manager;
this.activeSpacesView =
Collections2.transform(manager.getActiveMemorySpaces(), this::getView);
}
/**
* @see TraceBaseCodeUnitsView#getTrace()
*/
public Trace getTrace() {
return manager.getTrace();
}
/**
* @see TraceBaseCodeUnitsView#getThread()
*/
public TraceThread getThread() {
return null;
}
/**
* @see TraceBaseCodeUnitsView#getFrameLevel()
*/
public int getFrameLevel() {
return 0;
}
/**
* Get the individual view from the given space
*
* @param space the space, bound to a specific address space
* @return the view
*/
protected abstract M getView(DBTraceCodeSpace space);
/**
* Create the appropriate unit (possibly caching) when there is no view or space for the given
* address's space
*
* <p>
* Views composing undefined units should generate (possibly delegating to a view) an undefined
* unit. Others should leave this null.
*
* @param snap the snap the client requested
* @param address the address the client requested
* @return the unit or null
*/
protected T nullOrUndefined(long snap, Address address) {
return null;
}
/**
* The address set when there is no view or space for the given range's space
*
* <p>
* Views composing undefined units should return the whole range. Others should leave this
* empty.
*
* @param within the range the client requested
* @return the full range or empty
*/
protected AddressSetView emptyOrFullAddressSetUndefined(AddressRange within) {
return new AddressSet();
}
/**
* The result of contains, covers, or intersects when there is no view or space for an address
* space
*
* <p>
* Views composing undefined units should return true, since the address is known to be in an
* unpopulated space. Others should leave this false.
*
* @return true if an undefined unit implicitly contains the address, false otherwise.
*/
protected boolean falseOrTrueUndefined() {
return false;
}
/**
* The result of iteration when there is no view or space for the given range's space
*
* <p>
* Views composing undefiend units should return an iterable that generates (possibly caching)
* undefined units. Others should leave this empty.
*
* @param snap the snap the client requested
* @param range the range of iteration
* @param forward true to iterate forward (min to max), false for backward (max to min)
* @return the iterator
*/
public Iterable<? extends T> emptyOrFullIterableUndefined(long snap, AddressRange range,
boolean forward) {
return Collections.emptyList();
}
/**
* @see #emptyOrFullIterableUndefined(long, AddressRange, boolean)
*/
public Iterable<? extends T> emptyOrFullIterableUndefined(TraceAddressSnapRange tasr) {
return Collections.emptyList();
}
@@ -84,6 +168,16 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return codeSpace == null ? null : getView(codeSpace);
}
/**
* Compute the address preceding the given
*
* <p>
* If this address is the minimum in its space, then this will choose the maximum address of the
* previous space, if it exists.
*
* @param address the address
* @return the previous address or null
*/
protected Address prevAddress(Address address) {
Address prev = address.previous();
if (prev != null) {
@@ -108,6 +202,15 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return prevRange.getMaxAddress();
}
/**
* Compute the address following the given
*
* <p>
* If the address is the maximum in its space, then this will choose the minimum address of the
* next space, if it exists.
*
* @return the next address or null
*/
protected Address nextAddress(Address address) {
Address next = address.next();
if (next != null) {
@@ -132,6 +235,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return nextRange.getMinAddress();
}
/**
* @see TraceBaseCodeUnitsView#size()
*/
public int size() {
int sum = 0;
for (M m : activeSpacesView) {
@@ -140,6 +246,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return sum;
}
/**
* @see TraceBaseCodeUnitsView#getBefore(long, Address)
*/
public T getBefore(long snap, Address address) {
Address prev = prevAddress(address);
if (prev == null) {
@@ -148,6 +257,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return getFloor(snap, prev);
}
/**
* @see TraceBaseCodeUnitsView#getFloor(long, Address)
*/
public T getFloor(long snap, Address address) {
try (LockHold hold = LockHold.lock(readLock())) {
for (AddressRange range : DBTraceUtils.getAddressSet(
@@ -163,6 +275,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
}
}
/**
* @see TraceBaseCodeUnitsView#getContaining(long, Address)
*/
public T getContaining(long snap, Address address) {
try (LockHold hold = LockHold.lock(readLock())) {
M m = getForSpace(address.getAddressSpace(), false);
@@ -173,6 +288,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
}
}
/**
* @see TraceBaseCodeUnitsView#getAt(long, Address)
*/
public T getAt(long snap, Address address) {
try (LockHold hold = LockHold.lock(readLock())) {
M m = getForSpace(address.getAddressSpace(), false);
@@ -183,6 +301,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
}
}
/**
* @see TraceBaseCodeUnitsView#getCeiling(long, Address)
*/
public T getCeiling(long snap, Address address) {
try (LockHold hold = LockHold.lock(readLock())) {
for (AddressRange range : DBTraceUtils.getAddressSet(
@@ -198,6 +319,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
}
}
/**
* @see TraceBaseCodeUnitsView#getAfter(long, Address)
*/
public T getAfter(long snap, Address address) {
Address next = nextAddress(address);
if (next == null) {
@@ -206,6 +330,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return getCeiling(snap, next);
}
/**
* @see TraceBaseCodeUnitsView#get(long, Address, Address, boolean)
*/
public Iterable<? extends T> get(long snap, Address min, Address max, boolean forward) {
if (min.hasSameAddressSpace(max)) {
return get(snap, new AddressRangeImpl(min, max), forward);
@@ -214,11 +341,17 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
forward);
}
/**
* @see TraceBaseCodeUnitsView#get(long, AddressSetView, boolean)
*/
public Iterable<? extends T> get(long snap, AddressSetView set, boolean forward) {
return () -> NestedIterator.start(set.iterator(forward),
r -> get(snap, r, forward).iterator());
}
/**
* @see TraceBaseCodeUnitsView#get(long, AddressRange, boolean)
*/
public Iterable<? extends T> get(long snap, AddressRange range, boolean forward) {
M m = getForSpace(range.getAddressSpace(), false);
if (m == null) {
@@ -227,15 +360,24 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return m.get(snap, range, forward);
}
/**
* @see TraceBaseCodeUnitsView#get(long, Address, boolean)
*/
public Iterable<? extends T> get(long snap, Address start, boolean forward) {
AddressFactory factory = manager.getBaseLanguage().getAddressFactory();
return get(snap, DBTraceUtils.getAddressSet(factory, start, forward), forward);
}
/**
* @see TraceBaseCodeUnitsView#get(long, boolean)
*/
public Iterable<? extends T> get(long snap, boolean forward) {
return get(snap, manager.getBaseLanguage().getAddressFactory().getAddressSet(), forward);
}
/**
* @see TraceBaseCodeUnitsView#getIntersecting(TraceAddressSnapRange)
*/
public Iterable<? extends T> getIntersecting(TraceAddressSnapRange tasr) {
M m = getForSpace(tasr.getX1().getAddressSpace(), false);
if (m == null) {
@@ -244,6 +386,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return m.getIntersecting(tasr);
}
/**
* @see TraceBaseCodeUnitsView#getAddressSetView(long, AddressRange)
*/
public AddressSetView getAddressSetView(long snap, AddressRange within) {
M m = getForSpace(within.getAddressSpace(), false);
if (m == null) {
@@ -252,6 +397,9 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return m.getAddressSetView(snap, within);
}
/**
* @see TraceBaseCodeUnitsView#getAddressSetView(long)
*/
public AddressSetView getAddressSetView(long snap) {
AddressSet result = new AddressSet();
for (AddressRange range : manager.getBaseLanguage().getAddressFactory().getAddressSet()) {
@@ -266,26 +414,41 @@ public abstract class AbstractBaseDBTraceCodeUnitsMemoryView<T extends DBTraceCo
return result;
}
/**
* @see TraceBaseCodeUnitsView#containsAddress(long, Address)
*/
public boolean containsAddress(long snap, Address address) {
return delegateRead(address.getAddressSpace(), m -> m.containsAddress(snap, address),
falseOrTrueUndefined());
}
/**
* @see TraceBaseCodeUnitsView#coversRange(Range, AddressRange)
*/
public boolean coversRange(Range<Long> span, AddressRange range) {
return delegateRead(range.getAddressSpace(), m -> m.coversRange(span, range),
falseOrTrueUndefined());
}
/**
* @see TraceBaseCodeUnitsView#coversRange(TraceAddressSnapRange)
*/
public boolean coversRange(TraceAddressSnapRange range) {
return delegateRead(range.getRange().getAddressSpace(), m -> m.coversRange(range),
falseOrTrueUndefined());
}
/**
* @see TraceBaseCodeUnitsView#intersectsRange(Range, AddressRange)
*/
public boolean intersectsRange(Range<Long> span, AddressRange range) {
return delegateRead(range.getAddressSpace(), m -> m.intersectsRange(span, range),
falseOrTrueUndefined());
}
/**
* @see TraceBaseCodeUnitsView#intersectsRange(TraceAddressSnapRange)
*/
public boolean intersectsRange(TraceAddressSnapRange range) {
return delegateRead(range.getRange().getAddressSpace(), m -> m.intersectsRange(range),
falseOrTrueUndefined());
@@ -21,21 +21,70 @@ import generic.NestedIterator;
import ghidra.program.model.address.*;
import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.listing.TraceBaseCodeUnitsView;
import ghidra.trace.model.thread.TraceThread;
/**
* An abstract implementation of a {@link TraceBaseCodeUnitsView} for a specific address space
*
* <p>
* Note that this class does not declare {@link TraceBaseCodeUnitsView} as an implemented interface,
* thought it does implement it structurally. If it were implemented nominally, the realizations
* would inherit the same interface twice, with different type parameters, which is not allowed.
*
* @param <T> the implementation type of the units contained in the view
*/
public abstract class AbstractBaseDBTraceCodeUnitsView<T extends DBTraceCodeUnitAdapter> {
protected final DBTraceCodeSpace space;
/**
* Construct a view
*
* @param space the space, bound to an address space
*/
public AbstractBaseDBTraceCodeUnitsView(DBTraceCodeSpace space) {
this.space = space;
}
/**
* Get the address space for this view
*
* @return the address space
*/
protected AddressSpace getAddressSpace() {
return space.space;
}
/**
* @see TraceBaseCodeUnitsView#getTrace()
*/
public Trace getTrace() {
return space.manager.getTrace();
}
/**
* @see TraceBaseCodeUnitsView#getThread()
*/
public TraceThread getThread() {
return space.getThread();
}
/**
* @see TraceBaseCodeUnitsView#getFrameLevel()
*/
public int getFrameLevel() {
return space.getFrameLevel();
}
/**
* @see TraceBaseCodeUnitsView#size()
*/
public abstract int size();
/**
* @see TraceBaseCodeUnitsView#getBefore(long, Address)
*/
public T getBefore(long snap, Address address) {
Address previous = address.previous();
if (previous == null) {
@@ -44,14 +93,29 @@ public abstract class AbstractBaseDBTraceCodeUnitsView<T extends DBTraceCodeUnit
return getFloor(snap, previous);
}
/**
* @see TraceBaseCodeUnitsView#getFloor(long, Address)
*/
public abstract T getFloor(long snap, Address address);
/**
* @see TraceBaseCodeUnitsView#getContaining(long, Address)
*/
public abstract T getContaining(long snap, Address address);
/**
* @see TraceBaseCodeUnitsView#getAt(long, Address)
*/
public abstract T getAt(long snap, Address address);
/**
* @see TraceBaseCodeUnitsView#getCeiling(long, Address)
*/
public abstract T getCeiling(long snap, Address address);
/**
* @see TraceBaseCodeUnitsView#getAfter(long, Address)
*/
public T getAfter(long snap, Address address) {
Address next = address.next();
if (next == null) {
@@ -60,50 +124,85 @@ public abstract class AbstractBaseDBTraceCodeUnitsView<T extends DBTraceCodeUnit
return getCeiling(snap, next);
}
public AddressSpace getAddressSpace() {
return space.space;
}
/**
* @see TraceBaseCodeUnitsView#get(long, Address, Address, boolean)
*/
public abstract Iterable<? extends T> get(long snap, Address min, Address max, boolean forward);
/**
* @see TraceBaseCodeUnitsView#getIntersecting(TraceAddressSnapRange)
*/
public abstract Iterable<? extends T> getIntersecting(TraceAddressSnapRange tasr);
/**
* @see TraceBaseCodeUnitsView#get(long, AddressSetView, boolean)
*/
public Iterable<? extends T> get(long snap, AddressSetView set, boolean forward) {
return () -> NestedIterator.start(set.iterator(forward),
r -> this.get(snap, r, forward).iterator());
}
/**
* @see TraceBaseCodeUnitsView#get(long, AddressRange, boolean)
*/
public Iterable<? extends T> get(long snap, AddressRange range, boolean forward) {
return get(snap, range.getMinAddress(), range.getMaxAddress(), forward);
}
/**
* @see TraceBaseCodeUnitsView#get(long, Address, boolean)
*/
public Iterable<? extends T> get(long snap, Address start, boolean forward) {
return forward //
? get(snap, start, getAddressSpace().getMaxAddress(), forward)
: get(snap, getAddressSpace().getMinAddress(), start, forward);
}
/**
* @see TraceBaseCodeUnitsView#get(long, boolean)
*/
public Iterable<? extends T> get(long snap, boolean forward) {
return get(snap, getAddressSpace().getMinAddress(), getAddressSpace().getMaxAddress(),
forward);
}
/**
* @see TraceBaseCodeUnitsView#getAddressSetView(long, AddressRange)
*/
public abstract AddressSetView getAddressSetView(long snap, AddressRange within);
/**
* @see TraceBaseCodeUnitsView#getAddressSetView(long)
*/
public AddressSetView getAddressSetView(long snap) {
return getAddressSetView(snap, space.all);
}
/**
* @see TraceBaseCodeUnitsView#containsAddress(long, Address)
*/
public abstract boolean containsAddress(long snap, Address address);
/**
* @see TraceBaseCodeUnitsView#coversRange(Range, AddressRange)
*/
public abstract boolean coversRange(Range<Long> span, AddressRange range);
/**
* @see TraceBaseCodeUnitsView#coversRange(TraceAddressSnapRange)
*/
public boolean coversRange(TraceAddressSnapRange range) {
return coversRange(range.getLifespan(), range.getRange());
}
/**
* @see TraceBaseCodeUnitsView#intersectsRange(Range, AddressRange)
*/
public abstract boolean intersectsRange(Range<Long> span, AddressRange range);
/**
* @see TraceBaseCodeUnitsView#intersectsRange(TraceAddressSnapRange)
*/
public boolean intersectsRange(TraceAddressSnapRange range) {
return intersectsRange(range.getLifespan(), range.getRange());
}
@@ -31,12 +31,23 @@ import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree.TraceAdd
import ghidra.trace.model.ImmutableTraceAddressSnapRange;
import ghidra.trace.model.Trace.TraceCodeChangeType;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.listing.TraceBaseDefinedUnitsView;
import ghidra.trace.util.TraceChangeRecord;
import ghidra.util.LockHold;
import ghidra.util.database.spatial.rect.Rectangle2DDirection;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* An abstract implementation of a single-type view for a defined unit type
*
* <p>
* This is <em>note</em> a base class of {@link DBTraceDefinedUnitsView}. This class supports the
* implementation of one or the other: Instruction or Defined data. {@link DBTraceDefinedUnitsView}
* is the implementation of the composition of both.
*
* @param <T>
*/
public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTraceCodeUnit<T>>
extends AbstractSingleDBTraceCodeUnitsView<T> {
@@ -44,6 +55,9 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
protected final static int CACHE_ADDRESS_BREADTH = 10000;
protected final static int CACHE_MAX_POINTS = 10000;
/**
* Cache for optimizing {@link AbstractBaseDBTraceDefinedUnitsView#getAt(long, Address)}
*/
protected class CacheForGetUnitContainingQueries
extends DBTraceCacheForContainingQueries<GetKey, T, T> {
@@ -64,6 +78,10 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
}
};
/**
* Cache for optimizing {@link AbstractBaseDBTraceDefinedUnitsView#getFloor(long, Address)} and
* similar.
*/
protected class CacheForGetUnitSequenceQueries extends DBTraceCacheForSequenceQueries<T> {
public CacheForGetUnitSequenceQueries() {
super(CACHE_MAX_REGIONS, CACHE_ADDRESS_BREADTH);
@@ -104,6 +122,12 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
protected final CacheForGetUnitSequenceQueries cacheForSequence =
new CacheForGetUnitSequenceQueries();
/**
* Construct the view
*
* @param space the space, bound to an address space
* @param mapSpace the map storing the actual code unit entries
*/
public AbstractBaseDBTraceDefinedUnitsView(DBTraceCodeSpace space,
DBTraceAddressSnapRangePropertyMapSpace<T, T> mapSpace) {
super(space);
@@ -121,6 +145,30 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
return !mapSpace.reduce(TraceAddressSnapRangeQuery.at(address, snap)).isEmpty();
}
/**
* Subtract from cur, the boxes covered by the entries intersecting the given query box
*
* <p>
* Compute C = A - B, where A B and C are sets of (possibly overlapping) boxes. A is given by
* {@code} cur, and B is the set of bounding boxes for entries intersecting the query box. Two
* temporary sets must be provided, and {@code cur} must be identical to one of them. This
* routine will mutate them. The returned result will be identical to one of them.
*
* <p>
* If repeated subtraction is needed, the temporary sets need only be constructed once. For each
* subsequent round of subtraction, {@code cur} should be the returned result of the previous
* round. The final result is the return value of the final round.
*
* <p>
* This is used in the implementation of {@link #coversRange(TraceAddressSnapRange)}.
*
* @param span the lifespan of the query box
* @param range the address range of the query box
* @param cur the set of boxes, identical to one of the temporary working sets.
* @param set1 a temporary set for working
* @param set2 a temporary set for working
* @return the result of subtraction, identical to one of the temporary working sets
*/
protected Set<TraceAddressSnapRange> subtractFrom(Range<Long> span, AddressRange range,
Set<TraceAddressSnapRange> cur, Set<TraceAddressSnapRange> set1,
Set<TraceAddressSnapRange> set2) {
@@ -239,6 +287,12 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
t -> true);
}
/**
* Clear the register context in the given box
*
* @param span the lifespan of the box
* @param range the address range of the box
*/
protected void clearContext(Range<Long> span, AddressRange range) {
DBTraceRegisterContextSpace ctxSpace =
space.trace.getRegisterContextManager().get(space, false);
@@ -248,6 +302,9 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
ctxSpace.clear(span, range);
}
/**
* @see TraceBaseDefinedUnitsView#clear(Range, AddressRange, boolean, TaskMonitor)
*/
public void clear(Range<Long> span, AddressRange range, boolean clearContext,
TaskMonitor monitor) throws CancelledException {
long startSnap = DBTraceUtils.lowerEndpoint(span);
@@ -275,6 +332,11 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
}
}
/**
* Notify domain object listeners that a unit was removed
*
* @param unit the removed unit
*/
protected void unitRemoved(T unit) {
cacheForContaining.notifyEntryRemoved(unit.getLifespan(), unit.getRange(), unit);
cacheForSequence.notifyEntryRemoved(unit.getLifespan(), unit.getRange(), unit);
@@ -283,6 +345,12 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
space, unit.getBounds(), unit, null));
}
/**
* Notify domain object listeners taht a unit's lifespan changed
*
* @param oldSpan the old snap
* @param unit the unit (having the new span)
*/
protected void unitSpanChanged(Range<Long> oldSpan, T unit) {
cacheForContaining.notifyEntryShapeChanged(unit.getLifespan(), unit.getRange(), unit);
cacheForSequence.notifyEntryShapeChanged(unit.getLifespan(), unit.getRange(), unit);
@@ -291,6 +359,18 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
space, unit, oldSpan, unit.getLifespan()));
}
/**
* Select a sub-lifespan from that given so that the box does not overlap an existing unit
*
* <p>
* The selected lifespan will have the same start snap at that given. The box is the bounding
* box of a unit the client is trying to create.
*
* @param span the lifespan of the box
* @param range the address range of the box
* @return the selected sub-lifespan
* @throws CodeUnitInsertionException if the start snap is contained in an existing unit
*/
protected Range<Long> truncateSoonestDefined(Range<Long> span, AddressRange range)
throws CodeUnitInsertionException {
T truncateBy =
@@ -308,6 +388,9 @@ public abstract class AbstractBaseDBTraceDefinedUnitsView<T extends AbstractDBTr
truncateBy.getStartSnap() - 1);
}
/**
* Invalidate the query-optimizing caches for this view
*/
public void invalidateCache() {
cacheForContaining.invalidate();
cacheForSequence.invalidate();
@@ -26,20 +26,46 @@ import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.listing.TraceCodeUnit;
import ghidra.util.*;
/**
* An abstract implementation of a multi-type view, by composing other single-type views
*
* @param <T> the implementation type of units contained in the view
* @param <P> the implementation type of views composed by this view
*/
public abstract class AbstractComposedDBTraceCodeUnitsView<T extends DBTraceCodeUnitAdapter, //
P extends AbstractSingleDBTraceCodeUnitsView<? extends T>>
extends AbstractBaseDBTraceCodeUnitsView<T> {
/**
* Compare two code units for forward iteration
*
* @param a a code unit
* @param b a code unit
* @return as in {@link Comparable#compareTo(Object)}
*/
protected static int compareForward(TraceCodeUnit a, TraceCodeUnit b) {
return a.getMinAddress().compareTo(b.getMinAddress());
}
/**
* Compare two code units for backward iteration
*
* @param a a code unit
* @param b a code unit
* @return as in {@link Comparable#compareTo(Object)}
*/
protected static int compareBackward(TraceCodeUnit a, TraceCodeUnit b) {
return b.getMaxAddress().compareTo(a.getMaxAddress());
}
protected final Collection<P> parts;
/**
* Construct a view
*
* @param space the space, bound to an address space
* @param parts the single-type views composed
*/
public AbstractComposedDBTraceCodeUnitsView(DBTraceCodeSpace space, Collection<P> parts) {
super(space);
this.parts = parts;
@@ -29,6 +29,15 @@ import ghidra.trace.util.TraceAddressSpace;
import ghidra.util.LockHold;
import ghidra.util.database.DBCachedObjectStore;
/**
* An abstract implementation of a table-backed code unit
*
* <p>
* This is implemented as a data entry in an address-snap-range property map. This is not suitable
* for data components, nor for undefined units.
*
* @param <T> the implementation type of this unit
*/
public abstract class AbstractDBTraceCodeUnit<T extends AbstractDBTraceCodeUnit<T>> extends
AbstractDBTraceAddressSnapRangePropertyMapData<T> implements DBTraceCodeUnitAdapter {
@@ -36,6 +45,14 @@ public abstract class AbstractDBTraceCodeUnit<T extends AbstractDBTraceCodeUnit<
protected ByteBuffer byteCache; // NOTE: Memory cannot be changed under a code unit
/**
* Construct a code unit
*
* @param space the space
* @param tree the storage R*-Tree
* @param store the object store
* @param record the record
*/
public AbstractDBTraceCodeUnit(DBTraceCodeSpace space,
DBTraceAddressSnapRangePropertyMapTree<T, ?> tree, DBCachedObjectStore<?> store,
DBRecord record) {
@@ -26,9 +26,19 @@ import ghidra.program.model.lang.Language;
import ghidra.trace.database.DBTrace;
import ghidra.trace.database.data.DBTraceDataSettingsAdapter.DBTraceDataSettingsSpace;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.listing.TraceData;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.LockHold;
/**
* An abstract implementation of a {@link TraceData} for a data component, i.e., field of a struct
* or element of an array
*
* <p>
* These are not backed directly by a table. The root data unit, along with its type, is stored in
* the table. If the type is composite, then these are generated, possibly recursively, for the
* components therein.
*/
public abstract class AbstractDBTraceDataComponent implements DBTraceDefinedDataAdapter {
protected final DBTraceData root;
@@ -47,6 +57,16 @@ public abstract class AbstractDBTraceDataComponent implements DBTraceDefinedData
protected AbstractDBTraceDataComponent[] componentCache = null;
/**
* Create a data component
*
* @param root the root data unit
* @param parent the parent component, possibly the root
* @param index the index of this component in its parent
* @param address the minimum address of this component
* @param dataType the data type of this component
* @param length the length of this component
*/
public AbstractDBTraceDataComponent(DBTraceData root, DBTraceDefinedDataAdapter parent,
int index, Address address, DataType dataType, int length) {
this.root = root;
@@ -173,6 +193,7 @@ public abstract class AbstractDBTraceDataComponent implements DBTraceDefinedData
/**
* {@inheritDoc}
*
* <p>
* In other words, this includes the symbol name of the root unit; whereas,
* {@link #getComponentPathName()} omits it.
*/
@@ -184,6 +205,7 @@ public abstract class AbstractDBTraceDataComponent implements DBTraceDefinedData
/**
* {@inheritDoc}
*
* <p>
* In other words, this omits the symbol name of the root unit; whereas, {@link #getPathName()}
* includes it.
*/
@@ -15,9 +15,22 @@
*/
package ghidra.trace.database.listing;
/**
* An abstract implementation of a single-type view
*
* @implNote This class cannot be removed. Despite it appearing not to do anything, this class
* serves as an upper bound on the views composed by
* {@link AbstractComposedDBTraceCodeUnitsView}.
* @param <T> the implementation type of the units contained in the view
*/
public abstract class AbstractSingleDBTraceCodeUnitsView<T extends DBTraceCodeUnitAdapter>
extends AbstractBaseDBTraceCodeUnitsView<T> {
/**
* Construct a view
*
* @param space the space, bound to an address space
*/
public AbstractSingleDBTraceCodeUnitsView(DBTraceCodeSpace space) {
super(space);
}
@@ -22,16 +22,24 @@ import com.google.common.collect.Iterators;
import ghidra.program.model.address.*;
import ghidra.trace.database.DBTraceUtils;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.listing.TraceBaseCodeUnitsView;
/**
* TODO: Document me
* An abstract implementation of {@link TraceBaseCodeUnitsView} for composing views of many address
* spaces, where the views include undefined units
*
* @param <T> type of units in the view. Must be a super-type of {@link UndefinedDBTraceData}.
* @param <M>
* @param <T> the implementation type of the units contained in the view. Must be a super-type of
* {@link UndefinedDBTraceData}.
* @param <M> the implementation type of the views being composed
*/
public abstract class AbstractWithUndefinedDBTraceCodeUnitsMemoryView<T extends DBTraceCodeUnitAdapter, M extends AbstractBaseDBTraceCodeUnitsView<T>>
extends AbstractBaseDBTraceCodeUnitsMemoryView<T, M> {
/**
* Construct a composite view
*
* @param manager the code manager, from which individual views are retrieved
*/
public AbstractWithUndefinedDBTraceCodeUnitsMemoryView(DBTraceCodeManager manager) {
super(manager);
}
@@ -32,8 +32,7 @@ import db.DBRecord;
import ghidra.lifecycle.Internal;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.*;
import ghidra.program.model.listing.ContextChangeException;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.ByteMemBufferImpl;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.util.ProgramContextImpl;
@@ -52,8 +51,7 @@ import ghidra.trace.database.symbol.DBTraceReferenceManager;
import ghidra.trace.database.thread.DBTraceThreadManager;
import ghidra.trace.model.AddressSnap;
import ghidra.trace.model.DefaultAddressSnap;
import ghidra.trace.model.listing.TraceCodeManager;
import ghidra.trace.model.listing.TraceCodeSpace;
import ghidra.trace.model.listing.*;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.TraceAddressSpace;
@@ -64,8 +62,119 @@ import ghidra.util.exception.CancelledException;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
public class DBTraceCodeManager
extends AbstractDBTraceSpaceBasedManager<DBTraceCodeSpace, DBTraceCodeRegisterSpace>
/**
* The implementation of {@link TraceCodeManager} for {@link DBTrace}
*
* <p>
* The "fluent" interfaces actually create quite a burden to implement here; however, we have some
* opportunity to extract common code among the various views. There are a few concepts and nuances
* to consider in order to handle all the fluent cases. The manager implements
* {@link TraceCodeOperations} directly, which means it must provide a version of each
* {@link TraceCodeUnitsView} that composes all memory address spaces. These are named with the
* suffix {@code MemoryView} and extend {@link AbstractBaseDBTraceCodeUnitsMemoryView}.
*
* <p>
* In addition, in order to support {@link #getCodeSpace(AddressSpace, boolean)}, it must provide a
* version of each that can be bound to a single memory address space. Same for
* {@link #getCodeRegisterSpace(TraceThread, int, boolean)}. These are named with the suffix
* {@code View} and extend {@link AbstractBaseDBTraceCodeUnitsView}.
*
* <p>
* Furthermore, there are three types of views:
*
* <ol>
* <li>Those defined by a table, i.e., defined data and instructions. These extend
* {@link AbstractBaseDBTraceDefinedUnitsView}.</li>
* <li>Those defined implicitly, but may have a support table, i.e., undefined units. This is
* implemented by {@link DBTraceUndefinedDataView}.</li>
* <li>Those defined as the composition of others, i.e., data and defined units. These extend
* {@link AbstractComposedDBTraceCodeUnitsView}.</li>
* </ol>
*
* <p>
* The first two types represent a view of a single code unit type, so they both extend
* {@link AbstractSingleDBTraceCodeUnitsView}.
*
* <p>
* The abstract classes do not nominally implement the trace manager's
* {@link TraceBaseCodeUnitsView} nor {@link TraceBaseDefinedUnitsView} interfaces, because Java
* prevents the (nominal) implementation of the same interface with different type parameters by the
* same class. E.g., {@link DBTraceDataView} would inherit
* {@code TraceBaseCodeUnitsView<DBTraceData>} via {@link AbstractBaseDBTraceCodeUnitsView}, but
* also {@code TraceBaseCodeUnitsView<TraceDataUnit>} via {@link TraceDataView}. Instead, the
* abstract classes <em>structurally</em> implement those interfaces, meaning they implement the
* methods required by the interface, but without naming the interface in their `implements` clause.
* The realizations, e.g., {@link DBTraceDataView}, <em>nominally</em> implement their corresponding
* interfaces, meaning they do name the interface. Each realization will inherit the structural
* implementation from the abstract classes, satisfying the requirements imposed by nominally
* implementing the interface.
*
* <p>
* Note, as a result, navigating from declarations in the interfaces to implementations in abstract
* classes using your IDE may not work as expected :/ . The best way is probably to display the type
* hierarchy of the interface declaring the desired method. Open one of the classes implementing it,
* then display all its methods, including those inherited, and search for desired method.
*
* <p>
* Here is the type hierarchy presented with notes regarding structural interface implementations:
* <ul>
* <li>{@link AbstractBaseDBTraceCodeUnitsView} structurally implements
* {@link TraceBaseCodeUnitsView}</li>
* <ul>
* <li>{@link AbstractComposedDBTraceCodeUnitsView}</li>
* <ul>
* <li>{@link DBTraceCodeUnitsView} nominally implements {@link TraceCodeUnitsView}</li>
* <li>{@link DBTraceDataView} nominally implements {@link TraceDataView}</li>
* <li>{@link DBTraceDefinedUnitsView} nominally implements {@link TraceDefinedUnitsView}</li>
* </ul>
* <li>{@link AbstractSingleDBTraceCodeUnitsView}</li>
* <ul>
* <li>{@link AbstractBaseDBTraceDefinedUnitsView} structurally implements
* {@link TraceBaseDefinedUnitsView}</li>
* <ul>
* <li>{@link DBTraceDefinedDataView} nominally implements {@link TraceDefinedDataView}</li>
* <li>{@link DBTraceInstructionsView} nominally implements {@link TraceInstructionsView}</li>
* </ul>
* <li>{@link DBTraceUndefinedDataView} nominally implements {@link TraceUndefinedDataView}</li>
* </ul>
* </ul>
*
* <p>
* The view composition is not hierarchical, as each may represent a different combination, and one
* type may appear in several compositions. The single-type views are named first, then the composed
* views:
* <ul>
* <li>Instructions - single-type view</li>
* <li>Defined Data - single-type view</li>
* <li>Undefined Data - single-type view</li>
* </ul>
*
* <p>
* Note that while the API presents separate views for defined data and undefined units, both are
* represented by the type {@link TraceData}. Meaning, a client with a data unit in hand cannot
* determine whether it is defined or undefined from its type alone. It must invoke
* {@link Data#isDefined()} instead. While the implementation provides a separate type, which we see
* mirrors the hierarchy of the views' implementation, the client interfaces do not.
*
* <ul>
* <li>Code Units - Instructions, Defined Data, Undefined Data</li>
* <li>Data - Defined Data, Undefined Data</li>
* <li>Defined Units - Instructions, Defined Data</li>
* </ul>
*
* <p>
* The {@code MemoryView} classes compose the memory address spaces into a single view. These need
* not mirror the same implementation hierarchy as the views they compose. Other than special
* handling for compositions including undefined units, each memory view need not know anything
* about the views it composes. There are two abstract classes:
* {@link AbstractBaseDBTraceCodeUnitsMemoryView}, which is suitable for composing views without
* undefined units, and {@link AbstractWithUndefinedDBTraceCodeUnitsMemoryView}, which extends the
* base making it suitable for composing views with undefined units. The realizations each extend
* from the appropriate abstract class. Again, the abstract classes do not nominally implement
* {@link TraceBaseCodeUnitsView}. They structurally implement it, partly satisfying the
* requirements on the realizations, which nominally implement their appropriate interfaces.
*/
public class DBTraceCodeManager extends AbstractDBTraceSpaceBasedManager<DBTraceCodeSpace>
implements TraceCodeManager, DBTraceDelegatingManager<DBTraceCodeSpace> {
public static final String NAME = "Code";
@@ -302,13 +411,13 @@ public class DBTraceCodeManager
@Override
protected DBTraceCodeSpace createSpace(AddressSpace space, DBTraceSpaceEntry ent)
throws VersionException, IOException {
return new DBTraceCodeSpace(this, dbh, space, ent);
return new DBTraceCodeSpace(this, dbh, space, ent, null);
}
@Override
protected DBTraceCodeRegisterSpace createRegisterSpace(AddressSpace space, TraceThread thread,
protected DBTraceCodeSpace createRegisterSpace(AddressSpace space, TraceThread thread,
DBTraceSpaceEntry ent) throws VersionException, IOException {
return new DBTraceCodeRegisterSpace(this, dbh, space, ent, thread);
return new DBTraceCodeSpace(this, dbh, space, ent, thread);
}
@Override
@@ -337,19 +446,19 @@ public class DBTraceCodeManager
}
@Override
public DBTraceCodeRegisterSpace getCodeRegisterSpace(TraceThread thread,
public DBTraceCodeSpace getCodeRegisterSpace(TraceThread thread,
boolean createIfAbsent) {
return getForRegisterSpace(thread, 0, createIfAbsent);
}
@Override
public DBTraceCodeRegisterSpace getCodeRegisterSpace(TraceThread thread, int frameLevel,
public DBTraceCodeSpace getCodeRegisterSpace(TraceThread thread, int frameLevel,
boolean createIfAbsent) {
return getForRegisterSpace(thread, frameLevel, createIfAbsent);
}
@Override
public DBTraceCodeRegisterSpace getCodeRegisterSpace(TraceStackFrame frame,
public DBTraceCodeSpace getCodeRegisterSpace(TraceStackFrame frame,
boolean createIfAbsent) {
return getForRegisterSpace(frame, createIfAbsent);
}
@@ -378,7 +487,7 @@ public class DBTraceCodeManager
for (DBTraceCodeSpace codeSpace : memSpaces.values()) {
codeSpace.clearPlatform(Range.all(), codeSpace.all, guest, monitor);
}
for (DBTraceCodeRegisterSpace codeSpace : regSpaces.values()) {
for (DBTraceCodeSpace codeSpace : regSpaces.values()) {
// TODO: I don't know any way to get guest instructions into register space
// The mapping manager does (should) not allow guest register addresses
// TODO: Test this if I ever get guest data units
@@ -1,107 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.trace.database.listing;
import java.io.IOException;
import db.DBHandle;
import ghidra.program.model.address.AddressSpace;
import ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager.DBTraceSpaceEntry;
import ghidra.trace.model.listing.TraceCodeRegisterSpace;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.exception.VersionException;
public class DBTraceCodeRegisterSpace extends DBTraceCodeSpace implements TraceCodeRegisterSpace {
protected final TraceThread thread;
private final int frameLevel;
public DBTraceCodeRegisterSpace(DBTraceCodeManager manager, DBHandle dbh, AddressSpace space,
DBTraceSpaceEntry ent, TraceThread thread) throws VersionException, IOException {
super(manager, dbh, space, ent);
this.thread = thread;
this.frameLevel = ent.getFrameLevel();
}
@Override
public TraceThread getThread() {
return thread;
}
@Override
public int getFrameLevel() {
return frameLevel;
}
@Override
protected DBTraceInstructionsRegisterView createInstructionsView() {
return new DBTraceInstructionsRegisterView(this);
}
@Override
protected DBTraceDefinedDataRegisterView createDefinedDataView() {
return new DBTraceDefinedDataRegisterView(this);
}
@Override
protected DBTraceDefinedUnitsRegisterView createDefinedUnitsView() {
return new DBTraceDefinedUnitsRegisterView(this);
}
@Override
protected DBTraceUndefinedDataRegisterView createUndefinedDataView() {
return new DBTraceUndefinedDataRegisterView(this);
}
@Override
protected DBTraceDataRegisterView createDataView() {
return new DBTraceDataRegisterView(this);
}
@Override
protected DBTraceCodeUnitsRegisterView createCodeUnitsView() {
return new DBTraceCodeUnitsRegisterView(this);
}
@Override
public DBTraceCodeUnitsRegisterView codeUnits() {
return (DBTraceCodeUnitsRegisterView) codeUnits;
}
@Override
public DBTraceInstructionsRegisterView instructions() {
return (DBTraceInstructionsRegisterView) instructions;
}
@Override
public DBTraceDataRegisterView data() {
return (DBTraceDataRegisterView) data;
}
@Override
public DBTraceDefinedDataRegisterView definedData() {
return (DBTraceDefinedDataRegisterView) definedData;
}
@Override
public DBTraceUndefinedDataRegisterView undefinedData() {
return (DBTraceUndefinedDataRegisterView) undefinedData;
}
@Override
public DBTraceDefinedUnitsRegisterView definedUnits() {
return (DBTraceDefinedUnitsRegisterView) definedUnits;
}
}
@@ -39,6 +39,7 @@ import ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager.DBTraceSpace
import ghidra.trace.database.space.DBTraceSpaceBased;
import ghidra.trace.database.symbol.DBTraceReferenceManager;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.listing.TraceCodeManager;
import ghidra.trace.model.listing.TraceCodeSpace;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.ByteArrayUtils;
@@ -48,10 +49,19 @@ import ghidra.util.exception.CancelledException;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
/**
* A space managed by the {@link DBTraceCodeManager}
*
* <p>
* This implements {@link TraceCodeManager#getCodeSpace(AddressSpace, boolean)} and
* {@link TraceCodeManager#getCodeRegisterSpace(TraceThread, int, boolean)}.
*/
public class DBTraceCodeSpace implements TraceCodeSpace, DBTraceSpaceBased {
protected final DBTraceCodeManager manager;
protected final DBHandle dbh;
protected final AddressSpace space;
protected final TraceThread thread;
protected final int frameLevel;
protected final ReadWriteLock lock;
protected final Language baseLanguage;
protected final DBTrace trace;
@@ -70,11 +80,24 @@ public class DBTraceCodeSpace implements TraceCodeSpace, DBTraceSpaceBased {
protected DBTraceDefinedUnitsView definedUnits;
protected DBTraceCodeUnitsView codeUnits;
/**
* Construct a space
*
* @param manager the manager
* @param dbh the database handle
* @param space the address space
* @param ent an entry describing this space
* @param thread a thread, if applicable, for a per-thread/frame space
* @throws VersionException if there is already a table of a different version
* @throws IOException if there is trouble accessing the database
*/
public DBTraceCodeSpace(DBTraceCodeManager manager, DBHandle dbh, AddressSpace space,
DBTraceSpaceEntry ent) throws VersionException, IOException {
DBTraceSpaceEntry ent, TraceThread thread) throws VersionException, IOException {
this.manager = manager;
this.dbh = dbh;
this.space = space;
this.thread = thread;
this.frameLevel = ent.getFrameLevel();
this.lock = manager.getLock();
this.baseLanguage = manager.getBaseLanguage();
this.trace = manager.getTrace();
@@ -88,10 +111,10 @@ public class DBTraceCodeSpace implements TraceCodeSpace, DBTraceSpaceBased {
int frameLevel = ent.getFrameLevel();
instructionMapSpace = new DBTraceAddressSnapRangePropertyMapSpace<>(
DBTraceInstruction.tableName(space, threadKey), factory, lock, space,
DBTraceInstruction.tableName(space, threadKey), factory, lock, space, null, 0,
DBTraceInstruction.class, (t, s, r) -> new DBTraceInstruction(this, t, s, r));
dataMapSpace = new DBTraceAddressSnapRangePropertyMapSpace<>(
DBTraceData.tableName(space, threadKey, frameLevel), factory, lock, space,
DBTraceData.tableName(space, threadKey, frameLevel), factory, lock, space, null, 0,
DBTraceData.class, (t, s, r) -> new DBTraceData(this, t, s, r));
instructions = createInstructionsView();
@@ -102,30 +125,57 @@ public class DBTraceCodeSpace implements TraceCodeSpace, DBTraceSpaceBased {
codeUnits = createCodeUnitsView(); // dep: instructions,definedData,undefinedData
}
/**
* A factory method for the instructions view
*/
protected DBTraceInstructionsView createInstructionsView() {
return new DBTraceInstructionsView(this);
}
/**
* A factory method for the defined data view
*/
protected DBTraceDefinedDataView createDefinedDataView() {
return new DBTraceDefinedDataView(this);
}
/**
* A factory method for the defined units view
*/
protected DBTraceDefinedUnitsView createDefinedUnitsView() {
return new DBTraceDefinedUnitsView(this);
}
/**
* A factory method for the undefined data view
*/
protected DBTraceUndefinedDataView createUndefinedDataView() {
return new DBTraceUndefinedDataView(this);
}
/**
* A factory method for the data view
*/
protected DBTraceDataView createDataView() {
return new DBTraceDataView(this);
}
/**
* A factory method for the code units view
*/
protected DBTraceCodeUnitsView createCodeUnitsView() {
return new DBTraceCodeUnitsView(this);
}
/**
* Clear all units belonging to the given guest platform
*
* @param span the lifespan
* @param range the address range
* @param guest the guest platform
* @param monitor a monitor for progress
* @throws CancelledException if the monitor was cancelled
*/
void clearPlatform(Range<Long> span, AddressRange range, DBTraceGuestPlatform guest,
TaskMonitor monitor) throws CancelledException {
// Note "makeWay" does not apply here.
@@ -170,12 +220,12 @@ public class DBTraceCodeSpace implements TraceCodeSpace, DBTraceSpaceBased {
@Override
public TraceThread getThread() {
return null;
return thread;
}
@Override
public int getFrameLevel() {
return 0;
return frameLevel;
}
@Override
@@ -221,6 +271,20 @@ public class DBTraceCodeSpace implements TraceCodeSpace, DBTraceSpaceBased {
}
}
/**
* Notify this space that some bytes have changed
*
* <p>
* If any unit(s) contained the changed bytes, they may need to be truncated, deleted, and/or
* replaced. Instructions are generally truncated or deleted without replacement. A data unit
* may be replaced if its length would match that of the original.
*
* @param changed the boxes whose bytes changed
* @param snap the snap where the client requested the change
* @param start the starting address where the client requested the change
* @param oldBytes the old bytes
* @param newBytes the new bytes
*/
public void bytesChanged(Set<TraceAddressSnapRange> changed, long snap, Address start,
byte[] oldBytes, byte[] newBytes) {
AddressSet diffs = ByteArrayUtils.computeDiffsAddressSet(start, oldBytes, newBytes);
@@ -44,6 +44,13 @@ import ghidra.util.Saveable;
import ghidra.util.exception.NoValueException;
import ghidra.util.prop.PropertyVisitor;
/**
* A base interface for implementations of {@link TraceCodeUnit}
*
* <p>
* This behaves somewhat like a mixin, allowing it to be used on code units as well as data
* components, e.g., fields of a struct data unit.
*/
public interface DBTraceCodeUnitAdapter extends TraceCodeUnit, MemBufferAdapter {
@Override
@@ -16,11 +16,21 @@
package ghidra.trace.database.listing;
import ghidra.program.model.address.*;
import ghidra.trace.model.listing.TraceCodeManager;
import ghidra.trace.model.listing.TraceCodeUnitsView;
/**
* The implementation of {@link TraceCodeManager#codeUnits()}
*/
public class DBTraceCodeUnitsMemoryView extends
AbstractWithUndefinedDBTraceCodeUnitsMemoryView<DBTraceCodeUnitAdapter, DBTraceCodeUnitsView>
implements TraceCodeUnitsView {
/**
* Construct the view
*
* @param manager the manager
*/
public DBTraceCodeUnitsMemoryView(DBTraceCodeManager manager) {
super(manager);
}
@@ -1,31 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.trace.database.listing;
import ghidra.trace.model.listing.TraceCodeUnitsRegisterView;
import ghidra.trace.model.thread.TraceThread;
public class DBTraceCodeUnitsRegisterView extends DBTraceCodeUnitsView
implements TraceCodeUnitsRegisterView {
public DBTraceCodeUnitsRegisterView(DBTraceCodeSpace space) {
super(space);
}
@Override
public TraceThread getThread() {
return space.getThread();
}
}
@@ -20,12 +20,21 @@ import java.util.List;
import com.google.common.collect.Range;
import ghidra.program.model.address.AddressRange;
import ghidra.trace.model.listing.TraceCodeSpace;
import ghidra.trace.model.listing.TraceCodeUnitsView;
/**
* The implementation of {@link TraceCodeSpace#codeUnits()}
*/
public class DBTraceCodeUnitsView extends
AbstractComposedDBTraceCodeUnitsView<DBTraceCodeUnitAdapter, AbstractSingleDBTraceCodeUnitsView<? extends DBTraceCodeUnitAdapter>>
implements TraceCodeUnitsView {
/**
* Construct the view
*
* @param space the space, bound to an address space
*/
public DBTraceCodeUnitsView(DBTraceCodeSpace space) {
super(space, List.of(space.instructions, space.definedData, space.undefinedData));
}

Some files were not shown because too many files have changed in this diff Show More