Documenting ifacedecomp

This commit is contained in:
caheckman 2021-01-30 12:52:39 -05:00
parent ab76cc6095
commit 6cc2d18349
9 changed files with 793 additions and 208 deletions

View file

@ -457,7 +457,7 @@ RECURSIVE = NO
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE = unify.hh unify.cc rulecompile.hh rulecompile.cc slgh_compile.hh slgh_compile.cc slghparse.cc slghparse.hh slghscan.cc slghpattern.hh slghpattern.cc slghpatexpress.hh slghpatexpress.cc slghsymbol.hh slghsymbol.cc ifacedecomp.hh ifacedecomp.cc codedata.hh codedata.cc semantics.hh semantics.cc grammar.hh grammar.cc callgraph.hh callgraph.cc filemanage.hh filemanage.cc graph.hh graph.cc loadimage_bfd.hh loadimage_bfd.cc pcodecompile.cc pcodecompile.hh pcodeparse.hh pcodeparse.cc inject_sleigh.hh inject_sleigh.cc context.hh context.cc consolemain.cc sleighexample.cc xml.cc double.hh double.cc paramid.hh paramid.cc prefersplit.hh prefersplit.cc
EXCLUDE = unify.hh unify.cc rulecompile.hh rulecompile.cc slgh_compile.hh slgh_compile.cc slghparse.cc slghparse.hh slghscan.cc slghpattern.hh slghpattern.cc slghpatexpress.hh slghpatexpress.cc slghsymbol.hh slghsymbol.cc codedata.hh codedata.cc semantics.hh semantics.cc grammar.hh grammar.cc callgraph.hh callgraph.cc filemanage.hh filemanage.cc graph.hh graph.cc loadimage_bfd.hh loadimage_bfd.cc pcodecompile.cc pcodecompile.hh pcodeparse.hh pcodeparse.cc inject_sleigh.hh inject_sleigh.cc context.hh context.cc consolemain.cc sleighexample.cc xml.cc double.hh double.cc paramid.hh paramid.cc prefersplit.hh prefersplit.cc
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix filesystem feature) are excluded
@ -870,18 +870,6 @@ GENERATE_XML = NO
XML_OUTPUT = xml
# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD =
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
# and cross-referencing information) to the XML output. Note that

View file

@ -574,7 +574,10 @@ int4 FlowBlock::getOutIndex(const FlowBlock *bl) const
void FlowBlock::printHeader(ostream &s) const
{
s << dec << index << ' ' << getStart() << '-' << getStop();
s << dec << index;
if (!getStart().isInvalid() && !getStop().isInvalid()) {
s << ' ' << getStart() << '-' << getStop();
}
}
/// Recursively print out the hierarchical structure of \b this FlowBlock.

View file

@ -54,8 +54,8 @@ public:
};
Comment(uint4 tp,const Address &fad,const Address &ad,int4 uq,const string &txt); ///< Constructor
Comment(void) {} ///< Constructor for use with restoreXml
void setEmitted(bool val) const { emitted = val; }
bool isEmitted(void) const { return emitted; }
void setEmitted(bool val) const { emitted = val; } ///< Mark that \b this comment has been emitted
bool isEmitted(void) const { return emitted; } ///< Return \b true if \b this comment is already emitted
uint4 getType(void) const { return type; } ///< Get the properties associated with the comment
const Address &getFuncAddr(void) const { return funcaddr; } ///< Get the address of the function containing the comment
const Address &getAddr(void) const { return addr; } ///< Get the address to which the instruction is attached

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Interface to the decompilation routines
/// \file ifacedecomp.hh
/// \brief Console interface commands for the decompiler engine
#ifndef __IFACE_DECOMP__
#define __IFACE_DECOMP__
@ -27,20 +28,22 @@
#include "rulecompile.hh"
#endif
/// \brief Interface capability point for all decompiler commands
class IfaceDecompCapability : public IfaceCapability {
static IfaceDecompCapability ifaceDecompCapability; // Singleton instance
IfaceDecompCapability(void); // Singleton
IfaceDecompCapability(const IfaceDecompCapability &op2); // Not implemented
IfaceDecompCapability &operator=(const IfaceDecompCapability &op2); // Not implemented
static IfaceDecompCapability ifaceDecompCapability; ///< Singleton instance
IfaceDecompCapability(void); ///< Singleton constructor
IfaceDecompCapability(const IfaceDecompCapability &op2); ///< Not implemented
IfaceDecompCapability &operator=(const IfaceDecompCapability &op2); ///< Not implemented
public:
virtual void registerCommands(IfaceStatus *status);
};
/// \brief Common data shared by decompiler commands
class IfaceDecompData : public IfaceData {
public:
Funcdata *fd; // Current function data
Architecture *conf;
CallGraph *cgraph;
Funcdata *fd; ///< Current function active in the console
Architecture *conf; ///< Current architecture/program active in the console
CallGraph *cgraph; ///< Call-graph information for the program
map<Funcdata*,PrototypePieces> prototypePieces;
void storePrototypePieces( Funcdata *fd_in, PrototypePieces pp_in ) { prototypePieces.insert(pair<Funcdata*,PrototypePieces>(fd_in,pp_in)); }
@ -52,18 +55,24 @@ public:
#ifdef OPACTION_DEBUG
bool jumptabledebug;
#endif
IfaceDecompData(void);
IfaceDecompData(void); ///< Constructor
virtual ~IfaceDecompData(void);
void allocateCallGraph(void);
void abortFunction(ostream &s);
void clearArchitecture(void);
void allocateCallGraph(void); ///< Allocate the call-graph object
void abortFunction(ostream &s); ///< Clear references to current function
void clearArchitecture(void); ///< Free all resources for the current architecture/program
void followFlow(ostream &s,int4 size);
Varnode *readVarnode(istream &s); ///< Read a varnode from the given stream
};
/// \brief Disassembly emitter that prints to a console stream
///
/// An instruction is printed to a stream simply, as an address
/// followed by the mnemonic and then column aligned operands.
class IfaceAssemblyEmit : public AssemblyEmit {
int4 mnemonicpad; // How much to pad the mnemonic
ostream *s;
int4 mnemonicpad; ///< How much to pad the mnemonic
ostream *s; ///< The current stream to write to
public:
IfaceAssemblyEmit(ostream *val,int4 mp) { s = val; mnemonicpad=mp; }
IfaceAssemblyEmit(ostream *val,int4 mp) { s = val; mnemonicpad=mp; } ///< Constructor
virtual void dump(const Address &addr,const string &mnem,const string &body) {
addr.printRaw(*s);
*s << ": " << mnem;
@ -72,22 +81,31 @@ public:
}
};
extern void execute(IfaceStatus *status,IfaceDecompData *dcp);
extern void mainloop(IfaceStatus *status);
extern void execute(IfaceStatus *status,IfaceDecompData *dcp); ///< Execute one command for the console
extern void mainloop(IfaceStatus *status); ///< Execute commands as they become available
/// \brief Root class for all decompiler specific commands
///
/// Commands share the data object IfaceDecompData and are capable of
/// iterating over all functions in the program/architecture.
class IfaceDecompCommand : public IfaceCommand {
protected:
IfaceStatus *status;
IfaceDecompData *dcp;
void iterateScopesRecursive(Scope *scope);
void iterateFunctionsAddrOrder(Scope *scope);
IfaceStatus *status; ///< The console owning \b this command
IfaceDecompData *dcp; ///< Data common to decompiler commands
void iterateScopesRecursive(Scope *scope); ///< Iterate recursively over all functions in given scope
void iterateFunctionsAddrOrder(Scope *scope); ///< Iterate over all functions in a given scope
public:
virtual void setData(IfaceStatus *root,IfaceData *data) { status = root; dcp = (IfaceDecompData *)data; }
virtual string getModule(void) const { return "decompile"; }
virtual IfaceData *createData(void) { return new IfaceDecompData(); }
/// \brief Perform the per-function aspect of \b this command.
///
/// \param fd is the particular function to operate on
virtual void iterationCallback(Funcdata *fd) {}
void iterateFunctionsAddrOrder(void);
void iterateFunctionsLeafOrder(void);
void iterateFunctionsAddrOrder(void); ///< Iterate command over all functions in all scopes
void iterateFunctionsLeafOrder(void); ///< Iterate command over all functions in a call-graph traversal
};
class IfcSource : public IfaceDecompCommand {
@ -257,11 +275,6 @@ public:
virtual void execute(istream &s);
};
class IfcBreakjump : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
};
class IfcPrintTree : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
@ -282,18 +295,10 @@ public:
virtual void execute(istream &s);
};
class IfcParamIDAnalysis : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
};
class IfcPrintParamMeasures : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
};
class IfcPrintParamMeasuresXml : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
};
class IfcRename : public IfaceDecompCommand {
public:
@ -403,6 +408,10 @@ public:
class IfcPrintInputs : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
static bool nonTrivialUse(Varnode *vn); ///< Check for non-trivial use of given Varnode
static int4 checkRestore(Varnode *vn); ///< Check if a Varnode is \e restored to its original input value
static bool findRestore(Varnode *vn,Funcdata *fd); ///< Check if storage is \e restored
static void print(Funcdata *fd,ostream &s); ///< Print information about function inputs
};
class IfcPrintInputsAll : public IfaceDecompCommand {
@ -465,6 +474,8 @@ class IfcDuplicateHash : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
virtual void iterationCallback(Funcdata *fd);
static void check(Funcdata *fd,ostream &s); ///< Check for duplicate hashes in given function
};
class IfcCallGraphDump : public IfaceDecompCommand {
@ -474,7 +485,7 @@ public:
class IfcCallGraphBuild : public IfaceDecompCommand {
protected:
bool quick;
bool quick; ///< Set to \b true if a quick analysis is desired
public:
virtual void execute(istream &s);
virtual void iterationCallback(Funcdata *fd);
@ -490,8 +501,6 @@ public:
};
class IfcCallGraphList : public IfaceDecompCommand {
protected:
bool quick;
public:
virtual void execute(istream &s);
virtual void iterationCallback(Funcdata *fd);
@ -505,6 +514,8 @@ public:
class IfcCallFixup : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
static void readPcodeSnippet(istream &s,string &name,string &outname,vector<string> &inname,
string &pcodestring);
};
class IfcCallOtherFixup : public IfaceDecompCommand {
@ -557,12 +568,12 @@ class IfcParseRule : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
};
#endif
class IfcExperimentalRules : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
};
#endif
#ifdef OPACTION_DEBUG
class IfcDebugAction : public IfaceDecompCommand {
@ -600,6 +611,11 @@ public:
virtual void execute(istream &s);
};
class IfcBreakjump : public IfaceDecompCommand {
public:
virtual void execute(istream &s);
};
#endif
#endif

View file

@ -249,7 +249,7 @@ void Override::printRaw(ostream &s,Architecture *glb) const
s << "dead code delay on " << spc->getName() << " set to " << dec << deadcodedelay[i] << endl;
}
for(iter=forcegoto.begin();iter!=forcegoto.end();++iter)
for(iter=indirectover.begin();iter!=indirectover.end();++iter)
s << "override indirect at " << (*iter).first << " to call directly to " << (*iter).second << endl;
map<Address,FuncProto *>::const_iterator fiter;

View file

@ -162,6 +162,12 @@ public:
bool doTrace(void); ///< Trace logical value as far as possible
};
/// \brief Class for splitting data-flow on \e laned registers
///
/// From a root Varnode and a description of its \e lanes, trace data-flow as far as
/// possible through the function, propagating each lane, using the doTrace() method. Then
/// using the apply() method, data-flow can be split, making each lane in every traced
/// register into an explicit Varnode
class LaneDivide : public TransformManager {
/// \brief Description of a large Varnode that needs to be traced (in the worklist)
class WorkNode {

View file

@ -20,7 +20,7 @@ vector<UnitTest *> UnitTest::tests;
/// Run all the tests unless a non-empty set of names is passed in.
/// In which case, only the named tests in the set are run.
/// \param testnames is the set of names
/// \param testNames is the set of names
void UnitTest::run(set<string> &testNames)
{

View file

@ -19,8 +19,8 @@
/// Include this file and any additional headers. Use TEST(testname) as
/// prototype in test function definitions. E.g.
/// test.cc:
/// #include "float.hh"
/// #include "test.hh"
/// \#include "float.hh"
/// \#include "test.hh"
///
/// TEST(zero_is_less_than_one) {
/// ASSERT(0.0 < 1.0);
@ -32,7 +32,7 @@
#include <string>
#include <iostream>
typedef void (*testfunc_t)();
typedef void (*testfunc_t)(); ///< A unit-test function
/// \brief Simple unit test class
///
@ -58,17 +58,20 @@ struct UnitTest {
};
/// \brief Main unit test macro
#define TEST(testname) \
void testname(); \
UnitTest testname##_obj{ #testname, testname }; \
void testname()
/// \brief Assert that a boolean is \b true for a unit test
#define ASSERT(test) \
if (!(test)) { \
std::cerr << " failed at " << __FILE__ << ":" << __LINE__ << " asserting \"" << #test << "\"." << std::endl; \
throw 0; \
}
/// \brief Assert that two values are equal for a unit test
#define ASSERT_EQUALS(a, b) \
if ((a) != (b)) { \
std::stringstream ssa, ssb; \
@ -79,6 +82,7 @@ struct UnitTest {
throw 0; \
}
/// \brief Assert that two values are not equal for a unit test
#define ASSERT_NOT_EQUALS(a, b) \
if ((a) == (b)) { \
std::stringstream ssa, ssb; \