diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMerge.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMerge.java
index c1c0fafe3d..11fed712fa 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMerge.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMerge.java
@@ -2159,6 +2159,10 @@ public class ProgramMerge {
monitor.setMessage("Replacing Function " + (count + 1) + " of " + totalAddresses +
"." + " Address = " + address.toString(true));
}
+
+ // Only use origin memory address
+ address = DiffUtility.getCompatibleMemoryAddress(address, originProgram);
+
if (isThunkFunction(address)) {
// Skip the thunk, but save it for processing during a second pass.
thunkSet.addRange(address, address);
@@ -2171,13 +2175,14 @@ public class ProgramMerge {
replaceThunks(thunkSet, monitor);
}
- private void replaceThunks(AddressSet thunkSet, TaskMonitor monitor) throws CancelledException {
+ private void replaceThunks(AddressSet originThunkSet, TaskMonitor monitor)
+ throws CancelledException {
long granularity;
// Now that all the non-thunk functions have been processed, process the saved thunks.
- long totalThunks = thunkSet.getNumAddresses();
+ long totalThunks = originThunkSet.getNumAddresses();
granularity = (totalThunks / PROGRESS_COUNTER_GRANULARITY) + 1;
monitor.initialize(totalThunks);
- AddressIterator thunkIter = thunkSet.getAddresses(true);
+ AddressIterator thunkIter = originThunkSet.getAddresses(true);
for (int count = 0; thunkIter.hasNext(); count++) {
monitor.checkCancelled();
Address address = thunkIter.next();
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolMerge.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolMerge.java
index 9fa9ce637a..6259f96911 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolMerge.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolMerge.java
@@ -4,9 +4,9 @@
* 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.
@@ -259,7 +259,7 @@ class SymbolMerge {
* parent namespace path. The primary symbol will be get set to the symbol that was primary in
* the source program.
*
- * @param address the program address where the symbols are being replaced.
+ * @param fromAddress the program address where the symbols are being replaced.
* This address should be derived from the "to" program.
* @param conflictSymbolIDMap maps the symbol IDs in the "from" program to the symbol IDs
* in the "to" program for any symbols (and their associated objects) that were created
@@ -267,33 +267,32 @@ class SymbolMerge {
* (key = "from" program's symbol ID; value = "to" program's symbol ID)
* @param monitor the task monitor for updating user progress and allowing cancelling.
*
- * @return a map of symbols that were created as conflicts during the replace. These map symbols
- * in the source program to a symbol with another name due to a duplicate symbol problem.
- * (key = "from" program's symbol; value = "to" program's symbol)
- *
* @throws CancelledException if the task monitor is cancelled.
* @throws DuplicateNameException if the name space can't be resolved due
* to a name conflict that can't be dealt with.
* @throws InvalidInputException
* the indicated address.
*/
- void replaceSymbols(Address address, LongLongHashtable conflictSymbolIDMap, TaskMonitor monitor)
+ void replaceSymbols(Address fromAddress, LongLongHashtable conflictSymbolIDMap,
+ TaskMonitor monitor)
throws CancelledException, DuplicateNameException, InvalidInputException {
- removeUniqueToSymbols(address, monitor);
- replaceFunctionSymbol(address, address, conflictSymbolIDMap, monitor);
- addFromSymbols(address, true, conflictSymbolIDMap, monitor);
+ Address toAddress = originToResultTranslator.getAddress(fromAddress);
- replacePrimary(address, conflictSymbolIDMap);
+ removeUniqueToSymbols(toAddress, monitor);
+ replaceFunctionSymbol(fromAddress, toAddress, conflictSymbolIDMap, monitor);
+ addFromSymbols(fromAddress, true, conflictSymbolIDMap, monitor);
+
+ replacePrimary(fromAddress, conflictSymbolIDMap);
// Remove this address as an entry point if its not one in program2.
- if (toSymbolTable.isExternalEntryPoint(address) &&
- !fromSymbolTable.isExternalEntryPoint(address)) {
- toSymbolTable.removeExternalEntryPoint(address);
+ if (toSymbolTable.isExternalEntryPoint(toAddress) &&
+ !fromSymbolTable.isExternalEntryPoint(fromAddress)) {
+ toSymbolTable.removeExternalEntryPoint(toAddress);
}
- else if (fromSymbolTable.isExternalEntryPoint(address) &&
- !toSymbolTable.isExternalEntryPoint(address)) {
- toSymbolTable.addExternalEntryPoint(address);
+ else if (fromSymbolTable.isExternalEntryPoint(toAddress) &&
+ !toSymbolTable.isExternalEntryPoint(toAddress)) {
+ toSymbolTable.addExternalEntryPoint(toAddress);
}
}
@@ -304,15 +303,14 @@ class SymbolMerge {
* not be removed at the address even if it is different. Otherwise, the
* function would inadvertently get removed.
*
- * @param address the program address where the symbols are being replaced.
+ * @param toAddress the program address where the symbols are being replaced.
* This address should be derived from the "to" program.
* @param monitor the task monitor for updating user progress and allowing cancelling.
*
* @throws CancelledException if the task monitor is cancelled.
*/
- private void removeUniqueToSymbols(Address fromAddress, TaskMonitor monitor)
+ private void removeUniqueToSymbols(Address toAddress, TaskMonitor monitor)
throws CancelledException {
- Address toAddress = originToResultTranslator.getAddress(fromAddress);
Symbol[] toSymbols = toSymbolTable.getUserSymbols(toAddress);
for (Symbol toSymbol : toSymbols) {
Symbol fromSymbol = SimpleDiffUtility.getSymbol(toSymbol, fromProgram);
@@ -349,10 +347,6 @@ class SymbolMerge {
* (key = "from" program's symbol ID; value = "to" program's symbol ID)
* @param monitor the task monitor for updating user progress and allowing cancelling.
*
- * @return an array of SymbolTranslators for symbols that ended up with different
- * pathnames in the destination program than they had in the source program. These map symbols
- * in the source program to a symbol with another name due to a duplicate symbol problem.
- *
* @throws CancelledException if the task monitor is canceled.
* @throws DuplicateNameException if a symbol couldn't be added due
* to a name conflict that can't be dealt with.
@@ -627,6 +621,7 @@ class SymbolMerge {
* @param setting indicates whether to replace or merge the symbols.
* @param replacePrimary true indicates that the primary symbol in the "to" program should be
* set to the same symbol as was primary in the "from" program.
+ * @param replaceFunction replace function if true
* @param conflictSymbolIDMap maps the symbol IDs in the "from" program to the symbol IDs
* in the "to" program for any symbols (and their associated objects) that were created
* with conflict names.
@@ -714,7 +709,6 @@ class SymbolMerge {
* with conflict names.
* (key = "from" program's symbol ID; value = "to" program's symbol ID)
* @param monitor the task monitor for notifying the user of this merge's progress.
- * @return the symbol now at the address in the toSymbolTable.
*
* @throws CancelledException if user cancels via the monitor.
* @throws InvalidInputException if a symbol name from the second program isn't valid
@@ -743,16 +737,16 @@ class SymbolMerge {
/**
*
- * @param address
+ * @param fromAddress
* This address should be derived from the "to" program.
* @param conflictSymbolIDMap maps the symbol IDs in the "from" program to the symbol IDs
* in the "to" program for any symbols (and their associated objects) that were created
* with conflict names.
* (key = "from" program's symbol ID; value = "to" program's symbol ID)
*/
- private void replacePrimary(Address address, LongLongHashtable conflictSymbolIDMap) {
+ private void replacePrimary(Address fromAddress, LongLongHashtable conflictSymbolIDMap) {
// Set the primary symbol.
- Symbol fromPrimary = fromSymbolTable.getPrimarySymbol(address);
+ Symbol fromPrimary = fromSymbolTable.getPrimarySymbol(fromAddress);
if (fromPrimary != null) {
Symbol newToPrimary = null;
try {
diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/map/AddressRangeMapDBTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/map/AddressRangeMapDBTest.java
index 8153dd0df3..c3187839fc 100644
--- a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/map/AddressRangeMapDBTest.java
+++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/map/AddressRangeMapDBTest.java
@@ -4,9 +4,9 @@
* 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.
@@ -54,7 +54,7 @@ public class AddressRangeMapDBTest extends AbstractGhidraHeadedIntegrationTest
Language language = service.getLanguage(new LanguageID("sparc:BE:64:default"));
program = new ProgramDB("test", language, language.getDefaultCompilerSpec(), this);
- MemoryMapDB memory = (MemoryMapDB) program.getMemory();
+ MemoryMapDB memory = program.getMemory();
addrMap = (AddressMap) getInstanceField("addrMap", memory);
space = program.getAddressFactory().getDefaultAddressSpace();
}
@@ -245,6 +245,72 @@ public class AddressRangeMapDBTest extends AbstractGhidraHeadedIntegrationTest
assertTrue(!iter.hasNext());
}
+ @Test
+ public void testAddressRangeIteratorWithImageBase() throws Exception {
+
+ AddressRangeMapDB map = new AddressRangeMapDB(program.getDBHandle(), addrMap,
+ new Lock("Test"), "TEST", this, LongField.INSTANCE, true);
+
+ int id = program.startTransaction("TEST");
+ try {
+
+ program.setImageBase(addr(0x0000001000L), true);
+
+ assertNull(map.getValue(addr(0x01000000000L)));
+
+ map.paintRange(addr(0x0000000000L), addr(0x0200001000L), ONE);
+ map.paintRange(addr(0x0100000000L), addr(0x0100001000L), TWO);
+ map.paintRange(addr(0x0080000000L), addr(0x0100000fffL), THREE);
+
+ map.clearRange(addr(0x0100000000L), addr(0x0100000010L));
+ map.clearRange(addr(0x01fffffff0L), addr(0x0200000010L));
+
+ // Force painted key range to cross wrap point
+ program.setImageBase(addr(0), true);
+ }
+ finally {
+ program.endTransaction(id, true);
+ }
+
+ // All address
+ AddressRangeIterator iter = map.getAddressRanges();
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x0000000000L), addr(0x007fffefffL)), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x007ffff000L), addr(0x00ffffefffL)), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x0fffff011L), addr(0x0ffffffffL)), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x0100000000L), addr(0x0100000000L)), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x0100000001L), addr(0x01ffffefefL)), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x01fffff011L), addr(0x0200000000L)), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0xfffffffffffff000L), addr(0xffffffffffffffffL)),
+ iter.next());
+ assertTrue(!iter.hasNext());
+
+ // Limited range of addresses starting at 0x0100000100
+ iter = map.getAddressRanges(addr(0x0100000100L));
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x0100000100L), addr(0x01ffffefefL)), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x01fffff011L), addr(0x0200000000L)), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0xfffffffffffff000L), addr(0xffffffffffffffffL)),
+ iter.next());
+ assertTrue(!iter.hasNext());
+
+ // Limited range of addresses from 0x0100000100 to 0x0200000100L
+ iter = map.getAddressRanges(addr(0x0100000100L), addr(0x0200000100L));
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x0100000100L), addr(0x01ffffefefL)), iter.next());
+ assertTrue(iter.hasNext());
+ assertEquals(new AddressRangeImpl(addr(0x01fffff011L), addr(0x0200000000L)), iter.next());
+ assertTrue(!iter.hasNext());
+ }
+
@Test
public void testMove() {
diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/util/ProgramMerge2Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/util/ProgramMerge2Test.java
index 1ce97f5713..eab4b52846 100644
--- a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/util/ProgramMerge2Test.java
+++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/util/ProgramMerge2Test.java
@@ -4402,8 +4402,8 @@ public class ProgramMerge2Test extends AbstractGhidraHeadedIntegrationTest {
AddressSet setToDiff = new AddressSet();
setToDiff.addRange(addr(p1, "SomeOverlay::01001630"),
addr(p1, "SomeOverlay::0100182f"));
- setToDiff.addRange(addr(p2, "SomeOverlay::01001830"),
- addr(p2, "SomeOverlay::0100192f"));
+ setToDiff.addRange(addr(p1, "SomeOverlay::01001830"),
+ addr(p1, "SomeOverlay::0100192f"));
setToDiff.addRange(addr(p1, "OtherOverlay::01001630"),
addr(p1, "OtherOverlay::0100192f"));
programMerge = new ProgramMergeManager(p1, p2, setToDiff);
@@ -4511,8 +4511,8 @@ public class ProgramMerge2Test extends AbstractGhidraHeadedIntegrationTest {
AddressSet setToDiff = new AddressSet();
setToDiff.addRange(addr(p1, "SomeOverlay::01001630"),
addr(p1, "SomeOverlay::0100182f"));
- setToDiff.addRange(addr(p2, "SomeOverlay::01001830"),
- addr(p2, "SomeOverlay::0100192f"));
+ setToDiff.addRange(addr(p1, "SomeOverlay::01001830"),
+ addr(p1, "SomeOverlay::0100192f"));
setToDiff.addRange(addr(p1, "OtherOverlay::01001630"),
addr(p1, "OtherOverlay::0100192f"));
programMerge = new ProgramMergeManager(p1, p2, setToDiff);
@@ -4617,8 +4617,8 @@ public class ProgramMerge2Test extends AbstractGhidraHeadedIntegrationTest {
AddressSet setToDiff = new AddressSet();
setToDiff.addRange(addr(p1, "SomeOverlay::01001630"),
addr(p1, "SomeOverlay::0100182f"));
- setToDiff.addRange(addr(p2, "SomeOverlay::01001830"),
- addr(p2, "SomeOverlay::0100192f"));
+ setToDiff.addRange(addr(p1, "SomeOverlay::01001830"),
+ addr(p1, "SomeOverlay::0100192f"));
setToDiff.addRange(addr(p1, "OtherOverlay::01001630"),
addr(p1, "OtherOverlay::0100192f"));
programMerge = new ProgramMergeManager(p1, p2, setToDiff);
@@ -4721,8 +4721,8 @@ public class ProgramMerge2Test extends AbstractGhidraHeadedIntegrationTest {
AddressSet setToDiff = new AddressSet();
setToDiff.addRange(addr(p1, "SomeOverlay::01001630"),
addr(p1, "SomeOverlay::0100182f"));
- setToDiff.addRange(addr(p2, "SomeOverlay::01001830"),
- addr(p2, "SomeOverlay::0100192f"));
+ setToDiff.addRange(addr(p1, "SomeOverlay::01001830"),
+ addr(p1, "SomeOverlay::0100192f"));
setToDiff.addRange(addr(p1, "OtherOverlay::01001630"),
addr(p1, "OtherOverlay::0100192f"));
programMerge = new ProgramMergeManager(p1, p2, setToDiff);
diff --git a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/api/markupitem/AbstractVTMarkupItemTest.java b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/api/markupitem/AbstractVTMarkupItemTest.java
index 134ebc103c..2c677ff726 100644
--- a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/api/markupitem/AbstractVTMarkupItemTest.java
+++ b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/api/markupitem/AbstractVTMarkupItemTest.java
@@ -339,7 +339,7 @@ public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedInteg
// verify we cannot unapply before we have applied
//
List markupItems = new ArrayList<>();
- Address destinationAddress = addr();
+ Address destinationAddress = addr(session.getDestinationProgram());
markupItem.setDefaultDestinationAddress(destinationAddress, TEST_ADDRESS_SOURCE);
markupItems.add(markupItem);
diff --git a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/AddressMapTestDummy.java b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/AddressMapTestDummy.java
index 4fdbd53d3b..bf2b1861c2 100644
--- a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/AddressMapTestDummy.java
+++ b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/AddressMapTestDummy.java
@@ -4,9 +4,9 @@
* 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.
@@ -22,12 +22,19 @@ import java.util.List;
import ghidra.program.database.map.AddressMap;
import ghidra.program.model.address.*;
+import ghidra.program.model.listing.Program;
public class AddressMapTestDummy implements AddressMap {
+ private Program program;
+
+ public AddressMapTestDummy(Program p) {
+ program = p;
+ }
+
@Override
public Address decodeAddress(long value) {
- return addr(value);
+ return addr(value, program);
}
@Override
diff --git a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/DummyTestProgramCorrelator.java b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/DummyTestProgramCorrelator.java
index dc3d3ed2e4..34b3fb48ec 100644
--- a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/DummyTestProgramCorrelator.java
+++ b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/DummyTestProgramCorrelator.java
@@ -4,9 +4,9 @@
* 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.
@@ -30,36 +30,27 @@ public class DummyTestProgramCorrelator extends VTAbstractProgramCorrelator {
private String name = "DummyTestProgramCorrelator";
private int matchCount = 1;
- public DummyTestProgramCorrelator() {
- this(1);
- }
-
public DummyTestProgramCorrelator(Program sourceProgram, AddressSetView sourceAddressSet,
Program destinationProgram, AddressSetView destinationAddressSet, ToolOptions options) {
super(sourceProgram, sourceAddressSet, destinationProgram, destinationAddressSet, options);
}
public DummyTestProgramCorrelator(Program sourceProgram, Program destinationProgram) {
- super(sourceProgram, createAddressSet(), destinationProgram, createAddressSet(),
- createOptions());
+ super(sourceProgram, createAddressSet(sourceProgram), destinationProgram,
+ createAddressSet(destinationProgram), createOptions());
}
- public DummyTestProgramCorrelator(int matchCount) {
- super(null, createAddressSet(), null, createAddressSet(), createOptions());
- this.matchCount = matchCount;
- }
-
- private static AddressSet createAddressSet() {
+ private static AddressSet createAddressSet(Program p) {
AddressSet as = new AddressSet();
- as.add(getRandomAddressRange());
- as.add(getRandomAddressRange());
- as.add(getRandomAddressRange());
+ as.add(getRandomAddressRange(p));
+ as.add(getRandomAddressRange(p));
+ as.add(getRandomAddressRange(p));
return as;
}
- private static AddressRange getRandomAddressRange() {
- Address addr1 = addr();
- Address addr2 = addr();
+ private static AddressRange getRandomAddressRange(Program p) {
+ Address addr1 = addr(p);
+ Address addr2 = addr(p);
return new AddressRangeImpl(min(addr1, addr2), max(addr1, addr2));
}
diff --git a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTAssociationDBTest.java b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTAssociationDBTest.java
index 737a9f9973..4c08da6e0e 100644
--- a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTAssociationDBTest.java
+++ b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTAssociationDBTest.java
@@ -4,9 +4,9 @@
* 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.
@@ -789,16 +789,18 @@ public class VTAssociationDBTest extends VTBaseTestCase {
private VTMatchInfo createRandomMatchWithUnrelatedAssociation(VTMatchInfo info) {
Address sourceAddress = info.getSourceAddress();
Address destinationAddress = info.getDestinationAddress();
- return createRandomMatch(otherAddr(sourceAddress), otherAddr(destinationAddress), db);
+ return createRandomMatch(otherAddr(sourceAddress, sourceProgram),
+ otherAddr(destinationAddress, destinationProgram), db);
}
private VTMatchInfo createRandomMatchWithConflictingDestinationAssociation(VTMatchInfo info) {
Address destinationAddress = info.getDestinationAddress();
- return createRandomMatch(info.getSourceAddress(), otherAddr(destinationAddress), db);
+ return createRandomMatch(info.getSourceAddress(),
+ otherAddr(destinationAddress, destinationProgram), db);
}
private VTMatchInfo createRandomMatchWithConflictingSourceAssociation(VTMatchInfo mainMatch) {
- return createRandomMatch(otherAddr(mainMatch.getSourceAddress()),
+ return createRandomMatch(otherAddr(mainMatch.getSourceAddress(), sourceProgram),
mainMatch.getDestinationAddress(), db);
}
diff --git a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTBaseTestCase.java b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTBaseTestCase.java
index 337de9be54..2151d1515b 100644
--- a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTBaseTestCase.java
+++ b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTBaseTestCase.java
@@ -50,15 +50,14 @@ public abstract class VTBaseTestCase extends AbstractGenericTest {
}
};
- private Program sourceProgram = new VTStubProgram(sourceDomainFile);
- private Program destinationProgram = new VTStubProgram(destinationDomainFile);
+ protected final Program sourceProgram = new VTStubProgram(sourceDomainFile);
+ protected final Program destinationProgram = new VTStubProgram(destinationDomainFile);
+
private FunctionManager functionManager = new VTSTubFunctionManager();
private Listing listing = new VTStubListing();
private SymbolTable symbolTable = new VTStubSymbolTable();
private Memory memory = new VTStubMemory();
- private AddressMap addressMap = new AddressMapTestDummy();
-
private static String[] randomTags = { "TAG1", "TAG2", "TAG3" };
private static GenericAddressSpace space =
new GenericAddressSpace("Test", 32, AddressSpace.TYPE_RAM, 3);
@@ -192,7 +191,12 @@ public abstract class VTBaseTestCase extends AbstractGenericTest {
private class VTStubProgram extends StubProgram {
- private DomainFile domainFile;
+ private final DomainFile domainFile;
+ private final AddressSpace defaultSpace =
+ new GenericAddressSpace("Test", 32, AddressSpace.TYPE_RAM, 3);
+ private final AddressFactory addrFactory =
+ new DefaultAddressFactory(new AddressSpace[] { defaultSpace }, defaultSpace);
+ private final AddressMap addressMap = new AddressMapTestDummy(this);
VTStubProgram(DomainFile domainFile) {
this.domainFile = domainFile;
@@ -240,7 +244,7 @@ public abstract class VTBaseTestCase extends AbstractGenericTest {
@Override
public AddressFactory getAddressFactory() {
- return null;
+ return addrFactory;
}
@Override
diff --git a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTDomainObjectEventsTest.java b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTDomainObjectEventsTest.java
index fe2af6475c..4c2ca49756 100644
--- a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTDomainObjectEventsTest.java
+++ b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTDomainObjectEventsTest.java
@@ -4,9 +4,9 @@
* 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.
@@ -95,7 +95,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
public void testEventsForAddingFirstMatchForAssociation() {
VTMatchSet matchSet = createMatchSet();
clearEvents();
- VTMatchInfo match = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo match = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
matchSet.addMatch(match);
@@ -107,7 +107,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
@Test
public void testEventsForAddingAdditionalMatchForAssociation() {
VTMatchSet matchSet = createMatchSet();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
matchSet.addMatch(matchInfo);
clearEvents();
@@ -124,7 +124,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
public void testEventsForRemovingLastMatchForAssociation() {
VTMatchSet manualMatchSet = db.getManualMatchSet();
clearEvents();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = manualMatchSet.addMatch(matchInfo);
clearEvents();
@@ -139,7 +139,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
public void testEventsForDeletingLastMatchForAssociation() {
VTMatchSet manualMatchSet = db.getManualMatchSet();
clearEvents();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = manualMatchSet.addMatch(matchInfo);
clearEvents();
@@ -155,7 +155,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
public void testEventsForRemovingNonLastMatchForAssociation() {
VTMatchSet manualMatchSet = db.getManualMatchSet();
clearEvents();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = manualMatchSet.addMatch(matchInfo);
clearEvents();
@@ -170,7 +170,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
public void testEventsForDeletingNonLastMatchForAssociation() {
VTMatchSet manualMatchSet = db.getManualMatchSet();
clearEvents();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = manualMatchSet.addMatch(matchInfo);
clearEvents();
@@ -184,7 +184,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
@Test
public void testEventsForRejectingMatch() throws VTAssociationStatusException {
VTMatchSet matchSet = createMatchSet();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = matchSet.addMatch(matchInfo);
clearEvents();
match.getAssociation().setRejected();
@@ -197,7 +197,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
public void testAssociationStatusChangedEvent() throws Exception {
VTMatchSet manualMatchSet = db.getManualMatchSet();
clearEvents();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = manualMatchSet.addMatch(matchInfo);
clearEvents();
@@ -214,7 +214,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
Msg.debug(this, "\tcalling clrearEvents()");
clearEvents();
Msg.debug(this, "\tcalling createRandomMatch()");
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
Msg.debug(this, "\tcalling addMatch()");
VTMatch match = manualMatchSet.addMatch(matchInfo);
Msg.debug(this, "\tcalling setAccepted()");
@@ -239,7 +239,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
public void testMarkupStatusChangedEventWhenApplying() throws Exception {
VTMatchSet manualMatchSet = db.getManualMatchSet();
clearEvents();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = manualMatchSet.addMatch(matchInfo);
match.getAssociation().setAccepted();
VTMarkupItem markupItem = VTTestUtils.createRandomMarkupItemStub(match);
@@ -259,7 +259,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
public void testMarkupStatusChangedEventWhenSettingStatus() throws Exception {
VTMatchSet manualMatchSet = db.getManualMatchSet();
clearEvents();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = manualMatchSet.addMatch(matchInfo);
match.getAssociation().setAccepted();
VTMarkupItem markupItem = VTTestUtils.createRandomMarkupItemStub(match);
@@ -295,7 +295,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
public void testTagAppliedEvent() throws VTAssociationStatusException {
VTMatchTagDB tag = db.createMatchTag("TEST");
VTMatchSet manualMatchSet = db.getManualMatchSet();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = manualMatchSet.addMatch(matchInfo);
match.getAssociation().setAccepted();
clearEvents();
@@ -313,7 +313,7 @@ public class VTDomainObjectEventsTest extends VTBaseTestCase {
@Test
public void testEventsForVotes() {
VTMatchSet manualMatchSet = db.getManualMatchSet();
- VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(null);
+ VTMatchInfo matchInfo = VTTestUtils.createRandomMatch(sourceProgram, destinationProgram);
VTMatch match = manualMatchSet.addMatch(matchInfo);
clearEvents();
match.getAssociation().setVoteCount(4);
diff --git a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTTestUtils.java b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTTestUtils.java
index 132e5fe0ca..873fa2abb1 100644
--- a/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTTestUtils.java
+++ b/Ghidra/Features/VersionTracking/src/test/java/ghidra/feature/vt/db/VTTestUtils.java
@@ -4,9 +4,9 @@
* 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.
@@ -27,7 +27,8 @@ import ghidra.feature.vt.api.main.*;
import ghidra.feature.vt.api.markupitem.MarkupTypeTestStub;
import ghidra.feature.vt.api.markuptype.VTMarkupType;
import ghidra.feature.vt.api.markuptype.VTMarkupTypeFactory;
-import ghidra.program.model.address.*;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.address.AddressFactory;
import ghidra.program.model.listing.Program;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
@@ -35,8 +36,6 @@ import ghidra.util.task.TaskMonitor;
public class VTTestUtils {
private static String[] randomTags = { "TAG1", "TAG2", "TAG3" };
- private static GenericAddressSpace space =
- new GenericAddressSpace("Test", 32, AddressSpace.TYPE_RAM, 3);
private VTTestUtils() {
// utility class
@@ -75,8 +74,8 @@ public class VTTestUtils {
return getRandomInt(0, Integer.MAX_VALUE);
}
- public static Address addr() {
- return addr(getRandomInt());
+ public static Address addr(Program p) {
+ return addr(getRandomInt(), p);
}
public static Address addr(String offset, Program p) {
@@ -84,14 +83,15 @@ public class VTTestUtils {
return addressFactory.getAddress(offset);
}
- public static Address addr(long offset) {
- return space.getAddress(offset);
+ public static Address addr(long offset, Program p) {
+ return p.getAddressFactory().getDefaultAddressSpace().getAddress(offset);
}
- public static Address otherAddr(Address address) {
- Address newAddress = addr();
- while (newAddress.equals(address)) {
- newAddress = addr();
+ public static Address otherAddr(Address addr, Program p) {
+ Address newAddress = addr(p);
+ long offset = addr.getOffset();
+ while (offset == newAddress.getOffset()) {
+ newAddress = addr(p);
}
return newAddress;
}
@@ -103,7 +103,19 @@ public class VTTestUtils {
* @return the match
*/
public static VTMatchInfo createRandomMatch(VTSession session) {
- return createRandomMatch(addr(), addr(), session);
+ return createRandomMatch(addr(session.getSourceProgram()),
+ addr(session.getDestinationProgram()), session);
+ }
+
+ /**
+ * Create a random dummy match with a null VTSession.
+ * @param session the match set manager to use when creating a random tag or
+ * null if you don't want to create a random tag.
+ * @return the match
+ */
+ public static VTMatchInfo createRandomMatch(Program sourceProgram,
+ Program destincationProgram) {
+ return createRandomMatch(addr(sourceProgram), addr(destincationProgram), null);
}
/**
@@ -184,7 +196,8 @@ public class VTTestUtils {
}
public static VTMatch createMatchSetWithOneMatch(VTSessionDB db) throws Exception {
- return createMatchSetWithOneMatch(db, addr(), addr());
+ return createMatchSetWithOneMatch(db, addr(db.getSourceProgram()),
+ addr(db.getDestinationProgram()));
}
public static VTMatch createMatchSetWithOneMatch(VTSessionDB db, Address sourceAddress,
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/map/AddressMapDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/map/AddressMapDB.java
index ec17ed2877..d883256bce 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/map/AddressMapDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/map/AddressMapDB.java
@@ -4,9 +4,9 @@
* 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.
@@ -295,6 +295,48 @@ public class AddressMapDB implements AddressMap {
return encodeAbsolute(addr, create ? INDEX_CREATE : INDEX_MATCH);
}
+ private Address checkAddressSpace(Address addr) {
+ AddressSpace space = addr.getAddressSpace();
+ if (space.getType() == AddressSpace.TYPE_DELETED) {
+ return addr;
+ }
+ if (space.isStackSpace()) {
+ AddressSpace myStackSpace = addrFactory.getStackSpace();
+ if (!space.equals(myStackSpace)) {
+ // Stack AddressSpace differs from my program's stack
+ throw new IllegalArgumentException(
+ "Unknown stack address from a different Program: " + addr.toString(true));
+ }
+ }
+ else if (space.isMemorySpace()) {
+ AddressSpace mySpace = addrFactory.getAddressSpace(space.getSpaceID()); // fast lookup
+ if (space != mySpace) {
+ // AddressSpace instance is not from my program's AddressFactory -
+ // perform a lookup by name and allow use if matching space is found.
+ // Although mixing address space use between programs is not preferred we try to
+ // accomodate provided all address characterics match. An ID lookup is performed
+ // first since it is the fastest way to verify the address originated from our
+ // address factory, otherwise we must attempt to find the same address space
+ // by name and check all characteristics via the equals method. This assumes
+ // a HashMap lookup based on an integer key is faster than a string key lookup.
+ mySpace = addrFactory.getAddressSpace(space.getName());
+
+ // NOTE: overlay spaces from different programs will never be equal if their
+ // 'orderedKey' differ. This can occur if they get renamed.
+ if (!space.equals(mySpace)) {
+ throw new IllegalArgumentException(
+ "Unknown address from a different Program: " + addr.toString(true));
+ }
+ // Transform into my address to avoid map contamination
+ if (mySpace instanceof OverlayAddressSpace myOvSpace) {
+ return myOvSpace.getAddressInThisSpaceOnly(addr.getOffset());
+ }
+ return mySpace.getAddress(addr.getOffset());
+ }
+ }
+ return addr;
+ }
+
/**
* Get absolute key encoding for the specified address
* @param addr address
@@ -315,6 +357,7 @@ public class AddressMapDB implements AddressMap {
case AddressSpace.TYPE_CODE:
case AddressSpace.TYPE_DELETED:
case AddressSpace.TYPE_OTHER:
+ addr = checkAddressSpace(addr);
int baseIndex = getBaseAddressIndex(addr, false, indexOperation);
long offset;
if (baseIndex < 0) {
@@ -347,6 +390,7 @@ public class AddressMapDB implements AddressMap {
return REGISTER_ADDR_TYPE_LONG | (addr.getOffset() & ADDR_OFFSET_MASK);
case AddressSpace.TYPE_STACK:
+ addr = checkAddressSpace(addr);
return STACK_ADDR_TYPE_LONG | (addr.getOffset() & ADDR_OFFSET_MASK);
case AddressSpace.TYPE_EXTERNAL:
@@ -425,7 +469,6 @@ public class AddressMapDB implements AddressMap {
}
// A new address map entry is required
- checkAddressSpace(addr.getAddressSpace());
int index = baseAddrs.length;
if (readOnly) {
// Create new base without modifying database
@@ -448,18 +491,6 @@ public class AddressMapDB implements AddressMap {
return index;
}
- void checkAddressSpace(AddressSpace addrSpace) {
- AddressSpace[] spaces = addrFactory.getPhysicalSpaces();
- for (AddressSpace space : spaces) {
- if (addrSpace.equals(space)) {
- return;
- }
- }
- if (addrSpace.getPhysicalSpace() != AddressSpace.OTHER_SPACE) { // not physical - but always exists in program
- throw new IllegalArgumentException("Address space not found in program");
- }
- }
-
@Override
public synchronized Address decodeAddress(long value) {
return decodeAddress(value, true);
@@ -621,6 +652,7 @@ public class AddressMapDB implements AddressMap {
case AddressSpace.TYPE_CODE:
case AddressSpace.TYPE_DELETED:
case AddressSpace.TYPE_OTHER:
+ addr = checkAddressSpace(addr);
boolean normalize = !addrIsNormalized && isInDefaultAddressSpace(addr);
int baseIndex = getBaseAddressIndex(addr, normalize, indexOperation);
long offset;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/map/AddressMapDBAdapterV1.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/map/AddressMapDBAdapterV1.java
index ba498e76a5..f82592aaf4 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/map/AddressMapDBAdapterV1.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/map/AddressMapDBAdapterV1.java
@@ -4,9 +4,9 @@
* 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.
@@ -75,7 +75,7 @@ class AddressMapDBAdapterV1 extends AddressMapDBAdapter {
if (segment != 0) {
spaceName += "_" + segment;
}
- GenericAddressSpace sp = new GenericAddressSpace(deletedName, 32,
+ GenericAddressSpace sp = new GenericAddressSpace(deletedName, 64,
AddressSpace.TYPE_DELETED, (int) rec.getKey());
sp.setShowSpaceName(true);
space = sp;
@@ -156,8 +156,8 @@ class AddressMapDBAdapterV1 extends AddressMapDBAdapter {
Address[] newAddrs = new Address[addresses.length + 1];
System.arraycopy(addresses, 0, newAddrs, 0, addresses.length);
- newAddrs[addresses.length] = addr.getAddressSpace().getAddressInThisSpaceOnly(
- normalizedOffset & ~AddressMapDB.ADDR_OFFSET_MASK);
+ newAddrs[addresses.length] = addr.getAddressSpace()
+ .getAddressInThisSpaceOnly(normalizedOffset & ~AddressMapDB.ADDR_OFFSET_MASK);
addresses = newAddrs;
return addresses;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDatabaseAdapter.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDatabaseAdapter.java
index b9e831da77..4f14e7c5a7 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDatabaseAdapter.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDatabaseAdapter.java
@@ -16,8 +16,7 @@
package ghidra.program.database.symbol;
import java.io.IOException;
-import java.util.Objects;
-import java.util.Set;
+import java.util.*;
import org.apache.commons.lang3.StringUtils;
@@ -185,13 +184,13 @@ abstract class SymbolDatabaseAdapter {
AddressMap oldAddrMap = addrMap.getOldAddressMap();
- long nextKey = 1; // only used for V0 upgrade if a record with key 0 is encountered
+ long zeroIdRemap = -1; // only used for V0 upgrade if a record with key 0 is encountered
if (oldAdapter instanceof SymbolDatabaseAdapterV0) {
// V0 is so old that there is not enough info in the current record to create new
// records. So store the current info in a temp database table and complete the upgrade
// when SymbolManager.programReady() is called. The missing info can be retrieved from
// other managers in the program at that point.
- nextKey =
+ zeroIdRemap =
((SymbolDatabaseAdapterV0) oldAdapter).extractLocalSymbols(tmpHandle, monitor);
}
@@ -205,8 +204,9 @@ abstract class SymbolDatabaseAdapter {
// We don't allow 0 keys starting with V1, set its key to next available
// which we got from the call to extractLocalSymbols() above
- if (rec.getKey() == 0) {
- rec.setKey(Math.max(1, nextKey));
+ if (zeroIdRemap > 0 && rec.getKey() == 0) {
+ // NOTE: V0 did not have concept of parent relationship
+ rec.setKey(zeroIdRemap);
}
tmpAdapter.updateSymbolRecord(rec);
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDatabaseAdapterV0.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDatabaseAdapterV0.java
index 42de8a41d4..bd61333d08 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDatabaseAdapterV0.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDatabaseAdapterV0.java
@@ -19,6 +19,7 @@ import java.io.IOException;
import java.util.Set;
import db.*;
+import ghidra.framework.data.OpenMode;
import ghidra.program.database.map.AddressIndexPrimaryKeyIterator;
import ghidra.program.database.map.AddressMap;
import ghidra.program.database.util.EmptyRecordIterator;
@@ -78,7 +79,7 @@ class SymbolDatabaseAdapterV0 extends SymbolDatabaseAdapter {
* Stores local symbols information in a temporary database table because this version
* is so old, we don't have enough information in the record to upgrade during the normal
* upgrade time. So we store off the information and will complete this upgrade when
- * {@link SymbolManager#programReady(int, int, TaskMonitor)} is called
+ * {@link SymbolManager#programReady(OpenMode, int, TaskMonitor)} is called
*
* @param handle handle to temporary database
* @param monitor the {@link TaskMonitor}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java
index 6d83b8145f..6275670096 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java
@@ -155,8 +155,8 @@ public class SymbolManager implements SymbolTable, ManagerDB {
throws IOException, CancelledException {
if (openMode == OpenMode.UPGRADE) {
- processOldLocalSymbols(monitor);
- processOldExternalEntryPoints(monitor);
+ processOldLocalSymbols(monitor); // migrate from temp table from V0 adapter upgrade
+ processOldExternalEntryPoints(monitor); // migrates from obsolete table: External Entries
if (currentRevision < ProgramDB.ADDED_VARIABLE_STORAGE_MANAGER_VERSION) {
// Eliminated namespace encoding within External address encoding
@@ -165,8 +165,9 @@ public class SymbolManager implements SymbolTable, ManagerDB {
// Migrate all other OldNamespaceAddresses used for variable symbols
processOldVariableAddresses(monitor);
}
+
if (currentRevision < ProgramDB.EXTERNAL_FUNCTIONS_ADDED_VERSION) {
- // SymbolType.EXTERNAL eliminated with program revision 17
+ // SymbolType.EXTERNAL eliminated with program revision 17 (switch to LABEL)
processOldExternalTypes(monitor);
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AbstractAddressSpace.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AbstractAddressSpace.java
index cd41cd2e36..ba4fe55969 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AbstractAddressSpace.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AbstractAddressSpace.java
@@ -637,7 +637,7 @@ abstract class AbstractAddressSpace implements AddressSpace {
@Override
public boolean isMemorySpace() {
- return type == TYPE_RAM || type == TYPE_CODE || type == TYPE_OTHER;
+ return type == TYPE_RAM || type == TYPE_CODE || type == TYPE_OTHER || type == TYPE_DELETED;
}
@Override
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AddressRangeImpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AddressRangeImpl.java
index e58123c0b8..42c8175b61 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AddressRangeImpl.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AddressRangeImpl.java
@@ -4,9 +4,9 @@
* 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.
@@ -53,18 +53,16 @@ public class AddressRangeImpl implements AddressRange, Serializable {
* maximum addresses are not comparable.
*/
public AddressRangeImpl(Address start, Address end) {
- if (!start.getAddressSpace().equals(end.getAddressSpace())) {
- throw new IllegalArgumentException("Start and end addresses are not in the same space.");
- }
-
if (start.compareTo(end) < 0) {
minAddress = start;
maxAddress = end;
- } else {
+ }
+ else {
// swap them if out of order
minAddress = end;
maxAddress = start;
}
+ AddressRange.checkValidRange(minAddress, maxAddress);
}
/**
@@ -120,8 +118,9 @@ public class AddressRangeImpl implements AddressRange, Serializable {
@Override
public BigInteger getBigLength() {
- return maxAddress.getOffsetAsBigInteger().subtract(minAddress.getOffsetAsBigInteger()).add(
- BigInteger.ONE);
+ return maxAddress.getOffsetAsBigInteger()
+ .subtract(minAddress.getOffsetAsBigInteger())
+ .add(BigInteger.ONE);
}
/**