mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-17 corrected function merge related issue impacting default thunks
This commit is contained in:
parent
e3b515a973
commit
5323952fe3
4 changed files with 123 additions and 76 deletions
|
@ -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?
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue