GP-2157 Marshaling refactor. Decompiler side.

This commit is contained in:
caheckman 2022-05-17 16:15:21 -04:00
parent 672c1f11e2
commit d8c10bf229
97 changed files with 5313 additions and 3733 deletions

View file

@ -24,6 +24,38 @@
class JoinRecord;
extern AttributeId ATTRIB_CUSTOM; ///< Marshaling attribute "custom"
extern AttributeId ATTRIB_DOTDOTDOT; ///< Marshaling attribute "dotdotdot"
extern AttributeId ATTRIB_EXTENSION; ///< Marshaling attribute "extension"
extern AttributeId ATTRIB_HASTHIS; ///< Marshaling attribute "hasthis"
extern AttributeId ATTRIB_INLINE; ///< Marshaling attribute "inline"
extern AttributeId ATTRIB_KILLEDBYCALL; ///< Marshaling attribute "killedbycall"
extern AttributeId ATTRIB_MAXSIZE; ///< Marshaling attribute "maxsize"
extern AttributeId ATTRIB_MINSIZE; ///< Marshaling attribute "minsize"
extern AttributeId ATTRIB_MODELLOCK; ///< Marshaling attribute "modellock"
extern AttributeId ATTRIB_NORETURN; ///< Marshaling attribute "noreturn"
extern AttributeId ATTRIB_POINTERMAX; ///< Marshaling attribute "pointermax"
extern AttributeId ATTRIB_SEPARATEFLOAT; ///< Marshaling attribute "separatefloat"
extern AttributeId ATTRIB_STACKSHIFT; ///< Marshaling attribute "stackshift"
extern AttributeId ATTRIB_STRATEGY; ///< Marshaling attribute "strategy"
extern AttributeId ATTRIB_THISBEFORERETPOINTER; ///< Marshaling attribute "thisbeforeretpointer"
extern AttributeId ATTRIB_VOIDLOCK; ///< Marshaling attribute "voidlock"
extern ElementId ELEM_GROUP; ///< Marshaling element \<group>
extern ElementId ELEM_INTERNALLIST; ///< Marshaling element \<internallist>
extern ElementId ELEM_KILLEDBYCALL; ///< Marshaling element \<killedbycall>
extern ElementId ELEM_LIKELYTRASH; ///< Marshaling element \<likelytrash>
extern ElementId ELEM_LOCALRANGE; ///< Marshaling element \<localrange>
extern ElementId ELEM_MODEL; ///< Marshaling element \<model>
extern ElementId ELEM_PARAM; ///< Marshaling element \<param>
extern ElementId ELEM_PARAMRANGE; ///< Marshaling element \<paramrange>
extern ElementId ELEM_PENTRY; ///< Marshaling element \<pentry>
extern ElementId ELEM_PROTOTYPE; ///< Marshaling element \<prototype>
extern ElementId ELEM_RESOLVEPROTOTYPE; ///< Marshaling element \<resolveprototype>
extern ElementId ELEM_RETPARAM; ///< Marshaling element \<retparam>
extern ElementId ELEM_RETURNSYM; ///< Marshaling element \<returnsym>
extern ElementId ELEM_UNAFFECTED; ///< Marshaling element \<unaffected>
/// \brief Exception thrown when a prototype can't be modeled properly
struct ParamUnassignedError : public LowlevelError {
ParamUnassignedError(const string &s) : LowlevelError(s) {} ///< Constructor
@ -85,7 +117,7 @@ private:
/// \brief Is the logical value left-justified within its container
bool isLeftJustified(void) const { return (((flags&force_left_justify)!=0)||(!spaceid->isBigEndian())); }
public:
ParamEntry(int4 grp) { group=grp; } ///< Constructor for use with restoreXml
ParamEntry(int4 grp) { group=grp; } ///< Constructor for use with decode
int4 getGroup(void) const { return group; } ///< Get the group id \b this belongs to
int4 getGroupSize(void) const { return groupsize; } ///< Get the number of groups occupied by \b this
int4 getSize(void) const { return size; } ///< Get the size of the memory range in bytes.
@ -102,13 +134,13 @@ public:
bool intersects(const Address &addr,int4 sz) const; ///< Does \b this intersect the given range in some way
int4 justifiedContain(const Address &addr,int4 sz) const; ///< Calculate endian aware containment
bool getContainer(const Address &addr,int4 sz,VarnodeData &res) const;
bool contains(const ParamEntry &op2) const; ///< Does \this contain the given entry (as a subpiece)
bool contains(const ParamEntry &op2) const; ///< Does \b this contain the given entry (as a subpiece)
OpCode assumedExtension(const Address &addr,int4 sz,VarnodeData &res) const;
int4 getSlot(const Address &addr,int4 skip) const;
AddrSpace *getSpace(void) const { return spaceid; } ///< Get the address space containing \b this entry
uintb getBase(void) const { return addressbase; } ///< Get the starting offset of \b this entry
Address getAddrBySlot(int4 &slot,int4 sz) const;
void restoreXml(const Element *el,const AddrSpaceManager *manage,bool normalstack,bool grouped,list<ParamEntry> &curList);
void decode(Decoder &decoder,const AddrSpaceManager *manage,bool normalstack,bool grouped,list<ParamEntry> &curList);
bool isParamCheckHigh(void) const { return ((flags & extracheck_high)!=0); } ///< Return \b true if there is a high overlap
bool isParamCheckLow(void) const { return ((flags & extracheck_low)!=0); } ///< Return \b true if there is a low overlap
static void orderWithinGroup(const ParamEntry &entry1,const ParamEntry &entry2); ///< Enforce ParamEntry group ordering rules
@ -302,11 +334,11 @@ public:
class FspecSpace : public AddrSpace {
public:
FspecSpace(AddrSpaceManager *m,const Translate *t,int4 ind); ///< Constructor
virtual void saveXmlAttributes(ostream &s,uintb offset) const;
virtual void saveXmlAttributes(ostream &s,uintb offset,int4 size) const;
virtual void encodeAttributes(Encoder &encoder,uintb offset) const;
virtual void encodeAttributes(Encoder &encoder,uintb offset,int4 size) const;
virtual void printRaw(ostream &s,uintb offset) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
virtual void decode(Decoder &decoder);
static const string NAME; ///< Reserved name for the fspec space
};
@ -342,7 +374,7 @@ private:
VarnodeData range; ///< The memory range affected
uint4 type; ///< The type of effect
public:
EffectRecord(void) {} ///< Constructor for use with restoreXml()
EffectRecord(void) {} ///< Constructor for use with decode()
EffectRecord(const EffectRecord &op2) { range = op2.range; type = op2.type; } ///< Copy constructor
EffectRecord(const Address &addr,int4 size); ///< Construct a memory range with an unknown effect
EffectRecord(const ParamEntry &entry,uint4 t); ///< Construct an effect on a parameter storage location
@ -352,8 +384,8 @@ public:
int4 getSize(void) const { return range.size; } ///< Get the size of the affected range
bool operator==(const EffectRecord &op2) const; ///< Equality operator
bool operator!=(const EffectRecord &op2) const; ///< Inequality operator
void saveXml(ostream &s) const; ///< Save the record to an XML stream
void restoreXml(uint4 grouptype,const Element *el,const AddrSpaceManager *manage); ///< Restore the record from an XML stream
void encode(Encoder &encoder) const; ///< Encode the record to a stream
void decode(uint4 grouptype,Decoder &decoder,const AddrSpaceManager *manage); ///< Decode the record from a stream
static bool compareByAddress(const EffectRecord &op1,const EffectRecord &op2);
};
@ -496,13 +528,13 @@ public:
/// \return the maximum number of passes across all parameters in \b this model
virtual int4 getMaxDelay(void) const=0;
/// \brief Restore the model from an XML stream
/// \brief Restore the model from an \<input> or \<output> element in the stream
///
/// \param el is the root \<input> or \<output> element
/// \param decoder is the stream decoder
/// \param manage is used to resolve references to address spaces
/// \param effectlist is a container collecting EffectRecords across all parameters
/// \param normalstack is \b true if parameters are pushed on the stack in the normal order
virtual void restoreXml(const Element *el,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,bool normalstack)=0;
virtual void decode(Decoder &decoder,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,bool normalstack)=0;
virtual ParamList *clone(void) const=0; ///< Clone this parameter list model
};
@ -539,12 +571,12 @@ protected:
void calcDelay(void); ///< Calculate the maximum heritage delay for any potential parameter in this list
void addResolverRange(AddrSpace *spc,uintb first,uintb last,ParamEntry *paramEntry,int4 position);
void populateResolver(void); ///< Build the ParamEntry resolver maps
void parsePentry(const Element *el,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,
void parsePentry(Decoder &decoder,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,
int4 groupid,bool normalstack,bool autokill,bool splitFloat,bool grouped);
void parseGroup(const Element *el,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,
void parseGroup(Decoder &decoder,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,
int4 groupid,bool normalstack,bool autokill,bool splitFloat);
public:
ParamListStandard(void) {} ///< Construct for use with restoreXml()
ParamListStandard(void) {} ///< Construct for use with decode()
ParamListStandard(const ParamListStandard &op2); ///< Copy constructor
virtual ~ParamListStandard(void);
const list<ParamEntry> &getEntry(void) const { return entry; } ///< Get the list of parameter entries
@ -562,7 +594,7 @@ public:
virtual AddrSpace *getSpacebase(void) const { return spacebase; }
virtual void getRangeList(AddrSpace *spc,RangeList &res) const;
virtual int4 getMaxDelay(void) const { return maxdelay; }
virtual void restoreXml(const Element *el,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,bool normalstack);
virtual void decode(Decoder &decoder,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,bool normalstack);
virtual ParamList *clone(void) const;
};
@ -593,7 +625,7 @@ public:
/// conventions. The assignMap() method may make less sense in this scenario.
class ParamListRegister : public ParamListStandard {
public:
ParamListRegister(void) : ParamListStandard() {} ///< Constructor for use with restoreXml()
ParamListRegister(void) : ParamListStandard() {} ///< Constructor for use with decode()
ParamListRegister(const ParamListRegister &op2) : ParamListStandard(op2) {} ///< Copy constructor
virtual uint4 getType(void) const { return p_register; }
virtual void fillinMap(ParamActive *active) const;
@ -610,11 +642,11 @@ public:
/// to inform the input model.
class ParamListStandardOut : public ParamListRegisterOut {
public:
ParamListStandardOut(void) : ParamListRegisterOut() {} ///< Constructor for use with restoreXml()
ParamListStandardOut(void) : ParamListRegisterOut() {} ///< Constructor for use with decode()
ParamListStandardOut(const ParamListStandardOut &op2) : ParamListRegisterOut(op2) {} ///< Copy constructor
virtual uint4 getType(void) const { return p_standard_out; }
virtual void assignMap(const vector<Datatype *> &proto,TypeFactory &typefactory,vector<ParameterPieces> &res) const;
virtual void restoreXml(const Element *el,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,bool normalstack);
virtual void decode(Decoder &decoder,const AddrSpaceManager *manage,vector<EffectRecord> &effectlist,bool normalstack);
virtual ParamList *clone(void) const;
};
@ -628,7 +660,7 @@ public:
/// need to be invoked.
class ParamListMerged : public ParamListStandard {
public:
ParamListMerged(void) : ParamListStandard() {} ///< Constructor for use with restoreXml
ParamListMerged(void) : ParamListStandard() {} ///< Constructor for use with decode
ParamListMerged(const ParamListMerged &op2) : ParamListStandard(op2) {} ///< Copy constructor
void foldIn(const ParamListStandard &op2); ///< Add another model to the union
void finalize(void) { populateResolver(); } ///< Fold-ins are finished, finalize \b this
@ -686,7 +718,7 @@ public:
enum {
extrapop_unknown = 0x8000 ///< Reserved extrapop value meaning the function's \e extrapop is unknown
};
ProtoModel(Architecture *g); ///< Constructor for use with restoreXml()
ProtoModel(Architecture *g); ///< Constructor for use with decode()
ProtoModel(const string &nm,const ProtoModel &op2); ///< Copy constructor changing the name
virtual ~ProtoModel(void); ///< Destructor
const string &getName(void) const { return name; } ///< Get the name of the prototype model
@ -909,7 +941,7 @@ public:
int4 getMaxOutputDelay(void) const { return output->getMaxDelay(); }
virtual bool isMerged(void) const { return false; } ///< Is \b this a merged prototype model
virtual void restoreXml(const Element *el); ///< Restore \b this model from an XML stream
virtual void decode(Decoder &decoder); ///< Restore \b this model from a stream
static uint4 lookupEffect(const vector<EffectRecord> &efflist,const Address &addr,int4 size);
static int4 lookupRecord(const vector<EffectRecord> &efflist,int4 listSize,const Address &addr,int4 size);
};
@ -969,7 +1001,7 @@ public:
void foldIn(ProtoModel *model); ///< Fold-in an additional prototype model
ProtoModel *selectModel(ParamActive *active) const; ///< Select the best model given a set of trials
virtual bool isMerged(void) const { return true; }
virtual void restoreXml(const Element *el);
virtual void decode(Decoder &decoder);
};
class Symbol;
@ -1116,18 +1148,19 @@ public:
virtual ProtoParameter *getOutput(void)=0; ///< Get the return-value description
virtual ProtoStore *clone(void) const=0; ///< Clone the entire collection of parameter descriptions
/// \brief Save any parameters that are not backed by symbols to an XML stream
/// \brief Encode any parameters that are not backed by symbols to a stream
///
/// Symbols are stored elsewhere, so symbol backed parameters are not serialized.
/// If there are any internal parameters an \<internallist> tag is emitted.
/// \param s is the output stream
virtual void saveXml(ostream &s) const=0;
/// If there are any internal parameters an \<internallist> element is emitted.
/// \param encoder is the stream encoder
virtual void encode(Encoder &encoder) const=0;
/// \brief Restore any internal parameter descriptions from an XML stream
/// \brief Restore any internal parameter descriptions from a stream
///
/// \param el is a root \<internallist> element containing \<param> and \<retparam> sub-tags.
/// Parse an \<internallist> element containing \<param> and \<retparam> child elements.
/// \param decoder is the stream decoder
/// \param model is prototype model for determining storage for unassigned parameters
virtual void restoreXml(const Element *el,ProtoModel *model)=0;
virtual void decode(Decoder &decoder,ProtoModel *model)=0;
};
/// \brief A parameter with a formal backing Symbol
@ -1183,8 +1216,8 @@ public:
virtual void clearOutput(void);
virtual ProtoParameter *getOutput(void);
virtual ProtoStore *clone(void) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,ProtoModel *model);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,ProtoModel *model);
};
/// \brief A collection of parameter descriptions without backing symbols
@ -1207,8 +1240,8 @@ public:
virtual void clearOutput(void);
virtual ProtoParameter *getOutput(void);
virtual ProtoStore *clone(void) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,ProtoModel *model);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,ProtoModel *model);
};
/// \brief Raw components of a function prototype (obtained from parsing source code)
@ -1258,10 +1291,10 @@ class FuncProto {
int4 injectid; ///< (If non-negative) id of p-code snippet that should replace this function
int4 returnBytesConsumed; ///< Number of bytes of return value that are consumed by callers (0 = all bytes)
void updateThisPointer(void); ///< Make sure any "this" parameter is properly marked
void saveEffectXml(ostream &s) const; ///< Save any overriding EffectRecords to XML stream
void saveLikelyTrashXml(ostream &s) const; ///< Save any overriding likelytrash registers to XML stream
void restoreEffectXml(void); ///< Merge in any EffectRecord overrides
void restoreLikelyTrashXml(void); ///< Merge in any \e likelytrash overrides
void encodeEffect(Encoder &encoder) const; ///< Encode any overriding EffectRecords to stream
void encodeLikelyTrash(Encoder &encoder) const; ///< Encode any overriding likelytrash registers to stream
void decodeEffect(void); ///< Merge in any EffectRecord overrides
void decodeLikelyTrash(void); ///< Merge in any \e likelytrash overrides
protected:
void paramShift(int4 paramshift); ///< Add parameters to the front of the input parameter list
bool isParamshiftApplied(void) const { return ((flags&paramshift_applied)!=0); } ///< Has a parameter shift been applied
@ -1502,8 +1535,8 @@ public:
/// \return the active set of flags for \b this prototype
uint4 getComparableFlags(void) const { return (flags & (dotdotdot | is_constructor | is_destructor | has_thisptr )); }
void saveXml(ostream &s) const;
void restoreXml(const Element *el,Architecture *glb);
void encode(Encoder &encoder) const;
void decode(Decoder &decoder,Architecture *glb);
};
class Funcdata;