GP-420 relaxed memory block naming restrictions and eliminated throwing of DuplicateNameException from memory block API

This commit is contained in:
ghidra1 2020-11-23 17:35:49 -05:00
parent 90c1ce5d59
commit d7dbcfebf5
30 changed files with 365 additions and 641 deletions

View file

@ -69,7 +69,7 @@ abstract class AbstractAddMemoryBlockCmd implements Command {
protected abstract MemoryBlock createMemoryBlock(Memory memory) protected abstract MemoryBlock createMemoryBlock(Memory memory)
throws LockException, MemoryConflictException, AddressOverflowException, throws LockException, MemoryConflictException, AddressOverflowException,
DuplicateNameException, CancelledException; CancelledException;
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(DomainObject obj) {
@ -95,9 +95,6 @@ abstract class AbstractAddMemoryBlockCmd implements Command {
catch (MemoryConflictException e) { catch (MemoryConflictException e) {
message = e.getMessage(); message = e.getMessage();
} }
catch (DuplicateNameException e) {
message = "Duplicate Name: " + e.getMessage();
}
catch (IllegalStateException e) { catch (IllegalStateException e) {
message = e.getMessage(); 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.Address;
import ghidra.program.model.address.AddressOverflowException; import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.exception.DuplicateNameException;
/** /**
* Command for adding Bit-mapped memory blocks. * Command for adding Bit-mapped memory blocks.
@ -56,7 +55,7 @@ public class AddBitMappedMemoryBlockCmd extends AbstractAddMemoryBlockCmd {
@Override @Override
protected MemoryBlock createMemoryBlock(Memory memory) protected MemoryBlock createMemoryBlock(Memory memory)
throws LockException, MemoryConflictException, AddressOverflowException, throws LockException, MemoryConflictException, AddressOverflowException,
IllegalArgumentException, DuplicateNameException { IllegalArgumentException {
return memory.createBitMappedBlock(name, start, mappedAddress, length, isOverlay); 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.Address;
import ghidra.program.model.address.AddressOverflowException; import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.exception.DuplicateNameException;
/** /**
* Command for adding byte-mapped memory blocks * Command for adding byte-mapped memory blocks
@ -83,7 +82,7 @@ public class AddByteMappedMemoryBlockCmd extends AbstractAddMemoryBlockCmd {
@Override @Override
protected MemoryBlock createMemoryBlock(Memory memory) protected MemoryBlock createMemoryBlock(Memory memory)
throws LockException, MemoryConflictException, AddressOverflowException, throws LockException, MemoryConflictException, AddressOverflowException,
IllegalArgumentException, DuplicateNameException { IllegalArgumentException {
return memory.createByteMappedBlock(name, start, mappedAddress, length, return memory.createByteMappedBlock(name, start, mappedAddress, length,
byteMappingScheme, byteMappingScheme,
isOverlay); isOverlay);

View file

@ -20,7 +20,6 @@ import ghidra.program.database.mem.FileBytes;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException; import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.mem.*; 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. * 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 @Override
protected MemoryBlock createMemoryBlock(Memory memory) throws LockException, protected MemoryBlock createMemoryBlock(Memory memory) throws LockException,
MemoryConflictException, AddressOverflowException, DuplicateNameException { MemoryConflictException, AddressOverflowException {
return memory.createInitializedBlock(name, start, fileBytes, offset, length, isOverlay); 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.address.AddressOverflowException;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
/** /**
* Command for adding a new memory block initialized with a specific byte. * Command for adding a new memory block initialized with a specific byte.
@ -54,7 +53,7 @@ public class AddInitializedMemoryBlockCmd extends AbstractAddMemoryBlockCmd {
@Override @Override
protected MemoryBlock createMemoryBlock(Memory memory) protected MemoryBlock createMemoryBlock(Memory memory)
throws LockException, MemoryConflictException, AddressOverflowException, throws LockException, MemoryConflictException, AddressOverflowException,
DuplicateNameException, CancelledException { CancelledException {
return memory.createInitializedBlock(name, start, length, initialValue, null, isOverlay); 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.Address;
import ghidra.program.model.address.AddressOverflowException; import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.exception.DuplicateNameException;
/** /**
* Command for adding uninitialized memory blocks * Command for adding uninitialized memory blocks
@ -47,7 +46,7 @@ public class AddUninitializedMemoryBlockCmd extends AbstractAddMemoryBlockCmd {
@Override @Override
protected MemoryBlock createMemoryBlock(Memory memory) throws LockException, protected MemoryBlock createMemoryBlock(Memory memory) throws LockException,
MemoryConflictException, AddressOverflowException, DuplicateNameException { MemoryConflictException, AddressOverflowException {
return memory.createUninitializedBlock(name, start, length, isOverlay); return memory.createUninitializedBlock(name, start, length, isOverlay);
} }

View file

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

View file

@ -176,11 +176,6 @@ class MemoryMapManager {
return true; 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) { void setProgram(Program program) {
this.program = program; this.program = program;
} }
@ -279,6 +274,8 @@ class MemoryMapManager {
return false; return false;
} }
catch (LockException e) { catch (LockException e) {
msg = e.getMessage();
return false;
} }
MemoryBlock newBlock = memory.getBlock(newStart); MemoryBlock newBlock = memory.getBlock(newStart);
try { try {
@ -288,10 +285,6 @@ class MemoryMapManager {
msg = e.getMessage(); msg = e.getMessage();
return false; return false;
} }
catch (DuplicateNameException e) {
msg = e.getMessage();
return false;
}
return true; return true;
} }

View file

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

View file

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

View file

@ -227,8 +227,9 @@ public class MemoryBlockUtils {
block = program.getMemory().createInitializedBlock(name, start, fileBytes, offset, block = program.getMemory().createInitializedBlock(name, start, fileBytes, offset,
length, isOverlay); length, isOverlay);
} }
catch (MemoryConflictException | DuplicateNameException e) { catch (MemoryConflictException e) {
block = createBlockNoDuplicateName(program, name, start, fileBytes, offset, length); block = program.getMemory()
.createInitializedBlock(name, start, fileBytes, offset, length, true);
log.appendMsg("Conflict attempting to create memory block: " + name + log.appendMsg("Conflict attempting to create memory block: " + name +
" at address " + start.toString() + " Created block in new overlay instead"); " at address " + start.toString() + " Created block in new overlay instead");
} }
@ -242,22 +243,6 @@ public class MemoryBlockUtils {
return block; 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. * 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 * 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) { catch (MemoryConflictException e) {
block = memory.createInitializedBlock(name, start, dataInput, dataLength, monitor, block = memory.createInitializedBlock(name, start, dataInput, dataLength, monitor,
true); 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); throw new RuntimeException(e);
} }
catch (CancelledException e) { catch (CancelledException e) {

View file

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

View file

@ -23,7 +23,6 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.SystemUtilities; import ghidra.util.SystemUtilities;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.NotFoundException; import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
@ -328,8 +327,6 @@ public class MemoryDiff {
&& blockDiff.isNameDifferent()) { && blockDiff.isNameDifferent()) {
try { try {
block1.setName(block2.getName()); block1.setName(block2.getName());
} catch (DuplicateNameException e) {
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
} catch (LockException e) { } catch (LockException e) {
Msg.error(this, "Unexpected Exception: " + e.getMessage(), 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.database.*;
import ghidra.program.model.listing.ProgramChangeSet; import ghidra.program.model.listing.ProgramChangeSet;
import ghidra.program.model.mem.MemoryBlock; 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 { public class MemoryMergeManagerTest extends AbstractMergeTest {
@ -49,9 +50,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[0].setName("LatestText"); blocks[0].setName("LatestText");
commit = true; commit = true;
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }
@ -71,9 +69,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
try { try {
blocks[0].setName("MY_Text"); blocks[0].setName("MY_Text");
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }
@ -106,9 +101,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[0].setName("LatestText"); blocks[0].setName("LatestText");
commit = true; commit = true;
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }
@ -128,9 +120,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
try { try {
blocks[0].setName("MY_Text"); blocks[0].setName("MY_Text");
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }
@ -162,9 +151,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[0].setName("LatestText"); blocks[0].setName("LatestText");
commit = true; commit = true;
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }
@ -184,9 +170,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
try { try {
blocks[0].setName("MY_Text"); blocks[0].setName("MY_Text");
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }
@ -350,9 +333,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
try { try {
blocks[4].setName("special-debug"); blocks[4].setName("special-debug");
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }
@ -384,9 +364,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[4].setExecute(true); blocks[4].setExecute(true);
blocks[4].setName("not-used"); blocks[4].setName("not-used");
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }
@ -715,9 +692,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[2].setComment("LatestResource"); blocks[2].setComment("LatestResource");
commit = true; commit = true;
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }
@ -739,9 +713,6 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
blocks[1].setName("My_Data"); blocks[1].setName("My_Data");
blocks[2].setComment("My_Resource"); blocks[2].setComment("My_Resource");
} }
catch (DuplicateNameException e) {
Assert.fail();
}
catch (LockException e) { catch (LockException e) {
Assert.fail(); Assert.fail();
} }

View file

@ -23,7 +23,7 @@ import ghidra.program.model.address.*;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv; import ghidra.test.TestEnv;
import ghidra.util.task.TaskMonitorAdapter; import ghidra.util.task.TaskMonitor;
public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest { public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest {
private TestEnv env; 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 { private void doTest() throws Exception {
AddressFactory af = program.getAddressFactory(); AddressFactory af = program.getAddressFactory();
@ -232,7 +271,7 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
MemoryBlock overlayBlock1 = null; MemoryBlock overlayBlock1 = null;
try { try {
overlayBlock1 = program.getMemory().createInitializedBlock(".overlay1", 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 { finally {
program.endTransaction(transactionID, true); program.endTransaction(transactionID, true);
@ -248,7 +287,7 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
transactionID = program.startTransaction(testName.getMethodName()); transactionID = program.startTransaction(testName.getMethodName());
try { try {
overlayBlock1 = program.getMemory().getBlock(overlayBlock1.getName()); overlayBlock1 = program.getMemory().getBlock(overlayBlock1.getName());
program.getMemory().removeBlock(overlayBlock1, TaskMonitorAdapter.DUMMY_MONITOR); program.getMemory().removeBlock(overlayBlock1, TaskMonitor.DUMMY);
} }
finally { finally {
program.endTransaction(transactionID, true); program.endTransaction(transactionID, true);
@ -267,26 +306,38 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
MemoryBlock overlayBlock4 = null; MemoryBlock overlayBlock4 = null;
try { try {
overlayBlock2 = program.getMemory().createInitializedBlock(".overlay2", overlayBlock2 = program.getMemory().createInitializedBlock(".overlay2",
af.getAddress("2000"), 0x200, (byte) 0x22, TaskMonitorAdapter.DUMMY_MONITOR, true); af.getAddress("2000"), 0x200, (byte) 0x22, TaskMonitor.DUMMY, true);
overlayBlock3 = program.getMemory().createInitializedBlock(".overlay3", overlayBlock3 = program.getMemory()
af.getAddress("3000"), 0x300, (byte) 0x33, TaskMonitorAdapter.DUMMY_MONITOR, true); .createInitializedBlock("my_overlay_x",
overlayBlock4 = program.getMemory().createInitializedBlock(".overlay4", af.getAddress("3000"), 0x300, (byte) 0x33, TaskMonitor.DUMMY, true);
af.getAddress("4000"), 0x400, (byte) 0x44, TaskMonitorAdapter.DUMMY_MONITOR, true); overlayBlock4 = program.getMemory()
.createInitializedBlock("my overlay:x",
af.getAddress("4000"), 0x400, (byte) 0x44, TaskMonitor.DUMMY, true);
} }
finally { finally {
program.endTransaction(transactionID, true); program.endTransaction(transactionID, true);
} }
assertEquals(origSpaceCount + 4, af.getNumAddressSpaces()); assertEquals(origSpaceCount + 4, af.getNumAddressSpaces());
MemoryBlock[] blocks = program.getMemory().getBlocks(); MemoryBlock[] blocks = program.getMemory().getBlocks();
assertEquals(overlayBlock1.getName(), blocks[origBlockCount + 0].getName()); assertEquals(".overlay1", blocks[origBlockCount + 0].getName());
assertEquals(overlayBlock2.getName(), blocks[origBlockCount + 1].getName()); assertEquals(".overlay2", blocks[origBlockCount + 1].getName());
assertEquals(overlayBlock3.getName(), blocks[origBlockCount + 2].getName()); assertEquals("my_overlay_x", blocks[origBlockCount + 2].getName());
assertEquals(overlayBlock4.getName(), blocks[origBlockCount + 3].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()); transactionID = program.startTransaction(testName.getMethodName());
try { try {
program.getMemory().removeBlock(overlayBlock2, TaskMonitorAdapter.DUMMY_MONITOR); program.getMemory().removeBlock(overlayBlock2, TaskMonitor.DUMMY);
program.getMemory().removeBlock(overlayBlock3, TaskMonitorAdapter.DUMMY_MONITOR); program.getMemory().removeBlock(overlayBlock3, TaskMonitor.DUMMY);
} }
finally { finally {
program.endTransaction(transactionID, true); program.endTransaction(transactionID, true);
@ -296,6 +347,12 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
assertEquals(overlayBlock1.getName(), blocks[origBlockCount + 0].getName()); assertEquals(overlayBlock1.getName(), blocks[origBlockCount + 0].getName());
assertEquals(overlayBlock4.getName(), blocks[origBlockCount + 1].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(); program.undo();
assertEquals(origSpaceCount + 4, af.getNumAddressSpaces()); assertEquals(origSpaceCount + 4, af.getNumAddressSpaces());
blocks = program.getMemory().getBlocks(); blocks = program.getMemory().getBlocks();
@ -308,6 +365,12 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
assertEquals(overlayBlock3.getName(), blocks[origBlockCount + 2].getName()); assertEquals(overlayBlock3.getName(), blocks[origBlockCount + 2].getName());
assertEquals(overlayBlock4.getName(), blocks[origBlockCount + 3].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(); program.redo();
assertEquals(origSpaceCount + 2, af.getNumAddressSpaces()); assertEquals(origSpaceCount + 2, af.getNumAddressSpaces());
blocks = program.getMemory().getBlocks(); blocks = program.getMemory().getBlocks();
@ -317,5 +380,6 @@ public class OverlayAddressSpaceTest extends AbstractGhidraHeadedIntegrationTest
overlayBlock4 = program.getMemory().getBlock(overlayBlock4.getName()); overlayBlock4 = program.getMemory().getBlock(overlayBlock4.getName());
assertEquals(overlayBlock1.getName(), blocks[origBlockCount + 0].getName()); assertEquals(overlayBlock1.getName(), blocks[origBlockCount + 0].getName());
assertEquals(overlayBlock4.getName(), blocks[origBlockCount + 1].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.address.*;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.exception.*; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public class MyTestMemory extends AddressSet implements Memory { public class MyTestMemory extends AddressSet implements Memory {
@ -376,8 +377,7 @@ public class MyTestMemory extends AddressSet implements Memory {
@Override @Override
public MemoryBlock createInitializedBlock(String name, Address start, FileBytes fileBytes, public MemoryBlock createInitializedBlock(String name, Address start, FileBytes fileBytes,
long offset, long size, boolean overlay) throws LockException, DuplicateNameException, long offset, long size, boolean overlay) {
MemoryConflictException, AddressOverflowException {
throw new UnsupportedOperationException(); 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.address.OverlayAddressSpace;
import ghidra.program.model.lang.Language; import ghidra.program.model.lang.Language;
import ghidra.program.util.LanguageTranslator; import ghidra.program.util.LanguageTranslator;
import ghidra.util.exception.AssertException;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
class OverlaySpaceAdapterDB { class OverlaySpaceAdapterDB {
@ -62,12 +61,12 @@ class OverlaySpaceAdapterDB {
AddressSpace space = factory.getAddressSpace(templateSpaceName); AddressSpace space = factory.getAddressSpace(templateSpaceName);
try { try {
OverlayAddressSpace sp = OverlayAddressSpace sp =
factory.addOverlayAddressSpace(spaceName, space, minOffset, maxOffset); factory.addOverlayAddressSpace(spaceName, true, space, minOffset, maxOffset);
sp.setDatabaseKey(rec.getKey()); sp.setDatabaseKey(rec.getKey());
} }
catch (DuplicateNameException e) { catch (IllegalArgumentException e) {
throw new AssertException( throw new RuntimeException(
"Should not have duplicateNameException when recreating factory"); "Unexpected error initializing overlay address spaces", e);
} }
} }
} }
@ -140,7 +139,7 @@ class OverlaySpaceAdapterDB {
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {
throw new RuntimeException( throw new RuntimeException(
"Unexpected error1 updating overlay address spaces"); "Unexpected error updating overlay address spaces", e);
} }
} }
} }
@ -151,13 +150,14 @@ class OverlaySpaceAdapterDB {
AddressSpace origSpace = AddressSpace origSpace =
factory.getAddressSpace(rec.getString(OV_SPACE_BASE_COL)); factory.getAddressSpace(rec.getString(OV_SPACE_BASE_COL));
try { try {
space = factory.addOverlayAddressSpace(spaceName, origSpace, minOffset, space = factory.addOverlayAddressSpace(spaceName, true, origSpace,
minOffset,
maxOffset); maxOffset);
space.setDatabaseKey(rec.getKey()); space.setDatabaseKey(rec.getKey());
} }
catch (DuplicateNameException e) { catch (IllegalArgumentException e) {
throw new RuntimeException( 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; return originalFactory;
} }
public void addOverlayAddressSpace(OverlayAddressSpace ovSpace) throws DuplicateNameException { void addOverlayAddressSpace(OverlayAddressSpace ovSpace) throws DuplicateNameException {
addAddressSpace(ovSpace); 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; int unique = 0;
if (originalSpace.getType() == AddressSpace.TYPE_RAM || if (originalSpace.getType() == AddressSpace.TYPE_RAM ||
originalSpace.getType() == AddressSpace.TYPE_OTHER) { originalSpace.getType() == AddressSpace.TYPE_OTHER) {
unique = getNextUniqueID(); unique = getNextUniqueID();
} }
OverlayAddressSpace ovSpace = OverlayAddressSpace ovSpace =
new OverlayAddressSpace(name, originalSpace, unique, minOffset, maxOffset); new OverlayAddressSpace(spaceName, originalSpace, unique, minOffset, maxOffset);
try {
addAddressSpace(ovSpace); addAddressSpace(ovSpace);
}
catch (DuplicateNameException e) {
throw new RuntimeException(e); // unexpected
}
return ovSpace; 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 @Override
public Address getAddress(int spaceID, long offset) { public Address getAddress(int spaceID, long offset) {
Address addr = super.getAddress(spaceID, offset); Address addr = super.getAddress(spaceID, offset);
@ -146,10 +253,29 @@ public class ProgramAddressFactory extends DefaultAddressFactory {
removeAddressSpace(name); 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 @Override
protected void renameOverlaySpace(String oldName, String newName) protected String renameOverlaySpace(String oldOverlaySpaceName, String newName) {
throws DuplicateNameException { try {
super.renameOverlaySpace(oldName, newName); 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() { private int getNextUniqueID() {

View file

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

View file

@ -27,7 +27,6 @@ import ghidra.program.database.map.AddressMapDB;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.exception.AssertException; import ghidra.util.exception.AssertException;
import ghidra.util.exception.DuplicateNameException;
public class MemoryBlockDB implements MemoryBlock { public class MemoryBlockDB implements MemoryBlock {
@ -155,7 +154,7 @@ public class MemoryBlockDB implements MemoryBlock {
} }
@Override @Override
public void setName(String name) throws DuplicateNameException, LockException { public void setName(String name) throws LockException {
String oldName = getName(); String oldName = getName();
memMap.lock.acquire(); memMap.lock.acquire();
try { try {
@ -163,10 +162,10 @@ public class MemoryBlockDB implements MemoryBlock {
if (oldName.equals(name)) { if (oldName.equals(name)) {
return; return;
} }
memMap.checkBlockName(name, isOverlay()); memMap.checkBlockName(name);
try { try {
if (isOverlay()) { if (isOverlay()) {
memMap.overlayBlockRenamed(oldName, name); memMap.overlayBlockRenamed(startAddress.getAddressSpace().getName(), name);
} }
record.setString(MemoryMapDBAdapter.NAME_COL, name); record.setString(MemoryMapDBAdapter.NAME_COL, name);
adapter.updateBlockRecord(record); 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, public MemoryBlock createInitializedBlock(String name, Address start, long size,
byte initialValue, TaskMonitor monitor, boolean overlay) byte initialValue, TaskMonitor monitor, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException, throws LockException, MemoryConflictException, AddressOverflowException,
CancelledException, DuplicateNameException { CancelledException {
InputStream fillStream = null; InputStream fillStream = null;
if (initialValue != 0) { if (initialValue != 0) {
@ -572,17 +572,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
} }
private Address createOverlaySpace(String name, Address start, long dataLength) private Address createOverlaySpace(String name, Address start, long dataLength)
throws MemoryConflictException, AddressOverflowException, DuplicateNameException, throws MemoryConflictException, AddressOverflowException, LockException {
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));
}
start.addNoWrap(dataLength - 1);// just tests the AddressOverflow condition. start.addNoWrap(dataLength - 1);// just tests the AddressOverflow condition.
@ -596,8 +586,8 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override @Override
public MemoryBlock createInitializedBlock(String name, Address start, InputStream is, public MemoryBlock createInitializedBlock(String name, Address start, InputStream is,
long length, TaskMonitor monitor, boolean overlay) throws MemoryConflictException, long length, TaskMonitor monitor, boolean overlay) throws MemoryConflictException,
AddressOverflowException, CancelledException, LockException, DuplicateNameException { AddressOverflowException, CancelledException, LockException {
checkBlockName(name, overlay); checkBlockName(name);
lock.acquire(); lock.acquire();
try { try {
checkBlockSize(length, true); checkBlockSize(length, true);
@ -640,10 +630,10 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override @Override
public MemoryBlock createInitializedBlock(String name, Address start, FileBytes fileBytes, 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 { MemoryConflictException, AddressOverflowException, IndexOutOfBoundsException {
checkBlockName(name, overlay); checkBlockName(name);
lock.acquire(); lock.acquire();
try { try {
checkBlockSize(length, true); checkBlockSize(length, true);
@ -694,9 +684,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override @Override
public MemoryBlock createUninitializedBlock(String name, Address start, long size, public MemoryBlock createUninitializedBlock(String name, Address start, long size,
boolean overlay) throws MemoryConflictException, AddressOverflowException, boolean overlay) throws MemoryConflictException, AddressOverflowException,
LockException, DuplicateNameException { LockException {
checkBlockName(name, overlay); checkBlockName(name);
lock.acquire(); lock.acquire();
try { try {
checkBlockSize(size, false); checkBlockSize(size, false);
@ -730,9 +720,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override @Override
public MemoryBlock createBitMappedBlock(String name, Address start, Address mappedAddress, public MemoryBlock createBitMappedBlock(String name, Address start, Address mappedAddress,
long length, boolean overlay) throws MemoryConflictException, AddressOverflowException, long length, boolean overlay) throws MemoryConflictException, AddressOverflowException,
LockException, IllegalArgumentException, DuplicateNameException { LockException, IllegalArgumentException {
checkBlockName(name, overlay); checkBlockName(name);
lock.acquire(); lock.acquire();
try { try {
checkBlockSize(length, false); checkBlockSize(length, false);
@ -765,10 +755,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
@Override @Override
public MemoryBlock createByteMappedBlock(String name, Address start, Address mappedAddress, public MemoryBlock createByteMappedBlock(String name, Address start, Address mappedAddress,
long length, ByteMappingScheme byteMappingScheme, boolean overlay) long length, ByteMappingScheme byteMappingScheme, boolean overlay)
throws MemoryConflictException, AddressOverflowException, LockException, throws MemoryConflictException, AddressOverflowException, LockException {
DuplicateNameException {
checkBlockName(name, overlay); checkBlockName(name);
int mappingScheme = 0; // use for 1:1 mapping int mappingScheme = 0; // use for 1:1 mapping
if (byteMappingScheme == null) { if (byteMappingScheme == null) {
@ -810,27 +799,18 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
/** /**
* Check new block name for validity * Check new block name for validity
* @param name new block name * @param name new block name
* @param isOverlay true if block is overlay
* @throws IllegalArgumentException if invalid block name specified * @throws IllegalArgumentException if invalid block name specified
* @throws DuplicateNameException if name conflicts with an address space name
*/ */
void checkBlockName( void checkBlockName(String name) throws IllegalArgumentException {
String name, boolean isOverlay) if (!Memory.isValidMemoryBlockName(name)) {
throws IllegalArgumentException, DuplicateNameException {
if (!Memory.isValidAddressSpaceName(name)) {
throw new IllegalArgumentException("Invalid block name: " + 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 @Override
public MemoryBlock createBlock(MemoryBlock block, String name, Address start, long length) public MemoryBlock createBlock(MemoryBlock block, String name, Address start, long length)
throws MemoryConflictException, AddressOverflowException, LockException, throws MemoryConflictException, AddressOverflowException, LockException {
DuplicateNameException { checkBlockName(name);
checkBlockName(name, false);
lock.acquire(); lock.acquire();
try { try {
checkBlockSize(length, block.isInitialized()); checkBlockSize(length, block.isInitialized());
@ -2054,10 +2034,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
} }
} }
public void overlayBlockRenamed(String oldName, String name) public void overlayBlockRenamed(String oldOverlaySpaceName, String name)
throws DuplicateNameException, LockException { throws LockException {
program.renameOverlaySpace(oldName, name); program.renameOverlaySpace(oldOverlaySpaceName, name);
} }
@Override @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 { throws DuplicateNameException {
if (getAddressSpace(newName) != null) { if (getAddressSpace(newName) != null) {
throw new DuplicateNameException("AddressSpace named " + newName + " already exists!"); throw new DuplicateNameException("AddressSpace named " + newName + " already exists!");
} }
AddressSpace space = getAddressSpace(oldName); AddressSpace space = getAddressSpace(oldOverlaySpaceName);
if (space != null && space.isOverlaySpace()) { if (space != null && space.isOverlaySpace()) {
((OverlayAddressSpace) space).setName(newName); ((OverlayAddressSpace) space).setName(newName);
spaceNameTable.remove(oldName); spaceNameTable.remove(oldOverlaySpaceName);
spaceNameTable.put(space.getName(), space); 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.database.mem.*;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program; 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; 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. * 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) * naming rules)
* @param start start address of the block * @param start start address of the block
* @param is source of the data used to fill the block or null for zero initialization. * @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 * address space
* @throws CancelledException user cancelled operation * @throws CancelledException user cancelled operation
* @throws IllegalArgumentException if invalid block name specified * @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, public MemoryBlock createInitializedBlock(String name, Address start, InputStream is,
long length, TaskMonitor monitor, boolean overlay) long length, TaskMonitor monitor, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException, throws LockException, MemoryConflictException, AddressOverflowException,
CancelledException, IllegalArgumentException, DuplicateNameException; CancelledException, IllegalArgumentException;
/** /**
* Create an initialized memory block and add it to this Memory. * 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) * naming rules)
* @param start start of the block * @param start start of the block
* @param size block length (positive non-zero value required) * @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 * @throws AddressOverflowException if the start is beyond the
* address space * address space
* @throws IllegalArgumentException if invalid block name specified * @throws IllegalArgumentException if invalid block name specified
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
* @throws CancelledException user cancelled operation * @throws CancelledException user cancelled operation
*/ */
public MemoryBlock createInitializedBlock(String name, Address start, long size, public MemoryBlock createInitializedBlock(String name, Address start, long size,
byte initialValue, TaskMonitor monitor, boolean overlay) byte initialValue, TaskMonitor monitor, boolean overlay)
throws LockException, IllegalArgumentException, DuplicateNameException, throws LockException, IllegalArgumentException, MemoryConflictException,
MemoryConflictException, AddressOverflowException, CancelledException; AddressOverflowException, CancelledException;
/** /**
* Create an initialized memory block using bytes from a {@link FileBytes} object. * 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) * naming rules)
* @param start starting address of the block * @param start starting address of the block
* @param fileBytes the {@link FileBytes} object to use as the underlying source of bytes. * @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 * @throws IndexOutOfBoundsException if file bytes range specified by offset and size
* is out of bounds for the specified fileBytes. * is out of bounds for the specified fileBytes.
* @throws IllegalArgumentException if invalid block name specified * @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, public MemoryBlock createInitializedBlock(String name, Address start, FileBytes fileBytes,
long offset, long size, boolean overlay) throws LockException, IllegalArgumentException, 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. * 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) * naming rules)
* @param start start of the block * @param start start of the block
* @param size block length * @param size block length
@ -200,15 +198,14 @@ public interface Memory extends AddressSetView {
* @throws AddressOverflowException if the start is beyond the * @throws AddressOverflowException if the start is beyond the
* address space * address space
* @throws IllegalArgumentException if invalid block name specified * @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, public MemoryBlock createUninitializedBlock(String name, Address start, long size,
boolean overlay) throws LockException, IllegalArgumentException, DuplicateNameException, boolean overlay) throws LockException, IllegalArgumentException,
MemoryConflictException, AddressOverflowException; MemoryConflictException, AddressOverflowException;
/** /**
* Create a bit overlay memory block and add it to this Memory. * 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) * naming rules)
* @param start start of the block * @param start start of the block
* @param mappedAddress start address in the source block for the * @param mappedAddress start address in the source block for the
@ -225,17 +222,15 @@ public interface Memory extends AddressSetView {
* previous block * previous block
* @throws AddressOverflowException if block specification exceeds bounds of address space * @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IllegalArgumentException if invalid block name specified * @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, public MemoryBlock createBitMappedBlock(String name, Address start, Address mappedAddress,
long length, boolean overlay) throws LockException, MemoryConflictException, long length, boolean overlay) throws LockException, MemoryConflictException,
AddressOverflowException, AddressOverflowException, IllegalArgumentException;
IllegalArgumentException, DuplicateNameException;
/** /**
* Create a memory block that uses the bytes located at a different location with a 1:1 * Create a memory block that uses the bytes located at a different location with a 1:1
* byte mapping scheme. * 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) * naming rules)
* @param start start of the block * @param start start of the block
* @param mappedAddress start address in the source block for the * @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 MemoryConflictException if the new block overlaps with a previous block
* @throws AddressOverflowException if block specification exceeds bounds of address space * @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IllegalArgumentException if invalid block name * @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, public MemoryBlock createByteMappedBlock(String name, Address start, Address mappedAddress,
long length, ByteMappingScheme byteMappingScheme, boolean overlay) long length, ByteMappingScheme byteMappingScheme, boolean overlay)
throws LockException, MemoryConflictException, AddressOverflowException, throws LockException, MemoryConflictException, AddressOverflowException,
IllegalArgumentException, DuplicateNameException; IllegalArgumentException;
/** /**
* Create a memory block that uses the bytes located at a different location with a 1:1 * Create a memory block that uses the bytes located at a different location with a 1:1
* byte mapping scheme. * 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) * naming rules)
* @param start start of the block * @param start start of the block
* @param mappedAddress start address in the source block for the * @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 MemoryConflictException if the new block overlaps with a previous block
* @throws AddressOverflowException if block specification exceeds bounds of address space * @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IllegalArgumentException if invalid block name * @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, default public MemoryBlock createByteMappedBlock(String name, Address start,
Address mappedAddress, long length, boolean overlay) throws LockException, Address mappedAddress, long length, boolean overlay) throws LockException,
MemoryConflictException, MemoryConflictException,
AddressOverflowException, IllegalArgumentException, DuplicateNameException { AddressOverflowException, IllegalArgumentException {
return createByteMappedBlock(name, start, mappedAddress, length, null, overlay); 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 * have block filled with 0's. Method will only create physical space blocks
* and will not create an overlay block. * and will not create an overlay block.
* @param block source 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). * naming rules).
* @param start start of the block * @param start start of the block
* @param length the size of the new 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 MemoryConflictException if block specification conflicts with an existing block
* @throws AddressOverflowException if the new memory block would extend * @throws AddressOverflowException if the new memory block would extend
* beyond the end of the address space. * beyond the end of the address space.
* @throws IllegalArgumentException if invalid block name specified * @throws IllegalArgumentException if invalid block name specifiede
* @throws DuplicateNameException if name conflicts with an existing address space/overlay name
*/ */
public MemoryBlock createBlock(MemoryBlock block, String name, Address start, long length) public MemoryBlock createBlock(MemoryBlock block, String name, Address start, long length)
throws LockException, IllegalArgumentException, MemoryConflictException, throws LockException, IllegalArgumentException, MemoryConflictException,
AddressOverflowException, DuplicateNameException; AddressOverflowException;
/** /**
* Remove the memory block. * Remove the memory block.
@ -816,17 +808,22 @@ public interface Memory extends AddressSetView {
public AddressSourceInfo getAddressSourceInfo(Address address); public AddressSourceInfo getAddressSourceInfo(Address address);
/** /**
* Validate the given address space or block name: cannot be null, cannot be an empty string, cannot contain blank * Validate the given block name: cannot be null, cannot be an empty string,
* or reserved characters (e.g., colon). * 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 * @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) { if (name == null || name.length() == 0) {
return false; return false;
} }
for (int i = 0; i < name.length(); i++) { for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i); char c = name.charAt(i);
if (c <= 0x20 || c >= 0x7f || c == ':') { if (c < 0x20) {
return false; return false;
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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