mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Let FunctionPrototype grab extrapop from the prototype model
This commit is contained in:
parent
11d7420af5
commit
927bf3df10
3 changed files with 51 additions and 106 deletions
|
@ -40,7 +40,7 @@ import ghidra.program.model.symbol.*;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.UndefinedFunction;
|
import ghidra.util.UndefinedFunction;
|
||||||
import ghidra.util.exception.UsrException;
|
import ghidra.util.exception.UsrException;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import ghidra.util.xml.SpecXmlUtils;
|
import ghidra.util.xml.SpecXmlUtils;
|
||||||
import ghidra.util.xml.XmlUtilities;
|
import ghidra.util.xml.XmlUtilities;
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ public class DecompileCallback {
|
||||||
* Establish function and debug context for next decompilation
|
* Establish function and debug context for next decompilation
|
||||||
*
|
*
|
||||||
* @param func is the function to be decompiled
|
* @param func is the function to be decompiled
|
||||||
|
* @param entry is the function's entry address
|
||||||
* @param dbg is the debugging context (or null)
|
* @param dbg is the debugging context (or null)
|
||||||
*/
|
*/
|
||||||
public void setFunction(Function func, Address entry, DecompileDebug dbg) {
|
public void setFunction(Function func, Address entry, DecompileDebug dbg) {
|
||||||
|
@ -132,11 +133,11 @@ public class DecompileCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by the decompiler to return a message
|
* Cache a message returned by the decompiler process
|
||||||
*
|
*
|
||||||
* @param msg
|
* @param msg is the message
|
||||||
*/
|
*/
|
||||||
public void setNativeMessage(String msg) {
|
void setNativeMessage(String msg) {
|
||||||
nativeMessage = msg;
|
nativeMessage = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +214,8 @@ public class DecompileCallback {
|
||||||
* Collect any/all comments for the function starting at the indicated
|
* Collect any/all comments for the function starting at the indicated
|
||||||
* address
|
* address
|
||||||
*
|
*
|
||||||
* @param addrstring = string rep of function address
|
* @param addrstring is the XML rep of function address
|
||||||
|
* @param types is the string encoding of the comment type flags
|
||||||
* @return XML document describing comments
|
* @return XML document describing comments
|
||||||
*/
|
*/
|
||||||
public String getComments(String addrstring, String types) {
|
public String getComments(String addrstring, String types) {
|
||||||
|
@ -300,13 +302,6 @@ public class DecompileCallback {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ops pcode ops
|
|
||||||
* @param fallthruoffset number of bytes after instruction start that pcode
|
|
||||||
* flow falls into
|
|
||||||
*
|
|
||||||
* @return XML document string representing all the pcode
|
|
||||||
*/
|
|
||||||
/**
|
/**
|
||||||
* Build an XML representation of all the pcode op's a given Instruction is
|
* Build an XML representation of all the pcode op's a given Instruction is
|
||||||
* defined to perform.
|
* defined to perform.
|
||||||
|
@ -315,8 +310,8 @@ public class DecompileCallback {
|
||||||
* @param fallthruoffset number of bytes after instruction start that pcode
|
* @param fallthruoffset number of bytes after instruction start that pcode
|
||||||
* flow falls into
|
* flow falls into
|
||||||
* @param paramshift special instructions for injection use
|
* @param paramshift special instructions for injection use
|
||||||
* @param addrFactory
|
* @param addrFactory is the address factory for recovering address space names
|
||||||
* @return XML document as string
|
* @return XML document as string representing all the p-code
|
||||||
*/
|
*/
|
||||||
public static String buildInstruction(PcodeOp[] ops, int fallthruoffset, int paramshift,
|
public static String buildInstruction(PcodeOp[] ops, int fallthruoffset, int paramshift,
|
||||||
AddressFactory addrFactory) {
|
AddressFactory addrFactory) {
|
||||||
|
@ -446,7 +441,7 @@ public class DecompileCallback {
|
||||||
|
|
||||||
if (pseudoDisassembler == null) {
|
if (pseudoDisassembler == null) {
|
||||||
pseudoDisassembler = Disassembler.getDisassembler(program, false, false, false,
|
pseudoDisassembler = Disassembler.getDisassembler(program, false, false, false,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, msg -> {
|
TaskMonitor.DUMMY, msg -> {
|
||||||
// TODO: Should we log errors?
|
// TODO: Should we log errors?
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -859,35 +854,11 @@ public class DecompileCallback {
|
||||||
return resBuf;
|
return resBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * For registers, return their name.
|
|
||||||
// *
|
|
||||||
// * TODO: should look in the scope and return the global register.
|
|
||||||
// *
|
|
||||||
// * @param addr
|
|
||||||
// * @return xml string
|
|
||||||
// */
|
|
||||||
// private String buildRegisterRef(Register reg) {
|
|
||||||
// Symbol sym = program.getSymbolTable().getPrimarySymbol(reg.getAddress());
|
|
||||||
// if (sym==null)
|
|
||||||
// return null;
|
|
||||||
//
|
|
||||||
// boolean readonly = false;
|
|
||||||
// DataType dt = dtmanage.findInteger(reg.getMinimumByteSize());
|
|
||||||
// String symstring =
|
|
||||||
// HighVariable.buildMappedSymbolXML(dtmanage, reg.getName(), dt,
|
|
||||||
// reg.getMinimumByteSize(), true, true, readonly, false, -1, -1);
|
|
||||||
// if (debug != null)
|
|
||||||
// debug.getType(dt);
|
|
||||||
//// Namespace namespc = sym.getParentNamespace();
|
|
||||||
// return buildResult(reg.getAddress(), null, symstring, null);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate non-data symbol, probably a code label
|
* Generate description of a non-data symbol, probably a code label
|
||||||
*
|
*
|
||||||
* @param sym
|
* @param sym is the symbol
|
||||||
* @return
|
* @return the XML description
|
||||||
*/
|
*/
|
||||||
private String buildLabel(Symbol sym, Address addr) {
|
private String buildLabel(Symbol sym, Address addr) {
|
||||||
// TODO: Assume this is not data
|
// TODO: Assume this is not data
|
||||||
|
@ -973,7 +944,7 @@ public class DecompileCallback {
|
||||||
* @param addr The queried address
|
* @param addr The queried address
|
||||||
* @param includeDefaultNames true if default parameter names should be
|
* @param includeDefaultNames true if default parameter names should be
|
||||||
* included
|
* included
|
||||||
* @return
|
* @return XML string describing the function or the hole
|
||||||
*/
|
*/
|
||||||
private String buildFunctionXML(Function func, Address addr, boolean includeDefaultNames) {
|
private String buildFunctionXML(Function func, Address addr, boolean includeDefaultNames) {
|
||||||
Address entry = func.getEntryPoint();
|
Address entry = func.getEntryPoint();
|
||||||
|
@ -1179,7 +1150,7 @@ public class DecompileCallback {
|
||||||
* Return the global object being referred to by addr
|
* Return the global object being referred to by addr
|
||||||
*
|
*
|
||||||
* @param addr = Address being queried
|
* @param addr = Address being queried
|
||||||
* @return
|
* @return the global object
|
||||||
*/
|
*/
|
||||||
private Object lookupSymbol(Address addr) {
|
private Object lookupSymbol(Address addr) {
|
||||||
ExternalReference ref = getExternalReference(addr);
|
ExternalReference ref = getExternalReference(addr);
|
||||||
|
|
|
@ -121,10 +121,10 @@ public class FunctionPrototype {
|
||||||
* Populate Function Prototype from information attached to a function in the Program DB.
|
* Populate Function Prototype from information attached to a function in the Program DB.
|
||||||
*
|
*
|
||||||
* @param f is the function to grab prototype from
|
* @param f is the function to grab prototype from
|
||||||
* @param default_extrapop is the default extrapop to use if the function's is unknown
|
* @param overrideExtrapop is the override value to use for extrapop
|
||||||
* @param override_extrapop is true if the extrapop should be overridden
|
* @param doOverride is true if the override value should be used
|
||||||
*/
|
*/
|
||||||
void grabFromFunction(Function f, int default_extrapop, boolean override_extrapop) {
|
void grabFromFunction(Function f, int overrideExtrapop, boolean doOverride) {
|
||||||
modelname = f.getCallingConventionName();
|
modelname = f.getCallingConventionName();
|
||||||
modellock =
|
modellock =
|
||||||
((modelname != null) && (modelname != Function.UNKNOWN_CALLING_CONVENTION_STRING));
|
((modelname != null) && (modelname != Function.UNKNOWN_CALLING_CONVENTION_STRING));
|
||||||
|
@ -160,16 +160,21 @@ public class FunctionPrototype {
|
||||||
// stackshift is the normal stack change because of a call.
|
// stackshift is the normal stack change because of a call.
|
||||||
//
|
//
|
||||||
int purge = f.getStackPurgeSize();
|
int purge = f.getStackPurgeSize();
|
||||||
if (override_extrapop || purge == Function.INVALID_STACK_DEPTH_CHANGE ||
|
if (doOverride) {
|
||||||
purge == Function.UNKNOWN_STACK_DEPTH_CHANGE) {
|
extrapop = overrideExtrapop;
|
||||||
extrapop = default_extrapop;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PrototypeModel protoModel = f.getCallingConvention();
|
PrototypeModel protoModel = f.getCallingConvention();
|
||||||
if (protoModel == null) {
|
if (protoModel == null) {
|
||||||
protoModel = f.getProgram().getCompilerSpec().getDefaultCallingConvention();
|
protoModel = f.getProgram().getCompilerSpec().getDefaultCallingConvention();
|
||||||
}
|
}
|
||||||
extrapop = purge + protoModel.getStackshift();
|
if (purge == Function.INVALID_STACK_DEPTH_CHANGE ||
|
||||||
|
purge == Function.UNKNOWN_STACK_DEPTH_CHANGE) {
|
||||||
|
extrapop = protoModel.getExtrapop();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
extrapop = purge + protoModel.getStackshift();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param function function associated with the higher level function abstraction.
|
* @param function function associated with the higher level function abstraction.
|
||||||
* @param langParser language parser used to disassemble/get info on the language
|
* @param language description of the processor language of the function
|
||||||
|
* @param compilerSpec description of the compiler that produced the function
|
||||||
* @param dtManager data type manager
|
* @param dtManager data type manager
|
||||||
* @param showNamespace true signals to print function names with their namespace
|
* @param showNamespace true signals to print function names with their namespace
|
||||||
*/
|
*/
|
||||||
|
@ -124,33 +125,20 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate the information for the HighFunction from the information stored in Ghidra attached
|
* Populate the information for the HighFunction from the information in the
|
||||||
* to the function.
|
* Function object.
|
||||||
*
|
*
|
||||||
* @param default_extrapop
|
* @param overrideExtrapop is the value to use if extrapop is overridden
|
||||||
* @param includeDefaultNames
|
* @param includeDefaultNames is true if default symbol names should be considered locked
|
||||||
* @param override_extrapop
|
* @param doOverride is true if extrapop is overridden
|
||||||
*/
|
*/
|
||||||
public void grabFromFunction(int default_extrapop, boolean includeDefaultNames,
|
public void grabFromFunction(int overrideExtrapop, boolean includeDefaultNames,
|
||||||
boolean override_extrapop) {
|
boolean doOverride) {
|
||||||
localSymbols.grabFromFunction(includeDefaultNames); // Locals must be read first
|
localSymbols.grabFromFunction(includeDefaultNames); // Locals must be read first
|
||||||
proto.grabFromFunction(func, default_extrapop, override_extrapop);
|
proto.grabFromFunction(func, overrideExtrapop, doOverride);
|
||||||
jumpTables = null;
|
jumpTables = null;
|
||||||
protoOverrides = null;
|
protoOverrides = null;
|
||||||
grabOverrides();
|
grabOverrides();
|
||||||
|
|
||||||
// This reads any old actions from the StringProperty
|
|
||||||
// This is needed for backward compatibility
|
|
||||||
// String actstring = HighFunction.tagFindInclude("actionlist",funcstring);
|
|
||||||
// if (actstring != null) {
|
|
||||||
// try {
|
|
||||||
// Element el = stringTree(actstring);
|
|
||||||
// readActionXML(el,this);
|
|
||||||
// } catch (PcodeXMLException e) {
|
|
||||||
// Err.error(this, null, "Error", "Unexpected Exception: " + e.getMessage(), e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -312,10 +300,10 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read in the Jump Table list for this function from an XML rep
|
* Read in the Jump Table list for this function from XML
|
||||||
*
|
*
|
||||||
* @param el
|
* @param parser is the XML stream
|
||||||
* @throws PcodeXMLException
|
* @throws PcodeXMLException for any format errors
|
||||||
*/
|
*/
|
||||||
private void readJumpTableListXML(XmlPullParser parser) throws PcodeXMLException {
|
private void readJumpTableListXML(XmlPullParser parser) throws PcodeXMLException {
|
||||||
XmlElement el = parser.start("jumptablelist");
|
XmlElement el = parser.start("jumptablelist");
|
||||||
|
@ -425,11 +413,9 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
* @param high is the HighVariable to split
|
* @param high is the HighVariable to split
|
||||||
* @param vn is a representative of the merge group to split out
|
* @param vn is a representative of the merge group to split out
|
||||||
* @return a HighVariable containing just the forced merge group of vn
|
* @return a HighVariable containing just the forced merge group of vn
|
||||||
* @throws PcodeException
|
* @throws PcodeException if the split can't be performed
|
||||||
*/
|
*/
|
||||||
public HighVariable splitOutMergeGroup(HighVariable high, Varnode vn) throws PcodeException {
|
public HighVariable splitOutMergeGroup(HighVariable high, Varnode vn) throws PcodeException {
|
||||||
// if (high.isNameLocked() || high.isTypeLocked())
|
|
||||||
// return high; // Locked variable should not be speculatively merged
|
|
||||||
try {
|
try {
|
||||||
ArrayList<Varnode> newinst = new ArrayList<Varnode>();
|
ArrayList<Varnode> newinst = new ArrayList<Varnode>();
|
||||||
ArrayList<Varnode> oldinst = new ArrayList<Varnode>();
|
ArrayList<Varnode> oldinst = new ArrayList<Varnode>();
|
||||||
|
@ -508,9 +494,13 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build an XML string that represents all the information about this HighFunction.
|
* Build an XML string that represents all the information about this HighFunction. The
|
||||||
|
* size describes how many bytes starting from the entry point are used by the function, but
|
||||||
|
* this doesn't need to be strictly accurate as it is only used to associate the function with
|
||||||
|
* addresses near its entry point.
|
||||||
*
|
*
|
||||||
* @param entryPoint pass null to use the function entryPoint, pass an address to force an entry point
|
* @param entryPoint pass null to use the function entryPoint, pass an address to force an entry point
|
||||||
|
* @param size describes how many bytes the function occupies as code
|
||||||
* @return the XML string
|
* @return the XML string
|
||||||
*/
|
*/
|
||||||
public String buildFunctionXML(Address entryPoint, int size) {
|
public String buildFunctionXML(Address entryPoint, int size) {
|
||||||
|
@ -588,28 +578,6 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
return resBuf.toString();
|
return resBuf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert old decompiler tags to new Register variables
|
|
||||||
*/
|
|
||||||
// public void updateVersion() {
|
|
||||||
// StringPropertyMap stringmap = func.getProgram().getUsrPropertyManager().getStringPropertyMap(DECOMPILER_TAG_MAP);
|
|
||||||
// String funcstring = null;
|
|
||||||
// if (stringmap != null)
|
|
||||||
// funcstring = stringmap.getString(func.getEntryPoint());
|
|
||||||
//
|
|
||||||
// String actstring = HighFunction.tagFindInclude("actionlist",funcstring);
|
|
||||||
// if (actstring == null) return;
|
|
||||||
// try {
|
|
||||||
// Element el = stringTree(actstring);
|
|
||||||
// readActionXML(el,this);
|
|
||||||
// } catch (PcodeXMLException e) {
|
|
||||||
// Err.error(this, null, "Error", "Unexpected Exception: " + e.getMessage(), e);
|
|
||||||
// }
|
|
||||||
// locals.grabFromFunction();
|
|
||||||
// getLocalVariableMap().storeUnMappedToDatabase();
|
|
||||||
// updateProperties();
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static ErrorHandler getErrorHandler(final Object errOriginator,
|
public static ErrorHandler getErrorHandler(final Object errOriginator,
|
||||||
final String targetName) {
|
final String targetName) {
|
||||||
return new ErrorHandler() {
|
return new ErrorHandler() {
|
||||||
|
@ -708,14 +676,15 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and XML SAX parse tree from an input XML string
|
* Create XML parse tree from an input XML string
|
||||||
*
|
*
|
||||||
* TODO: this probably doesn't belong here.
|
* TODO: this probably doesn't belong here.
|
||||||
*
|
*
|
||||||
* @param xml string to parse
|
* @param xml is the XML string to parse
|
||||||
* @return an XML tree element
|
* @param handler is the handler to use for parsing errors
|
||||||
|
* @return the XML tree
|
||||||
*
|
*
|
||||||
* @throws PcodeXMLException
|
* @throws PcodeXMLException for format errors in the XML
|
||||||
*/
|
*/
|
||||||
static public XmlPullParser stringTree(InputStream xml, ErrorHandler handler)
|
static public XmlPullParser stringTree(InputStream xml, ErrorHandler handler)
|
||||||
throws PcodeXMLException {
|
throws PcodeXMLException {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue