mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-11-05 18:30:17 +00:00
GP-3572: Fix emu GUI crashes with mem-mapped PC
This commit is contained in:
parent
5e87119ef1
commit
bed48fe0bc
5 changed files with 64 additions and 30 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue