mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Adjustments to default hidden return assignment action
This commit is contained in:
parent
2848eb56a5
commit
548d71007f
7 changed files with 91 additions and 37 deletions
|
@ -731,7 +731,8 @@ void ParamListStandard::assignMap(const PrototypePieces &proto,TypeFactory &type
|
|||
for(int4 i=0;i<proto.intypes.size();++i) {
|
||||
res.emplace_back();
|
||||
Datatype *dt = proto.intypes[i];
|
||||
if (assignAddress(dt,proto,i,typefactory,status,res.back()) == AssignAction::fail)
|
||||
uint4 responseCode = assignAddress(dt,proto,i,typefactory,status,res.back());
|
||||
if (responseCode == AssignAction::fail || responseCode == AssignAction::no_assignment)
|
||||
throw ParamUnassignedError("Cannot assign parameter address for " + dt->getName());
|
||||
}
|
||||
}
|
||||
|
@ -1503,7 +1504,12 @@ void ParamListStandardOut::assignMap(const PrototypePieces &proto,TypeFactory &t
|
|||
return; // Leave the address as invalid
|
||||
}
|
||||
uint4 responseCode = assignAddress(proto.outtype,proto,-1,typefactory,status,res.back());
|
||||
if (responseCode != AssignAction::success) { // Could not assign an address (too big)
|
||||
|
||||
if (responseCode == AssignAction::fail)
|
||||
responseCode = AssignAction::hiddenret_ptrparam; // Invoke default hidden return input assignment action
|
||||
|
||||
if (responseCode == AssignAction::hiddenret_ptrparam || responseCode == AssignAction::hiddenret_specialreg ||
|
||||
responseCode == AssignAction::hiddenret_specialreg_void) { // Could not assign an address (too big)
|
||||
AddrSpace *spc = spacebase;
|
||||
if (spc == (AddrSpace *)0)
|
||||
spc = typefactory.getArch()->getDefaultDataSpace();
|
||||
|
|
|
@ -356,7 +356,7 @@ AssignAction *AssignAction::decodeAction(Decoder &decoder,const ParamListStandar
|
|||
action = new ConvertToPointer(res);
|
||||
}
|
||||
else if (elemId == ELEM_HIDDEN_RETURN) {
|
||||
action = new HiddenReturnAssign(res,false);
|
||||
action = new HiddenReturnAssign(res,hiddenret_specialreg);
|
||||
}
|
||||
else if (elemId == ELEM_JOIN_PER_PRIMITIVE) {
|
||||
bool consumeMostSig = false;
|
||||
|
@ -721,10 +721,10 @@ void ConsumeAs::decode(Decoder &decoder)
|
|||
decoder.closeElement(elemId);
|
||||
}
|
||||
|
||||
HiddenReturnAssign::HiddenReturnAssign(const ParamListStandard *res,bool voidLock)
|
||||
HiddenReturnAssign::HiddenReturnAssign(const ParamListStandard *res,uint4 code)
|
||||
: AssignAction(res)
|
||||
{
|
||||
retCode = voidLock ? hiddenret_specialreg_void : hiddenret_specialreg;
|
||||
retCode = code;
|
||||
}
|
||||
|
||||
uint4 HiddenReturnAssign::assignAddress(Datatype *dt,const PrototypePieces &proto,int4 pos,TypeFactory &tlist,
|
||||
|
@ -736,12 +736,24 @@ uint4 HiddenReturnAssign::assignAddress(Datatype *dt,const PrototypePieces &prot
|
|||
void HiddenReturnAssign::decode(Decoder &decoder)
|
||||
|
||||
{
|
||||
retCode = hiddenret_specialreg;
|
||||
uint4 elemId = decoder.openElement(ELEM_HIDDEN_RETURN);
|
||||
uint4 attribId = decoder.getNextAttributeId();
|
||||
if (attribId == ATTRIB_VOIDLOCK)
|
||||
retCode = hiddenret_specialreg_void;
|
||||
else
|
||||
retCode = hiddenret_specialreg;
|
||||
for(;;) {
|
||||
uint4 attribId = decoder.getNextAttributeId();
|
||||
if (attribId == ATTRIB_VOIDLOCK)
|
||||
retCode = hiddenret_specialreg_void;
|
||||
else if (attribId == ATTRIB_STRATEGY) {
|
||||
string strategyString = decoder.readString();
|
||||
if (strategyString == "normalparam")
|
||||
retCode = hiddenret_ptrparam;
|
||||
else if (strategyString == "special")
|
||||
retCode = hiddenret_specialreg;
|
||||
else
|
||||
throw DecoderError("Bad <hidden_return> strategy: " + strategyString);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
decoder.closeElement(elemId);
|
||||
}
|
||||
|
||||
|
|
|
@ -200,7 +200,8 @@ class AssignAction {
|
|||
public:
|
||||
enum {
|
||||
success, ///< Data-type is fully assigned
|
||||
fail, ///< Action could not be applied (not enough resources)
|
||||
fail, ///< Action could not be applied
|
||||
no_assignment, ///< Do not assign storage for this parameter
|
||||
hiddenret_ptrparam, ///< Hidden return pointer as first input parameter
|
||||
hiddenret_specialreg, ///< Hidden return pointer in dedicated input register
|
||||
hiddenret_specialreg_void ///< Hidden return pointer, but no normal return
|
||||
|
@ -327,19 +328,24 @@ public:
|
|||
virtual void decode(Decoder &decoder);
|
||||
};
|
||||
|
||||
/// \brief Allocate the return value as special input register
|
||||
/// \brief Allocate the return value as an input parameter
|
||||
///
|
||||
/// The assignAddress() method signals with \b hiddenret_specialreg, indicating that the
|
||||
/// input register assignMap() method should use storage class TYPECLASS_HIDDENRET to assign
|
||||
/// an additional input register to hold a pointer to the return value. This is different than
|
||||
/// the default \e hiddenret action that assigns a location based TYPECLASS_PTR and generally
|
||||
/// consumes a general purpose input register.
|
||||
/// A pointer to where the return value is to be stored is passed in as an input parameter.
|
||||
/// This action signals this by returning one of
|
||||
/// - \b hiddenret_ptrparam - indicating the pointer is allocated as a normal input parameter
|
||||
/// - \b hiddenret_specialreg - indicating the pointer is passed in a dedicated register
|
||||
/// - \b hiddenret_specialreg_void
|
||||
///
|
||||
/// Usually, if a hidden return input is present, the normal register used for return
|
||||
/// will also hold the pointer at the point(s) where the function returns. A signal of
|
||||
/// \b hiddenret_specialreg_void indicates the normal return register is not used to pass back
|
||||
/// the pointer.
|
||||
class HiddenReturnAssign : public AssignAction {
|
||||
uint4 retCode; ///< The specific signal to pass back
|
||||
public:
|
||||
HiddenReturnAssign(const ParamListStandard *res,bool voidLock); ///< Constructor
|
||||
HiddenReturnAssign(const ParamListStandard *res,uint4 code); ///< Constructor
|
||||
virtual AssignAction *clone(const ParamListStandard *newResource) const {
|
||||
return new HiddenReturnAssign(newResource, retCode == hiddenret_specialreg_void); }
|
||||
return new HiddenReturnAssign(newResource, retCode); }
|
||||
virtual uint4 assignAddress(Datatype *dt,const PrototypePieces &proto,int4 pos,TypeFactory &tlist,
|
||||
vector<int4> &status,ParameterPieces &res) const;
|
||||
virtual void decode(Decoder &decoder);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue