WIP: More GUI work, use shared_ptr to store Function references.

This commit is contained in:
nemerle
2016-05-03 13:59:14 +02:00
parent 60a4fefe95
commit 0521206de5
36 changed files with 545 additions and 365 deletions

View File

@@ -3,7 +3,7 @@
/* CALL GRAPH NODE */
struct CALL_GRAPH
{
ilFunction proc; /* Pointer to procedure in pProcList */
PtrFunction proc; /* Pointer to procedure in pProcList */
std::vector<CALL_GRAPH *> outEdges; /* array of out edges */
public:
void write();
@@ -12,8 +12,8 @@ public:
}
public:
void writeNodeCallGraph(int indIdx);
bool insertCallGraph(ilFunction caller, ilFunction callee);
bool insertCallGraph(Function *caller, ilFunction callee);
void insertArc(ilFunction newProc);
bool insertCallGraph(PtrFunction caller, PtrFunction callee);
//bool insertCallGraph(PtrFunction caller, PtrFunction callee);
void insertArc(PtrFunction newProc);
};
//extern CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */

View File

@@ -1,5 +1,8 @@
#pragma once
#include <QtCore/QObject>
#include "src/Command.h"
#include "project.h"
class Project;
class DccFrontend : public QObject
{
@@ -14,3 +17,28 @@ signals:
public slots:
};
struct MachineStateInitialization : public Command {
MachineStateInitialization() : Command("Initialize simulated machine state",eProject) {}
bool execute(CommandContext *ctx) override;
};
struct FindMain : public Command {
FindMain() : Command("Locate the main entry point",eProject) {}
bool execute(CommandContext *ctx);
};
struct CreateFunction : public Command {
QString m_name;
SegOffAddr m_addr;
FunctionType *m_type;
CreateFunction(QString name,SegOffAddr address,FunctionType *f) : Command("Create function",eProject),
m_name(name),
m_addr(address),
m_type(f)
{}
QString instanceDescription() const override;
bool execute(CommandContext *ctx) override;
};

View File

@@ -7,7 +7,8 @@
#include "CallConvention.h"
#include <llvm/ADT/ilist.h>
//#include <llvm/ADT/ilist_node.h>
#include <memory>
#include <stdint.h>
#include <QtCore/QString>
#include <bitset>
#include <map>
@@ -22,7 +23,7 @@ struct Disassembler;
struct Function;
struct CALL_GRAPH;
struct PROG;
struct IStructuredTextTarget;
struct Function;
namespace llvm
@@ -55,15 +56,11 @@ enum PROC_FLAGS
PROC_IJMP =0x00000200,/* Proc incomplete due to indirect jmp */
PROC_ICALL =0x00000400, /* Proc incomplete due to indirect call */
PROC_HLL =0x00001000, /* Proc is likely to be from a HLL */
// CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */
// CALL_C =0x00004000, /* Proc uses C calling convention */
// CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */
PROC_NEAR =0x00010000, /* Proc exits with near return */
PROC_FAR =0x00020000, /* Proc exits with far return */
GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph */
SI_REGVAR =0x00200000, /* SI is used as a stack variable */
DI_REGVAR =0x00400000, /* DI is used as a stack variable */
//PROC_IS_FUNC=0x00800000, /* Proc is a function - determined by return type */
REG_ARGS =0x01000000, /* Proc has registers as arguments */
// PROC_VARARG =0x02000000, /* Proc has variable arguments */
PROC_OUTPUT =0x04000000, /* C for this proc has been output */
@@ -146,7 +143,15 @@ public:
}
void push_back(BB *v) { m_listBB.push_back(v);}
};
struct Function : public llvm::ilist_node<Function>
typedef std::shared_ptr<struct Function> PtrFunction;
enum DecompilationStep : uint32_t {
eNotDecoded, // no processing done yet
eDisassemblyInProgress,
eDissassembled, // low level disassembly done
//eStackTracing, // tracing stack depth across function calls
};
struct Function : public std::enable_shared_from_this<Function>
{
typedef llvm::iplist<BB> BasicBlockListType;
// BasicBlock iterators...
@@ -154,7 +159,7 @@ struct Function : public llvm::ilist_node<Function>
typedef BasicBlockListType::const_iterator const_iterator;
protected:
BasicBlockListType BasicBlocks; ///< The basic blocks
Function(FunctionType *ty) : procEntry(0),depth(0),flg(0),cbParam(0),m_dfsLast(0),numBBs(0),
Function(FunctionType *ty) : nStep(eNotDecoded),procEntry(0),depth(0),flg(0),cbParam(0),m_dfsLast(0),numBBs(0),
hasCase(false),liveAnal(0)
{
type = ty;
@@ -164,16 +169,16 @@ protected:
}
public:
int nStep; // decompilation step number for this function
DecompilationStep nStep; // decompilation step number for this function
FunctionType * type;
uint32_t procEntry; /* label number */
QString name; /* Meaningful name for this proc */
STATE state; /* Entry state */
int depth; /* Depth at which we found it - for printing */
uint32_t flg; /* Combination of Icode & Proc flags */
int16_t cbParam; /* Probable no. of bytes of parameters */
STKFRAME args; /* Array of arguments */
LOCAL_ID localId; /* Local identifiers */
int depth; /* Depth at which we found it - for printing */
uint32_t flg; /* Combination of Icode & Proc flags */
int16_t cbParam; /* Probable no. of bytes of parameters */
STKFRAME args; /* Array of arguments */
LOCAL_ID localId; /* Local identifiers */
/* Icodes and control flow graph */
CIcodeRec Icode; /* Object with ICODE records */
@@ -193,9 +198,9 @@ public:
delete type;
}
public:
static Function *Create(FunctionType *ty=0,int /*Linkage*/=0,const QString &nm="",void */*module*/=0)
static PtrFunction Create(FunctionType *ty=0,int /*Linkage*/=0,const QString &nm="",void */*module*/=0)
{
Function *r=new Function(ty);
PtrFunction r(new Function(ty));
r->name = nm;
return r;
}
@@ -237,6 +242,7 @@ public:
void controlFlowAnalysis();
void newRegArg(iICODE picode, iICODE ticode);
void writeProcComments(QTextStream & ostr);
void toStructuredText(IStructuredTextTarget *out,int level);
void displayCFG();
void displayStats();
@@ -277,31 +283,13 @@ protected:
void genLiveKtes();
bool findDerivedSeq(derSeq &derivedGi);
bool nextOrderGraph(derSeq &derivedGi);
void addOutEdgesForConditionalJump(BB* pBB, int next_ip, LLInst *ll);
void addOutEdgesForConditionalJump(BB* pBB, int next_ip, LLInst *ll);
private:
bool decodeIndirectJMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
bool decodeIndirectJMP2(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
};
namespace llvm {
template<> struct ilist_traits<typename ::Function>
: public ilist_default_traits<typename ::Function> {
// createSentinel is used to get hold of the node that marks the end of the
// list... (same trick used here as in ilist_traits<Instruction>)
typename ::Function *createSentinel() const {
return static_cast<typename ::Function*>(&Sentinel);
}
static void destroySentinel(typename ::Function*) {}
typename ::Function *provideInitialHead() const { return createSentinel(); }
typename ::Function *ensureHead(::Function*) const { return createSentinel(); }
static void noteHead(typename ::Function*, typename ::Function*) {}
private:
mutable ilist_node<typename ::Function> Sentinel;
};
}
typedef llvm::iplist<Function> FunctionListType;
typedef std::list<PtrFunction> FunctionListType;
typedef FunctionListType lFunction;
typedef lFunction::iterator ilFunction;

View File

@@ -10,11 +10,11 @@ struct STKFRAME : public SymbolTableCommon<STKSYM>
//std::vector<STKSYM> sym;
//STKSYM * sym; /* Symbols */
int16_t m_minOff; /* Initial offset in stack frame*/
int16_t maxOff; /* Maximum offset in stack frame*/
int16_t m_maxOff; /* Maximum offset in stack frame*/
int cb; /* Number of bytes in arguments */
int numArgs; /* No. of arguments in the table*/
void adjustForArgType(size_t numArg_, hlType actType_);
STKFRAME() : m_minOff(0),maxOff(0),cb(0),numArgs(0)
STKFRAME() : m_minOff(0),m_maxOff(0),cb(0),numArgs(0)
{
}

View File

@@ -84,7 +84,7 @@ void parse (CALL_GRAPH * *); /* parser.c */
extern int strSize (const uint8_t *, char); /* parser.c */
//void disassem(int pass, Function * pProc); /* disassem.c */
void interactDis(Function *, int initIC); /* disassem.c */
void interactDis(const PtrFunction &, int initIC); /* disassem.c */
bool JmpInst(llIcode opcode); /* idioms.c */
queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */

View File

