mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GT-3223_emteere cache of block name to block lookup
This commit is contained in:
parent
ded1fbbeb4
commit
9c3ae59860
2 changed files with 92 additions and 7 deletions
|
@ -15,20 +15,51 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.program.database.mem;
|
package ghidra.program.database.mem;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import ghidra.app.plugin.core.memory.UninitializedBlockCmd;
|
import ghidra.app.plugin.core.memory.UninitializedBlockCmd;
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
import ghidra.program.database.ProgramDB;
|
import ghidra.program.database.ProgramDB;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.address.AddressOverflowException;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.address.AddressRange;
|
||||||
import ghidra.program.model.mem.*;
|
import ghidra.program.model.address.AddressRangeImpl;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.address.AddressSet;
|
||||||
|
import ghidra.program.model.address.AddressSetView;
|
||||||
|
import ghidra.program.model.address.AddressSpace;
|
||||||
|
import ghidra.program.model.data.ArrayDataType;
|
||||||
|
import ghidra.program.model.data.ByteDataType;
|
||||||
|
import ghidra.program.model.data.DataType;
|
||||||
|
import ghidra.program.model.data.PointerDataType;
|
||||||
|
import ghidra.program.model.listing.Data;
|
||||||
|
import ghidra.program.model.listing.Function;
|
||||||
|
import ghidra.program.model.listing.Listing;
|
||||||
|
import ghidra.program.model.listing.ProgramFragment;
|
||||||
|
import ghidra.program.model.listing.ProgramModule;
|
||||||
|
import ghidra.program.model.mem.LiveMemoryHandler;
|
||||||
|
import ghidra.program.model.mem.LiveMemoryListener;
|
||||||
|
import ghidra.program.model.mem.Memory;
|
||||||
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
|
import ghidra.program.model.mem.MemoryBlock;
|
||||||
|
import ghidra.program.model.mem.MemoryBlockException;
|
||||||
|
import ghidra.program.model.mem.MemoryBlockSourceInfo;
|
||||||
|
import ghidra.program.model.mem.MemoryBlockStub;
|
||||||
|
import ghidra.program.model.mem.MemoryBlockType;
|
||||||
|
import ghidra.program.model.mem.MemoryConflictException;
|
||||||
|
import ghidra.program.model.symbol.Reference;
|
||||||
|
import ghidra.program.model.symbol.ReferenceManager;
|
||||||
|
import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
import ghidra.test.ToyProgramBuilder;
|
import ghidra.test.ToyProgramBuilder;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
@ -315,6 +346,41 @@ public class MemoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
MemoryBlock block = mem.getBlock(addr(95));
|
MemoryBlock block = mem.getBlock(addr(95));
|
||||||
assertEquals(newBlock, block);
|
assertEquals(newBlock, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetBlockByName() throws Exception {
|
||||||
|
|
||||||
|
MemoryBlock block1 = createBlock("Test1", addr(100), 100);
|
||||||
|
MemoryBlock block2 = createBlock("Test2", addr(300), 100);
|
||||||
|
|
||||||
|
MemoryBlock block = mem.getBlock("Test1");
|
||||||
|
assertEquals("Test1", block.getName());
|
||||||
|
assertEquals("get same block", block, block1);
|
||||||
|
|
||||||
|
mem.split(block, addr(150));
|
||||||
|
block = mem.getBlock("Test1");
|
||||||
|
assertEquals("Test1", block.getName());
|
||||||
|
assertEquals(50, block.getSize());
|
||||||
|
|
||||||
|
// non-existent block
|
||||||
|
block = mem.getBlock("NoExist");
|
||||||
|
assertNull(block);
|
||||||
|
|
||||||
|
// now exists
|
||||||
|
mem.getBlock("Test1").setName("NoExist");
|
||||||
|
block = mem.getBlock("NoExist");
|
||||||
|
assertEquals("NoExist", block.getName());
|
||||||
|
|
||||||
|
mem.removeBlock(block, new TaskMonitorAdapter());
|
||||||
|
block = mem.getBlock("NoExist");
|
||||||
|
assertNull("block should be deleted", block);
|
||||||
|
|
||||||
|
block = mem.getBlock("Test1");
|
||||||
|
assertNull("block deleted", block);
|
||||||
|
|
||||||
|
block = mem.getBlock("Test2");
|
||||||
|
assertEquals("Test2", block.getName());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSave() throws Exception {
|
public void testSave() throws Exception {
|
||||||
|
|
|
@ -59,6 +59,10 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
|
||||||
private AddressSet allInitializedAddrSet = new AddressSet();
|
private AddressSet allInitializedAddrSet = new AddressSet();
|
||||||
private MemoryBlock lastBlock;// the last accessed block
|
private MemoryBlock lastBlock;// the last accessed block
|
||||||
private LiveMemoryHandler liveMemory;
|
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 static MemoryBlock NoBlock = new MemoryBlockStub(); // placeholder for no block, not given out
|
||||||
|
|
||||||
Lock lock;
|
Lock lock;
|
||||||
private Set<MemoryBlock> potentialOverlappingBlocks;
|
private Set<MemoryBlock> potentialOverlappingBlocks;
|
||||||
|
@ -182,6 +186,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
|
||||||
lastBlock = null;
|
lastBlock = null;
|
||||||
blocks = newBlocks;
|
blocks = newBlocks;
|
||||||
addrMap.memoryMapChanged(this);
|
addrMap.memoryMapChanged(this);
|
||||||
|
nameBlockMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLanguage(Language newLanguage) {
|
public void setLanguage(Language newLanguage) {
|
||||||
|
@ -302,11 +307,22 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized MemoryBlock getBlock(String blockName) {
|
public synchronized MemoryBlock getBlock(String blockName) {
|
||||||
|
// find block that might have been cached from previous call
|
||||||
|
MemoryBlock memoryBlock = nameBlockMap.get(blockName);
|
||||||
|
if (memoryBlock == NoBlock) {
|
||||||
|
// found placeholder, have searched and found nothing before
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
for (MemoryBlock block : blocks) {
|
for (MemoryBlock block : blocks) {
|
||||||
if (block.getName().equals(blockName)) {
|
if (block.getName().equals(blockName)) {
|
||||||
|
nameBlockMap.put(blockName, block);
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store placeholder there is no memory block with that name
|
||||||
|
nameBlockMap.put(blockName, NoBlock);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,6 +390,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
|
||||||
if (program != null) {
|
if (program != null) {
|
||||||
program.setChanged(ChangeManager.DOCR_MEMORY_BLOCK_CHANGED, block, null);
|
program.setChanged(ChangeManager.DOCR_MEMORY_BLOCK_CHANGED, block, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// name could have changed
|
||||||
|
nameBlockMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fireBytesChanged(Address addr, int count) {
|
void fireBytesChanged(Address addr, int count) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue