mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-10-23 21:50:49 +00:00
GP-3747 PR-5644 reworked updateFunctionDefinition part of PR.
This commit is contained in:
parent
152b6349b0
commit
45eb6eb187
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user