@@ -11,10 +11,7 @@ struct IDcc {
static IDcc *get();
virtual void BaseInit()=0;
virtual void Init(QObject *tgt)=0;
virtual ilFunction GetFirstFuncHandle()=0;
virtual ilFunction GetNextFuncHandle(ilFunction iter)=0;
virtual ilFunction GetCurFuncHandle()=0;
virtual bool isValidFuncHandle(ilFunction) = 0;
virtual PtrFunction GetCurFuncHandle()=0;
virtual void analysis_Once()=0;
virtual bool load(QString name)=0; // load and preprocess -> find entry point
virtual void prtout_asm(IStructuredTextTarget *,int level=0)=0;

View File

@@ -7,12 +7,16 @@
#pragma once
#include "bundle.h"
#include <memory>
#include <fstream>
#include <vector>
#include <QString>
#include <QTextStream>
struct LLInst;
struct Function;
typedef std::shared_ptr<Function> PtrFunction;
struct Disassembler
{
protected:
@@ -30,8 +34,8 @@ public:
g_lab=0;
}
public:
void disassem(Function *ppProc);
void disassem(Function *ppProc, int i);
void disassem(PtrFunction ppProc);
void disassem(PtrFunction ppProc, int i);
void dis1Line(LLInst &inst, int loc_ip, int pass);
};
/* Definitions for extended keys (first key is zero) */

View File

@@ -13,6 +13,7 @@
#include <QtCore/QString>
#include <list>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <stdint.h>
#include <assert.h>
@@ -60,6 +61,8 @@ struct LoaderMetadata {
return QString("b%1%2").arg(compiler_version).arg(codeModelChar());
case ePascal:
return QString("tp%1").arg(compiler_version);
default:
return "xxx";
}
case eMicrosoft:
assert(compiler_language==eAnsiCorCPP);
@@ -67,6 +70,8 @@ struct LoaderMetadata {
case eLogitech:
assert(compiler_language==eModula2);
return QString("l%1%2").arg(compiler_version).arg(codeModelChar());
case eUnknownVendor:
return "xxx";
}
return "xxx";
}
@@ -85,11 +90,6 @@ class Project : public QObject
{
Q_OBJECT
public:
typedef llvm::iplist<Function> FunctionListType;
typedef FunctionListType lFunction;
typedef FunctionListType::iterator ilFunction;
public:
DosLoader * m_selected_loader;
bool m_metadata_available=false;
LoaderMetadata m_loader_data;
@@ -101,6 +101,8 @@ public:
PROG prog; /* Loaded program image parameters */
CommandStream m_project_command_stream;
std::unordered_map<PtrFunction,CommandStream> m_function_streams;
bool m_error_state;
struct PatternLocator *m_pattern_locator;
public:
@@ -121,9 +123,10 @@ public:
const QString & project_name() const {return m_project_name;}
const QString & binary_path() const {return m_fname;}
QString output_name(const char *ext);
ilFunction funcIter(Function *to_find);
ilFunction findByEntry(uint32_t entry);
ilFunction createFunction(FunctionType *f, const QString & name, SegOffAddr addr);
ilFunction funcIter(Function *to_find);
PtrFunction findByEntry(uint32_t entry);
PtrFunction findByName(const QString &name);
PtrFunction createFunction(FunctionType *f, const QString & name, SegOffAddr addr);
bool valid(ilFunction iter);
int getSymIdxByAdd(uint32_t adr);
@@ -142,14 +145,15 @@ public:
const FunctionListType &functions() const { return pProcList; }
FunctionListType &functions() { return pProcList; }
bool addCommand(Command *cmd) { return m_project_command_stream.add(cmd); emit commandListChanged(); }
bool addCommand(Command *cmd);
bool addCommand(PtrFunction f, Command *cmd); // Add function level command
void dumpAllErrors();
void setLoader(DosLoader *ins);
void processCommands(int count=1);
public slots:
void onCommandStreamFinished(bool state);
signals:
void newFunctionCreated(Function &);
void newFunctionCreated(PtrFunction);
void loaderSelected();
void commandListChanged();
protected:

View File

@@ -49,6 +49,7 @@ struct STKSYM : public SymbolCommon
bool hasMacro=false; /* This type needs a macro */
QString macro; /* Macro name */
bool invalid=false; /* Boolean: invalid entry in formal arg list*/
int arrayMembers=1; // for local variables if >1 marks this stack symbol as an array
void setArgName(int i)
{
char buf[32];