diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.hh index cb361c36bd..2c1c5e49b5 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.hh @@ -255,7 +255,7 @@ protected: void parseProtoEval(const Element *el); ///< Apply prototype evaluation configuration void parseDefaultProto(const Element *el); ///< Apply default prototype model configuration void parseGlobal(const Element *el); ///< Apply global space configuration - void addOtherSpace(void); ////add OTHER space and all of its overlays to the symboltab + void addOtherSpace(void); ///< Add OTHER space and all of its overlays to the symboltab void parseReadOnly(const Element *el); ///< Apply read-only region configuration void parseVolatile(const Element *el); ///< Apply volatile region configuration void parseReturnAddress(const Element *el); ///< Apply return address configuration diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 90f698a5e0..a81af0231a 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -820,12 +820,16 @@ int4 ActionShadowVar::apply(Funcdata &data) /// \brief Determine if given Varnode might be a pointer constant. /// -/// If it is a pointer, return the symbol it points to, or NULL otherwise. +/// If it is a pointer, return the symbol it points to, or NULL otherwise. If it is determined +/// that the Varnode is a pointer to a specific symbol, the encoding of the full pointer is passed back. +/// Usually this is just the constant value of the Varnode, but in this case of partial pointers +/// (like \e near pointers) the full pointer may contain additional information. /// \param spc is the address space being pointed to /// \param vn is the given Varnode /// \param op is the lone descendant of the Varnode /// \param slot is the slot index of the Varnode /// \param rampoint will hold the Address of the resolved symbol +/// \param fullEncoding will hold the full pointer encoding being passed back /// \param data is the function being analyzed /// \return the recovered symbol or NULL SymbolEntry *ActionConstantPtr::isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,int4 slot, diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh index dd30309fc7..00db843979 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh @@ -92,7 +92,7 @@ class HeritageInfo { bool warningissued; ///< \b true if warning issued previously void set(AddrSpace *spc,int4 dl,int4 dcdl) { space=spc; delay=dl; deadcodedelay=dcdl; deadremoved=0; warningissued=false; loadGuardSearch = false; } ///< Set all fields - bool isHeritaged(void) const { return (space != (AddrSpace *)0); } + bool isHeritaged(void) const { return (space != (AddrSpace *)0); } ///< Return \b true if heritage is performed on this space void reset(void) { deadremoved = 0; deadcodedelay = delay; warningissued = false; loadGuardSearch = false; } ///< Reset }; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/printlanguage.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/printlanguage.cc index d91c59a0c9..7ccb7d48dc 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/printlanguage.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/printlanguage.cc @@ -263,7 +263,6 @@ void PrintLanguage::pushVnLHS(const Varnode *vn,const PcodeOp *op) /// ending with the given operator token, needs to be surrounded by parentheses to convey /// the proper meaning. /// \param op2 is the input token to \b this operator -/// \param stage is the stage of \b this operator currently being printed /// \return \b true if \b op2 (as input to \b this) should be parenthesized bool PrintLanguage::parentheses(const OpToken *op2) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc index 8f7b87bf23..9faa63e35d 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc @@ -3216,7 +3216,7 @@ int4 RuleSignShift::applyOp(PcodeOp *op,Funcdata &data) return 1; } -/// \class RuleSignShift +/// \class RuleTestSign /// \brief Convert sign-bit test to signed comparison: `(V s>> 0x1f) != 0 => V s< 0` void RuleTestSign::getOpList(vector &oplist) const diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc index 9248dc7f45..5be86d347f 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc @@ -170,10 +170,11 @@ SubvariableFlow::ReplaceOp *SubvariableFlow::createOp(OpCode opc,int4 numparam,R } -/// \brief Create a logical subraph operator node given one of its input variable nodes +/// \brief Create a logical subgraph operator node given one of its input variable nodes /// /// \param opc is the opcode of the new logical operator /// \param numparam is the number of parameters in the new operator +/// \param op is the original PcodeOp being replaced /// \param inrvn is the given input variable node /// \param slot is the input slot of the variable node /// \return the new logical subgraph operator objects @@ -1045,7 +1046,7 @@ void SubvariableFlow::addTerminalPatchSameOp(PcodeOp *pullop,ReplaceVarnode *rvn /// /// This doesn't count as a Varnode holding a logical value that needs to be patched (by itself). /// A PatchRecord terminating the logical subgraph along the given edge is created. -/// \param pullup is the operation taking the boolean input +/// \param pullop is the operation taking the boolean input /// \param rvn is the given bit variable /// \param slot is the input slot of the variable to the operation void SubvariableFlow::addBooleanPatch(PcodeOp *pullop,ReplaceVarnode *rvn,int4 slot) @@ -1206,6 +1207,11 @@ bool SubvariableFlow::processNextWork(void) return traceForward(rvn); } +/// \param f is the function to attempt the subvariable transform on +/// \param root is a starting Varnode containing a smaller logical value +/// \param mask is a mask where 1 bits indicate the position of the logical value within the \e root Varnode +/// \param aggr is \b true if we should use aggressive (less restrictive) tests during the trace +/// \param sext is \b true if we should assume sign extensions from the logical value into its container SubvariableFlow::SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext) { @@ -1233,6 +1239,10 @@ SubvariableFlow::SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr, createLink((ReplaceOp *)0,mask,0,root); } +/// Push the logical value around, setting up explicit transforms as we go that convert them +/// into explicit Varnodes. If at any point, we cannot naturally interpret the flow of the +/// logical value, return \b false. +/// \return \b true if a full transform has been constructed that can make logical values into explicit Varnodes bool SubvariableFlow::doTrace(void) { @@ -1260,7 +1270,7 @@ bool SubvariableFlow::doTrace(void) void SubvariableFlow::doReplacement(void) -{ // Create the actual replacement data-flow with -fd- +{ list::iterator iter; // Define all the outputs first diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.hh index bc8e67bb1b..96e8dc9e12 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.hh @@ -110,12 +110,17 @@ class SubvariableFlow { Varnode *getReplaceVarnode(ReplaceVarnode *rvn); bool processNextWork(void); ///< Extend the subgraph from the next node in the worklist public: - SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext); - bool doTrace(void); - void doReplacement(void); + SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext); ///< Constructor + bool doTrace(void); ///< Trace logical value through data-flow, constructing transform + void doReplacement(void); ///< Perform the discovered transform, making logical values explicit }; -// Class for splitting up varnodes that hold 2 logical variables +/// \brief Class for splitting up Varnodes that hold 2 logical variables +/// +/// Starting from a \e root Varnode provided to the constructor, \b this class looks for data-flow +/// that consistently holds 2 logical values in a single Varnode. If doTrace() returns \b true, +/// a consistent view has been created and invoking apply() will split all Varnodes and PcodeOps +/// involved in the data-flow into their logical pieces. class SplitFlow : public TransformManager { LaneDescription laneDescription; ///< Description of how to split Varnodes vector worklist; ///< Pending work list of Varnodes to push the split through diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh index 305031334b..8b522ed631 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh @@ -50,8 +50,8 @@ private: TransformOp *def; ///< Defining op for new Varnode void createReplacement(Funcdata *fd); ///< Create the new/modified variable this placeholder represents public: - Varnode *getOriginal(void) const { return vn; } - TransformOp *getDef(void) const { return def; } + Varnode *getOriginal(void) const { return vn; } ///< Get the original Varnode \b this placeholder models + TransformOp *getDef(void) const { return def; } ///< Get the operator that defines this placeholder variable }; /// \brief Placeholder node for PcodeOp that will exist after a transform is applied to a function @@ -77,8 +77,8 @@ private: void createReplacement(Funcdata *fd); ///< Create the new/modified op this placeholder represents bool attemptInsertion(Funcdata *fd); ///< Try to put the new PcodeOp into its basic block public: - TransformVar *getOut(void) const { return output; } - TransformVar *getIn(int4 i) const { return input[i]; } + TransformVar *getOut(void) const { return output; } ///< Get the output placeholder variable for \b this operator + TransformVar *getIn(int4 i) const { return input[i]; } ///< Get the i-th input placeholder variable for \b this }; /// \brief Description of logical lanes within a \b big Varnode @@ -121,7 +121,7 @@ public: TransformManager(Funcdata *f) { fd = f; } ///< Constructor virtual ~TransformManager(void); ///< Destructor virtual bool preserveAddress(Varnode *vn,int4 bitSize,int4 lsbOffset) const; - Funcdata *getFunction(void) const { return fd; } + Funcdata *getFunction(void) const { return fd; } ///< Get function being transformed void clearVarnodeMarks(void); ///< Clear mark for all Varnodes in the map TransformVar *newPreexistingVarnode(Varnode *vn); ///< Make placeholder for preexisting Varnode TransformVar *newUnique(int4 size); ///< Make placeholder for new unique space Varnode diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.hh index 908c6bf1c0..9aaca41aa6 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.hh @@ -137,9 +137,9 @@ private: list descend; ///< List of every op using this varnode as input mutable Cover *cover; ///< Addresses covered by the def->use of this Varnode mutable union { - Datatype *dataType; ///< For type propagate algorithm - ValueSet *valueSet; - } temp; + Datatype *dataType; ///< Temporary data-type associated with \b this for use in type propagate algorithm + ValueSet *valueSet; ///< Value set associated with \b this when performing Value Set Analysis + } temp; ///< Temporary storage for analysis algorithms uintb consumed; ///< What parts of this varnode are used uintb nzm; ///< Which bits do we know are zero friend class VarnodeBank;