From 927bf3df108a9200e101c0f8042687027d1b83bc Mon Sep 17 00:00:00 2001 From: caheckman <48068198+caheckman@users.noreply.github.com> Date: Fri, 6 Sep 2019 13:17:52 -0400 Subject: [PATCH] Let FunctionPrototype grab extrapop from the prototype model --- .../app/decompiler/DecompileCallback.java | 59 ++++---------- .../model/pcode/FunctionPrototype.java | 19 +++-- .../program/model/pcode/HighFunction.java | 79 ++++++------------- 3 files changed, 51 insertions(+), 106 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java index 6cfced2521..5696212774 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java @@ -40,7 +40,7 @@ import ghidra.program.model.symbol.*; import ghidra.util.Msg; import ghidra.util.UndefinedFunction; import ghidra.util.exception.UsrException; -import ghidra.util.task.TaskMonitorAdapter; +import ghidra.util.task.TaskMonitor; import ghidra.util.xml.SpecXmlUtils; import ghidra.util.xml.XmlUtilities; @@ -103,6 +103,7 @@ public class DecompileCallback { * Establish function and debug context for next decompilation * * @param func is the function to be decompiled + * @param entry is the function's entry address * @param dbg is the debugging context (or null) */ 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; } @@ -213,7 +214,8 @@ public class DecompileCallback { * Collect any/all comments for the function starting at the indicated * 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 */ 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 * defined to perform. @@ -315,8 +310,8 @@ public class DecompileCallback { * @param fallthruoffset number of bytes after instruction start that pcode * flow falls into * @param paramshift special instructions for injection use - * @param addrFactory - * @return XML document as string + * @param addrFactory is the address factory for recovering address space names + * @return XML document as string representing all the p-code */ public static String buildInstruction(PcodeOp[] ops, int fallthruoffset, int paramshift, AddressFactory addrFactory) { @@ -446,7 +441,7 @@ public class DecompileCallback { if (pseudoDisassembler == null) { pseudoDisassembler = Disassembler.getDisassembler(program, false, false, false, - TaskMonitorAdapter.DUMMY_MONITOR, msg -> { + TaskMonitor.DUMMY, msg -> { // TODO: Should we log errors? }); } @@ -859,35 +854,11 @@ public class DecompileCallback { 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 - * @return + * @param sym is the symbol + * @return the XML description */ private String buildLabel(Symbol sym, Address addr) { // TODO: Assume this is not data @@ -973,7 +944,7 @@ public class DecompileCallback { * @param addr The queried address * @param includeDefaultNames true if default parameter names should be * included - * @return + * @return XML string describing the function or the hole */ private String buildFunctionXML(Function func, Address addr, boolean includeDefaultNames) { Address entry = func.getEntryPoint(); @@ -1179,7 +1150,7 @@ public class DecompileCallback { * Return the global object being referred to by addr * * @param addr = Address being queried - * @return + * @return the global object */ private Object lookupSymbol(Address addr) { ExternalReference ref = getExternalReference(addr); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/FunctionPrototype.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/FunctionPrototype.java index db3249972b..34ae07d970 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/FunctionPrototype.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/FunctionPrototype.java @@ -121,10 +121,10 @@ public class FunctionPrototype { * Populate Function Prototype from information attached to a function in the Program DB. * * @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 override_extrapop is true if the extrapop should be overridden + * @param overrideExtrapop is the override value to use for extrapop + * @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(); modellock = ((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. // int purge = f.getStackPurgeSize(); - if (override_extrapop || purge == Function.INVALID_STACK_DEPTH_CHANGE || - purge == Function.UNKNOWN_STACK_DEPTH_CHANGE) { - extrapop = default_extrapop; + if (doOverride) { + extrapop = overrideExtrapop; } else { PrototypeModel protoModel = f.getCallingConvention(); if (protoModel == null) { 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(); + } } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunction.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunction.java index ffdcc8f2f2..6aba92aa4a 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunction.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunction.java @@ -54,7 +54,8 @@ public class HighFunction extends PcodeSyntaxTree { /** * @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 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 - * to the function. + * Populate the information for the HighFunction from the information in the + * Function object. * - * @param default_extrapop - * @param includeDefaultNames - * @param override_extrapop + * @param overrideExtrapop is the value to use if extrapop is overridden + * @param includeDefaultNames is true if default symbol names should be considered locked + * @param doOverride is true if extrapop is overridden */ - public void grabFromFunction(int default_extrapop, boolean includeDefaultNames, - boolean override_extrapop) { + public void grabFromFunction(int overrideExtrapop, boolean includeDefaultNames, + boolean doOverride) { localSymbols.grabFromFunction(includeDefaultNames); // Locals must be read first - proto.grabFromFunction(func, default_extrapop, override_extrapop); + proto.grabFromFunction(func, overrideExtrapop, doOverride); jumpTables = null; protoOverrides = null; 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 - * @throws PcodeXMLException + * @param parser is the XML stream + * @throws PcodeXMLException for any format errors */ private void readJumpTableListXML(XmlPullParser parser) throws PcodeXMLException { XmlElement el = parser.start("jumptablelist"); @@ -425,11 +413,9 @@ public class HighFunction extends PcodeSyntaxTree { * @param high is the HighVariable to split * @param vn is a representative of the merge group to split out * @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 { -// if (high.isNameLocked() || high.isTypeLocked()) -// return high; // Locked variable should not be speculatively merged try { ArrayList newinst = new ArrayList(); ArrayList oldinst = new ArrayList(); @@ -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 size describes how many bytes the function occupies as code * @return the XML string */ public String buildFunctionXML(Address entryPoint, int size) { @@ -588,28 +578,6 @@ public class HighFunction extends PcodeSyntaxTree { 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, final String targetName) { 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. * - * @param xml string to parse - * @return an XML tree element + * @param xml is the XML string to parse + * @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) throws PcodeXMLException {