GP-3572: Fix emu GUI crashes with mem-mapped PC

This commit is contained in:
Dan 2023-06-23 17:30:00 -04:00
parent 5e87119ef1
commit bed48fe0bc
5 changed files with 64 additions and 30 deletions

View file

@ -43,10 +43,12 @@ import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.address.AddressSpace;
import ghidra.trace.model.*;
import ghidra.trace.model.Trace.TraceMemoryStateChangeType;
import ghidra.trace.model.Trace.TraceSnapshotChangeType;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.model.time.TraceSnapshot;
import ghidra.util.Msg;
import ghidra.util.Swing;
@ -249,7 +251,20 @@ public abstract class DebuggerReadsMemoryTrait {
// NB. provider should call contextChanged, updating actions
}
protected boolean isConsistent() {
TraceProgramView view = current.getView();
if (view == null || visible.isEmpty()) {
return true; // Some have special logic for empty
}
AddressSpace space = visible.getFirstRange().getAddressSpace();
int id = space.getSpaceID();
return space == view.getAddressFactory().getAddressSpace(id);
}
protected void doAutoRead() {
if (!isConsistent()) {
return;
}
autoSpec.readMemory(tool, current, visible).exceptionally(ex -> {
Msg.error(this, "Could not auto-read memory: " + ex);
return null;

View file

@ -65,8 +65,9 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, Loca
if (!thread.getLifespan().contains(snap)) {
return null;
}
TraceMemorySpace regs =
trace.getMemoryManager().getMemoryRegisterSpace(thread, frame, false);
TraceMemorySpace regs = reg.getAddressSpace().isRegisterSpace()
? trace.getMemoryManager().getMemoryRegisterSpace(thread, frame, false)
: trace.getMemoryManager().getMemorySpace(reg.getAddressSpace(), false);
if (regs == null) {
return null;
}
@ -106,10 +107,10 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, Loca
return false;
}
Register register = computeRegister(coordinates);
if (register == null) {
AddressSpace as = space.getAddressSpace();
if (register == null || register.getAddressSpace() != as) {
return false;
}
AddressSpace as = space.getAddressSpace();
AddressRange regRng = coordinates.getPlatform()
.getConventionalRegisterRange(as.isRegisterSpace() ? as : null, register);
return range.getRange().intersects(regRng);

View file

@ -309,9 +309,9 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
}
private void refreshRange(AddressRange range) {
TraceMemorySpace space = getRegisterMemorySpace(false);
TraceMemorySpace mem = getRegisterMemorySpace(range.getAddressSpace(), false);
// ... If I got an event for it, it ought to exist.
assert space != null;
assert mem != null;
// TODO: Just certain rows?
regsTableModel.fireTableDataChanged();
@ -852,7 +852,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
}
BigInteger getRegisterValue(Register register) {
TraceMemorySpace regs = getRegisterMemorySpace(false);
TraceMemorySpace regs = getRegisterMemorySpace(register.getAddressSpace(), false);
if (regs == null) {
return BigInteger.ZERO;
}
@ -921,13 +921,14 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
dataType = new PointerTypedef(null, ptrType.getDataType(), ptrType.getLength(),
ptrType.getDataTypeManager(), space);
}
TraceCodeSpace space = getRegisterMemorySpace(true).getCodeSpace(true);
TraceCodeSpace code =
getRegisterMemorySpace(register.getAddressSpace(), true).getCodeSpace(true);
long snap = current.getViewSnap();
TracePlatform platform = current.getPlatform();
space.definedUnits()
code.definedUnits()
.clear(platform, Lifespan.at(snap), register, TaskMonitor.DUMMY);
if (dataType != null) {
space.definedData().create(platform, Lifespan.nowOn(snap), register, dataType);
code.definedData().create(platform, Lifespan.nowOn(snap), register, dataType);
}
}
catch (CodeUnitInsertionException | CancelledException e) {
@ -998,11 +999,13 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
* values are populated.
*/
void prepareRegisterSpace() {
if (current.getThread() != null &&
current.getTrace().getObjectManager().getRootSchema() != null) {
try (Transaction tx =
current.getTrace().openTransaction("Create/initialize register space")) {
getRegisterMemorySpace(true);
Trace trace = current.getTrace();
if (current.getThread() != null && trace.getObjectManager().getRootSchema() != null) {
AddressSpace regSpace = current.getPlatform().getAddressFactory().getRegisterSpace();
if (regSpace != null) {
try (Transaction tx = trace.openTransaction("Create/initialize register space")) {
getRegisterMemorySpace(regSpace, true);
}
}
}
}
@ -1023,15 +1026,19 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
.unionedAddresses(snap -> mem.getAddressesWithState(snap,
platform.mapGuestToHost(platform.getLanguage().getRegisterAddresses()),
state -> state == TraceMemoryState.KNOWN));
TraceMemorySpace regs = getRegisterMemorySpace(false);
AddressSpace regSpace = current.getPlatform().getAddressFactory().getRegisterSpace();
if (regSpace == null) {
viewKnown = new AddressSet(viewKnownMem);
return;
}
TraceMemorySpace regs = getRegisterMemorySpace(regSpace, false);
if (regs == null) {
viewKnown = new AddressSet(viewKnownMem);
return;
}
AddressSetView hostRegs =
platform.mapGuestToHost(platform.getLanguage().getRegisterAddresses());
AddressSetView overlayRegs =
TraceRegisterUtils.getOverlaySet(regs.getAddressSpace(), hostRegs);
AddressSetView overlayRegs = TraceRegisterUtils.getOverlaySet(regSpace, hostRegs);
AddressSetView viewKnownRegs = view.getViewport()
.unionedAddresses(snap -> regs.getAddressesWithState(snap, overlayRegs,
state -> state == TraceMemoryState.KNOWN));
@ -1042,7 +1049,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
if (viewKnown == null) {
return false;
}
TraceMemorySpace regs = getRegisterMemorySpace(false);
TraceMemorySpace regs = getRegisterMemorySpace(register.getAddressSpace(), false);
if (regs == null && register.getAddressSpace().isRegisterSpace()) {
return false;
}
@ -1061,8 +1068,10 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
if (!isRegisterKnown(register)) {
return false;
}
TraceMemorySpace curSpace = getRegisterMemorySpace(current, false);
TraceMemorySpace prevSpace = getRegisterMemorySpace(previous, false);
TraceMemorySpace curSpace =
getRegisterMemorySpace(current, register.getAddressSpace(), false);
TraceMemorySpace prevSpace =
getRegisterMemorySpace(previous, register.getAddressSpace(), false);
if (prevSpace == null) {
return false;
}
@ -1124,7 +1133,12 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
}
protected static TraceMemorySpace getRegisterMemorySpace(DebuggerCoordinates coords,
boolean createIfAbsent) {
AddressSpace space, boolean createIfAbsent) {
if (!space.isRegisterSpace()) {
return coords.getTrace()
.getMemoryManager()
.getMemorySpace(space, createIfAbsent);
}
TraceThread thread = coords.getThread();
if (thread == null) {
return null;
@ -1134,8 +1148,9 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
.getMemoryRegisterSpace(thread, coords.getFrame(), createIfAbsent);
}
protected TraceMemorySpace getRegisterMemorySpace(boolean createIfAbsent) {
return getRegisterMemorySpace(current, createIfAbsent);
protected TraceMemorySpace getRegisterMemorySpace(AddressSpace space,
boolean createIfAbsent) {
return getRegisterMemorySpace(current, space, createIfAbsent);
}
protected TraceCodeSpace getRegisterCodeSpace(boolean createIfAbsent) {

View file

@ -353,14 +353,15 @@ public class DebuggerLegacyStackPanel extends JPanel {
currentStack = null;
Trace curTrace = current.getTrace();
TraceMemorySpace regs =
curTrace.getMemoryManager().getMemoryRegisterSpace(current.getThread(), false);
if (regs == null) {
Register pc = curTrace.getBaseLanguage().getProgramCounter();
if (pc == null) {
contextChanged();
return;
}
Register pc = curTrace.getBaseLanguage().getProgramCounter();
if (pc == null) {
TraceMemorySpace regs = pc.getAddressSpace().isRegisterSpace()
? curTrace.getMemoryManager().getMemoryRegisterSpace(current.getThread(), false)
: curTrace.getMemoryManager().getMemorySpace(pc.getAddressSpace(), false);
if (regs == null) {
contextChanged();
return;
}

View file

@ -225,7 +225,9 @@ public class DisassembleAtPcDebuggerBot implements DebuggerBot {
TraceData pcUnit = null;
try (Transaction tx =
trace.openTransaction("Disassemble: PC is code pointer")) {
TraceCodeSpace regCode = codeManager.getCodeRegisterSpace(thread, frameLevel, true);
TraceCodeSpace regCode = pc.getAddressSpace().isRegisterSpace()
? codeManager.getCodeRegisterSpace(thread, frameLevel, true)
: codeManager.getCodeSpace(pc.getAddressSpace(), true);
// TODO: Should be same platform as pc, not necessarily base
AddressSpace space = trace.getBaseAddressFactory().getDefaultAddressSpace();
PointerTypedef type = new PointerTypedef(null, VoidDataType.dataType,