Merge remote-tracking branch 'origin/patch'

This commit is contained in:
ghidra1 2020-11-24 11:39:15 -05:00
commit 133d6c251f
34 changed files with 383 additions and 667 deletions

View File

@ -69,7 +69,7 @@ abstract class AbstractAddMemoryBlockCmd implements Command {
protected abstract MemoryBlock createMemoryBlock(Memory memory)
throws LockException, MemoryConflictException, AddressOverflowException,
DuplicateNameException, CancelledException;
CancelledException;
@Override
public boolean applyTo(DomainObject obj) {
@ -95,9 +95,6 @@ abstract class AbstractAddMemoryBlockCmd implements Command {
catch (MemoryConflictException e) {
message = e.getMessage();
}
catch (DuplicateNameException e) {
message = "Duplicate Name: " + e.getMessage();
}
catch (IllegalStateException e) {
message = e.getMessage();
}

View File

@ -19,7 +19,6 @@ import ghidra.framework.store.LockException;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.mem.*;
import ghidra.util.exception.DuplicateNameException;
/**
* Command for adding Bit-mapped memory blocks.
@ -56,7 +55,7 @@ public class AddBitMappedMemoryBlockCmd extends AbstractAddMemoryBlockCmd {
@Override
protected MemoryBlock createMemoryBlock(Memory memory)
throws LockException, MemoryConflictException, AddressOverflowException,
IllegalArgumentException, DuplicateNameException {
IllegalArgumentException {
return memory.createBitMappedBlock(name, start, mappedAddress, length, isOverlay);
}

View File

@ -20,7 +20,6 @@ import ghidra.program.database.mem.ByteMappingScheme;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.mem.*;
import ghidra.util.exception.DuplicateNameException;
/**
* Command for adding byte-mapped memory blocks
@ -83,7 +82,7 @@ public class AddByteMappedMemoryBlockCmd extends AbstractAddMemoryBlockCmd {
@Override
protected MemoryBlock createMemoryBlock(Memory memory)
throws LockException, MemoryConflictException, AddressOverflowException,
IllegalArgumentException, DuplicateNameException {
IllegalArgumentException {
return memory.createByteMappedBlock(name, start, mappedAddress, length,
byteMappingScheme,
isOverlay);

View File

@ -20,7 +20,6 @@ import ghidra.program.database.mem.FileBytes;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.mem.*;
import ghidra.util.exception.DuplicateNameException;
/**
* Command for adding a new memory block using bytes from an imported {@link FileBytes} object.
@ -55,7 +54,7 @@ public class AddFileBytesMemoryBlockCmd extends AbstractAddMemoryBlockCmd {
@Override
protected MemoryBlock createMemoryBlock(Memory memory) throws LockException,
MemoryConflictException, AddressOverflowException, DuplicateNameException {
MemoryConflictException, AddressOverflowException {
return memory.createInitializedBlock(name, start, fileBytes, offset, length, isOverlay);
}

View File

@ -20,7 +20,6 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.mem.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
/**
* Command for adding a new memory block initialized with a specific byte.
@ -54,7 +53,7 @@ public class AddInitializedMemoryBlockCmd extends AbstractAddMemoryBlockCmd {
@Override
protected MemoryBlock createMemoryBlock(Memory memory)
throws LockException, MemoryConflictException, AddressOverflowException,
DuplicateNameException, CancelledException {
CancelledException {
return memory.createInitializedBlock(name, start, length, initialValue, null, isOverlay);
}

View File

@ -19,7 +19,6 @@ import ghidra.framework.store.LockException;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.mem.*;
import ghidra.util.exception.DuplicateNameException;
/**
* Command for adding uninitialized memory blocks
@ -47,7 +46,7 @@ public class AddUninitializedMemoryBlockCmd extends AbstractAddMemoryBlockCmd {
@Override
protected MemoryBlock createMemoryBlock(Memory memory) throws LockException,
MemoryConflictException, AddressOverflowException, DuplicateNameException {
MemoryConflictException, AddressOverflowException {
return memory.createUninitializedBlock(name, start, length, isOverlay);
}

View File

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +15,11 @@
*/
package ghidra.app.merge.memory;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import javax.swing.SwingUtilities;
import ghidra.app.merge.*;
import ghidra.app.util.HelpTopics;
import ghidra.framework.store.LockException;
@ -24,14 +28,10 @@ import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.exception.*;
import ghidra.util.exception.AssertException;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import javax.swing.SwingUtilities;
/**
* Merge memory blocks that have changes to the name, permissions or comments.
*
@ -96,6 +96,7 @@ public class MemoryMergeManager implements MergeResolver {
/* (non-Javadoc)
* @see ghidra.app.merge.MergeResolver#getName()
*/
@Override
public String getName() {
return "Memory Block Merger";
}
@ -103,6 +104,7 @@ public class MemoryMergeManager implements MergeResolver {
/* (non-Javadoc)
* @see ghidra.app.merge.MergeResolver#getDescription()
*/
@Override
public String getDescription() {
return "Merge Memory Blocks";
}
@ -110,6 +112,7 @@ public class MemoryMergeManager implements MergeResolver {
/* (non-Javadoc)
* @see ghidra.app.merge.MergeResolver#apply()
*/
@Override
public void apply() {
conflictOption = mergePanel.getSelectedOption();
@ -123,6 +126,7 @@ public class MemoryMergeManager implements MergeResolver {
/* (non-Javadoc)
* @see ghidra.app.merge.MergeResolver#cancel()
*/
@Override
public void cancel() {
conflictOption = CANCELED;
}
@ -130,6 +134,7 @@ public class MemoryMergeManager implements MergeResolver {
/* (non-Javadoc)
* @see ghidra.app.merge.MergeResolver#merge(ghidra.util.task.TaskMonitor)
*/
@Override
public void merge(TaskMonitor monitor) {
mergeManager.setInProgress(MEMORY_PHASE);
@ -325,12 +330,11 @@ public class MemoryMergeManager implements MergeResolver {
private void processConflicts() throws CancelledException {
int currentBlockIndex = -1;
for (int i = 0; i < conflictList.size(); i++) {
for (ConflictInfo info : conflictList) {
if (currentMonitor.isCancelled()) {
throw new CancelledException();
}
ConflictInfo info = conflictList.get(i);
if (currentBlockIndex != info.index) {
currentMonitor.setProgress(++progressIndex);
}
@ -414,10 +418,6 @@ public class MemoryMergeManager implements MergeResolver {
try {
resultBlocks[info.index].setName(getUniqueBlockName(sourceBlock.getName()));
}
catch (DuplicateNameException e) {
// should not happen since we created a unique name
throw new AssertException();
}
catch (LockException e) {
// should not happen since overlay name change should not happen during merge
throw new AssertException();
@ -439,6 +439,7 @@ public class MemoryMergeManager implements MergeResolver {
final String myStr, final String origStr) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
if (mergePanel == null) {
mergePanel = new MemoryMergePanel(mergeManager, conflictCount);
@ -494,10 +495,6 @@ public class MemoryMergeManager implements MergeResolver {
try {
resultBlocks[index].setName(getUniqueBlockName(myName));
}
catch (DuplicateNameException e) {
// should not happen since we created a unique name
throw new AssertException();
}
catch (LockException e) {
// should not happen since overlay name change should not happen during merge
throw new AssertException();
@ -555,8 +552,7 @@ public class MemoryMergeManager implements MergeResolver {
}
private boolean hasConflict(int index) {
for (int i = 0; i < conflictList.size(); i++) {
ConflictInfo info = conflictList.get(i);
for (ConflictInfo info : conflictList) {
if (index == info.index) {
return true;
}
@ -564,6 +560,7 @@ public class MemoryMergeManager implements MergeResolver {
return false;
}
@Override
public String[][] getPhases() {
return new String[][] { MEMORY_PHASE };
}

View File

@ -25,7 +25,6 @@ import ghidra.program.database.mem.FileBytes;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.util.NamingUtilities;
import ghidra.util.datastruct.StringKeyIndexer;
import ghidra.util.exception.AssertException;
@ -294,7 +293,7 @@ class AddBlockModel {
private void validateInfo() {
message = "";
isValid = hasValidName() && hasValidStartAddress() && hasValidLength() &&
hasNoMemoryConflicts() && hasMappedAddressIfNeeded() && hasUniqueNameIfOverlay() &&
hasNoMemoryConflicts() && hasMappedAddressIfNeeded() &&
hasInitialValueIfNeeded() && hasFileBytesInfoIfNeeded() && isOverlayIfOtherSpace();
}
@ -335,21 +334,6 @@ class AddBlockModel {
return false;
}
private boolean hasUniqueNameIfOverlay() {
if (!isOverlay) {
return true;
}
AddressFactory factory = program.getAddressFactory();
AddressSpace[] spaces = factory.getAddressSpaces();
for (AddressSpace space : spaces) {
if (space.getName().equals(blockName)) {
message = "Address Space named " + blockName + " already exists";
return false;
}
}
return true;
}
private boolean isOverlayIfOtherSpace() {
if (startAddr.getAddressSpace().equals(AddressSpace.OTHER_SPACE)) {
if (!isOverlay) {
@ -422,14 +406,13 @@ class AddBlockModel {
message = "Please enter a name";
return false;
}
if (nameExists(blockName)) {
message = "Block name already exists";
return false;
}
if (!NamingUtilities.isValidName(blockName)) {
if (!Memory.isValidMemoryBlockName(blockName)) {
message = "Block name is invalid";
return false;
}
if (nameExists(blockName)) {
message = "Warning! Block name already exists";
}
return true;
}

View File

@ -176,11 +176,6 @@ class MemoryMapManager {
return true;
}
boolean isDuplicateName(String name) {
// block names may not duplicate existing address spaces (includes overlay blocks)
return program.getAddressFactory().getAddressSpace(name) != null;
}
void setProgram(Program program) {
this.program = program;
}
@ -279,6 +274,8 @@ class MemoryMapManager {
return false;
}
catch (LockException e) {
msg = e.getMessage();
return false;
}
MemoryBlock newBlock = memory.getBlock(newStart);
try {
@ -288,10 +285,6 @@ class MemoryMapManager {
msg = e.getMessage();
return false;
}
catch (DuplicateNameException e) {
msg = e.getMessage();
return false;
}
return true;
}

View File

@ -37,7 +37,6 @@ import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.util.Msg;
import ghidra.util.exception.DuplicateNameException;
class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> {
@ -267,16 +266,11 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> {
if (name.equals(block.getName())) {
break;
}
if (!Memory.isValidAddressSpaceName(name)) {
if (!Memory.isValidMemoryBlockName(name)) {
Msg.showError(this, provider.getComponent(), "Invalid Name",
"Invalid Memory Block Name: " + name);
break;
}
if (provider.getMemoryMapManager().isDuplicateName(name)) {
Msg.showError(this, provider.getComponent(), "Duplicate Name",
"Address space/overlay named " + name + " already exists.");
break;
}
if (!name.equals(block.getName())) {
int id = program.startTransaction("Rename Memory Block");
try {
@ -288,11 +282,6 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> {
this.provider.setStatusText(e.getMessage());
return;
}
catch (DuplicateNameException e) {
program.endTransaction(id, false);
this.provider.setStatusText(e.getMessage());
return;
}
catch (RuntimeException e1) {
program.endTransaction(id, false);
throw e1;

View File

@ -85,14 +85,10 @@ class SplitBlockDialog extends DialogComponentProvider {
newBlockName = block.getName() + ".split";
blockTwoNameField.setText(newBlockName);
}
if (!Memory.isValidAddressSpaceName(newBlockName)) {
if (!Memory.isValidMemoryBlockName(newBlockName)) {
setStatusText("Invalid Block Name: " + newBlockName);
return;
}
if (plugin.getMemoryMapManager().isDuplicateName(newBlockName)) {
setStatusText("Address space/overlay named " + newBlockName + " already exists.");
return;
}
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
plugin.getMemoryMapManager().splitBlock(block, blockTwoStart.getAddress(), newBlockName);
close();

View File

@ -227,8 +227,9 @@ public class MemoryBlockUtils {
block = program.getMemory().createInitializedBlock(name, start, fileBytes, offset,
length, isOverlay);
}
catch (MemoryConflictException | DuplicateNameException e) {
block = createBlockNoDuplicateName(program, name, start, fileBytes, offset, length);
catch (MemoryConflictException e) {
block = program.getMemory()
.createInitializedBlock(name, start, fileBytes, offset, length, true);
log.appendMsg("Conflict attempting to create memory block: " + name +
" at address " + start.toString() + " Created block in new overlay instead");
}
@ -242,22 +243,6 @@ public class MemoryBlockUtils {
return block;
}
private static MemoryBlock createBlockNoDuplicateName(Program program, String blockName,
Address start, FileBytes fileBytes, long offset, long length)
throws LockException, MemoryConflictException, AddressOverflowException {
int count = 1;
String name = blockName;
while (true) {
try {
return program.getMemory().createInitializedBlock(name, start, fileBytes, offset,
length, true);
}
catch (DuplicateNameException e) {
name = blockName + "_" + count++;
}
}
}
/**
* Creates a new initialized block in memory using the bytes from the given input stream.
* If there is a conflict when creating this block (some other block occupies at least some
@ -300,9 +285,11 @@ public class MemoryBlockUtils {
catch (MemoryConflictException e) {
block = memory.createInitializedBlock(name, start, dataInput, dataLength, monitor,
true);
log.appendMsg("Conflict attempting to create memory block: " + name +
" at address " + start.toString() + " Created block in new overlay instead");
}
}
catch (LockException | DuplicateNameException | MemoryConflictException e) {
catch (LockException | MemoryConflictException e) {
throw new RuntimeException(e);
}
catch (CancelledException e) {

View File

@ -225,13 +225,7 @@ public class MzLoader extends AbstractLibrarySupportLoader {
mem.split(block, splitAddr);
mem.join(blocks[i - 1], blocks[i]);
blocks = mem.getBlocks();
try {
blocks[i].setName(oldName);
}
catch (DuplicateNameException e) {
throw new AssertException(e);
}
blocks[i].setName(oldName);
break;
}
}

View File

@ -23,7 +23,6 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.util.Msg;
import ghidra.util.SystemUtilities;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
@ -328,8 +327,6 @@ public class MemoryDiff {
&& blockDiff.isNameDifferent()) {
try {
block1.setName(block2.getName());
} catch (DuplicateNameException e) {
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
} catch (LockException e) {
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
}

View File

@ -30,7 +30,8 @@ import ghidra.framework.store.LockException;
import ghidra.program.database.*;
import ghidra.program.model.listing.ProgramChangeSet;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.util.exception.*;
import ghidra.util.exception.AssertException;
import ghidra.util.exception.CancelledException;
public class MemoryMergeManagerTest extends AbstractMergeTest {
@ -49,9 +50,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[0].setName("LatestText");
commit = true;
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -71,9 +69,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
try {
blocks[0].setName("MY_Text");
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -106,9 +101,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[0].setName("LatestText");
commit = true;
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -128,9 +120,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
try {
blocks[0].setName("MY_Text");
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -162,9 +151,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[0].setName("LatestText");
commit = true;
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -184,9 +170,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
try {
blocks[0].setName("MY_Text");
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -350,9 +333,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
try {
blocks[4].setName("special-debug");
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -384,9 +364,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[4].setExecute(true);
blocks[4].setName("not-used");
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -715,9 +692,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[2].setComment("LatestResource");
commit = true;
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -739,9 +713,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[1].setName("My_Data");
blocks[2].setComment("My_Resource");
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}

View File

@ -262,8 +262,8 @@ public class AddBlockModelTest extends AbstractGhidraHeadedIntegrationTest
}
@Test
public void testDuplicateNameSetting() {
model.setBlockName(".data");
public void testInvalidNameSetting() {
model.setBlockName("");
assertTrue(!model.isValidInfo());
assertTrue(model.getMessage().length() > 0);
}
@ -271,11 +271,12 @@ public class AddBlockModelTest extends AbstractGhidraHeadedIntegrationTest
@Test
public void testDuplicateName() {
model.setBlockName(".data");
model.setOverlay(false);
model.setStartAddress(getAddr(0x100));
model.setLength(100);
model.setBlockType(MemoryBlockType.DEFAULT);
model.setInitialValue(0xa);
assertFalse(model.execute());
assertTrue(model.execute());
}
@Test

View File

@ -502,6 +502,7 @@ public class MemoryMapProvider2Test extends AbstractGhidraHeadedIntegrationTest
JTextField nameField =
(JTextField) findComponentByName(d.getComponent(), "Block Name");
JTextField lengthField = (JTextField) findComponentByName(d.getComponent(), "Length");
JTextField commentField =
(JTextField) findComponentByName(d.getComponent(), "Comment");
JCheckBox executeCB = (JCheckBox) findComponentByName(d.getComponent(), "Execute");
@ -512,15 +513,16 @@ public class MemoryMapProvider2Test extends AbstractGhidraHeadedIntegrationTest
runSwing(() -> {
nameField.setText(".rsrc");
lengthField.setText("0x100");
commentField.setText("this is a block test");
initialValue.setText("0xb");
executeCB.setSelected(true);
});
assertFalse(okButton.isEnabled());
assertTrue(okButton.isEnabled());
String msg = findLabelStr(d.getComponent(), "statusLabel");
assertEquals("Block name already exists", msg);
assertFalse(okButton.isEnabled());
assertEquals("Warning! Block name already exists", msg);
close(d);
}

View File

@ -437,7 +437,7 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
runSwing(() -> {
blockTwoLength.setText("0x2000");
blockTwoName.setText("split &%");
blockTwoName.setText("split\t");
});
assertTrue(okButton.isEnabled());
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));

View File

@ -135,7 +135,7 @@ public class MemoryBlockUtilTest extends AbstractGhidraHeadedIntegrationTest {
}
@Test
public void testDuplicateExceptionHandling() throws Exception {
public void testDuplicateHandling() throws Exception {
ByteProvider byteProvider = new ByteArrayProvider(new byte[1000]);
FileBytes fileBytes =
MemoryBlockUtils.createFileBytes(prog, byteProvider, TaskMonitor.DUMMY);
@ -151,8 +151,12 @@ public class MemoryBlockUtilTest extends AbstractGhidraHeadedIntegrationTest {
assertEquals(3, blocks.length);
assertEquals("test", blocks[0].getName());
assertEquals("test_1", blocks[1].getName());
assertEquals("test_2", blocks[2].getName());
assertEquals("test", blocks[1].getName());
assertEquals("test", blocks[2].getName());
assertEquals("test", blocks[0].getStart().getAddressSpace().getName());
assertEquals("test.1", blocks[1].getStart().getAddressSpace().getName());
assertEquals("test.2", blocks[2].getStart().getAddressSpace().getName());
}

View File

@ -23,7 +23,7 @@ import ghidra.program.model.address.*;
import ghidra.program.model.mem.*;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv;
import ghidra.util.task.TaskMonitorAdapter;
import ghidra.util.task.TaskMonitor;
public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest {
private TestEnv env;
@ -222,6 +222,45 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
}
@Test
public void testOverlayRename() throws Exception {
ProgramBuilder builder = new ProgramBuilder("Test", ProgramBuilder._TOY, this);
program = builder.getProgram();
AddressFactory af = program.getAddressFactory();
int transactionID = program.startTransaction(testName.getMethodName());
try {
MemoryBlock overlayBlock1 = program.getMemory()
.createInitializedBlock("my overlay x", af.getAddress("1000"), 0x100,
(byte) 0x11, TaskMonitor.DUMMY, true);
MemoryBlock overlayBlock2 = program.getMemory()
.createInitializedBlock("my overlay:x", af.getAddress("1000"), 0x100,
(byte) 0x11, TaskMonitor.DUMMY, true);
assertEquals("my_overlay_x", overlayBlock1.getStart().getAddressSpace().getName());
assertEquals("my_overlay_x.1", overlayBlock2.getStart().getAddressSpace().getName());
overlayBlock1.setName("my new name");
assertEquals("my new name", overlayBlock1.getName());
assertEquals("my_new_name", overlayBlock1.getStart().getAddressSpace().getName());
assertNull(af.getAddressSpace("my_overlay_x"));
assertNotNull(af.getAddressSpace("my_new_name"));
overlayBlock2.setName("my new name");
assertEquals("my new name", overlayBlock2.getName());
assertEquals("my_new_name.1", overlayBlock2.getStart().getAddressSpace().getName());
assertNull(af.getAddressSpace("my_overlay_x.1"));
assertNotNull(af.getAddressSpace("my_new_name.1"));
}
finally {
program.endTransaction(transactionID, true);
}
}
private void doTest() throws Exception {
AddressFactory af = program.getAddressFactory();
@ -232,7 +271,7 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
MemoryBlock overlayBlock1 = null;
try {
overlayBlock1 = program.getMemory().createInitializedBlock(".overlay1",
af.getAddress("1000"), 0x100, (byte) 0x11, TaskMonitorAdapter.DUMMY_MONITOR, true);
af.getAddress("1000"), 0x100, (byte) 0x11, TaskMonitor.DUMMY, true);
}
finally {
program.endTransaction(transactionID, true);
@ -248,7 +287,7 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
transactionID = program.startTransaction(testName.getMethodName());
try {
overlayBlock1 = program.getMemory().getBlock(overlayBlock1.getName());
program.getMemory().removeBlock(overlayBlock1, TaskMonitorAdapter.DUMMY_MONITOR);
program.getMemory().removeBlock(overlayBlock1, TaskMonitor.DUMMY);
}
finally {
program.endTransaction(transactionID, true);
@ -267,26 +306,38 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
MemoryBlock overlayBlock4 = null;
try {
overlayBlock2 = program.getMemory().createInitializedBlock(".overlay2",
af.getAddress("2000"), 0x200, (byte) 0x22, TaskMonitorAdapter.DUMMY_MONITOR, true);
overlayBlock3 = program.getMemory().createInitializedBlock(".overlay3",
af.getAddress("3000"), 0x300, (byte) 0x33, TaskMonitorAdapter.DUMMY_MONITOR, true);
overlayBlock4 = program.getMemory().createInitializedBlock(".overlay4",
af.getAddress("4000"), 0x400, (byte) 0x44, TaskMonitorAdapter.DUMMY_MONITOR, true);
af.getAddress("2000"), 0x200, (byte) 0x22, TaskMonitor.DUMMY, true);
overlayBlock3 = program.getMemory()
.createInitializedBlock("my_overlay_x",
af.getAddress("3000"), 0x300, (byte) 0x33, TaskMonitor.DUMMY, true);
overlayBlock4 = program.getMemory()
.createInitializedBlock("my overlay:x",
af.getAddress("4000"), 0x400, (byte) 0x44, TaskMonitor.DUMMY, true);
}
finally {
program.endTransaction(transactionID, true);
}
assertEquals(origSpaceCount + 4, af.getNumAddressSpaces());
MemoryBlock[] blocks = program.getMemory().getBlocks();
assertEquals(overlayBlock1.getName(), blocks[origBlockCount + 0].getName());
assertEquals(overlayBlock2.getName(), blocks[origBlockCount + 1].getName());
assertEquals(overlayBlock3.getName(), blocks[origBlockCount + 2].getName());
assertEquals(overlayBlock4.getName(), blocks[origBlockCount + 3].getName());
assertEquals(".overlay1", blocks[origBlockCount + 0].getName());
assertEquals(".overlay2", blocks[origBlockCount + 1].getName());
assertEquals("my_overlay_x", blocks[origBlockCount + 2].getName());
assertEquals("my_overlay_x",
blocks[origBlockCount + 2].getStart().getAddressSpace().getName());
assertEquals("my overlay:x", blocks[origBlockCount + 3].getName());
assertEquals("my_overlay_x.1",
blocks[origBlockCount + 3].getStart().getAddressSpace().getName());
AddressSpace ovSpace3 = program.getAddressFactory().getAddressSpace("my_overlay_x");
assertNotNull(ovSpace3);
AddressSpace ovSpace4 = program.getAddressFactory().getAddressSpace("my_overlay_x.1");
assertNotNull(ovSpace4);
transactionID = program.startTransaction(testName.getMethodName());
try {
program.getMemory().removeBlock(overlayBlock2, TaskMonitorAdapter.DUMMY_MONITOR);
program.getMemory().removeBlock(overlayBlock3, TaskMonitorAdapter.DUMMY_MONITOR);
program.getMemory().removeBlock(overlayBlock2, TaskMonitor.DUMMY);
program.getMemory().removeBlock(overlayBlock3, TaskMonitor.DUMMY);
}
finally {
program.endTransaction(transactionID, true);
@ -296,6 +347,12 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
assertEquals(overlayBlock1.getName(), blocks[origBlockCount + 0].getName());
assertEquals(overlayBlock4.getName(), blocks[origBlockCount + 1].getName());
ovSpace3 = program.getAddressFactory().getAddressSpace("my_overlay_x");
assertNull(ovSpace3);
ovSpace4 = program.getAddressFactory().getAddressSpace("my_overlay_x.1");
assertNotNull(ovSpace4);
program.undo();
assertEquals(origSpaceCount + 4, af.getNumAddressSpaces());
blocks = program.getMemory().getBlocks();
@ -308,6 +365,12 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
assertEquals(overlayBlock3.getName(), blocks[origBlockCount + 2].getName());
assertEquals(overlayBlock4.getName(), blocks[origBlockCount + 3].getName());
ovSpace3 = program.getAddressFactory().getAddressSpace("my_overlay_x");
assertNotNull(ovSpace3);
ovSpace4 = program.getAddressFactory().getAddressSpace("my_overlay_x.1");
assertNotNull(ovSpace4);
program.redo();
assertEquals(origSpaceCount + 2, af.getNumAddressSpaces());
blocks = program.getMemory().getBlocks();
@ -317,5 +380,6 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
overlayBlock4 = program.getMemory().getBlock(overlayBlock4.getName());
assertEquals(overlayBlock1.getName(), blocks[origBlockCount + 0].getName());
assertEquals(overlayBlock4.getName(), blocks[origBlockCount + 1].getName());
}
}

View File

@ -24,7 +24,8 @@ import ghidra.program.database.mem.*;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.util.exception.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
public class MyTestMemory extends AddressSet implements Memory {
@ -376,8 +377,7 @@ public class MyTestMemory extends AddressSet implements Memory {
@Override
public MemoryBlock createInitializedBlock(String name, Address start, FileBytes fileBytes,
long offset, long size, boolean overlay) throws LockException, DuplicateNameException,
MemoryConflictException, AddressOverflowException {
long offset, long size, boolean overlay) {
throw new UnsupportedOperationException();
}

View File

@ -1,359 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.feature.vt.db;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import ghidra.framework.store.LockException;
import ghidra.program.database.mem.*;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;
public class MemoryTestDummy extends AddressSet implements Memory {
MemoryTestDummy(Address start, Address end) {
super(start, end);
}
@Override
public MemoryBlock convertToInitialized(MemoryBlock unitializedBlock, byte initialValue)
throws LockException, MemoryBlockException, NotFoundException {
return null;
}
@Override
public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock)
throws LockException, MemoryBlockException, NotFoundException {
return null;
}
@Override
public MemoryBlock createBitMappedBlock(String name, Address start, Address mappedAddress,
long length, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException {
return null;
}
@Override
public MemoryBlock createBlock(MemoryBlock block, String name, Address start, long length)
throws LockException, MemoryConflictException, AddressOverflowException {
return null;
}
@Override
public MemoryBlock createByteMappedBlock(String name, Address start, Address mappedAddress,
long length, ByteMappingScheme byteMappingScheme, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException,
IllegalArgumentException {
return null;
}
@Override
public MemoryBlock createInitializedBlock(String name, Address start, InputStream is,
long length, TaskMonitor monitor, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException,
CancelledException, DuplicateNameException {
return null;
}
@Override
public MemoryBlock createInitializedBlock(String name, Address start, long size,
byte initialValue, TaskMonitor monitor, boolean overlay)
throws LockException, DuplicateNameException, MemoryConflictException,
AddressOverflowException, CancelledException {
return null;
}
@Override
public MemoryBlock createUninitializedBlock(String name, Address start, long size,
boolean overlay) throws LockException, DuplicateNameException, MemoryConflictException,
AddressOverflowException {
return null;
}
@Override
public Address findBytes(Address addr, byte[] bytes, byte[] masks, boolean forward,
TaskMonitor monitor) {
return null;
}
@Override
public Address findBytes(Address startAddr, Address endAddr, byte[] bytes, byte[] masks,
boolean forward, TaskMonitor monitor) {
return null;
}
@Override
public MemoryBlock getBlock(Address addr) {
return null;
}
@Override
public MemoryBlock getBlock(String blockName) {
return null;
}
@Override
public MemoryBlock[] getBlocks() {
return null;
}
@Override
public byte getByte(Address addr) throws MemoryAccessException {
return 0;
}
@Override
public int getBytes(Address addr, byte[] dest) throws MemoryAccessException {
return 0;
}
@Override
public int getBytes(Address addr, byte[] dest, int dIndex, int size)
throws MemoryAccessException {
return 0;
}
@Override
public AddressSetView getExecuteSet() {
return null;
}
@Override
public AddressSetView getLoadedAndInitializedAddressSet() {
return null;
}
@Override
public AddressSetView getInitializedAddressSet() {
return null;
}
@Override
public AddressSetView getAllInitializedAddressSet() {
return null;
}
@Override
public int getInt(Address addr) throws MemoryAccessException {
return 0;
}
@Override
public int getInt(Address addr, boolean bigEndian) throws MemoryAccessException {
return 0;
}
@Override
public int getInts(Address addr, int[] dest) throws MemoryAccessException {
return 0;
}
@Override
public int getInts(Address addr, int[] dest, int dIndex, int nElem)
throws MemoryAccessException {
return 0;
}
@Override
public int getInts(Address addr, int[] dest, int dIndex, int nElem, boolean isBigEndian)
throws MemoryAccessException {
return 0;
}
@Override
public LiveMemoryHandler getLiveMemoryHandler() {
return null;
}
@Override
public long getLong(Address addr) throws MemoryAccessException {
return 0;
}
@Override
public long getLong(Address addr, boolean bigEndian) throws MemoryAccessException {
return 0;
}
@Override
public int getLongs(Address addr, long[] dest) throws MemoryAccessException {
return 0;
}
@Override
public int getLongs(Address addr, long[] dest, int dIndex, int nElem)
throws MemoryAccessException {
return 0;
}
@Override
public int getLongs(Address addr, long[] dest, int dIndex, int nElem, boolean isBigEndian)
throws MemoryAccessException {
return 0;
}
@Override
public Program getProgram() {
return null;
}
@Override
public short getShort(Address addr) throws MemoryAccessException {
return 0;
}
@Override
public short getShort(Address addr, boolean bigEndian) throws MemoryAccessException {
return 0;
}
@Override
public int getShorts(Address addr, short[] dest) throws MemoryAccessException {
return 0;
}
@Override
public int getShorts(Address addr, short[] dest, int dIndex, int nElem)
throws MemoryAccessException {
return 0;
}
@Override
public int getShorts(Address addr, short[] dest, int dIndex, int nElem, boolean isBigEndian)
throws MemoryAccessException {
return 0;
}
@Override
public long getSize() {
return 0;
}
@Override
public boolean isBigEndian() {
return false;
}
@Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws LockException, MemoryBlockException, NotFoundException {
return null;
}
@Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws LockException, MemoryBlockException, MemoryConflictException,
AddressOverflowException, NotFoundException {
// no op
}
@Override
public void removeBlock(MemoryBlock block, TaskMonitor monitor) throws LockException {
// no op
}
@Override
public void setByte(Address addr, byte value) throws MemoryAccessException {
// no op
}
@Override
public void setBytes(Address addr, byte[] source) throws MemoryAccessException {
// no op
}
@Override
public void setBytes(Address addr, byte[] source, int sIndex, int size)
throws MemoryAccessException {
// no op
}
@Override
public void setInt(Address addr, int value) throws MemoryAccessException {
// no op
}
@Override
public void setInt(Address addr, int value, boolean bigEndian) throws MemoryAccessException {
// no op
}
@Override
public void setLiveMemoryHandler(LiveMemoryHandler handler) {
// no op
}
@Override
public void setLong(Address addr, long value) throws MemoryAccessException {
// no op
}
@Override
public void setLong(Address addr, long value, boolean bigEndian) throws MemoryAccessException {
// no op
}
@Override
public void setShort(Address addr, short value) throws MemoryAccessException {
// no op
}
@Override
public void setShort(Address addr, short value, boolean bigEndian)
throws MemoryAccessException {
// no op
}
@Override
public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, LockException, NotFoundException {
// no op
}
@Override
public FileBytes createFileBytes(String filename, long offset, long size, InputStream is,
TaskMonitor monitor) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public List<FileBytes> getAllFileBytes() {
throw new UnsupportedOperationException();
}
@Override
public boolean deleteFileBytes(FileBytes descriptor) {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock createInitializedBlock(String name, Address start, FileBytes fileBytes,
long offset, long size, boolean overlay) throws LockException, DuplicateNameException,
MemoryConflictException, AddressOverflowException {
throw new UnsupportedOperationException();
}
@Override
public AddressSourceInfo getAddressSourceInfo(Address address) {
throw new UnsupportedOperationException();
}
}

View File

@ -24,7 +24,6 @@ import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.address.OverlayAddressSpace;
import ghidra.program.model.lang.Language;
import ghidra.program.util.LanguageTranslator;
import ghidra.util.exception.AssertException;
import ghidra.util.exception.DuplicateNameException;
class OverlaySpaceAdapterDB {
@ -62,12 +61,12 @@ class OverlaySpaceAdapterDB {
AddressSpace space = factory.getAddressSpace(templateSpaceName);
try {
OverlayAddressSpace sp =
factory.addOverlayAddressSpace(spaceName, space, minOffset, maxOffset);
factory.addOverlayAddressSpace(spaceName, true, space, minOffset, maxOffset);
sp.setDatabaseKey(rec.getKey());
}
catch (DuplicateNameException e) {
throw new AssertException(
"Should not have duplicateNameException when recreating factory");
catch (IllegalArgumentException e) {
throw new RuntimeException(
"Unexpected error initializing overlay address spaces", e);
}
}
}
@ -140,7 +139,7 @@ class OverlaySpaceAdapterDB {
}
catch (DuplicateNameException e) {
throw new RuntimeException(
"Unexpected error1 updating overlay address spaces");
"Unexpected error updating overlay address spaces", e);
}
}
}
@ -151,13 +150,14 @@ class OverlaySpaceAdapterDB {
AddressSpace origSpace =
factory.getAddressSpace(rec.getString(OV_SPACE_BASE_COL));
try {
space = factory.addOverlayAddressSpace(spaceName, origSpace, minOffset,
space = factory.addOverlayAddressSpace(spaceName, true, origSpace,
minOffset,
maxOffset);
space.setDatabaseKey(rec.getKey());
}
catch (DuplicateNameException e) {
catch (IllegalArgumentException e) {
throw new RuntimeException(
"Unexpected error2 updating overlay address spaces");
"Unexpected error updating overlay address spaces", e);
}
}
}

View File

@ -97,23 +97,130 @@ public class ProgramAddressFactory extends DefaultAddressFactory {
return originalFactory;
}
public void addOverlayAddressSpace(OverlayAddressSpace ovSpace) throws DuplicateNameException {
void addOverlayAddressSpace(OverlayAddressSpace ovSpace) throws DuplicateNameException {
addAddressSpace(ovSpace);
}
public OverlayAddressSpace addOverlayAddressSpace(String name, AddressSpace originalSpace,
long minOffset, long maxOffset) throws DuplicateNameException {
/**
* Create a new OverlayAddressSpace based upon the given overlay blockName and base AddressSpace
* @param name the preferred name of the overlay address space to be created.
* This name may be modified if preserveName is false to produce a valid overlay space
* name and avoid duplication.
* @param preserveName if true specified name will be preserved, if false an unique acceptable
* overlay space name will be generated from the specified name.
* @param originalSpace the base AddressSpace to overlay
* @param minOffset the min offset of the space
* @param maxOffset the max offset of the space
* @return the new overlay space
* @throws IllegalArgumentException if originalSpace is not permitted or preserveName is true
* and a space with specified name already exists.
*/
OverlayAddressSpace addOverlayAddressSpace(String name, boolean preserveName,
AddressSpace originalSpace, long minOffset, long maxOffset) {
if (!originalSpace.isMemorySpace() || originalSpace.isOverlaySpace()) {
throw new IllegalArgumentException(
"Invalid address space for overlay: " + originalSpace.getName());
}
AddressSpace space = getAddressSpace(originalSpace.getName());
if (space != originalSpace) {
throw new IllegalArgumentException("Unknown memory address space instance");
}
String spaceName = name;
if (!preserveName) {
spaceName = fixupOverlaySpaceName(name);
spaceName = getUniqueOverlayName(spaceName);
}
else if (getAddressSpace(name) != null) { // check before allocating unique ID
throw new IllegalArgumentException("Space named " + name + " already exists!");
}
int unique = 0;
if (originalSpace.getType() == AddressSpace.TYPE_RAM ||
originalSpace.getType() == AddressSpace.TYPE_OTHER) {
unique = getNextUniqueID();
}
OverlayAddressSpace ovSpace =
new OverlayAddressSpace(name, originalSpace, unique, minOffset, maxOffset);
addAddressSpace(ovSpace);
new OverlayAddressSpace(spaceName, originalSpace, unique, minOffset, maxOffset);
try {
addAddressSpace(ovSpace);
}
catch (DuplicateNameException e) {
throw new RuntimeException(e); // unexpected
}
return ovSpace;
}
/**
* Get a unique address space name based on the specified
* baseOverlayName
* @param baseOverlayName base overlay address space name
* @return unique overlay space name
*/
private String getUniqueOverlayName(String baseOverlayName) {
if (getAddressSpace(baseOverlayName) == null) {
return baseOverlayName;
}
int index = 1;
while (true) {
String revisedName = baseOverlayName + "." + index++;
if (getAddressSpace(revisedName) == null) {
return revisedName;
}
}
}
/**
* Get base overlay name removing any numeric suffix which may
* have been added to avoid duplication. This method is intended
* to be used during rename only.
* @param overlayName existing overlay space name
* @return base overlay name with any trailing index removed
* which may have been added to avoid duplication.
*/
private String getBaseOverlayName(String overlayName) {
int index = overlayName.lastIndexOf('.');
if (index < 1) {
return overlayName;
}
int value;
try {
value = Integer.parseInt(overlayName.substring(index + 1));
}
catch (NumberFormatException e) {
return overlayName;
}
if (value < 1) {
return overlayName;
}
String baseName = overlayName.substring(0, index);
return overlayName.equals(baseName + '.' + value) ? baseName : overlayName;
}
/**
* Generate an allowed address space name from a block name. Use of unsupported
* characters will be converted to underscore (includes colon and all whitespace chars).
* double-underscore to ensure uniqueness.
* @param blockName corresponding memory block name
* @return overlay space name
*/
private String fixupOverlaySpaceName(String blockName) {
int len = blockName.length();
StringBuffer buf = new StringBuffer(len);
for (int i = 0; i < len; i++) {
char c = blockName.charAt(i);
if (c == ':' || c <= 0x20) {
buf.append('_');
}
else {
buf.append(c);
}
}
return buf.toString();
}
@Override
public Address getAddress(int spaceID, long offset) {
Address addr = super.getAddress(spaceID, offset);
@ -146,10 +253,29 @@ public class ProgramAddressFactory extends DefaultAddressFactory {
removeAddressSpace(name);
}
/**
* Rename overlay with preferred newName. Actual name used will be returned
* and may differ from specified newName to ensure validity and avoid
* duplication.
* @param oldOverlaySpaceName the existing overlay address space name
* @param newName the preferred new name of the overlay address space.
* This name may be modified to produce a valid overlay space
* name to avoid duplication.
* @return new name applied to existing overlay space
*/
@Override
protected void renameOverlaySpace(String oldName, String newName)
throws DuplicateNameException {
super.renameOverlaySpace(oldName, newName);
protected String renameOverlaySpace(String oldOverlaySpaceName, String newName) {
try {
String revisedName = fixupOverlaySpaceName(newName);
if (revisedName.equals(getBaseOverlayName(oldOverlaySpaceName))) {
return oldOverlaySpaceName;
}
revisedName = getUniqueOverlayName(revisedName);
return super.renameOverlaySpace(oldOverlaySpaceName, revisedName);
}
catch (DuplicateNameException e) {
throw new RuntimeException(e); // unexpected
}
}
private int getNextUniqueID() {

View File

@ -1184,46 +1184,55 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
}
/**
* Creates a new OverlayAddressSpace with the given name and base AddressSpace
* @param overlaySpaceName the name of the overlay space to create
* @param templateSpace the base AddressSpace to overlay
* Create a new OverlayAddressSpace based upon the given overlay blockName and base AddressSpace
* @param blockName the name of the overlay memory block which corresponds to the new overlay address
* space to be created. This name may be modified to produce a valid overlay space name and avoid
* duplication.
* @param originalSpace the base AddressSpace to overlay
* @param minOffset the min offset of the space
* @param maxOffset the max offset of the space
* @return the new space
* @throws DuplicateNameException if an AddressSpace already exists with the given name.
* @throws LockException if the program is shared and not checked out exclusively.
* @throws MemoryConflictException if image base override is active
*/
public AddressSpace addOverlaySpace(String overlaySpaceName, AddressSpace templateSpace,
public AddressSpace addOverlaySpace(String blockName, AddressSpace originalSpace,
long minOffset, long maxOffset)
throws DuplicateNameException, LockException, MemoryConflictException {
throws LockException, MemoryConflictException {
checkExclusiveAccess();
if (imageBaseOverride) {
throw new MemoryConflictException(
"Overlay spaces may not be created while an image-base override is active");
}
OverlayAddressSpace ovSpace = addressFactory.addOverlayAddressSpace(overlaySpaceName,
templateSpace, minOffset, maxOffset);
OverlayAddressSpace ovSpace = null;
lock.acquire();
try {
ovSpace = addressFactory.addOverlayAddressSpace(blockName, false, originalSpace,
minOffset, maxOffset);
overlaySpaceAdapter.addOverlaySpace(ovSpace);
}
catch (IOException e) {
dbError(e);
}
finally {
lock.release();
}
return ovSpace;
}
public void renameOverlaySpace(String oldName, String newName)
throws DuplicateNameException, LockException {
public void renameOverlaySpace(String oldOverlaySpaceName, String newName)
throws LockException {
checkExclusiveAccess();
addressFactory.renameOverlaySpace(oldName, newName);
try {
overlaySpaceAdapter.renameOverlaySpace(oldName, newName);
addrMap.renameOverlaySpace(oldName, newName);
}
catch (IOException e) {
dbError(e);
String revisedName = addressFactory.renameOverlaySpace(oldOverlaySpaceName, newName);
if (!revisedName.equals(oldOverlaySpaceName)) {
try {
overlaySpaceAdapter.renameOverlaySpace(oldOverlaySpaceName, revisedName);
addrMap.renameOverlaySpace(oldOverlaySpaceName, revisedName);
}
catch (IOException e) {
dbError(e);
}
}
}

View File

@ -27,7 +27,6 @@ import ghidra.program.database.map.AddressMapDB;
import ghidra.program.model.address.*;
import ghidra.program.model.mem.*;
import ghidra.util.exception.AssertException;
import ghidra.util.exception.DuplicateNameException;
public class MemoryBlockDB implements MemoryBlock {
@ -155,7 +154,7 @@ public class MemoryBlockDB implements MemoryBlock {
}
@Override
public void setName(String name) throws DuplicateNameException, LockException {
public void setName(String name) throws LockException {
String oldName = getName();
memMap.lock.acquire();
try {
@ -163,10 +162,10 @@ public class MemoryBlockDB implements MemoryBlock {
if (oldName.equals(name)) {
return;
}
memMap.checkBlockName(name, isOverlay());
memMap.checkBlockName(name);
try {
if (isOverlay()) {
memMap.overlayBlockRenamed(oldName, name);
memMap.overlayBlockRenamed(startAddress.getAddressSpace().getName(), name);
}
record.setString(MemoryMapDBAdapter.NAME_COL, name);
adapter.updateBlockRecord(record);

View File

@ -556,7 +556,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
public MemoryBlock createInitializedBlock(String name, Address start, long size,
byte initialValue, TaskMonitor monitor, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException,
CancelledException, DuplicateNameException {
CancelledException {
InputStream fillStream = null;
if (initialValue != 0) {
@ -572,17 +572,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
private Address createOverlaySpace(String name, Address start, long dataLength)
throws MemoryConflictException, AddressOverflowException, DuplicateNameException,
LockException {
AddressSpace space = start.getAddressSpace();
if (space.isOverlaySpace()) {
throw new IllegalArgumentException("An overlay block may not be overlayed");
}
if (!space.isMemorySpace()) {
throw new IllegalArgumentException(
"Invalid physical address for overlay block: " + start.toString(true));
}
throws MemoryConflictException, AddressOverflowException, LockException {
start.addNoWrap(dataLength - 1);// just tests the AddressOverflow condition.
@ -596,8 +586,8 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override
public MemoryBlock createInitializedBlock(String name, Address start, InputStream is,
long length, TaskMonitor monitor, boolean overlay) throws MemoryConflictException,
AddressOverflowException, CancelledException, LockException, DuplicateNameException {
checkBlockName(name, overlay);
AddressOverflowException, CancelledException, LockException {
checkBlockName(name);
lock.acquire();
try {
checkBlockSize(length, true);
@ -640,10 +630,10 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override
public MemoryBlock createInitializedBlock(String name, Address start, FileBytes fileBytes,
long offset, long length, boolean overlay) throws LockException, DuplicateNameException,
long offset, long length, boolean overlay) throws LockException,
MemoryConflictException, AddressOverflowException, IndexOutOfBoundsException {
checkBlockName(name, overlay);
checkBlockName(name);
lock.acquire();
try {
checkBlockSize(length, true);
@ -694,9 +684,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override
public MemoryBlock createUninitializedBlock(String name, Address start, long size,
boolean overlay) throws MemoryConflictException, AddressOverflowException,
LockException, DuplicateNameException {
LockException {
checkBlockName(name, overlay);
checkBlockName(name);
lock.acquire();
try {
checkBlockSize(size, false);
@ -730,9 +720,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override
public MemoryBlock createBitMappedBlock(String name, Address start, Address mappedAddress,
long length, boolean overlay) throws MemoryConflictException, AddressOverflowException,
LockException, IllegalArgumentException, DuplicateNameException {
LockException, IllegalArgumentException {
checkBlockName(name, overlay);
checkBlockName(name);
lock.acquire();
try {
checkBlockSize(length, false);
@ -765,10 +755,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override
public MemoryBlock createByteMappedBlock(String name, Address start, Address mappedAddress,
long length, ByteMappingScheme byteMappingScheme, boolean overlay)
throws MemoryConflictException, AddressOverflowException, LockException,
DuplicateNameException {
throws MemoryConflictException, AddressOverflowException, LockException {
checkBlockName(name, overlay);
checkBlockName(name);
int mappingScheme = 0; // use for 1:1 mapping
if (byteMappingScheme == null) {
@ -810,27 +799,18 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
/**
* Check new block name for validity
* @param name new block name
* @param isOverlay true if block is overlay
* @throws IllegalArgumentException if invalid block name specified
* @throws DuplicateNameException if name conflicts with an address space name
*/
void checkBlockName(
String name, boolean isOverlay)
throws IllegalArgumentException, DuplicateNameException {
if (!Memory.isValidAddressSpaceName(name)) {
void checkBlockName(String name) throws IllegalArgumentException {
if (!Memory.isValidMemoryBlockName(name)) {
throw new IllegalArgumentException("Invalid block name: " + name);
}
if (isOverlay && getAddressFactory().getAddressSpace(name) != null) {
throw new DuplicateNameException(
"Block name conflicts with existing address space: " + name);
}
}
@Override
public MemoryBlock createBlock(MemoryBlock block, String name, Address start, long length)
throws MemoryConflictException, AddressOverflowException, LockException,
DuplicateNameException {
checkBlockName(name, false);
throws MemoryConflictException, AddressOverflowException, LockException {
checkBlockName(name);
lock.acquire();
try {
checkBlockSize(length, block.isInitialized());
@ -2054,10 +2034,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
}
public void overlayBlockRenamed(String oldName, String name)
throws DuplicateNameException, LockException {
program.renameOverlaySpace(oldName, name);
public void overlayBlockRenamed(String oldOverlaySpaceName, String name)
throws LockException {
program.renameOverlaySpace(oldOverlaySpaceName, name);
}
@Override

View File

@ -392,17 +392,28 @@ public class DefaultAddressFactory implements AddressFactory {
}
}
protected void renameOverlaySpace(String oldName, String newName)
/**
* Rename overlay with newName.
* @param oldOverlaySpaceName the existing overlay address space name
* @param newName the new name of the overlay address space.
* @return new name applied to existing overlay space
* @throws DuplicateNameException if space with newName already exists
* @throws IllegalArgumentException if specified oldOverlaySpaceName was not found as
* an existing overlay space
*/
protected String renameOverlaySpace(String oldOverlaySpaceName, String newName)
throws DuplicateNameException {
if (getAddressSpace(newName) != null) {
throw new DuplicateNameException("AddressSpace named " + newName + " already exists!");
}
AddressSpace space = getAddressSpace(oldName);
AddressSpace space = getAddressSpace(oldOverlaySpaceName);
if (space != null && space.isOverlaySpace()) {
((OverlayAddressSpace) space).setName(newName);
spaceNameTable.remove(oldName);
spaceNameTable.remove(oldOverlaySpaceName);
spaceNameTable.put(space.getName(), space);
return newName;
}
throw new IllegalArgumentException("No such overlay space: " + oldOverlaySpaceName);
}
/**

View File

@ -23,7 +23,8 @@ import ghidra.framework.store.LockException;
import ghidra.program.database.mem.*;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.util.exception.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
/**
@ -108,7 +109,7 @@ public interface Memory extends AddressSetView {
/**
* Create an initialized memory block and add it to this Memory.
* @param name block name (See {@link Memory#isValidAddressSpaceName(String)} for
* @param name block name (See {@link Memory#isValidMemoryBlockName(String)} for
* naming rules)
* @param start start address of the block
* @param is source of the data used to fill the block or null for zero initialization.
@ -125,16 +126,15 @@ public interface Memory extends AddressSetView {
* address space
* @throws CancelledException user cancelled operation
* @throws IllegalArgumentException if invalid block name specified
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
*/
public MemoryBlock createInitializedBlock(String name, Address start, InputStream is,
long length, TaskMonitor monitor, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException,
CancelledException, IllegalArgumentException, DuplicateNameException;
CancelledException, IllegalArgumentException;
/**
* Create an initialized memory block and add it to this Memory.
* @param name block name (See {@link Memory#isValidAddressSpaceName(String)} for
* @param name block name (See {@link Memory#isValidMemoryBlockName(String)} for
* naming rules)
* @param start start of the block
* @param size block length (positive non-zero value required)
@ -150,18 +150,17 @@ public interface Memory extends AddressSetView {
* @throws AddressOverflowException if the start is beyond the
* address space
* @throws IllegalArgumentException if invalid block name specified
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
* @throws CancelledException user cancelled operation
*/
public MemoryBlock createInitializedBlock(String name, Address start, long size,
byte initialValue, TaskMonitor monitor, boolean overlay)
throws LockException, IllegalArgumentException, DuplicateNameException,
MemoryConflictException, AddressOverflowException, CancelledException;
throws LockException, IllegalArgumentException, MemoryConflictException,
AddressOverflowException, CancelledException;
/**
* Create an initialized memory block using bytes from a {@link FileBytes} object.
*
* @param name block name (See {@link Memory#isValidAddressSpaceName(String)} for
* @param name block name (See {@link Memory#isValidMemoryBlockName(String)} for
* naming rules)
* @param start starting address of the block
* @param fileBytes the {@link FileBytes} object to use as the underlying source of bytes.
@ -178,15 +177,14 @@ public interface Memory extends AddressSetView {
* @throws IndexOutOfBoundsException if file bytes range specified by offset and size
* is out of bounds for the specified fileBytes.
* @throws IllegalArgumentException if invalid block name specified
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
*/
public MemoryBlock createInitializedBlock(String name, Address start, FileBytes fileBytes,
long offset, long size, boolean overlay) throws LockException, IllegalArgumentException,
DuplicateNameException, MemoryConflictException, AddressOverflowException;
MemoryConflictException, AddressOverflowException;
/**
* Create an uninitialized memory block and add it to this Memory.
* @param name block name (See {@link Memory#isValidAddressSpaceName(String)} for
* @param name block name (See {@link Memory#isValidMemoryBlockName(String)} for
* naming rules)
* @param start start of the block
* @param size block length
@ -200,15 +198,14 @@ public interface Memory extends AddressSetView {
* @throws AddressOverflowException if the start is beyond the
* address space
* @throws IllegalArgumentException if invalid block name specified
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
*/
public MemoryBlock createUninitializedBlock(String name, Address start, long size,
boolean overlay) throws LockException, IllegalArgumentException, DuplicateNameException,
boolean overlay) throws LockException, IllegalArgumentException,
MemoryConflictException, AddressOverflowException;
/**
* Create a bit overlay memory block and add it to this Memory.
* @param name block name (See {@link Memory#isValidAddressSpaceName(String)} for
* @param name block name (See {@link Memory#isValidMemoryBlockName(String)} for
* naming rules)
* @param start start of the block
* @param mappedAddress start address in the source block for the
@ -225,17 +222,15 @@ public interface Memory extends AddressSetView {
* previous block
* @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IllegalArgumentException if invalid block name specified
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
*/
public MemoryBlock createBitMappedBlock(String name, Address start, Address mappedAddress,
long length, boolean overlay) throws LockException, MemoryConflictException,
AddressOverflowException,
IllegalArgumentException, DuplicateNameException;
AddressOverflowException, IllegalArgumentException;
/**
* Create a memory block that uses the bytes located at a different location with a 1:1
* byte mapping scheme.
* @param name block name (See {@link Memory#isValidAddressSpaceName(String)} for
* @param name block name (See {@link Memory#isValidMemoryBlockName(String)} for
* naming rules)
* @param start start of the block
* @param mappedAddress start address in the source block for the
@ -250,17 +245,16 @@ public interface Memory extends AddressSetView {
* @throws MemoryConflictException if the new block overlaps with a previous block
* @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IllegalArgumentException if invalid block name
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
*/
public MemoryBlock createByteMappedBlock(String name, Address start, Address mappedAddress,
long length, ByteMappingScheme byteMappingScheme, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException,
IllegalArgumentException, DuplicateNameException;
IllegalArgumentException;
/**
* Create a memory block that uses the bytes located at a different location with a 1:1
* byte mapping scheme.
* @param name block name (See {@link Memory#isValidAddressSpaceName(String)} for
* @param name block name (See {@link Memory#isValidMemoryBlockName(String)} for
* naming rules)
* @param start start of the block
* @param mappedAddress start address in the source block for the
@ -274,12 +268,11 @@ public interface Memory extends AddressSetView {
* @throws MemoryConflictException if the new block overlaps with a previous block
* @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IllegalArgumentException if invalid block name
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
*/
default public MemoryBlock createByteMappedBlock(String name, Address start,
Address mappedAddress, long length, boolean overlay) throws LockException,
MemoryConflictException,
AddressOverflowException, IllegalArgumentException, DuplicateNameException {
AddressOverflowException, IllegalArgumentException {
return createByteMappedBlock(name, start, mappedAddress, length, null, overlay);
}
@ -289,7 +282,7 @@ public interface Memory extends AddressSetView {
* have block filled with 0's. Method will only create physical space blocks
* and will not create an overlay block.
* @param block source block
* @param name block name (See {@link Memory#isValidAddressSpaceName(String)} for
* @param name block name (See {@link Memory#isValidMemoryBlockName(String)} for
* naming rules).
* @param start start of the block
* @param length the size of the new block.
@ -298,12 +291,11 @@ public interface Memory extends AddressSetView {
* @throws MemoryConflictException if block specification conflicts with an existing block
* @throws AddressOverflowException if the new memory block would extend
* beyond the end of the address space.
* @throws IllegalArgumentException if invalid block name specified
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
* @throws IllegalArgumentException if invalid block name specifiede
*/
public MemoryBlock createBlock(MemoryBlock block, String name, Address start, long length)
throws LockException, IllegalArgumentException, MemoryConflictException,
AddressOverflowException, DuplicateNameException;
AddressOverflowException;
/**
* Remove the memory block.
@ -816,17 +808,22 @@ public interface Memory extends AddressSetView {
public AddressSourceInfo getAddressSourceInfo(Address address);
/**
* Validate the given address space or block name: cannot be null, cannot be an empty string, cannot contain blank
* or reserved characters (e.g., colon).
* Validate the given block name: cannot be null, cannot be an empty string,
* cannot contain control characters (ASCII 0..0x19).
* <BR>
* NOTE: When producing an overlay memory space which corresponds to a block, the space
* name will be modified to be consistent with address space name restrictions
* and to ensure uniqueness.
* @param name memory block name
* @return true if name is valid else false
*/
public static boolean isValidAddressSpaceName(String name) {
public static boolean isValidMemoryBlockName(String name) {
if (name == null || name.length() == 0) {
return false;
}
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (c <= 0x20 || c >= 0x7f || c == ':') {
if (c < 0x20) {
return false;
}
}

View File

@ -23,7 +23,6 @@ import ghidra.framework.store.LockException;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.util.NamingUtilities;
import ghidra.util.exception.DuplicateNameException;
/**
* Interface that defines a block in memory.
@ -90,12 +89,11 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
* Set the name for this block (See {@link NamingUtilities#isValidName(String)} for
* naming rules). Specified name must not conflict with an address space name.
* @param name the new name for this block.
* @throws DuplicateNameException if name conflicts with an address space name
* @throws IllegalArgumentException if invalid name specified
* @throws LockException renaming an Overlay block without exclusive access
*/
public void setName(String name)
throws IllegalArgumentException, DuplicateNameException, LockException;
throws IllegalArgumentException, LockException;
/**
* Get the comment associated with this block.

View File

@ -20,7 +20,6 @@ import java.util.List;
import ghidra.framework.store.LockException;
import ghidra.program.model.address.Address;
import ghidra.util.exception.DuplicateNameException;
/**
* MemoryBlockStub can be extended for use by tests. It throws an UnsupportedOperationException
@ -81,7 +80,7 @@ public class MemoryBlockStub implements MemoryBlock {
}
@Override
public void setName(String name) throws DuplicateNameException, LockException {
public void setName(String name) throws LockException {
throw new UnsupportedOperationException();
}

View File

@ -24,7 +24,7 @@ import ghidra.framework.store.LockException;
import ghidra.program.database.mem.*;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.util.exception.*;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
/**
@ -187,24 +187,19 @@ public class MemoryStub extends AddressSet implements Memory {
@Override
public MemoryBlock createInitializedBlock(String name, Address start, InputStream is,
long length, TaskMonitor monitor, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException,
CancelledException, DuplicateNameException {
long length, TaskMonitor monitor, boolean overlay) {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock createInitializedBlock(String name, Address start, long size,
byte initialValue, TaskMonitor monitor, boolean overlay)
throws LockException, DuplicateNameException, MemoryConflictException,
AddressOverflowException, CancelledException {
byte initialValue, TaskMonitor monitor, boolean overlay) {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock createUninitializedBlock(String name, Address start, long size,
boolean overlay) throws LockException, DuplicateNameException, MemoryConflictException,
AddressOverflowException {
boolean overlay) {
throw new UnsupportedOperationException();
}
@ -463,8 +458,7 @@ public class MemoryStub extends AddressSet implements Memory {
@Override
public MemoryBlock createInitializedBlock(String name, Address start, FileBytes fileBytes,
long offset, long size, boolean overlay) throws LockException, DuplicateNameException,
MemoryConflictException, AddressOverflowException {
long offset, long size, boolean overlay) {
throw new UnsupportedOperationException();
}

View File

@ -145,16 +145,15 @@ public class JavaLoader extends AbstractLibrarySupportLoader {
try {
block = memory.createInitializedBlock("method_lookup", address,
JavaClassUtil.METHOD_INDEX_SIZE, (byte) 0xff, monitor, false);
block.setRead(true);
block.setWrite(false);
block.setExecute(false);
}
catch (LockException | DuplicateNameException | MemoryConflictException
catch (LockException | MemoryConflictException
| AddressOverflowException | CancelledException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
block.setRead(true);
block.setWrite(false);
block.setExecute(false);
}
private void createMethodMemoryBlocks(Program program, ByteProvider provider,

View File

@ -114,9 +114,6 @@ public class RepositoryScreenShots extends AbstractListingMergeManagerTest {
blocks[1].setName("LatestText");
commit = true;
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}
@ -133,9 +130,6 @@ public class RepositoryScreenShots extends AbstractListingMergeManagerTest {
try {
blocks[1].setName("MY_Text");
}
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) {
Assert.fail();
}