GP-3747 PR-5644 reworked updateFunctionDefinition part of PR.

This commit is contained in:
ghidra007 2023-08-21 19:47:55 +00:00
parent 152b6349b0
commit 45eb6eb187

View File

@ -16,7 +16,17 @@
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
package classrecovery;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import ghidra.app.cmd.function.ApplyFunctionSignatureCmd;
@ -30,21 +40,78 @@ import ghidra.app.util.NamespaceUtils;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.database.data.DataTypeUtilities;
import ghidra.program.flatapi.FlatProgramAPI;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOutOfBoundsException;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.AddressRangeIterator;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.address.GlobalNamespace;
import ghidra.program.model.data.ArrayDataType;
import ghidra.program.model.data.Category;
import ghidra.program.model.data.CategoryPath;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeComponent;
import ghidra.program.model.data.DataTypeConflictHandler;
import ghidra.program.model.data.DataTypeDependencyException;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.data.FunctionDefinition;
import ghidra.program.model.data.FunctionDefinitionDataType;
import ghidra.program.model.data.NoisyStructureBuilder;
import ghidra.program.model.data.ParameterDefinition;
import ghidra.program.model.data.Pointer;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.data.Structure;
import ghidra.program.model.data.StructureDataType;
import ghidra.program.model.data.Undefined1DataType;
import ghidra.program.model.data.Undefined4DataType;
import ghidra.program.model.data.Undefined8DataType;
import ghidra.program.model.data.VoidDataType;
import ghidra.program.model.lang.CompilerSpec;
import ghidra.program.model.listing.*;
import ghidra.program.model.listing.Bookmark;
import ghidra.program.model.listing.BookmarkManager;
import ghidra.program.model.listing.BookmarkType;
import ghidra.program.model.listing.CircularDependencyException;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.FlowOverride;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Function.FunctionUpdateType;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.listing.FunctionSignature;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.InstructionIterator;
import ghidra.program.model.listing.Listing;
import ghidra.program.model.listing.Parameter;
import ghidra.program.model.listing.Program;
import ghidra.program.model.listing.ReturnParameterImpl;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.pcode.*;
import ghidra.program.model.symbol.*;
import ghidra.program.model.pcode.HighFunction;
import ghidra.program.model.pcode.HighVariable;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.PcodeOpAST;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.RefType;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.ReferenceIterator;
import ghidra.program.model.symbol.ReferenceManager;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolIterator;
import ghidra.program.model.symbol.SymbolTable;
import ghidra.program.model.symbol.SymbolType;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramMemoryUtil;
import ghidra.util.InvalidNameException;
import ghidra.util.Msg;
import ghidra.util.bytesearch.*;
import ghidra.util.bytesearch.GenericByteSequencePattern;
import ghidra.util.bytesearch.GenericMatchAction;
import ghidra.util.bytesearch.Match;
import ghidra.util.bytesearch.MemoryBytePatternSearcher;
import ghidra.util.datastruct.ListAccumulator;
import ghidra.util.exception.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.task.TaskMonitor;
public class RecoveredClassHelper {
@ -7828,9 +7895,21 @@ public class RecoveredClassHelper {
ParameterDefinition[] currentArgs = functionDefinition.getArguments();
ParameterDefinition[] changedArgs = newFunctionDefinition.getArguments();
// only update if there are differences
if (!currentArgs.equals(changedArgs)) {
functionDefinition.setArguments(changedArgs);
// only update if same number of params and there are differences
// if different number then user must decide whether to update the definition
if (currentArgs.length > 0 && currentArgs.length == changedArgs.length) {
// keep the original function definition's this param if there is one hard coded
// if only the this is different then don't update changed flag
if (currentArgs[0].getName().equals("this")) {
changedArgs[0] = currentArgs[0];
}
// if other than hard-coded this is different then change
// to use to changedArgs
if (!areEqualFunctionArgs(currentArgs, changedArgs)) {
functionDefinition.setArguments(changedArgs);
changed = true;
}
}
if (!functionDefinition.getReturnType().equals(newFunctionDefinition.getReturnType())) {
@ -7844,6 +7923,44 @@ public class RecoveredClassHelper {
}
private boolean areEqualFunctionArgs(ParameterDefinition[] currentArgs,
ParameterDefinition[] changedArgs) {
// not equals if diff num or arguments
if (currentArgs.length != changedArgs.length) {
return false;
}
// equals if both have no args
if (currentArgs.length == 0) {
return true;
}
// not equals if any args are not equal
for (int i = 0; i < currentArgs.length; i++) {
if (!areEqualArgs(currentArgs[i], changedArgs[i])) {
return false;
}
}
// equals if all args are equal
return true;
}
private boolean areEqualArgs(ParameterDefinition def1, ParameterDefinition def2) {
if (!def1.isEquivalent(def2)) {
return false;
}
if (!def1.getName().equals(def2.getName())) {
return false;
}
return true;
}
public List<Structure> getClassStructures() throws CancelledException {
Category category = program.getDataTypeManager().getCategory(classDataTypesCategoryPath);