Added global 'Project' class, and DccFrontend

This commit is contained in:
Artur K 2012-03-13 09:04:32 +01:00
parent 902a5ec3d8
commit c2e5ac2694
13 changed files with 233 additions and 106 deletions

View File

@ -58,6 +58,7 @@ set(dcc_SOURCES
src/parser.cpp
src/perfhlib.cpp
src/procs.cpp
src/project.cpp
src/proplong.cpp
src/reducible.cpp
src/scanner.cpp
@ -87,6 +88,7 @@ set(dcc_HEADERS
include/idioms/xor_idioms.h
include/locident.h
include/perfhlib.h
include/project.h
include/scanner.h
include/state.h
include/symtab.h

View File

@ -20,7 +20,7 @@
#include "bundle.h"
#include "Procedure.h"
#include "BasicBlock.h"
struct Project;
/* CALL GRAPH NODE */
struct CALL_GRAPH
{
@ -60,7 +60,6 @@ typedef struct { /* Command line option flags */
} OPTION;
extern OPTION option; /* Command line options */
extern SYMTAB symtab; /* Global symbol table */
struct PROG /* Loaded program image parameters */
{
@ -111,8 +110,17 @@ extern STATS stats; /* Icode statistics */
/**** Global function prototypes ****/
void FrontEnd(char *filename, CALL_GRAPH * *); /* frontend.c */
class DccFrontend
{
void LoadImage(Project &proj);
void parse(Project &proj);
std::string m_fname;
public:
DccFrontend(const std::string &fname) : m_fname(fname)
{
}
bool FrontEnd(); /* frontend.c */
};
void udm(void); /* udm.c */
void freeCFG(BB * cfg); /* graph.c */

71
include/project.h Normal file
View File

@ -0,0 +1,71 @@
#pragma once
#include <string>
#include <stdint.h>
#include <cassert>
#include <list>
#include <llvm/ADT/ilist.h>
#include "symtab.h"
struct Function;
struct CALL_GRAPH;
typedef llvm::iplist<Function> FunctionListType;
typedef FunctionListType lFunction;
typedef lFunction::iterator ilFunction;
struct Project
{
SYMTAB symtab; /* Global symbol table */
std::string m_fname;
FunctionListType pProcList;
CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
Project() {}
// no copies
Project(const Project&) = delete;
const Project &operator=(const Project & l) =delete;
// only moves
Project(Project && l)
{
m_fname =l.m_fname;
size_t before=l.pProcList.size();
pProcList.splice(pProcList.end(),l.pProcList);
callGraph=l.callGraph;
l.m_fname.clear();
l.pProcList.clear();
l.callGraph=0;
assert(before==pProcList.size());
}
Project &operator=(Project && l)
{
if(this == &l)
return *this;
m_fname =l.m_fname;
size_t before=l.pProcList.size();
pProcList.splice(pProcList.end(),l.pProcList);
callGraph=l.callGraph;
l.m_fname.clear();
l.pProcList.clear();
l.callGraph=0;
assert(before==pProcList.size());
return *this;
}
static Project *get();
public:
ilFunction funcIter(Function *to_find);
ilFunction findByEntry(uint32_t entry);
ilFunction createFunction();
bool valid(ilFunction iter);
int getSymIdxByAdd(uint32_t adr);
bool validSymIdx(size_t idx);
size_t symbolSize(size_t idx);
hlType symbolType(size_t idx);
const std::string &symbolName(size_t idx);
const SYM &getSymByIdx(size_t idx) const;
protected:
void writeGlobSymTable();
};
//extern Project g_proj;

View File

@ -12,6 +12,8 @@
#include "types.h"
#include "dcc.h"
#include "machine_x86.h"
#include "project.h"
extern Project g_proj;
using namespace std;
// Conditional operator symbols in C. Index by condOp enumeration type
static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
@ -116,15 +118,12 @@ COND_EXPR *GlobalVariable::Create(int16_t segValue, int16_t off)
{
COND_EXPR *newExp;
uint32_t adr;
size_t i;
newExp = new COND_EXPR(IDENTIFIER);
newExp->expr.ident.idType = GLOB_VAR;
adr = opAdr(segValue, off);
for (i = 0; i < symtab.size(); i++)
if (symtab[i].label == adr)
break;
if (i == symtab.size())
auto i=g_proj.getSymIdxByAdd(adr);
if ( not g_proj.validSymIdx(i) )
{
printf ("Error, glob var not found in symtab\n");
delete newExp;
@ -478,7 +477,7 @@ int hlTypeSize (const COND_EXPR *expr, Function * pproc)
switch (expr->expr.ident.idType)
{
case GLOB_VAR:
return (symtab[expr->expr.ident.idNode.globIdx].size);
return (g_proj.symbolSize(expr->expr.ident.idNode.globIdx));
case REGISTER:
if (expr->expr.ident.regiType == BYTE_REG)
return (1);
@ -541,7 +540,7 @@ hlType expType (const COND_EXPR *expr, Function * pproc)
switch (expr->expr.ident.idType)
{
case GLOB_VAR:
return (symtab[expr->expr.ident.idNode.globIdx].type);
return g_proj.symbolType(expr->expr.ident.idNode.globIdx);
case REGISTER:
if (expr->expr.ident.regiType == BYTE_REG)
return (TYPE_BYTE_SIGN);
@ -700,7 +699,7 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
switch (expr->expr.ident.idType)
{
case GLOB_VAR:
o << symtab[expr->expr.ident.idNode.globIdx].name;
o << g_proj.symtab[expr->expr.ident.idNode.globIdx].name;
break;
case REGISTER:
id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx];

View File

@ -14,7 +14,7 @@
#include <sstream>
#include <string.h>
#include <stdio.h>
#include "project.h"
bundle cCode; /* Procedure declaration and code */
using namespace std;
@ -94,13 +94,6 @@ char *cChar (uint8_t c)
* Note: to get to the value of the variable:
* com file: prog.Image[operand]
* exe file: prog.Image[operand+0x100] */
static void printGlobVar (std::ostream &ostr,SYM * psym);
static void printGlobVar (SYM * psym)
{
std::ostringstream ostr;
printGlobVar(ostr,psym);
cCode.appendDecl(ostr.str());
}
static void printGlobVar (std::ostream &ostr,SYM * psym)
{
int j;
@ -135,7 +128,7 @@ static void printGlobVar (std::ostream &ostr,SYM * psym)
// Note: Not called at present.
/* Writes the contents of the symbol table, along with any variable
* initialization. */
static void writeGlobSymTable()
void Project::writeGlobSymTable()
{
std::ostringstream ostr;
@ -228,10 +221,9 @@ void Function::codeGen (std::ostream &fs)
ostr<<", ";
}
ostr<<")\n";
cCode.appendDecl( ostr.str() );
/* Write comments */
writeProcComments();
writeProcComments( ostr );
/* Write local variables */
if (! (flg & PROC_ASM))
@ -249,7 +241,7 @@ void Function::codeGen (std::ostream &fs)
((flg & DI_REGVAR) && (refId.id.regi == rDI)))
{
refId.setLocalName(++numLoc);
cCode.appendDecl( "int %s;\n", refId.name.c_str());
ostr << "int "<<refId.name<<";\n";
}
/* Other registers are named when they are first used in
* the output C code, and appended to the proc decl. */
@ -258,10 +250,11 @@ void Function::codeGen (std::ostream &fs)
{
/* Name local variables and output appropriate type */
refId.setLocalName(++numLoc);
cCode.appendDecl( "%s %s;\n",hlTypes[refId.type], refId.name.c_str());
ostr << TypeContainer::typeName(refId.type)<<" "<<refId.name<<";\n";
}
}
}
cCode.appendDecl(ostr.str());
/* Write procedure's code */
if (flg & PROC_ASM) /* generate assembler */
{

View File

@ -5,6 +5,7 @@
****************************************************************************/
#include "dcc.h"
#include "project.h"
#include <string.h>
/* Global variables - extern to other modules */
@ -15,8 +16,8 @@ PROG prog; /* programs fields */
OPTION option; /* Command line options */
//Function * pProcList; /* List of procedures, topologically sort */
//Function * pLastProc; /* Pointer to last node in procedure list */
FunctionListType pProcList;
CALL_GRAPH *callGraph; /* Call graph of the program */
//FunctionListType pProcList;
//CALL_GRAPH *callGraph; /* Call graph of the program */
static char *initargs(int argc, char *argv[]);
static void displayTotalStats(void);
@ -26,7 +27,7 @@ static void displayTotalStats(void);
* main
***************************************************************************/
#include <iostream>
extern Project g_proj;
int main(int argc, char *argv[])
{
// llvm::MCOperand op=llvm::MCOperand::CreateImm(11);
@ -41,7 +42,9 @@ int main(int argc, char *argv[])
* building the call graph and attaching appropriate bits of code for
* each procedure.
*/
FrontEnd (option.filename, &callGraph);
DccFrontend fe(option.filename);
if(false==fe.FrontEnd ())
return -1;
/* In the middle is a so called Universal Decompiling Machine.
* It processes the procedure list and I-code and attaches where it can
@ -53,9 +56,9 @@ int main(int argc, char *argv[])
* analysis, data flow etc. and outputs it to output file ready for
* re-compilation.
*/
BackEnd(option.filename, callGraph);
BackEnd(option.filename, g_proj.callGraph);
callGraph->write();
g_proj.callGraph->write();
if (option.Stats)
displayTotalStats();

View File

@ -10,7 +10,7 @@
#include <stdlib.h>
#include <string.h>
#include <malloc.h> /* For malloc, free, realloc */
#include "project.h"
typedef struct { /* PSP structure */
uint16_t int20h; /* interrupt 20h */
uint16_t eof; /* segment, end of allocation block */
@ -58,17 +58,22 @@ static void displayMemMap(void);
* FrontEnd - invokes the loader, parser, disassembler (if asm1), icode
* rewritter, and displays any useful information.
****************************************************************************/
void FrontEnd (char *filename, CALL_GRAPH * *pcallGraph)
extern Project g_proj;
bool DccFrontend::FrontEnd ()
{
g_proj.callGraph = 0;
g_proj.m_fname = m_fname;
/* Load program into memory */
LoadImage(filename);
LoadImage(g_proj);
if (option.verbose)
displayLoadInfo();
/* Do depth first flow analysis building call graph and procedure list,
* and attaching the I-code to each procedure */
parse (pcallGraph);
parse (g_proj);
if (option.asm1)
{
@ -77,7 +82,7 @@ void FrontEnd (char *filename, CALL_GRAPH * *pcallGraph)
/* Search through code looking for impure references and flag them */
Disassembler ds(1);
for(Function &f : pProcList)
for(Function &f : g_proj.pProcList)
{
f.markImpure();
if (option.asm1)
@ -87,17 +92,18 @@ void FrontEnd (char *filename, CALL_GRAPH * *pcallGraph)
}
if (option.Interact)
{
interactDis(&pProcList.front(), 0); /* Interactive disassembler */
interactDis(&g_proj.pProcList.front(), 0); /* Interactive disassembler */
}
/* Converts jump target addresses to icode offsets */
for(Function &f : pProcList)
for(Function &f : g_proj.pProcList)
{
f.bindIcodeOff();
}
/* Print memory bitmap */
if (option.Map)
displayMemMap();
return(true); // we no longer own proj !
}
@ -191,22 +197,22 @@ static void displayMemMap(void)
/*****************************************************************************
* LoadImage
****************************************************************************/
static void LoadImage(char *filename)
void DccFrontend::LoadImage(Project &proj)
{
FILE *fp;
int i, cb;
uint8_t buf[4];
/* Open the input file */
if ((fp = fopen(filename, "rb")) == NULL)
if ((fp = fopen(proj.m_fname.c_str(), "rb")) == NULL)
{
fatalError(CANNOT_OPEN, filename);
fatalError(CANNOT_OPEN, proj.m_fname.c_str());
}
/* Read in first 2 bytes to check EXE signature */
if (fread(&header, 1, 2, fp) != 2)
{
fatalError(CANNOT_READ, filename);
fatalError(CANNOT_READ, proj.m_fname.c_str());
}
if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) {
@ -214,7 +220,7 @@ static void LoadImage(char *filename)
fseek(fp, 0, SEEK_SET);
if (fread(&header, sizeof(header), 1, fp) != 1)
{
fatalError(CANNOT_READ, filename);
fatalError(CANNOT_READ, proj.m_fname.c_str());
}
/* This is a typical DOS kludge! */
@ -292,16 +298,9 @@ static void LoadImage(char *filename)
prog.Image[1] = 0x20; /* for termination checking */
/* Read in the image past where a PSP would go */
#ifdef __DOSWIN__
if (cb > 0xFFFF)
{
printf("Image size of %ld bytes too large for fread!\n", cb);
fatalError(CANNOT_READ, filename);
}
#endif
if (cb != (int)fread(prog.Image + sizeof(PSP), 1, (size_t)cb, fp))
{
fatalError(CANNOT_READ, filename);
fatalError(CANNOT_READ, proj.m_fname.c_str());
}
/* Set up memory map */

View File

@ -7,7 +7,8 @@
#include <string.h>
#include <malloc.h> /* For free() */
#include "graph.h"
#include "project.h"
extern Project g_proj;
//static BB * rmJMP(Function * pProc, int marker, BB * pBB);
static void mergeFallThrough(Function * pProc, BB * pBB);
static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, int *first, int *last);
@ -165,9 +166,11 @@ void Function::markImpure()
{
if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF))
continue;
assert(icod.ll()->caseTbl.numEntries<symtab.size());
psym = &symtab[icod.ll()->caseTbl.numEntries];
for (int c = (int)psym->label; c < (int)psym->label+psym->size; c++)
//assert that case tbl has less entries then symbol table ????
//WARNING: Case entries are held in symbol table !
assert(g_proj.validSymIdx(icod.ll()->caseTbl.numEntries));
const SYM &psym(g_proj.getSymByIdx(icod.ll()->caseTbl.numEntries));
for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++)
{
if (BITMAP(c, BM_CODE))
{

View File

@ -304,7 +304,6 @@ void Function::highLevelGen()
rhs = COND_EXPR::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
lhs = COND_EXPR::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
}
switch (ll->getOpcode())
{
case iADD:

View File

@ -10,11 +10,12 @@
#include <algorithm>
#include "dcc.h"
#include "project.h"
using namespace std;
extern Project g_proj;
//static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate);
static boolT process_JMP (ICODE * pIcode, STATE * pstate, CALL_GRAPH * pcallGraph);
static void setBits(int16_t type, uint32_t start, uint32_t len);
//static SYM * updateGlobSym(uint32_t operand, int size, uint16_t duFlag,bool &created);
static void process_MOV(LLInst &ll, STATE * pstate);
static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag);
void interactDis(Function * initProc, int ic);
@ -31,7 +32,7 @@ static uint32_t SynthLab;
/* Parses the program, builds the call graph, and returns the list of
* procedures found */
void parse (CALL_GRAPH * *pcallGraph)
void DccFrontend::parse(Project &proj)
{
STATE state;
@ -45,11 +46,12 @@ void parse (CALL_GRAPH * *pcallGraph)
SynthLab = SYNTHESIZED_MIN;
// default-construct a Function object !
pProcList.push_back(Function::Create());
auto func = proj.createFunction();
/* Check for special settings of initial state, based on idioms of the
startup code */
state.checkStartup();
Function &start_proc(pProcList.front());
Function &start_proc(proj.pProcList.front());
/* Make a struct for the initial procedure */
if (prog.offMain != -1)
{
@ -71,37 +73,20 @@ void parse (CALL_GRAPH * *pcallGraph)
start_proc.state = state;
/* Set up call graph initial node */
*pcallGraph = new CALL_GRAPH;
(*pcallGraph)->proc = pProcList.begin();
proj.callGraph = new CALL_GRAPH;
proj.callGraph->proc = proj.pProcList.begin();
/* This proc needs to be called to set things up for LibCheck(), which
checks a proc to see if it is a know C (etc) library */
SetupLibCheck();
//ERROR: proj and g_proj are 'live' at this point !
/* Recursively build entire procedure list */
pProcList.front().FollowCtrl (*pcallGraph, &state);
proj.pProcList.front().FollowCtrl (proj.callGraph, &state);
/* This proc needs to be called to clean things up from SetupLibCheck() */
CleanupLibCheck();
}
/* Updates the type of the symbol in the symbol table. The size is updated
* if necessary (0 means no update necessary). */
static void updateSymType (uint32_t symbol, hlType symType, int size)
{ int i;
for (i = 0; i < symtab.size(); i++)
if (symtab[i].label == symbol)
{
symtab[i].type = symType;
if (size != 0)
symtab[i].size = size;
break;
}
}
/* Returns the size of the string pointed by sym and delimited by delim.
* Size includes delimiter. */
int strSize (uint8_t *sym, char delim)
@ -123,7 +108,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
uint32_t offset;
eErrorId err;
boolT done = false;
SYMTAB &global_symbol_table(g_proj.symtab);
if (name.find("chkstk") != string::npos)
{
// Danger! Dcc will likely fall over in this code.
@ -332,7 +317,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
size = prog.fCOM ?
strSize (&prog.Image[operand], '$') :
strSize (&prog.Image[operand], '$'); // + 0x100
updateSymType (operand, TYPE_STR, size);
global_symbol_table.updateSymType (operand, TypeContainer(TYPE_STR, size));
}
}
else if ((ll->src.op() == 0x2F) && (pstate->f[rAH]))
@ -591,16 +576,13 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
if (pIcode.ll()->testFlags(I))
{
/* Search procedure list for one with appropriate entry point */
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
[pIcode](const Function &f) ->
bool { return f.procEntry==pIcode.ll()->src.op(); });
ilFunction iter = g_proj.findByEntry(pIcode.ll()->src.op());
/* Create a new procedure node and save copy of the state */
if (iter==pProcList.end())
if ( not g_proj.valid(iter) )
{
pProcList.push_back(Function::Create());
Function &x(pProcList.back());
iter = (++pProcList.rbegin()).base();
iter = g_proj.createFunction();
Function &x(*iter);
x.procEntry = pIcode.ll()->src.op();
LibCheck(x);
@ -608,7 +590,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
{
/* A library function. No need to do any more to it */
pcallGraph->insertCallGraph (this, iter);
iter = (++pProcList.rbegin()).base();
//iter = (++pProcList.rbegin()).base();
last_insn.ll()->src.proc.proc = &x;
return false;
}
@ -647,7 +629,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
}
else
pcallGraph->insertCallGraph (this, iter);
g_proj.callGraph->insertCallGraph (this, iter);
last_insn.ll()->src.proc.proc = &(*iter); // ^ target proc
@ -780,13 +762,13 @@ static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag
if (pm->segValue) /* there is a value in the seg field */
{
operand = opAdr (pm->segValue, pm->off);
psym = symtab.updateGlobSym (operand, size, duFlag,created_new);
psym = g_proj.symtab.updateGlobSym (operand, size, duFlag,created_new);
}
else if (pstate->f[pm->seg]) /* new value */
{
pm->segValue = pstate->r[pm->seg];
operand = opAdr(pm->segValue, pm->off);
psym = symtab.updateGlobSym (operand, size, duFlag,created_new);
psym = g_proj.symtab.updateGlobSym (operand, size, duFlag,created_new);
/* Flag new memory locations that are segment values */
if (created_new)
@ -888,7 +870,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
LLOperand * pm = (d == SRC)? &pIcode.ll()->src: &pIcode.ll()->dst;
SYM * psym;
if (pm->regi == 0 || pm->regi >= INDEX_BX_SI)
if ( Machine_X86::isMemOff(pm->regi) )
{
if (pm->regi == INDEX_BP) /* indexed on bp */
{
@ -916,7 +898,8 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
{
setBits (BM_DATA, psym->label, (uint32_t)size);
pIcode.ll()->setFlags(SYM_USE);
pIcode.ll()->caseTbl.numEntries = psym - &symtab[0];
pIcode.ll()->caseTbl.numEntries = distance(&g_proj.symtab[0],psym);
}
}
@ -965,7 +948,7 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
{
setBits(BM_DATA, psym->label, (uint32_t)size);
pIcode.ll()->setFlags(SYM_DEF);
pIcode.ll()->caseTbl.numEntries = distance(&symtab[0],psym);
pIcode.ll()->caseTbl.numEntries = distance(&g_proj.symtab[0],psym);
}
}

View File

@ -8,8 +8,9 @@
#include <cstring>
#include <cassert>
#include "dcc.h"
#include "project.h"
extern Project g_proj;
/* Static indentation buffer */
static constexpr int indSize=81; /* size of indentation buffer; max 20 */
static char indentBuf[indSize] =
@ -60,10 +61,7 @@ bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
{
auto iter = std::find_if(pProcList.begin(),pProcList.end(),
[caller](const Function &f)->bool {return caller==&f;});
assert(iter!=pProcList.end());
return insertCallGraph(iter,callee);
return insertCallGraph(g_proj.funcIter(caller),callee);
}
@ -99,7 +97,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
COND_EXPR *lhs;
STKFRAME * call_args_stackframe, *target_stackframe;
ID *id;
int i, tidx;
int tidx;
boolT regExist;
condId type;
Function * tproc;

67
src/project.cpp Normal file
View File

@ -0,0 +1,67 @@
#include <utility>
#include "project.h"
#include "Procedure.h"
Project g_proj;
bool Project::valid(ilFunction iter)
{
return iter!=pProcList.end();
}
ilFunction Project::funcIter(Function *to_find)
{
auto iter=std::find_if(pProcList.begin(),pProcList.end(),
[to_find](const Function &f)->bool {return to_find==&f;});
assert(iter!=pProcList.end());
return iter;
}
ilFunction Project::findByEntry(uint32_t entry)
{
/* Search procedure list for one with appropriate entry point */
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
[entry](const Function &f) ->
bool { return f.procEntry==entry; });
return iter;
}
ilFunction Project::createFunction()
{
pProcList.push_back(Function::Create());
return (++pProcList.rbegin()).base();
}
int Project::getSymIdxByAdd(uint32_t adr)
{
size_t i;
for (i = 0; i < symtab.size(); i++)
if (symtab[i].label == adr)
break;
return i;
}
bool Project::validSymIdx(size_t idx)
{
return idx<symtab.size();
}
const SYM &Project::getSymByIdx(size_t idx) const
{
return symtab[idx];
}
size_t Project::symbolSize(size_t idx)
{
assert(validSymIdx(idx));
return symtab[idx].size;
}
hlType Project::symbolType(size_t idx)
{
assert(validSymIdx(idx));
return symtab[idx].type;
}
const std::string &Project::symbolName(size_t idx)
{
assert(validSymIdx(idx));
return symtab[idx].name;
}
Project *get()
{
return &g_proj;
}

View File

@ -9,7 +9,9 @@
#include <stdio.h>
#include "dcc.h"
#include "disassem.h"
#include "project.h"
extern Project g_proj;
static void displayCFG(Function * pProc);
static void displayDfs(BB * pBB);
@ -71,7 +73,7 @@ void udm(void)
/* Build the control flow graph, find idioms, and convert low-level
* icodes to high-level ones */
Disassembler ds(2);
for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter)
for (auto iter = g_proj.pProcList.rbegin(); iter!=g_proj.pProcList.rend(); ++iter)
{
iter->buildCFG(ds);
}
@ -81,10 +83,10 @@ void udm(void)
* and intermediate instructions. Find expressions by forward
* substitution algorithm */
std::bitset<32> live_regs;
pProcList.front().dataFlow (live_regs);
g_proj.pProcList.front().dataFlow (live_regs);
/* Control flow analysis - structuring algorithm */
for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter)
for (auto iter = g_proj.pProcList.rbegin(); iter!=g_proj.pProcList.rend(); ++iter)
{
iter->controlFlowAnalysis();
}