Skip to content

Commit 9e87e86

Browse files
committed
Improved memory handling
* Added dynamic initialization of an existing memory area while running emulation * Removed an inconvenient memory read error even when a block was previously initialized
1 parent c499242 commit 9e87e86

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

src/main/java/ghidraemu/GhidraEmuProvider.java

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import ghidra.app.util.viewer.listingpanel.ListingPanel;
3636
import ghidra.framework.plugintool.PluginTool;
3737
import ghidra.pcode.emulate.EmulateExecutionState;
38+
import ghidra.pcode.error.LowlevelError;
3839
import ghidra.pcode.memstate.MemoryFaultHandler;
3940
import ghidra.program.database.mem.FileBytes;
4041
import ghidra.program.model.address.Address;
@@ -459,7 +460,7 @@ public boolean updateStopEmu(){
459460
return true;
460461
}
461462

462-
public void interrupt(Address pc, String errMsg) {
463+
public void interrupt(Address pc, Address address, String errMsg) {
463464
Boolean isRunning = null;
464465
if (sw == null ) {
465466
isRunning = false;
@@ -469,15 +470,41 @@ public void interrupt(Address pc, String errMsg) {
469470
} else {
470471
isRunning = false;
471472
}
473+
}
474+
475+
// Let's try to give this instruction a chance again
476+
// if the address refers to an existing memory area
477+
if (address != null) {
478+
for (MemoryBlock block : program.getMemory().getBlocks()){
479+
if (block.contains(address)) {
480+
if (!block.isInitialized()) {
481+
int transactionID = -1;
482+
try {
483+
transactionID = program.startTransaction("Initialize the memory block");
484+
program.getMemory().convertToInitialized(block, (byte) 0);
485+
} catch (Exception ex){
486+
ex.printStackTrace();
487+
} finally {
488+
program.endTransaction(transactionID, true);
489+
plugin.console.addMessage(originator, "The memory block " + block.getName() + " was successfully initialized!");
490+
}
491+
return;
492+
} else {
493+
// Yes, oddities still occur. Let's skip it
494+
return;
495+
}
496+
}
497+
}
472498
}
473-
474499
if (isRunning) {
475500
if (!sw.isCancelled()){
476501
sw.publishWrap(errMsg);
477502
}
478503
} else {
479504
plugin.console.addMessage(originator, errMsg);
480-
}
505+
}
506+
507+
481508
// Update the emulation context before exit
482509
readEmuRegisters();
483510
readMemFromEmu(isRunning);
@@ -550,11 +577,11 @@ public boolean uninitializedRead(Address address, int size, byte[] buf, int bufO
550577
Register reg = program.getRegister(address, size);
551578
if (reg != null) {
552579
String badRegErr = "Uninitialized register READ at " + pc + ": " + reg;
553-
interrupt(pc, badRegErr);
580+
interrupt(pc, address, badRegErr);
554581
return true;
555582
}
556583
String badMemErr ="Uninitialized memory READ at pc = " + pc + " to address = " + address.toString(true) + " with size = " + size;
557-
interrupt(pc, badMemErr);
584+
interrupt(pc, address, badMemErr);
558585
return true;
559586
}
560587

@@ -563,7 +590,7 @@ public boolean unknownAddress(Address address, boolean write) {
563590
Address pc = emuHelper.getExecutionAddress();
564591
String access = write ? "written" : "read";
565592
String errMsg = "Unknown address " + access + " at " + pc + ": " + address;
566-
interrupt(pc, errMsg);
593+
interrupt(pc, address, errMsg);
567594
return false;
568595
}
569596
};
@@ -577,13 +604,13 @@ public boolean unknownAddress(Address address, boolean write) {
577604
public void checkCanceled() throws CancelledException {
578605
if (sw != null && !sw.isCancelled() && !sw.isDone()){
579606
// just running
580-
Address address = emuHelper.getExecutionAddress();
581-
Instruction currentInstruction = program.getListing().getInstructionAt(address);
607+
Address pc = emuHelper.getExecutionAddress();
608+
Instruction currentInstruction = program.getListing().getInstructionAt(pc);
582609
if (currentInstruction == null){
583-
interrupt(address, badInsn);
610+
interrupt(pc, null, badInsn);
584611
return;
585612
}
586-
addTracedIfNotLast(address);
613+
addTracedIfNotLast(pc);
587614

588615
// delayed branch instructions painting (SuperH, MIPS, Sparc)
589616
if (hasBranchDelaySlot){
@@ -788,7 +815,7 @@ public boolean readMemFromEmu(boolean isRunning) {
788815
} catch (Exception ex){
789816
ex.printStackTrace();
790817
} finally {
791-
program.endTransaction(transactionID, true);
818+
program.endTransaction(transactionID, true);
792819
}
793820
}
794821
break;

0 commit comments

Comments
 (0)