mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Merge remote-tracking branch 'origin/GP-1103_ghidravore_fixed_issues_related_to_moving_memory_with_pinned_symbols--SQUASHED'
This commit is contained in:
commit
1c09b26f6b
7 changed files with 435 additions and 128 deletions
|
@ -33,18 +33,25 @@ import ghidra.program.model.mem.*;
|
|||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.util.AddressLabelInfo;
|
||||
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.exception.NotFoundException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
public class PinnedSymbolTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
private static int EXPECTED_PROCESSOR_SYMBOLS = 9;
|
||||
private static int EXPECTED_USER_SYMBOLS = 2;
|
||||
private static int ORIGINAL_BOB_ADDRESS = 4;
|
||||
private static int ORIGINAL_FUNCTION_ADDRESS = 0xc;
|
||||
|
||||
private Program program;
|
||||
private AddressSpace space;
|
||||
private int transactionID;
|
||||
private SymbolTable symbolTable;
|
||||
|
||||
private Address originalBobAddress;
|
||||
private Address originalFunctionAddress;
|
||||
|
||||
public PinnedSymbolTest() {
|
||||
super();
|
||||
}
|
||||
|
@ -56,22 +63,29 @@ public class PinnedSymbolTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
checkProcessorSymbolsInPlace(EXPECTED_PROCESSOR_SYMBOLS + EXPECTED_USER_SYMBOLS);
|
||||
assertNotNull(symbolTable.getPrimarySymbol(addr(4)));
|
||||
|
||||
program.setImageBase(addr(0x100), true);
|
||||
long imageBaseMove = 0x100;
|
||||
Address movedBobAddress = originalBobAddress.add(imageBaseMove);
|
||||
Address movedFunctionAddress = originalFunctionAddress.add(imageBaseMove);
|
||||
|
||||
program.setImageBase(addr(imageBaseMove), true);
|
||||
|
||||
// expect one new symbol for pinned function
|
||||
checkProcessorSymbolsInPlace(EXPECTED_PROCESSOR_SYMBOLS + EXPECTED_USER_SYMBOLS + 1);
|
||||
|
||||
// check bob symbol
|
||||
assertNotNull(symbolTable.getPrimarySymbol(addr(0x104)));
|
||||
assertEquals(0, symbolTable.getLabelHistory(addr(0x4)).length);
|
||||
assertEquals(1, symbolTable.getLabelHistory(addr(0x104)).length);
|
||||
assertNull(symbolTable.getPrimarySymbol(originalBobAddress));
|
||||
assertNotNull(symbolTable.getPrimarySymbol(movedBobAddress));
|
||||
|
||||
assertEquals(0, symbolTable.getLabelHistory(originalBobAddress).length);
|
||||
assertEquals(1, symbolTable.getLabelHistory(movedBobAddress).length);
|
||||
|
||||
// check function symbol - function should move, but pinned label should remain.
|
||||
Symbol symbol = symbolTable.getPrimarySymbol(addr(0xc));
|
||||
Symbol symbol = symbolTable.getPrimarySymbol(originalFunctionAddress);
|
||||
assertNotNull(symbol);
|
||||
assertEquals(SymbolType.LABEL, symbol.getSymbolType());
|
||||
assertEquals("MyFunction", symbol.getName());
|
||||
symbol = symbolTable.getPrimarySymbol(addr(0x10c));
|
||||
|
||||
symbol = symbolTable.getPrimarySymbol(movedFunctionAddress);
|
||||
assertNotNull(symbol);
|
||||
assertEquals(SymbolType.FUNCTION, symbol.getSymbolType());
|
||||
assertEquals(SourceType.DEFAULT, symbol.getSource());
|
||||
|
@ -84,25 +98,30 @@ public class PinnedSymbolTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
MemoryBlockException, MemoryConflictException, NotFoundException {
|
||||
|
||||
checkProcessorSymbolsInPlace(EXPECTED_PROCESSOR_SYMBOLS + EXPECTED_USER_SYMBOLS);
|
||||
assertNotNull(symbolTable.getPrimarySymbol(addr(4)));
|
||||
assertNotNull(symbolTable.getPrimarySymbol(originalBobAddress));
|
||||
|
||||
long moveAmount = 0x200;
|
||||
Address movedBobAddress = originalBobAddress.add(moveAmount);
|
||||
Address movedFunctionAddress = originalFunctionAddress.add(moveAmount);
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
MemoryBlock block = memory.getBlock(addr(0));
|
||||
memory.moveBlock(block, addr(0x200), TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
memory.moveBlock(block, addr(moveAmount), TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
|
||||
checkProcessorSymbolsInPlace(EXPECTED_PROCESSOR_SYMBOLS + EXPECTED_USER_SYMBOLS + 1);
|
||||
|
||||
// check bob symbol
|
||||
assertNotNull(symbolTable.getPrimarySymbol(addr(0x204)));
|
||||
assertEquals(0, symbolTable.getLabelHistory(addr(0x4)).length);
|
||||
assertEquals(1, symbolTable.getLabelHistory(addr(0x204)).length);
|
||||
assertNull(symbolTable.getPrimarySymbol(originalBobAddress));
|
||||
assertNotNull(symbolTable.getPrimarySymbol(movedBobAddress));
|
||||
assertEquals(0, symbolTable.getLabelHistory(originalBobAddress).length);
|
||||
assertEquals(1, symbolTable.getLabelHistory(movedBobAddress).length);
|
||||
|
||||
// check function symbol - function should move, but pinned label should remain.
|
||||
Symbol symbol = symbolTable.getPrimarySymbol(addr(0xc));
|
||||
Symbol symbol = symbolTable.getPrimarySymbol(originalFunctionAddress);
|
||||
assertNotNull(symbol);
|
||||
assertEquals(SymbolType.LABEL, symbol.getSymbolType());
|
||||
assertEquals("MyFunction", symbol.getName());
|
||||
symbol = symbolTable.getPrimarySymbol(addr(0x20c));
|
||||
symbol = symbolTable.getPrimarySymbol(movedFunctionAddress);
|
||||
assertNotNull(symbol);
|
||||
assertEquals(SymbolType.FUNCTION, symbol.getSymbolType());
|
||||
assertEquals(SourceType.DEFAULT, symbol.getSource());
|
||||
|
@ -113,7 +132,7 @@ public class PinnedSymbolTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
public void testDeleteMemoryBlock() throws LockException {
|
||||
|
||||
checkProcessorSymbolsInPlace(EXPECTED_PROCESSOR_SYMBOLS + EXPECTED_USER_SYMBOLS);
|
||||
assertNotNull(symbolTable.getPrimarySymbol(addr(4)));
|
||||
assertNotNull(symbolTable.getPrimarySymbol(originalBobAddress));
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
MemoryBlock block = memory.getBlock(addr(0));
|
||||
|
@ -122,17 +141,106 @@ public class PinnedSymbolTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
checkProcessorSymbolsInPlace(EXPECTED_PROCESSOR_SYMBOLS + 1);
|
||||
|
||||
// check bob symbol is gone
|
||||
assertNull(symbolTable.getPrimarySymbol(addr(4)));
|
||||
assertEquals(0, symbolTable.getLabelHistory(addr(0x4)).length);
|
||||
assertNull(symbolTable.getPrimarySymbol(originalBobAddress));
|
||||
assertEquals(0, symbolTable.getLabelHistory(originalBobAddress).length);
|
||||
|
||||
// check the pinned function symbol is now just a pinned code symbol
|
||||
Symbol symbol = symbolTable.getPrimarySymbol(addr(0xc));
|
||||
Symbol symbol = symbolTable.getPrimarySymbol(originalFunctionAddress);
|
||||
assertNotNull(symbol);
|
||||
assertEquals(SymbolType.LABEL, symbol.getSymbolType());
|
||||
assertEquals("MyFunction", symbol.getName());
|
||||
assertTrue(symbol.isPinned());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveMemoryBlockSymbolAlreadyExistsAtDestination() throws Exception {
|
||||
long moveAmount = 0x200;
|
||||
Address movedBobAddress = originalBobAddress.add(moveAmount);
|
||||
|
||||
symbolTable.createLabel(movedBobAddress, "Joe", SourceType.USER_DEFINED);
|
||||
|
||||
Symbol[] symbolsAtOrig = symbolTable.getSymbols(originalBobAddress);
|
||||
assertTrue(symbolsAtOrig[0].isPrimary());
|
||||
|
||||
Symbol[] symbolsAtMoved = symbolTable.getSymbols(movedBobAddress);
|
||||
assertTrue(symbolsAtMoved[0].isPrimary());
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
MemoryBlock block = memory.getBlock(addr(0));
|
||||
memory.moveBlock(block, addr(moveAmount), TaskMonitor.DUMMY);
|
||||
|
||||
symbolsAtOrig = symbolTable.getSymbols(originalBobAddress);
|
||||
assertEquals(0, symbolsAtOrig.length);
|
||||
|
||||
symbolsAtMoved = symbolTable.getSymbols(movedBobAddress);
|
||||
assertEquals(2, symbolsAtMoved.length);
|
||||
|
||||
assertEquals("Joe", symbolsAtMoved[0].getName());
|
||||
assertEquals("Bob", symbolsAtMoved[1].getName());
|
||||
|
||||
assertTrue(symbolsAtMoved[0].isPrimary()); // joe should be primary
|
||||
assertTrue(!symbolsAtMoved[1].isPrimary()); // bob should not be primary
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moveBlockWithFunctionFromOnePinnedSymbolToAnother() throws Exception {
|
||||
long moveAmount = 0x100;
|
||||
Address functionAddressAfterMove = addr(ORIGINAL_FUNCTION_ADDRESS + moveAmount);
|
||||
symbolTable.createLabel(functionAddressAfterMove, "TARGET", SourceType.USER_DEFINED);
|
||||
Symbol target = symbolTable.getPrimarySymbol(functionAddressAfterMove);
|
||||
target.setPinned(true);
|
||||
|
||||
assertEquals(SymbolType.LABEL, target.getSymbolType());
|
||||
assertTrue(target.isPinned());
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
MemoryBlock block = memory.getBlock(addr(0));
|
||||
memory.moveBlock(block, addr(moveAmount), TaskMonitor.DUMMY);
|
||||
|
||||
Symbol result = symbolTable.getPrimarySymbol(functionAddressAfterMove);
|
||||
assertEquals(SymbolType.FUNCTION, result.getSymbolType());
|
||||
assertEquals("TARGET", result.getName());
|
||||
assertTrue(result.isPinned());
|
||||
|
||||
Symbol leftover = symbolTable.getPrimarySymbol(originalFunctionAddress);
|
||||
assertEquals(SymbolType.LABEL, leftover.getSymbolType());
|
||||
assertEquals("MyFunction", leftover.getName());
|
||||
assertTrue(leftover.isPinned());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPinnedStayWhenBlockMovedOnTopOfThem() throws Exception {
|
||||
Address moveToAddress = addr(0x200);
|
||||
|
||||
Symbol symbol = symbolTable.createLabel(moveToAddress, "MyPinned", SourceType.USER_DEFINED);
|
||||
symbol.setPinned(true);
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
MemoryBlock block = memory.getBlock(addr(0));
|
||||
memory.moveBlock(block, moveToAddress, TaskMonitor.DUMMY);
|
||||
|
||||
SymbolIterator symbols = symbolTable.getSymbols("MyPinned");
|
||||
Symbol s = symbols.next();
|
||||
assertEquals(moveToAddress, s.getAddress());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLabelCollision() throws Exception {
|
||||
int moveAmount = 0x100;
|
||||
Address movedBobAddress = originalBobAddress.add(moveAmount);
|
||||
symbolTable.createLabel(movedBobAddress, "Bob", SourceType.USER_DEFINED);
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
MemoryBlock block = memory.getBlock(addr(0));
|
||||
memory.moveBlock(block, addr(0x100), TaskMonitor.DUMMY);
|
||||
|
||||
Symbol[] symbols = symbolTable.getSymbols(movedBobAddress);
|
||||
assertEquals(1, symbols.length);
|
||||
assertEquals("Bob", symbols[0].getName());
|
||||
}
|
||||
|
||||
private void checkProcessorSymbolsInPlace(int expectedSymbols) {
|
||||
assertEquals(expectedSymbols, symbolTable.getNumSymbols());// 8 processor symbols and 2 user defined
|
||||
assertNotNull(symbolTable.getPrimarySymbol(addr(0)));
|
||||
|
@ -160,12 +268,17 @@ public class PinnedSymbolTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
program = new ProgramDB("z80", lang, lang.getDefaultCompilerSpec(), this);
|
||||
symbolTable = program.getSymbolTable();
|
||||
space = program.getAddressFactory().getDefaultAddressSpace();
|
||||
|
||||
originalBobAddress = addr(ORIGINAL_BOB_ADDRESS);
|
||||
originalFunctionAddress = addr(ORIGINAL_FUNCTION_ADDRESS);
|
||||
|
||||
transactionID = program.startTransaction("Test");
|
||||
createMemBlock();
|
||||
createProcessorSymbols(lang);
|
||||
createBobSymbol();
|
||||
createPinnedFunctionSymbol();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void createProcessorSymbols(Language lang) throws InvalidInputException {
|
||||
|
@ -179,14 +292,14 @@ public class PinnedSymbolTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
}
|
||||
|
||||
private void createBobSymbol() throws InvalidInputException {
|
||||
symbolTable.createLabel(addr(4), "Bob", SourceType.USER_DEFINED);
|
||||
symbolTable.createLabel(originalBobAddress, "Bob", SourceType.USER_DEFINED);
|
||||
}
|
||||
|
||||
private void createPinnedFunctionSymbol()
|
||||
throws DuplicateNameException, InvalidInputException, OverlappingFunctionException {
|
||||
Address addr = addr(0xc);
|
||||
AddressSet set = new AddressSet(addr);
|
||||
Function fun = program.getFunctionManager().createFunction("MyFunction", addr, set,
|
||||
throws InvalidInputException, OverlappingFunctionException {
|
||||
AddressSet set = new AddressSet(originalFunctionAddress);
|
||||
Function fun = program.getFunctionManager()
|
||||
.createFunction("MyFunction", originalFunctionAddress, set,
|
||||
SourceType.USER_DEFINED);
|
||||
Symbol symbol = fun.getSymbol();
|
||||
symbol.setPinned(true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue