GP-17 corrected function merge related issue impacting default thunks

This commit is contained in:
ghidra1 2021-06-03 22:54:48 -04:00
parent e3b515a973
commit 5323952fe3
4 changed files with 123 additions and 76 deletions

View file

@ -935,8 +935,14 @@ class SymbolMerger extends AbstractListingMerger {
}
private void processModifiedFunctionNamespace(long id, Symbol mySym, Symbol resultSym) {
Namespace myNs = mySym.getParentNamespace();
Namespace resultNs = resultSym.getParentNamespace();
SourceType mySource = mySym.getSource();
Namespace myNs = // default thunks may lie about their namespace
mySource == SourceType.DEFAULT ? mySym.getProgram().getGlobalNamespace()
: mySym.getParentNamespace();
SourceType resultSource = resultSym.getSource();
Namespace resultNs = // default thunks may lie about their namespace
resultSource == SourceType.DEFAULT ? resultSym.getProgram().getGlobalNamespace()
: resultSym.getParentNamespace();
try {
Namespace desiredNs = resolveNamespace(myPgm, myNs);
// Is the result namespace the one we actually want it to be?

View file

@ -51,22 +51,33 @@ public class FunctionMerge {
String fromName = fromFunction.getName();
Symbol fromSymbol = fromFunction.getSymbol();
SourceType fromSource = fromSymbol.getSource();
// can't handle reversion to DEFAULT - use existing function if fromSymbol is DEFAULT
if (fromSource == SourceType.DEFAULT) {
return toFunction.getSymbol();
}
Namespace fromNamespace = fromSymbol.getParentNamespace();
Namespace expectedToNamespace = DiffUtility.getNamespace(fromNamespace, toProgram);
if (expectedToNamespace != null) {
Symbol existingSymbol = toProgram.getSymbolTable().getSymbol(fromName,
originEntryPoint, expectedToNamespace);
if (existingSymbol != null) {
// TODO Change the function symbol to this one. // FIXME
if (!existingSymbol.isPrimary()) {
existingSymbol.setPrimary();
}
return existingSymbol;
}
}
String toName = toFunction.getName();
Symbol toSymbol = toFunction.getSymbol();
Namespace currentToNamespace = toSymbol.getParentNamespace();
SourceType toSource = toSymbol.getSource();
boolean toDefault = toSource == SourceType.DEFAULT;
Namespace currentToNamespace = // default thunks will lie about their namespace
toDefault ? toFunction.getProgram().getGlobalNamespace()
: toSymbol.getParentNamespace();
Symbol expectedNamespaceSymbol =
SimpleDiffUtility.getSymbol(fromNamespace.getSymbol(), toProgram);
boolean sameNamespace = currentToNamespace.getSymbol() == expectedNamespaceSymbol;
if (fromName.equals(toName) && sameNamespace) {
if (!toDefault && fromName.equals(toName) && sameNamespace) {
return toSymbol; // function symbol name and namespace match.
}
Namespace desiredToNamespace = currentToNamespace;
@ -74,15 +85,17 @@ public class FunctionMerge {
desiredToNamespace = new SymbolMerge(fromProgram, toProgram).resolveNamespace(
fromNamespace, conflictSymbolIDMap);
}
// Move it to the new namespace.
if (currentToNamespace != desiredToNamespace) {
toFunction.setParentNamespace(desiredToNamespace);
}
// Rename the function so that we will be able to move it.
boolean hasDifferentName = !fromName.equals(toName);
if (hasDifferentName) {
toFunction.setName(fromName, fromSource);
}
// Move it to the new namespace.
if (currentToNamespace != desiredToNamespace) {
toFunction.setParentNamespace(desiredToNamespace);
}
// TODO May want to save the symbol info if the function didn't get desired pathname. // FIXME
@ -97,28 +110,39 @@ public class FunctionMerge {
// Assumes: The function in the destination program should already be replaced at this point.
FunctionManager fromFunctionMgr = fromProgram.getFunctionManager();
FunctionManager toFunctionMgr = toProgram.getFunctionManager();
Function fromFunc = fromFunctionMgr.getFunctionAt(entryPoint);
Function toFunc = toFunctionMgr.getFunctionAt(entryPoint);
if ((fromFunc != null) && (toFunc != null)) {
String fromName = fromFunc.getName();
Symbol fromSymbol = fromFunc.getSymbol();
SourceType source = fromSymbol.getSource();
Function fromFunction = fromFunctionMgr.getFunctionAt(entryPoint);
Function toFunction = toFunctionMgr.getFunctionAt(entryPoint);
if ((fromFunction != null) && (toFunction != null)) {
String fromName = fromFunction.getName();
Symbol fromSymbol = fromFunction.getSymbol();
SourceType fromSource = fromSymbol.getSource();
// can't handle reversion to DEFAULT - use existing function if fromSymbol is DEFAULT
if (fromSource == SourceType.DEFAULT) {
return toFunction.getSymbol();
}
Namespace fromNamespace = fromSymbol.getParentNamespace();
Namespace expectedToNamespace = DiffUtility.getNamespace(fromNamespace, toProgram);
if (expectedToNamespace != null) {
Symbol existingSymbol =
toProgram.getSymbolTable().getSymbol(fromName, entryPoint, expectedToNamespace);
if (existingSymbol != null) {
// TODO Change the function symbol to this one. // FIXME
if (!existingSymbol.isPrimary()) {
existingSymbol.setPrimary();
}
return existingSymbol;
}
}
String toName = toFunc.getName();
Symbol toSymbol = toFunc.getSymbol();
Namespace currentToNamespace = toSymbol.getParentNamespace();
String toName = toFunction.getName();
Symbol toSymbol = toFunction.getSymbol();
SourceType toSource = toSymbol.getSource();
boolean toDefault = toSource == SourceType.DEFAULT;
Namespace currentToNamespace = // default thunks will lie about their namespace
toDefault ? toFunction.getProgram().getGlobalNamespace()
: toSymbol.getParentNamespace();
Symbol expectedNamespaceSymbol =
SimpleDiffUtility.getSymbol(fromNamespace.getSymbol(), toProgram);
boolean sameNamespace = currentToNamespace.getSymbol() == expectedNamespaceSymbol;
if (fromName.equals(toName) && sameNamespace) {
if (!toDefault && fromName.equals(toName) && sameNamespace) {
return toSymbol; // function symbol name and namespace match.
}
Namespace desiredToNamespace = currentToNamespace;
@ -126,19 +150,21 @@ public class FunctionMerge {
desiredToNamespace = new SymbolMerge(fromProgram, toProgram).resolveNamespace(
fromNamespace, conflictSymbolIDMap);
}
// Move it to the new namespace.
if (currentToNamespace != desiredToNamespace) {
toFunction.setParentNamespace(desiredToNamespace);
}
// Rename the function so that we will be able to move it.
boolean hasDifferentName = !fromName.equals(toName);
if (hasDifferentName) {
toFunc.setName(fromName, source);
}
// Move it to the new namespace.
if (currentToNamespace != desiredToNamespace) {
toFunc.setParentNamespace(desiredToNamespace);
toFunction.setName(fromName, fromSource);
}
// TODO May want to save the symbol info if the function didn't get desired pathname. // FIXME
return toFunc.getSymbol();
return toFunction.getSymbol();
}
return null;
}
@ -155,22 +181,28 @@ public class FunctionMerge {
monitor.setProgress(++count);
monitor.checkCanceled();
Function originFunction = originIter.next();
SourceType originSource = originFunction.getSymbol().getSource();
Address originEntryPoint = originFunction.getEntryPoint();
Address resultEntryPoint = originToResultTranslator.getAddress(originEntryPoint);
monitor.setMessage("Replacing function name " + count + " of " + max + ". Address=" +
originEntryPoint.toString(true));
monitor.setMessage("Replacing function name " + count + " of " + max);
Function resultFunction = toFunctionManager.getFunctionAt(resultEntryPoint);
if (resultFunction != null &&
!resultFunction.getName().equals(originFunction.getName())) {
try {
replaceFunctionSymbol(originEntryPoint, conflictSymbolIDMap, monitor);
if (resultFunction != null) {
// TODO: Gets complicated if
SourceType resultSource = resultFunction.getSymbol().getSource();
if (resultSource == SourceType.DEFAULT && originSource == SourceType.DEFAULT) {
continue;
}
catch (DuplicateNameException e) {
}
catch (InvalidInputException e) {
}
catch (CircularDependencyException e) {
// TODO MAy want message to user if can't replace name.
if (!resultFunction.getName().equals(originFunction.getName())) {
try {
replaceFunctionSymbol(originEntryPoint, conflictSymbolIDMap, monitor);
}
catch (DuplicateNameException e) {
}
catch (InvalidInputException e) {
}
catch (CircularDependencyException e) {
// TODO May want message to user if can't replace name.
}
}
}
}

View file

@ -2836,7 +2836,9 @@ public class ProgramMerge implements PropertyVisitor {
return resultFunction;
}
boolean isDefaultThunk = false;
if (originFunction.isThunk()) {
isDefaultThunk = originFunction.getSymbol().getSource() == SourceType.DEFAULT;
Function thunkedFunction = originFunction.getThunkedFunction(false);
Address thunkedEntryPoint = thunkedFunction.getEntryPoint();
Address resultThunkedEntryPoint =
@ -2869,15 +2871,17 @@ public class ProgramMerge implements PropertyVisitor {
// VariableReference[] restoreRefs = new VariableReference[0];
String originName = originFunction.getName();
Namespace desiredToNamespace = resultProgram.getGlobalNamespace();
try {
desiredToNamespace = symbolMerge.resolveNamespace(originFunction.getParentNamespace(),
conflictSymbolIDMap);
}
catch (DuplicateNameException e1) {
Msg.error(this, "Unexpected Exception: " + e1.getMessage(), e1);
}
catch (InvalidInputException e1) {
Msg.error(this, "Unexpected Exception: " + e1.getMessage(), e1);
if (!isDefaultThunk) {
try {
desiredToNamespace = symbolMerge
.resolveNamespace(originFunction.getParentNamespace(), conflictSymbolIDMap);
}
catch (DuplicateNameException e1) {
Msg.error(this, "Unexpected Exception: " + e1.getMessage(), e1);
}
catch (InvalidInputException e1) {
Msg.error(this, "Unexpected Exception: " + e1.getMessage(), e1);
}
}
AddressSetView oldResultBody = (resultFunction == null) ? null : resultFunction.getBody();

View file

@ -460,7 +460,9 @@ class SymbolMerge {
Symbol fromSymbol = fromFunc.getSymbol();
SourceType fromSource = fromSymbol.getSource();
String fromName = fromSymbol.getName();
Namespace fromNamespace = fromSymbol.getParentNamespace();
Namespace fromNamespace =
fromSource == SourceType.DEFAULT ? fromFunc.getProgram().getGlobalNamespace()
: fromSymbol.getParentNamespace();
Symbol toSymbol;
if (toFunc == null) {
@ -478,6 +480,7 @@ class SymbolMerge {
}
else {
toSymbol = toFunc.getSymbol();
// Replacing the function name.
if (toSymbol.equals(fromSymbol)) {
if (fromSource != SourceType.DEFAULT && toSymbol.getSource() != fromSource) {
@ -494,19 +497,19 @@ class SymbolMerge {
}
return; // Symbols aren't different.
}
String toName = toSymbol.getName();
Namespace newToNamespace = resolveNamespace(fromNamespace, conflictSymbolIDMap);
if (!toName.equals(fromName)) {
toFunc.setName(fromName, fromSource);
}
try {
toFunc.setParentNamespace(newToNamespace);
}
catch (CircularDependencyException | InvalidInputException e) {
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
}
String toName = toSymbol.getName();
if (toSymbol.getSource() != fromSource || !toName.equals(fromName)) {
toFunc.setName(fromName, fromSource);
}
}
boolean pinned = fromSymbol.isPinned();
@ -545,44 +548,46 @@ class SymbolMerge {
if (fromFunc != null) {
Symbol fromSymbol = fromFunc.getSymbol();
String fromName = fromSymbol.getName();
boolean fromDefault =
fromName.equals(SymbolUtilities.getDefaultFunctionName(fromEntryPoint));
Namespace fromNamespace = fromSymbol.getParentNamespace();
boolean fromDefault = fromSymbol.getSource() == SourceType.DEFAULT;
Namespace fromNamespace = // default thunk may lie about its namespace
fromDefault ? fromFunc.getProgram().getGlobalNamespace()
: fromSymbol.getParentNamespace();
Namespace resolveNamespace = resolveNamespace(fromNamespace, conflictSymbolIDMap);
if ((toFunc != null) && replacePrimary && !fromDefault) {
// Save "to" function name and namespace.
String toName = toFunc.getName();
Namespace toNamespace = toFunc.getParentNamespace();
SourceType source = toFunc.getSymbol().getSource();
SourceType toSource = toFunc.getSymbol().getSource();
boolean toDefault = toSource == SourceType.DEFAULT;
Namespace toNamespace = // default thunk may lie about its namespace
toDefault ? toFunc.getProgram().getGlobalNamespace()
: toFunc.getParentNamespace();
// Merging function name into function as primary.
replaceFunctionSymbol(fromEntryPoint, toEntryPoint, conflictSymbolIDMap, monitor);
if (!toName.equals(fromName) &&
!toName.equals(SymbolUtilities.getDefaultFunctionName(toEntryPoint))) {
if (!toDefault && !toName.equals(fromName)) {
// Merge "to" function name and namespace as label.
addFunctionAsLabel(toEntryPoint, conflictSymbolIDMap, toSymTab, source, toName,
addFunctionAsLabel(toEntryPoint, conflictSymbolIDMap, toSymTab, toSource,
toName,
toNamespace, -1L);
}
}
else {
if (toFunc != null) {
if (toFunc.getName()
.equals(SymbolUtilities.getDefaultFunctionName(toEntryPoint))) {
// Default "to" function so replace
replaceFunctionSymbol(fromEntryPoint, toEntryPoint, conflictSymbolIDMap,
monitor);
}
else if (!fromDefault) {
// No "to" function or not merging primary.
addFunctionAsLabel(toEntryPoint, conflictSymbolIDMap, toSymTab,
fromSymbol.getSource(), fromName, resolveNamespace, fromSymbol.getID());
}
else if (toFunc != null) {
if (toFunc.getSymbol().getSource() == SourceType.DEFAULT) {
// Default "to" function so replace
replaceFunctionSymbol(fromEntryPoint, toEntryPoint, conflictSymbolIDMap,
monitor);
}
else {
else if (!fromDefault) {
// No "to" function or not merging primary.
addFunctionAsLabel(toEntryPoint, conflictSymbolIDMap, toSymTab,
fromSymbol.getSource(), fromName, resolveNamespace, fromSymbol.getID());
}
}
else {
// No "to" function or not merging primary.
addFunctionAsLabel(toEntryPoint, conflictSymbolIDMap, toSymTab,
fromSymbol.getSource(), fromName, resolveNamespace, fromSymbol.getID());
}
}
}