Let FunctionPrototype grab extrapop from the prototype model

This commit is contained in:
caheckman 2019-09-06 13:17:52 -04:00
parent 11d7420af5
commit 927bf3df10
3 changed files with 51 additions and 106 deletions

View file

@ -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);

View file

@ -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,18 +160,23 @@ 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();
} }
if (purge == Function.INVALID_STACK_DEPTH_CHANGE ||
purge == Function.UNKNOWN_STACK_DEPTH_CHANGE) {
extrapop = protoModel.getExtrapop();
}
else {
extrapop = purge + protoModel.getStackshift(); extrapop = purge + protoModel.getStackshift();
} }
} }
}
/** /**
* check if the code injection does not return * check if the code injection does not return

View file

@ -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 {