mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-5480 Additinal improvement/fixes for ExternalLocation merge support
to address test failures.
This commit is contained in:
parent
6cc201b572
commit
5aec479fb2
7 changed files with 196 additions and 137 deletions
|
@ -556,7 +556,7 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
||||||
Symbol originalSymbol = symbolTables[ORIGINAL].getSymbol(originalID);
|
Symbol originalSymbol = symbolTables[ORIGINAL].getSymbol(originalID);
|
||||||
Address originalAddress = originalSymbol.getAddress();
|
Address originalAddress = originalSymbol.getAddress();
|
||||||
Symbol latestSymbol = SimpleDiffUtility.getMatchingExternalSymbol(programs[ORIGINAL],
|
Symbol latestSymbol = SimpleDiffUtility.getMatchingExternalSymbol(programs[ORIGINAL],
|
||||||
originalSymbol, programs[LATEST], latestAddIDs);
|
originalSymbol, programs[LATEST], false, latestAddIDs);
|
||||||
if (latestSymbol != null) {
|
if (latestSymbol != null) {
|
||||||
Address latestAddress = latestSymbol.getAddress();
|
Address latestAddress = latestSymbol.getAddress();
|
||||||
// Check the external space addresses to ensure they are the same.
|
// Check the external space addresses to ensure they are the same.
|
||||||
|
@ -577,7 +577,7 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
||||||
Symbol originalSymbol = symbolTables[ORIGINAL].getSymbol(originalID);
|
Symbol originalSymbol = symbolTables[ORIGINAL].getSymbol(originalID);
|
||||||
Address originalAddress = originalSymbol.getAddress();
|
Address originalAddress = originalSymbol.getAddress();
|
||||||
Symbol mySymbol = SimpleDiffUtility.getMatchingExternalSymbol(programs[ORIGINAL],
|
Symbol mySymbol = SimpleDiffUtility.getMatchingExternalSymbol(programs[ORIGINAL],
|
||||||
originalSymbol, programs[MY], myAddIDs);
|
originalSymbol, programs[MY], false, myAddIDs);
|
||||||
if (mySymbol != null) {
|
if (mySymbol != null) {
|
||||||
Address myAddress = mySymbol.getAddress();
|
Address myAddress = mySymbol.getAddress();
|
||||||
// Check the external space addresses to ensure they are the same.
|
// Check the external space addresses to ensure they are the same.
|
||||||
|
@ -1560,7 +1560,7 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
||||||
// Get the external symbol in LATEST that we think most likely matches MY external.
|
// Get the external symbol in LATEST that we think most likely matches MY external.
|
||||||
// Only try to match it with externals that were also added in LATEST.
|
// Only try to match it with externals that were also added in LATEST.
|
||||||
Symbol latestSymbol = SimpleDiffUtility.getMatchingExternalSymbol(programs[MY],
|
Symbol latestSymbol = SimpleDiffUtility.getMatchingExternalSymbol(programs[MY],
|
||||||
mySymbol, programs[LATEST], latestAddIDs);
|
mySymbol, programs[LATEST], false, latestAddIDs);
|
||||||
ExternalLocation latestExternalLocation = null;
|
ExternalLocation latestExternalLocation = null;
|
||||||
if (latestSymbol != null) {
|
if (latestSymbol != null) {
|
||||||
// We have a possible matching external from LATEST.
|
// We have a possible matching external from LATEST.
|
||||||
|
@ -4045,7 +4045,7 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
||||||
*/
|
*/
|
||||||
private void removeExternal(Program sourceProgram, ExternalLocation sourceExternalLocation) {
|
private void removeExternal(Program sourceProgram, ExternalLocation sourceExternalLocation) {
|
||||||
ExternalLocation resultExternalLocation = SimpleDiffUtility.getMatchingExternalLocation(
|
ExternalLocation resultExternalLocation = SimpleDiffUtility.getMatchingExternalLocation(
|
||||||
sourceProgram, sourceExternalLocation, programs[RESULT]);
|
sourceProgram, sourceExternalLocation, programs[RESULT], false);
|
||||||
if (resultExternalLocation == null) {
|
if (resultExternalLocation == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4054,7 +4054,7 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
||||||
functionManagers[RESULT].removeFunction(externalSpaceAddress);
|
functionManagers[RESULT].removeFunction(externalSpaceAddress);
|
||||||
// See if the location is now just a label.
|
// See if the location is now just a label.
|
||||||
resultExternalLocation = SimpleDiffUtility.getMatchingExternalLocation(sourceProgram,
|
resultExternalLocation = SimpleDiffUtility.getMatchingExternalLocation(sourceProgram,
|
||||||
sourceExternalLocation, programs[RESULT]);
|
sourceExternalLocation, programs[RESULT], false);
|
||||||
if (resultExternalLocation == null) {
|
if (resultExternalLocation == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -212,12 +212,12 @@ class FunctionMerger extends AbstractFunctionMerger implements ListingMerger {
|
||||||
public void autoMerge(int progressMin, int progressMax, TaskMonitor monitor)
|
public void autoMerge(int progressMin, int progressMax, TaskMonitor monitor)
|
||||||
throws ProgramConflictException, MemoryAccessException, CancelledException {
|
throws ProgramConflictException, MemoryAccessException, CancelledException {
|
||||||
|
|
||||||
latestResolvedDts = (Map<Long, DataType>) mergeManager.getResolveInformation(
|
latestResolvedDts = (Map<Long, DataType>) mergeManager
|
||||||
MergeConstants.RESOLVED_LATEST_DTS);
|
.getResolveInformation(MergeConstants.RESOLVED_LATEST_DTS);
|
||||||
myResolvedDts = (Map<Long, DataType>) mergeManager.getResolveInformation(
|
myResolvedDts = (Map<Long, DataType>) mergeManager
|
||||||
MergeConstants.RESOLVED_MY_DTS);
|
.getResolveInformation(MergeConstants.RESOLVED_MY_DTS);
|
||||||
origResolvedDts = (Map<Long, DataType>) mergeManager.getResolveInformation(
|
origResolvedDts = (Map<Long, DataType>) mergeManager
|
||||||
MergeConstants.RESOLVED_ORIGINAL_DTS);
|
.getResolveInformation(MergeConstants.RESOLVED_ORIGINAL_DTS);
|
||||||
|
|
||||||
initializeAutoMerge("Auto-merging Functions and determining conflicts.", progressMin,
|
initializeAutoMerge("Auto-merging Functions and determining conflicts.", progressMin,
|
||||||
progressMax, monitor);
|
progressMax, monitor);
|
||||||
|
@ -450,8 +450,8 @@ class FunctionMerger extends AbstractFunctionMerger implements ListingMerger {
|
||||||
conflictingMyEntries.add(latestOnly.intersect(changeMy));
|
conflictingMyEntries.add(latestOnly.intersect(changeMy));
|
||||||
if (!conflictingMyEntries.isEmpty()) {
|
if (!conflictingMyEntries.isEmpty()) {
|
||||||
entryConflictSet.add(latestBody); // Add Latest function's body.
|
entryConflictSet.add(latestBody); // Add Latest function's body.
|
||||||
entryConflictSet.add(
|
entryConflictSet
|
||||||
getBodies(functionManagers[MY], conflictingMyEntries)); // Add My conflicting function bodies.
|
.add(getBodies(functionManagers[MY], conflictingMyEntries)); // Add My conflicting function bodies.
|
||||||
}
|
}
|
||||||
newEntries.add(conflictingMyEntries);
|
newEntries.add(conflictingMyEntries);
|
||||||
}
|
}
|
||||||
|
@ -613,7 +613,7 @@ class FunctionMerger extends AbstractFunctionMerger implements ListingMerger {
|
||||||
Function myThunkedFunction = functions[MY].getThunkedFunction(false);
|
Function myThunkedFunction = functions[MY].getThunkedFunction(false);
|
||||||
Address myThunkedEntry = myThunkedFunction.getEntryPoint();
|
Address myThunkedEntry = myThunkedFunction.getEntryPoint();
|
||||||
Address myThunkedEntryAsLatest = SimpleDiffUtility.getCompatibleAddress(
|
Address myThunkedEntryAsLatest = SimpleDiffUtility.getCompatibleAddress(
|
||||||
functions[MY].getProgram(), myThunkedEntry, functions[LATEST].getProgram());
|
functions[MY].getProgram(), myThunkedEntry, functions[RESULT].getProgram());
|
||||||
if (!latestThunkedEntry.equals(myThunkedEntryAsLatest)) {
|
if (!latestThunkedEntry.equals(myThunkedEntryAsLatest)) {
|
||||||
// Save the thunk conflict
|
// Save the thunk conflict
|
||||||
saveThunkConflict(functions[RESULT]);
|
saveThunkConflict(functions[RESULT]);
|
||||||
|
@ -1065,10 +1065,8 @@ class FunctionMerger extends AbstractFunctionMerger implements ListingMerger {
|
||||||
mergeParamInfo(addr, paramInfoConflicts, parameterInfoChoice, monitor);
|
mergeParamInfo(addr, paramInfoConflicts, parameterInfoChoice, monitor);
|
||||||
}
|
}
|
||||||
else if (askUser && mergeManager != null) {
|
else if (askUser && mergeManager != null) {
|
||||||
Iterator<ParamInfoConflict> iter = paramInfoConflicts.iterator();
|
for (ParamInfoConflict pc : paramInfoConflicts) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
ParamInfoConflict pc = iter.next();
|
|
||||||
boolean useForAll = (parameterInfoChoice != ASK_USER);
|
boolean useForAll = (parameterInfoChoice != ASK_USER);
|
||||||
if (useForAll) {
|
if (useForAll) {
|
||||||
mergeParamInfo(addr, pc, parameterInfoChoice, monitor);
|
mergeParamInfo(addr, pc, parameterInfoChoice, monitor);
|
||||||
|
@ -1356,11 +1354,9 @@ class FunctionMerger extends AbstractFunctionMerger implements ListingMerger {
|
||||||
|
|
||||||
protected void mergeParameters(Address entryPtAddress, int chosenConflictOption,
|
protected void mergeParameters(Address entryPtAddress, int chosenConflictOption,
|
||||||
TaskMonitor monitor) {
|
TaskMonitor monitor) {
|
||||||
Function resultFunction =
|
Function resultFunction = listingMergeManager.mergeLatest.getResultProgram()
|
||||||
listingMergeManager.mergeLatest.getResultProgram()
|
.getFunctionManager()
|
||||||
.getFunctionManager()
|
.getFunctionAt(entryPtAddress);
|
||||||
.getFunctionAt(
|
|
||||||
entryPtAddress);
|
|
||||||
if (resultFunction == null) {
|
if (resultFunction == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1317,7 +1317,7 @@ public class ProgramMerge {
|
||||||
Program fromPgm = fromExtLoc.getSymbol().getProgram();
|
Program fromPgm = fromExtLoc.getSymbol().getProgram();
|
||||||
Namespace toNamespace = DiffUtility.createNamespace(fromPgm, fromNamespace, toPgm);
|
Namespace toNamespace = DiffUtility.createNamespace(fromPgm, fromNamespace, toPgm);
|
||||||
ExternalLocation toExternalLocation =
|
ExternalLocation toExternalLocation =
|
||||||
SimpleDiffUtility.getMatchingExternalLocation(fromPgm, fromExtLoc, toPgm);
|
SimpleDiffUtility.getMatchingExternalLocation(fromPgm, fromExtLoc, toPgm, false);
|
||||||
if (toExternalLocation == null) {
|
if (toExternalLocation == null) {
|
||||||
toExtMgr.addExtLocation(toNamespace, fromExtLabel, fromExtAddr, fromSourceType);
|
toExtMgr.addExtLocation(toNamespace, fromExtLabel, fromExtAddr, fromSourceType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -242,13 +242,16 @@ public class ExternalMergerTest extends AbstractExternalMergerTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
executeMerge(ASK_USER);
|
executeMerge(ASK_USER);
|
||||||
chooseButtonAndApply("Resolve External Add Conflict", LATEST_BUTTON);// Add Conflict
|
// NOTE: Duplicate external program address is not treated as conflict, bot external
|
||||||
|
// locations will be added.
|
||||||
|
chooseButtonAndApply("Resolve Reference Conflict", LATEST_BUTTON);// Add Conflict
|
||||||
waitForMergeCompletion();
|
waitForMergeCompletion();
|
||||||
|
|
||||||
ExternalManager externalManager = resultProgram.getExternalManager();
|
ExternalManager externalManager = resultProgram.getExternalManager();
|
||||||
ExternalLocation extLocApples =
|
ExternalLocation extLocApples =
|
||||||
externalManager.getUniqueExternalLocation("advapi32.dll", "apples");
|
externalManager.getUniqueExternalLocation("advapi32.dll", "apples");
|
||||||
assertNull(extLocApples);
|
assertNotNull(extLocApples);
|
||||||
|
|
||||||
ExternalLocation extLocOranges =
|
ExternalLocation extLocOranges =
|
||||||
externalManager.getUniqueExternalLocation("advapi32.dll", "oranges");
|
externalManager.getUniqueExternalLocation("advapi32.dll", "oranges");
|
||||||
assertNotNull(extLocOranges);
|
assertNotNull(extLocOranges);
|
||||||
|
@ -303,16 +306,19 @@ public class ExternalMergerTest extends AbstractExternalMergerTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
executeMerge(ASK_USER);
|
executeMerge(ASK_USER);
|
||||||
chooseButtonAndApply("Resolve External Add Conflict", MY_BUTTON);// Add Conflict
|
// NOTE: Duplicate external program address is not treated as conflict, bot external
|
||||||
|
// locations will be added.
|
||||||
|
chooseButtonAndApply("Resolve Reference Conflict", MY_BUTTON);// Add Conflict
|
||||||
waitForMergeCompletion();
|
waitForMergeCompletion();
|
||||||
|
|
||||||
ExternalManager externalManager = resultProgram.getExternalManager();
|
ExternalManager externalManager = resultProgram.getExternalManager();
|
||||||
ExternalLocation extLocApples =
|
ExternalLocation extLocApples =
|
||||||
externalManager.getUniqueExternalLocation("advapi32.dll", "apples");
|
externalManager.getUniqueExternalLocation("advapi32.dll", "apples");
|
||||||
assertNotNull(extLocApples);
|
assertNotNull(extLocApples);
|
||||||
|
|
||||||
ExternalLocation extLocOranges =
|
ExternalLocation extLocOranges =
|
||||||
externalManager.getUniqueExternalLocation("advapi32.dll", "oranges");
|
externalManager.getUniqueExternalLocation("advapi32.dll", "oranges");
|
||||||
assertNull(extLocOranges);
|
assertNotNull(extLocOranges);
|
||||||
|
|
||||||
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
||||||
Reference[] refs;
|
Reference[] refs;
|
||||||
|
@ -1406,7 +1412,7 @@ public class ExternalMergerTest extends AbstractExternalMergerTest {
|
||||||
public void testExtLabelRefAddDiffAddressConflictPickMy() throws Exception {
|
public void testExtLabelRefAddDiffAddressConflictPickMy() throws Exception {
|
||||||
|
|
||||||
mtf.initialize("NotepadMergeListingTest", new ProgramModifierListener() {
|
mtf.initialize("NotepadMergeListingTest", new ProgramModifierListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void modifyLatest(ProgramDB program) {
|
public void modifyLatest(ProgramDB program) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -929,7 +929,9 @@ public class FunctionMergerThunkTest extends AbstractExternalMergerTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
executeMerge(ASK_USER);
|
executeMerge(ASK_USER);
|
||||||
|
// Two diiferent external program addresses for the same external location (name match)
|
||||||
chooseButtonAndApply("Resolve External Add Conflict", KEEP_BOTH_BUTTON);
|
chooseButtonAndApply("Resolve External Add Conflict", KEEP_BOTH_BUTTON);
|
||||||
|
chooseButtonAndApply("Resolve Thunk Function Conflict", LATEST_BUTTON);
|
||||||
waitForMergeCompletion();
|
waitForMergeCompletion();
|
||||||
|
|
||||||
Function thunkFunction = getFunction(resultProgram, THUNK_A_ENTRY);
|
Function thunkFunction = getFunction(resultProgram, THUNK_A_ENTRY);
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -147,7 +147,6 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
|
|
||||||
mtf.initialize("NotepadMergeListingTest", new ProgramModifierListener() {
|
mtf.initialize("NotepadMergeListingTest", new ProgramModifierListener() {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void modifyLatest(ProgramDB program) {
|
public void modifyLatest(ProgramDB program) {
|
||||||
try {
|
try {
|
||||||
|
@ -656,8 +655,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -678,8 +676,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -741,8 +738,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -828,8 +824,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -913,8 +908,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -949,7 +943,8 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
executeMerge(ASK_USER);
|
executeMerge(ASK_USER);
|
||||||
chooseButtonAndApply("Resolve External Add Conflict", LATEST_BUTTON);
|
// The two external locations are not in conflict and can both exist
|
||||||
|
chooseButtonAndApply("Resolve Reference Conflict", LATEST_BUTTON);
|
||||||
waitForMergeCompletion();
|
waitForMergeCompletion();
|
||||||
|
|
||||||
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
||||||
|
@ -999,8 +994,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -1035,7 +1029,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
executeMerge(ASK_USER);
|
executeMerge(ASK_USER);
|
||||||
chooseButtonAndApply("Resolve External Add Conflict", MY_BUTTON);
|
chooseButtonAndApply("Resolve Reference Conflict", MY_BUTTON);
|
||||||
waitForMergeCompletion();
|
waitForMergeCompletion();
|
||||||
|
|
||||||
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
||||||
|
@ -1084,8 +1078,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -1130,7 +1123,6 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
executeMerge(ASK_USER);
|
executeMerge(ASK_USER);
|
||||||
chooseButtonAndApply("Resolve External Add Conflict", KEEP_BOTH_BUTTON);
|
|
||||||
chooseRadioButton("Resolve Reference Conflict", LATEST_BUTTON);// Since kept both, now choose reference conflict.
|
chooseRadioButton("Resolve Reference Conflict", LATEST_BUTTON);// Since kept both, now choose reference conflict.
|
||||||
waitForMergeCompletion();
|
waitForMergeCompletion();
|
||||||
|
|
||||||
|
@ -1188,8 +1180,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -1234,7 +1225,6 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
executeMerge(ASK_USER);
|
executeMerge(ASK_USER);
|
||||||
chooseButtonAndApply("Resolve External Add Conflict", KEEP_BOTH_BUTTON);
|
|
||||||
chooseRadioButton("Resolve Reference Conflict", MY_BUTTON);// Since kept both, now choose reference conflict.
|
chooseRadioButton("Resolve Reference Conflict", MY_BUTTON);// Since kept both, now choose reference conflict.
|
||||||
waitForMergeCompletion();
|
waitForMergeCompletion();
|
||||||
|
|
||||||
|
@ -1280,8 +1270,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -1316,9 +1305,10 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
executeMerge(ASK_USER);
|
executeMerge(ASK_USER);
|
||||||
chooseButtonAndApply("Resolve External Add Conflict", MERGE_BOTH_BUTTON);
|
chooseButtonAndApply("Resolve Reference Conflict", MY_BUTTON);
|
||||||
chooseVariousOptionsForConflictType("Resolve External Detail Conflict",
|
// NOTE: Locations are not considered conflicts since both get added
|
||||||
new int[] { INFO_ROW, KEEP_LATEST, KEEP_MY });// Namespace, Name
|
// chooseVariousOptionsForConflictType("Resolve External Detail Conflict",
|
||||||
|
// new int[] { INFO_ROW, KEEP_LATEST, KEEP_MY });// Namespace, Name
|
||||||
waitForMergeCompletion();
|
waitForMergeCompletion();
|
||||||
|
|
||||||
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
||||||
|
@ -1333,11 +1323,10 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr("0x10013d8"), -1);
|
refs = refMgr.getReferencesFrom(addr("0x10013d8"), -1);
|
||||||
assertEquals(1, refs.length);
|
assertEquals(1, refs.length);
|
||||||
assertEquals("ADVAPI32.DLL::getName",
|
assertEquals("USER32.DLL::getName",
|
||||||
((ExternalReference) refs[0]).getExternalLocation().toString());
|
((ExternalReference) refs[0]).getExternalLocation().toString());
|
||||||
assertEquals("77db2233",
|
assertNull(((ExternalReference) refs[0]).getExternalLocation().getAddress());
|
||||||
((ExternalReference) refs[0]).getExternalLocation().getAddress().toString());
|
assertEquals(SourceType.USER_DEFINED, refs[0].getSource());
|
||||||
assertEquals(SourceType.DEFAULT, refs[0].getSource());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1357,8 +1346,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013cc"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
refMgr.addExternalReference(addr(program, "0x10013cc"), "USER32.DLL", "printf",
|
||||||
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0,
|
addr(program, "0x01234567"), SourceType.USER_DEFINED, 0, RefType.DATA);
|
||||||
RefType.DATA);
|
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
refs = refMgr.getReferencesFrom(addr(program, "0x10013d8"), 0);
|
||||||
assertEquals(0, refs.length);
|
assertEquals(0, refs.length);
|
||||||
|
@ -1393,9 +1381,10 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
executeMerge(ASK_USER);
|
executeMerge(ASK_USER);
|
||||||
chooseButtonAndApply("Resolve External Add Conflict", MERGE_BOTH_BUTTON);
|
// NOTE: Locations are not considered conflicts since both get added
|
||||||
chooseVariousOptionsForConflictType("Resolve External Detail Conflict",
|
chooseButtonAndApply("Resolve Reference Conflict", LATEST_BUTTON);
|
||||||
new int[] { INFO_ROW, KEEP_MY, KEEP_LATEST });// Namespace, Name
|
// chooseVariousOptionsForConflictType("Resolve External Detail Conflict",
|
||||||
|
// new int[] { INFO_ROW, KEEP_MY, KEEP_LATEST });// Namespace, Name
|
||||||
waitForMergeCompletion();
|
waitForMergeCompletion();
|
||||||
|
|
||||||
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
ReferenceManager refMgr = resultProgram.getReferenceManager();
|
||||||
|
@ -1410,7 +1399,7 @@ public class RefMergerExtTest extends AbstractExternalMergerTest {
|
||||||
|
|
||||||
refs = refMgr.getReferencesFrom(addr("0x10013d8"), -1);
|
refs = refMgr.getReferencesFrom(addr("0x10013d8"), -1);
|
||||||
assertEquals(1, refs.length);
|
assertEquals(1, refs.length);
|
||||||
assertEquals("USER32.DLL::EXT_77db2233",
|
assertEquals("ADVAPI32.DLL::EXT_77db2233",
|
||||||
((ExternalReference) refs[0]).getExternalLocation().toString());
|
((ExternalReference) refs[0]).getExternalLocation().toString());
|
||||||
assertEquals("77db2233",
|
assertEquals("77db2233",
|
||||||
((ExternalReference) refs[0]).getExternalLocation().getAddress().toString());
|
((ExternalReference) refs[0]).getExternalLocation().getAddress().toString());
|
||||||
|
|
|
@ -190,7 +190,14 @@ public class SimpleDiffUtility {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert an address from the specified program to a comparable address in the
|
* Convert an address from the specified program to a comparable address in the
|
||||||
* specified otherProgram.
|
* specified otherProgram.
|
||||||
|
* <br>
|
||||||
|
* For external locations the match-up is very fuzzy and
|
||||||
|
* will use correlated references. If an exact match is required for an external location
|
||||||
|
* the {@link #getMatchingExternalLocation(Program, ExternalLocation, Program, boolean)} or
|
||||||
|
* {@link #getMatchingExternalSymbol(Program, Symbol, Program, boolean, Set)} should be used
|
||||||
|
* directly.
|
||||||
|
*
|
||||||
* @param program program which contains the specified address instance
|
* @param program program which contains the specified address instance
|
||||||
* @param addr address in program
|
* @param addr address in program
|
||||||
* @param otherProgram other program
|
* @param otherProgram other program
|
||||||
|
@ -250,7 +257,7 @@ public class SimpleDiffUtility {
|
||||||
else if (addr.isExternalAddress()) {
|
else if (addr.isExternalAddress()) {
|
||||||
Symbol s = program.getSymbolTable().getPrimarySymbol(addr);
|
Symbol s = program.getSymbolTable().getPrimarySymbol(addr);
|
||||||
if (s != null && s.isExternal()) {
|
if (s != null && s.isExternal()) {
|
||||||
s = getMatchingExternalSymbol(program, s, otherProgram, null);
|
s = getMatchingExternalSymbol(program, s, otherProgram, true, null);
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
return s.getAddress();
|
return s.getAddress();
|
||||||
}
|
}
|
||||||
|
@ -314,6 +321,10 @@ public class SimpleDiffUtility {
|
||||||
/**
|
/**
|
||||||
* Given a symbol for a specified program, get the corresponding symbol from the
|
* Given a symbol for a specified program, get the corresponding symbol from the
|
||||||
* specified otherProgram.
|
* specified otherProgram.
|
||||||
|
* <br>
|
||||||
|
* In the case of external locations this performs an exact match based upon symbol name,
|
||||||
|
* namespace and symbol type.
|
||||||
|
*
|
||||||
* @param symbol symbol to look for
|
* @param symbol symbol to look for
|
||||||
* @param otherProgram other program
|
* @param otherProgram other program
|
||||||
* @return corresponding symbol for otherProgram or null if no such symbol exists.
|
* @return corresponding symbol for otherProgram or null if no such symbol exists.
|
||||||
|
@ -405,6 +416,12 @@ public class SimpleDiffUtility {
|
||||||
|
|
||||||
ExternalLocation external = getExternalLocation(symbol);
|
ExternalLocation external = getExternalLocation(symbol);
|
||||||
|
|
||||||
|
// TODO: This match-up is exact based upon name and namespace and does not consider
|
||||||
|
// the original imported name or address, however these attributes must match.
|
||||||
|
|
||||||
|
// TODO: It is rather confusing to have two sets of methods for finding external
|
||||||
|
// locations. This should be simplified. getOther... getMatchingExternal...
|
||||||
|
|
||||||
SymbolTable otherSymbolTable = otherProgram.getSymbolTable();
|
SymbolTable otherSymbolTable = otherProgram.getSymbolTable();
|
||||||
List<Symbol> otherSymbols = otherSymbolTable.getSymbols(symbol.getName(), otherNamespace);
|
List<Symbol> otherSymbols = otherSymbolTable.getSymbols(symbol.getName(), otherNamespace);
|
||||||
|
|
||||||
|
@ -595,16 +612,24 @@ public class SimpleDiffUtility {
|
||||||
/**
|
/**
|
||||||
* Given an external symbol for a specified program, get the corresponding symbol,
|
* Given an external symbol for a specified program, get the corresponding symbol,
|
||||||
* which has the same name and path, from the specified otherProgram.<br>
|
* which has the same name and path, from the specified otherProgram.<br>
|
||||||
* Note: The type of the returned symbol may be different than the type of the symbol
|
* Note: In The type of the returned symbol may be different than the type of the symbol
|
||||||
|
* (i.e., Function vs Label).
|
||||||
* @param program program which contains the specified symbol instance
|
* @param program program which contains the specified symbol instance
|
||||||
* @param symbol symbol to look for
|
* @param symbol symbol to look for
|
||||||
* @param otherProgram other program
|
* @param otherProgram other program
|
||||||
|
* @param allowInferredMatch if true an inferred match may be performed using reference
|
||||||
|
* correlation (NOTE: reference correlation is only possible if the exact same binary
|
||||||
|
* is in use). This option is ignored if the two programs do not have the same
|
||||||
|
* original binary hash.
|
||||||
* @param otherRestrictedSymbolIds an optional set of symbol ID's from the other program
|
* @param otherRestrictedSymbolIds an optional set of symbol ID's from the other program
|
||||||
* which will be treated as the exclusive set of candidate symbols to consider.
|
* which will be treated as the exclusive set of candidate symbols to consider.
|
||||||
* @return corresponding external symbol for otherProgram or null if no such symbol exists.
|
* @return corresponding external symbol for otherProgram or null if no such symbol exists.
|
||||||
*/
|
*/
|
||||||
public static Symbol getMatchingExternalSymbol(Program program, Symbol symbol,
|
public static Symbol getMatchingExternalSymbol(Program program, Symbol symbol,
|
||||||
Program otherProgram, Set<Long> otherRestrictedSymbolIds) {
|
Program otherProgram, boolean allowInferredMatch, Set<Long> otherRestrictedSymbolIds) {
|
||||||
|
|
||||||
|
// TODO: It is rather confusing to have two sets of methods for finding external
|
||||||
|
// locations. This should be simplified. getOther... getMatchingExternal...
|
||||||
|
|
||||||
if (symbol == null) {
|
if (symbol == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -614,7 +639,13 @@ public class SimpleDiffUtility {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReferenceManager refMgr = program.getReferenceManager();
|
if (allowInferredMatch) {
|
||||||
|
// Inferred reference-based match only valid for the same program (i.e., multi-user merge)
|
||||||
|
if (program.getUniqueProgramID() != otherProgram.getUniqueProgramID()) {
|
||||||
|
allowInferredMatch = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ExternalManager extMgr = program.getExternalManager();
|
ExternalManager extMgr = program.getExternalManager();
|
||||||
ExternalLocation extLoc = extMgr.getExternalLocation(symbol);
|
ExternalLocation extLoc = extMgr.getExternalLocation(symbol);
|
||||||
|
|
||||||
|
@ -626,80 +657,111 @@ public class SimpleDiffUtility {
|
||||||
}
|
}
|
||||||
Address targetAddr = extLoc.getAddress();
|
Address targetAddr = extLoc.getAddress();
|
||||||
|
|
||||||
ReferenceManager otherRefMgr = otherProgram.getReferenceManager();
|
|
||||||
SymbolTable otherSymbMgr = otherProgram.getSymbolTable();
|
SymbolTable otherSymbMgr = otherProgram.getSymbolTable();
|
||||||
ExternalManager otherExtMgr = otherProgram.getExternalManager();
|
ExternalManager otherExtMgr = otherProgram.getExternalManager();
|
||||||
|
|
||||||
// Process references
|
|
||||||
ReferenceIterator refIter = refMgr.getReferencesTo(symbol.getAddress());
|
|
||||||
HashMap<Address, ExternalReferenceCount> matchesMap = new HashMap<>();
|
HashMap<Address, ExternalReferenceCount> matchesMap = new HashMap<>();
|
||||||
int totalMatchCnt = 0;
|
|
||||||
while (refIter.hasNext()) {
|
// Search by name
|
||||||
Reference ref = refIter.next();
|
if (symbol.getSource() != SourceType.DEFAULT) {
|
||||||
Reference otherRef =
|
|
||||||
otherRefMgr.getPrimaryReferenceFrom(ref.getFromAddress(), ref.getOperandIndex());
|
// TODO: Need to improve support for lookup based upon other fields
|
||||||
if (otherRef == null || !otherRef.isExternalReference()) {
|
// Need separate Symbol DB indexing of ExternalLocation fields (address,originalImportName)
|
||||||
continue;
|
|
||||||
}
|
Symbol otherParent = getSymbol(symbol.getParentSymbol(), otherProgram);
|
||||||
Address otherExtAddr = otherRef.getToAddress();
|
if (otherParent != null) {
|
||||||
ExternalReferenceCount refMatch = matchesMap.get(otherExtAddr);
|
SymbolIterator symbols =
|
||||||
if (refMatch == null) {
|
otherProgram.getSymbolTable().getExternalSymbols(symbol.getName());
|
||||||
Symbol otherSym = otherSymbMgr.getPrimarySymbol(otherExtAddr);
|
for (Symbol otherSym : symbols) {
|
||||||
if (otherRestrictedSymbolIds != null &&
|
ExternalLocation otherExtLoc = otherExtMgr.getExternalLocation(otherSym);
|
||||||
!otherRestrictedSymbolIds.contains(otherSym.getID())) {
|
if (otherExtLoc != null) {
|
||||||
continue;
|
ExternalMatchType matchType = testExternalMatch(otherExtLoc, extLoc);
|
||||||
|
if (matchType == ExternalMatchType.NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ExternalReferenceCount refMatch =
|
||||||
|
new ExternalReferenceCount(otherExtLoc, matchType);
|
||||||
|
refMatch.setRelativeRank(targetAddr, targetNamespace, targetName,
|
||||||
|
targetOrigImportedName);
|
||||||
|
matchesMap.put(otherSym.getAddress(), refMatch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ExternalLocation otherExtLoc = otherExtMgr.getExternalLocation(otherSym);
|
|
||||||
ExternalMatchType matchType = testExternalMatch(otherExtLoc, extLoc);
|
|
||||||
refMatch = new ExternalReferenceCount(otherExtLoc, matchType);
|
|
||||||
if (matchType != ExternalMatchType.NONE) {
|
|
||||||
refMatch.setRelativeRank(targetAddr, targetNamespace, targetName,
|
|
||||||
targetOrigImportedName);
|
|
||||||
}
|
|
||||||
matchesMap.put(otherExtAddr, refMatch);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++refMatch.refCount;
|
|
||||||
}
|
|
||||||
if (++totalMatchCnt == 20) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process thunk-references (include all)
|
if (allowInferredMatch && matchesMap.isEmpty()) {
|
||||||
if (extLoc.isFunction()) {
|
// Process references
|
||||||
Address[] thunkAddrs = extLoc.getFunction().getFunctionThunkAddresses();
|
ReferenceManager refMgr = program.getReferenceManager();
|
||||||
if (thunkAddrs != null) {
|
ReferenceManager otherRefMgr = otherProgram.getReferenceManager();
|
||||||
for (Address thunkAddr : thunkAddrs) {
|
ReferenceIterator refIter = refMgr.getReferencesTo(symbol.getAddress());
|
||||||
Symbol otherThunkSym = otherSymbMgr.getPrimarySymbol(thunkAddr);
|
int totalMatchCnt = 0;
|
||||||
if (otherThunkSym == null ||
|
while (refIter.hasNext()) {
|
||||||
otherThunkSym.getSymbolType() != SymbolType.FUNCTION) {
|
Reference ref = refIter.next();
|
||||||
|
Reference otherRef = otherRefMgr.getPrimaryReferenceFrom(ref.getFromAddress(),
|
||||||
|
ref.getOperandIndex());
|
||||||
|
if (otherRef == null || !otherRef.isExternalReference()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Address otherExtAddr = otherRef.getToAddress();
|
||||||
|
ExternalReferenceCount refMatch = matchesMap.get(otherExtAddr);
|
||||||
|
if (refMatch == null) {
|
||||||
|
Symbol otherSym = otherSymbMgr.getPrimarySymbol(otherExtAddr);
|
||||||
|
if (otherRestrictedSymbolIds != null &&
|
||||||
|
!otherRestrictedSymbolIds.contains(otherSym.getID())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Function otherFunc = (Function) otherThunkSym.getObject();
|
ExternalLocation otherExtLoc = otherExtMgr.getExternalLocation(otherSym);
|
||||||
Function otherThunkedFunc = otherFunc.getThunkedFunction(false);
|
ExternalMatchType matchType = testExternalMatch(otherExtLoc, extLoc);
|
||||||
if (otherThunkedFunc == null || !otherThunkedFunc.isExternal()) {
|
refMatch = new ExternalReferenceCount(otherExtLoc, matchType);
|
||||||
continue;
|
if (matchType != ExternalMatchType.NONE) {
|
||||||
|
refMatch.setRelativeRank(targetAddr, targetNamespace, targetName,
|
||||||
|
targetOrigImportedName);
|
||||||
}
|
}
|
||||||
ExternalReferenceCount refMatch =
|
matchesMap.put(otherExtAddr, refMatch);
|
||||||
matchesMap.get(otherThunkedFunc.getEntryPoint());
|
}
|
||||||
if (refMatch == null) {
|
else {
|
||||||
if (otherRestrictedSymbolIds != null &&
|
++refMatch.refCount;
|
||||||
!otherRestrictedSymbolIds.contains(otherThunkedFunc.getID())) {
|
}
|
||||||
|
if (++totalMatchCnt == 20) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process thunk-references (include all)
|
||||||
|
if (extLoc.isFunction()) {
|
||||||
|
Address[] thunkAddrs = extLoc.getFunction().getFunctionThunkAddresses();
|
||||||
|
if (thunkAddrs != null) {
|
||||||
|
for (Address thunkAddr : thunkAddrs) {
|
||||||
|
Symbol otherThunkSym = otherSymbMgr.getPrimarySymbol(thunkAddr);
|
||||||
|
if (otherThunkSym == null ||
|
||||||
|
otherThunkSym.getSymbolType() != SymbolType.FUNCTION) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ExternalLocation otherExtLoc =
|
Function otherFunc = (Function) otherThunkSym.getObject();
|
||||||
otherExtMgr.getExternalLocation(otherThunkedFunc.getSymbol());
|
Function otherThunkedFunc = otherFunc.getThunkedFunction(false);
|
||||||
ExternalMatchType matchType = testExternalMatch(otherExtLoc, extLoc);
|
if (otherThunkedFunc == null || !otherThunkedFunc.isExternal()) {
|
||||||
refMatch = new ExternalReferenceCount(otherExtLoc, matchType);
|
continue;
|
||||||
if (matchType != ExternalMatchType.NONE) {
|
}
|
||||||
refMatch.setRelativeRank(targetAddr, targetNamespace, targetName,
|
ExternalReferenceCount refMatch =
|
||||||
targetOrigImportedName);
|
matchesMap.get(otherThunkedFunc.getEntryPoint());
|
||||||
|
if (refMatch == null) {
|
||||||
|
if (otherRestrictedSymbolIds != null &&
|
||||||
|
!otherRestrictedSymbolIds.contains(otherThunkedFunc.getID())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ExternalLocation otherExtLoc =
|
||||||
|
otherExtMgr.getExternalLocation(otherThunkedFunc.getSymbol());
|
||||||
|
ExternalMatchType matchType = testExternalMatch(otherExtLoc, extLoc);
|
||||||
|
refMatch = new ExternalReferenceCount(otherExtLoc, matchType);
|
||||||
|
if (matchType != ExternalMatchType.NONE) {
|
||||||
|
refMatch.setRelativeRank(targetAddr, targetNamespace, targetName,
|
||||||
|
targetOrigImportedName);
|
||||||
|
}
|
||||||
|
matchesMap.put(otherThunkedFunc.getEntryPoint(), refMatch);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++refMatch.refCount;
|
||||||
}
|
}
|
||||||
matchesMap.put(otherThunkedFunc.getEntryPoint(), refMatch);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++refMatch.refCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -751,10 +813,14 @@ public class SimpleDiffUtility {
|
||||||
* @param program program which contains the specified external location instance
|
* @param program program which contains the specified external location instance
|
||||||
* @param externalLocation external location to look for
|
* @param externalLocation external location to look for
|
||||||
* @param otherProgram other program
|
* @param otherProgram other program
|
||||||
|
* @param allowInferredMatch if true an inferred match may be performed using reference
|
||||||
|
* correlation. NOTE: reference correlation is only possible if the exact same binary
|
||||||
|
* is in use. This option is ignored if the two programs do not have the same
|
||||||
|
* original binary hash and reference correlation will not be performed.
|
||||||
* @return corresponding external location for otherProgram or null if no such external location exists.
|
* @return corresponding external location for otherProgram or null if no such external location exists.
|
||||||
*/
|
*/
|
||||||
public static ExternalLocation getMatchingExternalLocation(Program program,
|
public static ExternalLocation getMatchingExternalLocation(Program program,
|
||||||
ExternalLocation externalLocation, Program otherProgram) {
|
ExternalLocation externalLocation, Program otherProgram, boolean allowInferredMatch) {
|
||||||
if (externalLocation == null) {
|
if (externalLocation == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -763,7 +829,7 @@ public class SimpleDiffUtility {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Symbol matchingExternalSymbol =
|
Symbol matchingExternalSymbol =
|
||||||
getMatchingExternalSymbol(program, symbol, otherProgram, null);
|
getMatchingExternalSymbol(program, symbol, otherProgram, allowInferredMatch, null);
|
||||||
if (matchingExternalSymbol == null) {
|
if (matchingExternalSymbol == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue