mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Documenting ifacedecomp
This commit is contained in:
parent
ab76cc6095
commit
6cc2d18349
9 changed files with 793 additions and 208 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
||||
{
|
||||
|
|
|
@ -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; \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue