diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc index b6c275dfe3..a59ad6f651 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc @@ -583,49 +583,35 @@ Address ParamListStandard::assignAddress(const Datatype *tp,vector &status return Address(); // Return invalid address to indicated we could not assign anything } -void ParamListStandard::assignMap(const vector &proto,bool isinput,TypeFactory &typefactory, - vector &res) const +void ParamListStandard::assignMap(const vector &proto,TypeFactory &typefactory,vector &res) const { vector status(numgroup,0); - if (isinput) { - if (res.size()==2) { // Check for hidden parameters defined by the output list - res.back().addr = assignAddress(res.back().type,status); // Reserve first param for hidden ret value - res.back().flags |= ParameterPieces::hiddenretparm; - if (res.back().addr.isInvalid()) - throw ParamUnassignedError("Cannot assign parameter address for " + res.back().type->getName()); - } - for(int4 i=1;igetSize() > pointermax)) { // Datatype is too big - // Assume datatype is stored elsewhere and only the pointer is passed - AddrSpace *spc = spacebase; - if (spc == (AddrSpace *)0) - spc = typefactory.getArch()->getDefaultDataSpace(); - int4 pointersize = spc->getAddrSize(); - int4 wordsize = spc->getWordSize(); - Datatype *pointertp = typefactory.getTypePointer(pointersize,proto[i],wordsize); - res.back().addr = assignAddress(pointertp,status); - res.back().type = pointertp; - res.back().flags = ParameterPieces::indirectstorage; - } - else - res.back().addr = assignAddress(proto[i],status); - if (res.back().addr.isInvalid()) - throw ParamUnassignedError("Cannot assign parameter address for " + proto[i]->getName()); - res.back().type = proto[i]; - res.back().flags = 0; - } + if (res.size() == 2) { // Check for hidden parameters defined by the output list + res.back().addr = assignAddress(res.back().type,status); // Reserve first param for hidden ret value + res.back().flags |= ParameterPieces::hiddenretparm; + if (res.back().addr.isInvalid()) + throw ParamUnassignedError("Cannot assign parameter address for " + res.back().type->getName()); } - else { + for(int4 i=1;igetMetatype() != TYPE_VOID) { - res.back().addr = assignAddress(proto[0],status); - if (res.back().addr.isInvalid()) - throw ParamUnassignedError("Cannot assign parameter address for " + proto[0]->getName()); + if ((pointermax != 0) && (proto[i]->getSize() > pointermax)) { // Datatype is too big + // Assume datatype is stored elsewhere and only the pointer is passed + AddrSpace *spc = spacebase; + if (spc == (AddrSpace*)0) spc = typefactory.getArch()->getDefaultDataSpace(); + int4 pointersize = spc->getAddrSize(); + int4 wordsize = spc->getWordSize(); + Datatype *pointertp = typefactory.getTypePointer(pointersize,proto[i],wordsize); + res.back().addr = assignAddress(pointertp,status); + res.back().type = pointertp; + res.back().flags = ParameterPieces::indirectstorage; } - res.back().type = proto[0]; + else + res.back().addr = assignAddress(proto[i],status); + if (res.back().addr.isInvalid()) + throw ParamUnassignedError("Cannot assign parameter address for " + proto[i]->getName()); + res.back().type = proto[i]; res.back().flags = 0; } } @@ -1210,40 +1196,21 @@ ParamList *ParamListStandard::clone(void) const return res; } -void ParamListStandardOut::assignMap(const vector &proto,bool isinput, - TypeFactory &typefactory,vector &res) const +void ParamListRegisterOut::assignMap(const vector &proto,TypeFactory &typefactory,vector &res) const + { vector status(numgroup,0); - - // This is always an output list so we ignore -isinput- res.emplace_back(); + if (proto[0]->getMetatype() != TYPE_VOID) { + res.back().addr = assignAddress(proto[0],status); + if (res.back().addr.isInvalid()) + throw ParamUnassignedError("Cannot assign parameter address for " + proto[0]->getName()); + } res.back().type = proto[0]; res.back().flags = 0; - if (proto[0]->getMetatype() == TYPE_VOID) { - return; // Leave the address as invalid - } - res.back().addr = assignAddress(proto[0],status); - if (res.back().addr.isInvalid()) { // Could not assign an address (too big) - AddrSpace *spc = spacebase; - if (spc == (AddrSpace *)0) - spc = typefactory.getArch()->getDefaultDataSpace(); - int4 pointersize = spc->getAddrSize(); - int4 wordsize = spc->getWordSize(); - Datatype *pointertp = typefactory.getTypePointer(pointersize, proto[0], wordsize); - res.back().addr = assignAddress(pointertp,status); - if (res.back().addr.isInvalid()) - throw ParamUnassignedError("Cannot assign return value as a pointer"); - res.back().type = pointertp; - res.back().flags = ParameterPieces::indirectstorage; - - res.emplace_back(); // Add extra storage location in the input params - res.back().type = pointertp; // that holds a pointer to where the return value should be stored - // leave its address invalid, to be filled in by the input list assignMap - res.back().flags = ParameterPieces::hiddenretparm; // Mark it as special - } } -void ParamListStandardOut::fillinMap(ParamActive *active) const +void ParamListRegisterOut::fillinMap(ParamActive *active) const { if (active->getNumTrials() == 0) return; // No trials to check @@ -1324,7 +1291,7 @@ void ParamListStandardOut::fillinMap(ParamActive *active) const } } -bool ParamListStandardOut::possibleParam(const Address &loc,int4 size) const +bool ParamListRegisterOut::possibleParam(const Address &loc,int4 size) const { list::const_iterator iter; @@ -1335,31 +1302,21 @@ bool ParamListStandardOut::possibleParam(const Address &loc,int4 size) const return false; } -void ParamListStandardOut::restoreXml(const Element *el,const AddrSpaceManager *manage,vector &effectlist,bool normalstack) - +void ParamListRegisterOut::restoreXml(const Element *el,const AddrSpaceManager *manage, + vector &effectlist,bool normalstack) { ParamListStandard::restoreXml(el,manage,effectlist,normalstack); - // Check for double precision entries list::iterator iter; - ParamEntry *previous1 = (ParamEntry *)0; - ParamEntry *previous2 = (ParamEntry *)0; for(iter=entry.begin();iter!=entry.end();++iter) { ParamEntry &curEntry(*iter); curEntry.extraChecks(entry); - if (previous1 != (ParamEntry *)0) { - ParamEntry::orderWithinGroup(*previous1, curEntry); - if (previous2 != (ParamEntry *)0) - ParamEntry::orderWithinGroup(*previous2, curEntry); - } - previous2 = previous1; - previous1 = &curEntry; } } -ParamList *ParamListStandardOut::clone(void) const +ParamList *ParamListRegisterOut::clone(void) const { - ParamList *res = new ParamListStandardOut(*this); + ParamList *res = new ParamListRegisterOut(*this); return res; } @@ -1390,6 +1347,65 @@ ParamList *ParamListRegister::clone(void) const return res; } +void ParamListStandardOut::assignMap(const vector &proto,TypeFactory &typefactory,vector &res) const + +{ + vector status(numgroup,0); + + res.emplace_back(); + res.back().type = proto[0]; + res.back().flags = 0; + if (proto[0]->getMetatype() == TYPE_VOID) { + return; // Leave the address as invalid + } + res.back().addr = assignAddress(proto[0],status); + if (res.back().addr.isInvalid()) { // Could not assign an address (too big) + AddrSpace *spc = spacebase; + if (spc == (AddrSpace *)0) + spc = typefactory.getArch()->getDefaultDataSpace(); + int4 pointersize = spc->getAddrSize(); + int4 wordsize = spc->getWordSize(); + Datatype *pointertp = typefactory.getTypePointer(pointersize, proto[0], wordsize); + res.back().addr = assignAddress(pointertp,status); + if (res.back().addr.isInvalid()) + throw ParamUnassignedError("Cannot assign return value as a pointer"); + res.back().type = pointertp; + res.back().flags = ParameterPieces::indirectstorage; + + res.emplace_back(); // Add extra storage location in the input params + res.back().type = pointertp; // that holds a pointer to where the return value should be stored + // leave its address invalid, to be filled in by the input list assignMap + res.back().flags = ParameterPieces::hiddenretparm; // Mark it as special + } +} + +void ParamListStandardOut::restoreXml(const Element *el,const AddrSpaceManager *manage,vector &effectlist,bool normalstack) + +{ + ParamListRegisterOut::restoreXml(el,manage,effectlist,normalstack); + // Check for double precision entries + list::iterator iter; + ParamEntry *previous1 = (ParamEntry *)0; + ParamEntry *previous2 = (ParamEntry *)0; + for(iter=entry.begin();iter!=entry.end();++iter) { + ParamEntry &curEntry(*iter); + if (previous1 != (ParamEntry *)0) { + ParamEntry::orderWithinGroup(*previous1, curEntry); + if (previous2 != (ParamEntry *)0) + ParamEntry::orderWithinGroup(*previous2, curEntry); + } + previous2 = previous1; + previous1 = &curEntry; + } +} + +ParamList *ParamListStandardOut::clone(void) const + +{ + ParamList *res = new ParamListStandardOut( *this ); + return res; +} + /// The given set of parameter entries are folded into \b this set. /// Duplicate entries are eliminated. Containing entries subsume what /// they contain. @@ -1884,7 +1900,7 @@ void ProtoModel::buildParamList(const string &strategy) } else if (strategy == "register") { input = new ParamListRegister(); - output = new ParamListStandardOut(); + output = new ParamListRegisterOut(); } else throw LowlevelError("Unknown strategy type: "+strategy); @@ -1985,7 +2001,7 @@ void ProtoModel::assignParameterStorage(const vector &typelist,vecto { if (ignoreOutputError) { try { - output->assignMap(typelist,false,*glb->types,res); + output->assignMap(typelist,*glb->types,res); } catch(ParamUnassignedError &err) { res.clear(); @@ -1996,9 +2012,9 @@ void ProtoModel::assignParameterStorage(const vector &typelist,vecto } } else { - output->assignMap(typelist,false,*glb->types,res); + output->assignMap(typelist,*glb->types,res); } - input->assignMap(typelist,true,*glb->types,res); + input->assignMap(typelist,*glb->types,res); } /// \brief Look up an effect from the given EffectRecord list diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh index 4372e80f5f..1264bde081 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh @@ -355,6 +355,7 @@ public: p_standard, ///< Standard input parameter model p_standard_out, ///< Standard output (return value) model p_register, ///< Unordered parameter passing locations model + p_register_out, ///< Multiple possible return value locations model p_merged ///< A merged model (multiple models merged together) }; virtual ~ParamList(void) {} ///< Destructor @@ -364,11 +365,9 @@ public: /// /// If we know the function prototype, recover how parameters are actually stored using the model. /// \param proto is the ordered list of data-types - /// \param isinput is \b true for the input prototype, \b false for output prototype /// \param typefactory is the TypeFactory (for constructing pointers) /// \param res will contain the storage locations corresponding to the datatypes - virtual void assignMap(const vector &proto,bool isinput, - TypeFactory &typefactory,vector &res) const=0; + virtual void assignMap(const vector &proto,TypeFactory &typefactory,vector &res) const=0; /// \brief Given an unordered list of storage locations, calculate a function prototype /// @@ -530,8 +529,7 @@ public: virtual ~ParamListStandard(void); const list &getEntry(void) const { return entry; } ///< Get the list of parameter entries virtual uint4 getType(void) const { return p_standard; } - virtual void assignMap(const vector &proto,bool isinput, - TypeFactory &typefactory,vector &res) const; + virtual void assignMap(const vector &proto,TypeFactory &typefactory,vector &res) const; virtual void fillinMap(ParamActive *active) const; virtual bool checkJoin(const Address &hiaddr,int4 hisize,const Address &loaddr,int4 losize) const; virtual bool checkSplit(const Address &loc,int4 size,int4 splitpoint) const; @@ -548,20 +546,19 @@ public: virtual ParamList *clone(void) const; }; -/// \brief A standard model for passing back return values from a function +/// \brief A model for passing back return values from a function /// -/// This models a resource list of potential storage locations for a return value, -/// at most 1 of which will be chosen for a given function. Order only matters in that the -/// first ParamEntry that fits is used. If no entry fits, the return value is -/// converted to a pointer data-type, storage allocation is attempted again, and the -/// return value is marked as a \e hidden return parameter to inform the input model. -class ParamListStandardOut : public ParamListStandard { +/// This is a resource list of potential storage locations for a return value, +/// at most 1 of which will be chosen for a given function. This models a simple strategy +/// for selecting a storage location. When assigning based on data-type (assignMap), the first list +/// entry that fits is chosen. When assigning from a set of actively used locations (fillinMap), +/// this class chooses the location that is the closest fitting match to an entry in the resource list. +class ParamListRegisterOut : public ParamListStandard { public: - ParamListStandardOut(void) : ParamListStandard() {} ///< Constructor - ParamListStandardOut(const ParamListStandardOut &op2) : ParamListStandard(op2) {} ///< Copy constructor - virtual uint4 getType(void) const { return p_standard_out; } - virtual void assignMap(const vector &proto,bool isinput, - TypeFactory &typefactory,vector &res) const; + ParamListRegisterOut(void) : ParamListStandard() {} ///< Constructor + ParamListRegisterOut(const ParamListRegisterOut &op2) : ParamListStandard(op2) {} ///< Copy constructor + virtual uint4 getType(void) const { return p_register_out; } + virtual void assignMap(const vector &proto,TypeFactory &typefactory,vector &res) const; virtual void fillinMap(ParamActive *active) const; virtual bool possibleParam(const Address &loc,int4 size) const; virtual void restoreXml(const Element *el,const AddrSpaceManager *manage,vector &effectlist,bool normalstack); @@ -584,6 +581,24 @@ public: virtual ParamList *clone(void) const; }; +/// \brief A standard model for returning output parameters from a function +/// +/// This has a more involved assignment strategy than its parent class. +/// Entries in the resource list are treated as a \e group, meaning that only one can +/// fit the desired storage size and type attributes of the return value. If no entry +/// fits, the return value is converted to a pointer data-type, storage allocation is +/// attempted again, and the return value is marked as a \e hidden return parameter +/// to inform the input model. +class ParamListStandardOut : public ParamListRegisterOut { +public: + ParamListStandardOut(void) : ParamListRegisterOut() {} ///< Constructor for use with restoreXml() + ParamListStandardOut(const ParamListStandardOut &op2) : ParamListRegisterOut(op2) {} ///< Copy constructor + virtual uint4 getType(void) const { return p_standard_out; } + virtual void assignMap(const vector &proto,TypeFactory &typefactory,vector &res) const; + virtual void restoreXml(const Element *el,const AddrSpaceManager *manage,vector &effectlist,bool normalstack); + virtual ParamList *clone(void) const; +}; + /// \brief A union of other input parameter passing models /// /// This model is viewed as a union of a constituent set of resource lists. @@ -599,8 +614,7 @@ public: void foldIn(const ParamListStandard &op2); ///< Add another model to the union void finalize(void) { populateResolver(); } ///< Fold-ins are finished, finalize \b this virtual uint4 getType(void) const { return p_merged; } - virtual void assignMap(const vector &proto,bool isinput, - TypeFactory &typefactory,vector &res) const { + virtual void assignMap(const vector &proto,TypeFactory &typefactory,vector &res) const { throw LowlevelError("Cannot assign prototype before model has been resolved"); } virtual void fillinMap(ParamActive *active) const { throw LowlevelError("Cannot determine prototype before model has been resolved"); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamList.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamList.java index 441738aef8..4a311ef65d 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamList.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamList.java @@ -38,12 +38,11 @@ public interface ParamList { * Given a list of datatypes, calculate the storage locations used for passing those datatypes * @param prog is the active progra * @param proto is the list of datatypes - * @param isinput is true if this parameter list is being processed for input arguments, false for output * @param res is the vector for holding the VariableStorage corresponding to datatypes * @param addAutoParams if true add/process auto-parameters */ - public void assignMap(Program prog, DataType[] proto, boolean isinput, - ArrayList res, boolean addAutoParams); + public void assignMap(Program prog, DataType[] proto, ArrayList res, + boolean addAutoParams); public void saveXml(StringBuilder buffer, boolean isInput); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListRegisterOut.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListRegisterOut.java new file mode 100644 index 0000000000..f6c1f788cf --- /dev/null +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListRegisterOut.java @@ -0,0 +1,44 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.program.model.lang; + +import java.util.ArrayList; + +import ghidra.program.model.data.DataType; +import ghidra.program.model.listing.Program; +import ghidra.program.model.listing.VariableStorage; + +/** + * A list of resources describing possible storage locations for a function's return value, + * and a strategy for selecting a storage location based on data-types in a function signature. + * + * The assignment strategy for this class is to take the first storage location in the list + * that fits for the given function signature's return data-type. + */ +public class ParamListRegisterOut extends ParamListStandard { + + @Override + public void assignMap(Program prog, DataType[] proto, ArrayList res, + boolean addAutoParams) { + int[] status = new int[numgroup]; + for (int i = 0; i < numgroup; ++i) { + status[i] = 0; + } + VariableStorage store = assignAddress(prog, proto[0], status, false, false); + res.add(store); + } + +} diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListStandard.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListStandard.java index 0fbef7bed6..462eb493c5 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListStandard.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListStandard.java @@ -143,37 +143,30 @@ public class ParamListStandard implements ParamList { } @Override - public void assignMap(Program prog, DataType[] proto, boolean isinput, - ArrayList res, boolean addAutoParams) { + public void assignMap(Program prog, DataType[] proto, ArrayList res, + boolean addAutoParams) { int[] status = new int[numgroup]; for (int i = 0; i < numgroup; ++i) { status[i] = 0; } - if (isinput) { - if (addAutoParams && res.size() == 2) { // Check for hidden parameters defined by the output list - DataTypeManager dtm = prog.getDataTypeManager(); - Pointer pointer = dtm.getPointer(proto[0]); - VariableStorage store = assignAddress(prog, pointer, status, true, false); - res.set(1, store); - } - for (int i = 1; i < proto.length; ++i) { - VariableStorage store; - if ((pointermax != 0) && (proto[i] != null) && - (proto[i].getLength() > pointermax)) { // DataType is too big - // Assume datatype is stored elsewhere and only the pointer is passed - DataTypeManager dtm = prog.getDataTypeManager(); - Pointer pointer = dtm.getPointer(proto[i]); - store = assignAddress(prog, pointer, status, false, true); - } - else { - store = assignAddress(prog, proto[i], status, false, false); - } - res.add(store); - } + if (addAutoParams && res.size() == 2) { // Check for hidden parameters defined by the output list + DataTypeManager dtm = prog.getDataTypeManager(); + Pointer pointer = dtm.getPointer(proto[0]); + VariableStorage store = assignAddress(prog, pointer, status, true, false); + res.set(1, store); } - else { - VariableStorage store = assignAddress(prog, proto[0], status, false, false); + for (int i = 1; i < proto.length; ++i) { + VariableStorage store; + if ((pointermax != 0) && (proto[i] != null) && (proto[i].getLength() > pointermax)) { // DataType is too big + // Assume datatype is stored elsewhere and only the pointer is passed + DataTypeManager dtm = prog.getDataTypeManager(); + Pointer pointer = dtm.getPointer(proto[i]); + store = assignAddress(prog, pointer, status, false, true); + } + else { + store = assignAddress(prog, proto[i], status, false, false); + } res.add(store); } } @@ -279,11 +272,12 @@ public class ParamListStandard implements ParamList { throw new XmlParseException( " in the join space not allowed in tag"); } - if (count > 1) { - ParamEntry.orderWithinGroup(pe.get(pe.size() - 2), lastEntry); - if (count > 2) { - ParamEntry.orderWithinGroup(pe.get(pe.size() - 3), lastEntry); - } + } + // Check that all entries in the group are distinguishable + for (int i = 1; i < count; ++i) { + ParamEntry curEntry = pe.get(pe.size() - 1 - i); + for (int j = 0; j < i; ++i) { + ParamEntry.orderWithinGroup(pe.get(pe.size() - 1 - j), curEntry); } } parser.end(el); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListStandardOut.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListStandardOut.java index e9f385943d..353ab02879 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListStandardOut.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ParamListStandardOut.java @@ -24,11 +24,23 @@ import ghidra.util.exception.InvalidInputException; import ghidra.xml.XmlParseException; import ghidra.xml.XmlPullParser; -public class ParamListStandardOut extends ParamListStandard { +/** + * A list of resources describing possible storage locations for a function's return value, + * and a strategy for selecting a storage location based on data-types in a function signature. + * + * Similar to the parent class, when assigning storage, the first entry that matches the data-type + * is chosen. But if this instance fails to find a match (because the return value data-type is too + * big) the data-type is converted to a pointer and storage is assigned based on that pointer. + * Additionally, if configured, this instance will signal that a hidden input parameter is required + * to fully model where the large return value is stored. + * + * The resource list is checked to ensure entries are distinguishable. + */ +public class ParamListStandardOut extends ParamListRegisterOut { @Override - public void assignMap(Program prog, DataType[] proto, boolean isinput, - ArrayList res, boolean addAutoParams) { + public void assignMap(Program prog, DataType[] proto, ArrayList res, + boolean addAutoParams) { int[] status = new int[numgroup]; for (int i = 0; i < numgroup; ++i) { @@ -64,11 +76,10 @@ public class ParamListStandardOut extends ParamListStandard { public void restoreXml(XmlPullParser parser, CompilerSpec cspec) throws XmlParseException { super.restoreXml(parser, cspec); - // ParamEntry tags in the output list are considered a group + // ParamEntry tags in the output list are considered a group. Check that entries are distinguishable. for (int i = 1; i < entry.length; ++i) { - ParamEntry.orderWithinGroup(entry[i - 1], entry[i]); - if (i > 1) { - ParamEntry.orderWithinGroup(entry[i - 2], entry[i]); + for (int j = 0; j < i; ++j) { + ParamEntry.orderWithinGroup(entry[j], entry[i]); } } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PrototypeModel.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PrototypeModel.java index a6be60647b..d6fda3962c 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PrototypeModel.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PrototypeModel.java @@ -199,7 +199,7 @@ public class PrototypeModel { DataType[] arr = new DataType[1]; arr[0] = clone; ArrayList res = new ArrayList<>(); - outputParams.assignMap(program, arr, false, res, false); + outputParams.assignMap(program, arr, res, false); if (res.size() > 0) { return res.get(0); } @@ -247,7 +247,7 @@ public class PrototypeModel { } DataType arr[] = new DataType[argIndex + 2]; - arr[0] = DataType.VOID; // Assume the return type is void + arr[0] = VoidDataType.dataType; // Assume the return type is void for (int i = 0; i < argIndex; ++i) { if (params != null && i < params.length) { arr[i + 1] = params[i].getDataType(); // Copy in current types if we have them @@ -291,8 +291,8 @@ public class PrototypeModel { } ArrayList res = new ArrayList<>(); - outputParams.assignMap(program, dataTypes, false, res, addAutoParams); - inputParams.assignMap(program, dataTypes, true, res, addAutoParams); + outputParams.assignMap(program, dataTypes, res, addAutoParams); + inputParams.assignMap(program, dataTypes, res, addAutoParams); VariableStorage[] finalres = new VariableStorage[res.size()]; res.toArray(finalres); @@ -351,7 +351,7 @@ public class PrototypeModel { } else if (strategy.equals("register")) { inputParams = new ParamListStandard(); - outputParams = new ParamListStandard(); + outputParams = new ParamListRegisterOut(); inputListType = InputListType.REGISTER; } else {