GP-1518 Decompiler support for unions

This commit is contained in:
caheckman 2021-11-19 14:39:42 -05:00
parent 53e2c4dc4f
commit 3fdbbbb231
65 changed files with 5119 additions and 1068 deletions

View file

@ -24,6 +24,7 @@
#include "prettyprint.hh"
class PrintLanguage;
class ResolvedUnion;
/// \brief Base class for high-level language capabilities
///
@ -220,8 +221,8 @@ public:
: name(nm) { type = t; highlight = hl; ptr_second.ct = c; }
/// \brief Construct a token for a field name
Atom(const string &nm,tagtype t,EmitXml::syntax_highlight hl,const Datatype *c,int4 off)
: name(nm) { type = t; highlight = hl; ptr_second.ct = c; offset = off; }
Atom(const string &nm,tagtype t,EmitXml::syntax_highlight hl,const Datatype *c,int4 off,const PcodeOp *o)
: name(nm) { type = t; highlight = hl; ptr_second.ct = c; offset = off; op = o; }
/// \brief Construct a token with an associated PcodeOp
Atom(const string &nm,tagtype t,EmitXml::syntax_highlight hl,const PcodeOp *o)
@ -268,9 +269,9 @@ protected:
void unsetMod(uint4 m) { mods &= ~m; } ///< Deactivate the given printing modification
void pushOp(const OpToken *tok,const PcodeOp *op); ///< Push an operator token onto the RPN stack
void pushAtom(const Atom &atom); ///< Push a variable token onto the RPN stack
void pushVnImplied(const Varnode *vn,const PcodeOp *op,uint4 m); ///< Push an implied variable onto the RPN stack
void pushVn(const Varnode *vn,const PcodeOp *op,uint4 m); ///< Push an expression rooted at a Varnode onto the RPN stack
void pushVnExplicit(const Varnode *vn,const PcodeOp *op); ///< Push an explicit variable onto the RPN stack
void pushVnLHS(const Varnode *vn,const PcodeOp *op); ///< Push a variable as the left-hand side of an expression
void pushSymbolDetail(const Varnode *vn,const PcodeOp *op,bool isRead); ///< Push symbol name with adornments matching given Varnode
bool parentheses(const OpToken *op2); ///< Determine if the given token should be emitted in its own parenthetic expression
void emitOp(const ReversePolish &entry); ///< Send an operator token from the RPN to the emitter
@ -328,8 +329,7 @@ protected:
/// \param sym is the given Symbol
/// \param vn is the Varnode holding the Symbol value
/// \param op is a PcodeOp associated with the Varnode
virtual void pushSymbol(const Symbol *sym,const Varnode *vn,
const PcodeOp *op)=0;
virtual void pushSymbol(const Symbol *sym,const Varnode *vn,const PcodeOp *op)=0;
/// \brief Push an address as a substitute for a Symbol onto the RPN stack
///
@ -338,8 +338,7 @@ protected:
/// \param addr is the storage address
/// \param vn is the Varnode representing the variable (if present)
/// \param op is a PcodeOp associated with the variable
virtual void pushUnnamedLocation(const Address &addr,
const Varnode *vn,const PcodeOp *op)=0;
virtual void pushUnnamedLocation(const Address &addr,const Varnode *vn,const PcodeOp *op)=0;
/// \brief Push a variable that represents only part of a symbol onto the RPN stack
///
@ -349,9 +348,9 @@ protected:
/// \param sz is the number of bytes in the partial variable
/// \param vn is the Varnode holding the partial value
/// \param op is a PcodeOp associate with the Varnode
/// \param outtype is the data-type expected by expression using the partial variable
/// \param inslot is the input slot of \b vn with \b op, or -1 if \b op writes \b vn
virtual void pushPartialSymbol(const Symbol *sym,int4 off,int4 sz,
const Varnode *vn,const PcodeOp *op,Datatype *outtype)=0;
const Varnode *vn,const PcodeOp *op,int4 inslot)=0;
/// \brief Push an identifier for a variable that mismatches with its Symbol
///
@ -365,6 +364,15 @@ protected:
virtual void pushMismatchSymbol(const Symbol *sym,int4 off,int4 sz,
const Varnode *vn,const PcodeOp *op)=0;
/// \brief Push the implied field of a given Varnode as an object member extraction operation
///
/// If a Varnode is \e implied and has a \e union data-type, the particular read of the varnode
/// may correspond to a particular field that needs to get printed as a token, even though the
/// Varnode itself is printed directly. This method pushes the field name token.
/// \param vn is the given Varnode
/// \param op is the particular PcodeOp reading the Varnode
virtual void pushImpliedField(const Varnode *vn,const PcodeOp *op)=0;
virtual void emitLineComment(int4 indent,const Comment *comm); ///< Emit a comment line
/// \brief Emit a variable declaration