mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Merge remote-tracking branch 'origin/GT-3223_emteere_performanceIssues' into Ghidra_9.1
This commit is contained in:
commit
ea55499623
5 changed files with 160 additions and 32 deletions
|
@ -19,15 +19,39 @@ import java.math.BigInteger;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressIterator;
|
||||
import ghidra.program.model.address.AddressOutOfBoundsException;
|
||||
import ghidra.program.model.address.AddressOverflowException;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.lang.InstructionPrototype;
|
||||
import ghidra.program.model.lang.InsufficientBytesException;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.model.lang.UnknownContextException;
|
||||
import ghidra.program.model.lang.UnknownInstructionException;
|
||||
import ghidra.program.model.listing.ContextChangeException;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.listing.ProgramContext;
|
||||
import ghidra.program.model.mem.ByteMemBufferImpl;
|
||||
import ghidra.program.model.mem.DumbMemBufferImpl;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.util.ProgramContextImpl;
|
||||
import ghidra.program.model.symbol.FlowType;
|
||||
import ghidra.program.model.symbol.RefType;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.SymbolType;
|
||||
|
||||
/**
|
||||
* PseudoDisassembler.java
|
||||
|
@ -71,6 +95,8 @@ public class PseudoDisassembler {
|
|||
|
||||
private boolean respectExecuteFlag = false;
|
||||
|
||||
private AddressSetView executeSet;
|
||||
|
||||
/**
|
||||
* Create a pseudo disassembler for the given program.
|
||||
*/
|
||||
|
@ -85,17 +111,17 @@ public class PseudoDisassembler {
|
|||
|
||||
this.programContext = program.getProgramContext();
|
||||
}
|
||||
|
||||
public PseudoDisassembler(Language lang, Memory mem) {
|
||||
program = null;
|
||||
|
||||
this.language = lang;
|
||||
|
||||
this.memory = mem;
|
||||
|
||||
pointerSize = language.getDefaultSpace().getPointerSize();
|
||||
|
||||
programContext = new ProgramContextImpl(language.getRegisters());
|
||||
|
||||
/**
|
||||
* @return cached addressSet of executable memory blocks
|
||||
*/
|
||||
private AddressSetView getExecuteSet() {
|
||||
if (executeSet != null) {
|
||||
return executeSet;
|
||||
}
|
||||
|
||||
executeSet = memory.getExecuteSet();
|
||||
return executeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -615,8 +641,6 @@ public class PseudoDisassembler {
|
|||
return false;
|
||||
}
|
||||
|
||||
AddressSetView executeSet = memory.getExecuteSet();
|
||||
|
||||
RepeatInstructionByteTracker repeatInstructionByteTracker =
|
||||
new RepeatInstructionByteTracker(MAX_REPEAT_BYTES_LIMIT, null);
|
||||
|
||||
|
@ -777,8 +801,8 @@ public class PseudoDisassembler {
|
|||
}
|
||||
}
|
||||
// if respecting execute flag on memory, test to make sure we did flow into non-execute memory
|
||||
if (respectExecuteFlag && !executeSet.isEmpty() &&
|
||||
!executeSet.contains(flows[j])) {
|
||||
AddressSetView execSet = getExecuteSet();
|
||||
if (respectExecuteFlag && !execSet.isEmpty() && !execSet.contains(flows[j])) {
|
||||
if (!flows[j].isExternalAddress()) {
|
||||
MemoryBlock block = memory.getBlock(flows[j]);
|
||||
// flowing into non-executable, but readable memory is bad
|
||||
|
@ -878,8 +902,8 @@ public class PseudoDisassembler {
|
|||
}
|
||||
|
||||
// check that body does not wander into non-executable memory
|
||||
AddressSetView executeSet = program.getMemory().getExecuteSet();
|
||||
if (respectExecuteFlag && !executeSet.isEmpty() && !body.subtract(executeSet).isEmpty()) {
|
||||
AddressSetView execSet = getExecuteSet();
|
||||
if (respectExecuteFlag && !execSet.isEmpty() && !body.subtract(execSet).isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,10 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
|
|||
private AddressSet allInitializedAddrSet = new AddressSet();
|
||||
private MemoryBlock lastBlock;// the last accessed block
|
||||
private LiveMemoryHandler liveMemory;
|
||||
|
||||
// lazy hashmap of block names to blocks, must be reloaded if blocks are removed or added
|
||||
private HashMap<String,MemoryBlock> nameBlockMap = new HashMap<String, MemoryBlock>();
|
||||
private final static MemoryBlock NoBlock = new MemoryBlockStub(); // placeholder for no block, not given out
|
||||
|
||||
Lock lock;
|
||||
private Set<MemoryBlock> potentialOverlappingBlocks;
|
||||
|
@ -182,6 +186,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
|
|||
lastBlock = null;
|
||||
blocks = newBlocks;
|
||||
addrMap.memoryMapChanged(this);
|
||||
nameBlockMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public void setLanguage(Language newLanguage) {
|
||||
|
@ -302,11 +307,25 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
|
|||
*/
|
||||
@Override
|
||||
public synchronized MemoryBlock getBlock(String blockName) {
|
||||
// find block that might have been cached from previous call
|
||||
MemoryBlock memoryBlock = nameBlockMap.get(blockName);
|
||||
if (memoryBlock != null) {
|
||||
if (memoryBlock == NoBlock) {
|
||||
// found placeholder, have searched and found nothing before
|
||||
return null;
|
||||
}
|
||||
return memoryBlock;
|
||||
}
|
||||
|
||||
for (MemoryBlock block : blocks) {
|
||||
if (block.getName().equals(blockName)) {
|
||||
nameBlockMap.put(blockName, block);
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
||||
// store placeholder there is no memory block with that name
|
||||
nameBlockMap.put(blockName, NoBlock);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -374,6 +393,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
|
|||
if (program != null) {
|
||||
program.setChanged(ChangeManager.DOCR_MEMORY_BLOCK_CHANGED, block, null);
|
||||
}
|
||||
|
||||
// name could have changed
|
||||
nameBlockMap = new HashMap<>();
|
||||
}
|
||||
|
||||
void fireBytesChanged(Address addr, int count) {
|
||||
|
|
|
@ -390,7 +390,7 @@ class BigRefListV0 extends RefList {
|
|||
if (maxLevel < level) {
|
||||
maxLevel = level;
|
||||
}
|
||||
if (level > currentRefLevel) {
|
||||
if (level >= currentRefLevel) {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -342,7 +342,7 @@ class RefListV0 extends RefList {
|
|||
if (maxLevel < level) {
|
||||
maxLevel = level;
|
||||
}
|
||||
if (level > currentRefLevel) {
|
||||
if (level >= currentRefLevel) {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue