From c2e5ac2694a95ef2f40e4fedbdcc19b47ff1ace5 Mon Sep 17 00:00:00 2001 From: Artur K Date: Tue, 13 Mar 2012 09:04:32 +0100 Subject: [PATCH] Added global 'Project' class, and DccFrontend --- CMakeLists.txt | 2 ++ include/dcc.h | 16 ++++++++--- include/project.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++ src/ast.cpp | 15 +++++----- src/backend.cpp | 19 ++++--------- src/dcc.cpp | 15 ++++++---- src/frontend.cpp | 39 +++++++++++++------------- src/graph.cpp | 11 +++++--- src/hlicode.cpp | 1 - src/parser.cpp | 65 ++++++++++++++++--------------------------- src/procs.cpp | 10 +++---- src/project.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++ src/udm.cpp | 8 ++++-- 13 files changed, 233 insertions(+), 106 deletions(-) create mode 100644 include/project.h create mode 100644 src/project.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c70470d..63e274f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/include/dcc.h b/include/dcc.h index da3ace2..49e2ec4 100644 --- a/include/dcc.h +++ b/include/dcc.h @@ -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 */ diff --git a/include/project.h b/include/project.h new file mode 100644 index 0000000..b6f626e --- /dev/null +++ b/include/project.h @@ -0,0 +1,71 @@ +#pragma once +#include +#include +#include +#include +#include +#include "symtab.h" +struct Function; +struct CALL_GRAPH; + +typedef llvm::iplist 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; diff --git a/src/ast.cpp b/src/ast.cpp index de234ac..e46d517 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -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]; diff --git a/src/backend.cpp b/src/backend.cpp index af61aa1..302c7d6 100644 --- a/src/backend.cpp +++ b/src/backend.cpp @@ -14,7 +14,7 @@ #include #include #include - +#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 "< /* 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 - +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(); diff --git a/src/frontend.cpp b/src/frontend.cpp index a39c49b..0c5e4ee 100644 --- a/src/frontend.cpp +++ b/src/frontend.cpp @@ -10,7 +10,7 @@ #include #include #include /* 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 */ diff --git a/src/graph.cpp b/src/graph.cpp index d4a1247..5b05db9 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -7,7 +7,8 @@ #include #include /* 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 &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.numEntriescaseTbl.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)) { diff --git a/src/hlicode.cpp b/src/hlicode.cpp index eea08b5..8c23d32 100644 --- a/src/hlicode.cpp +++ b/src/hlicode.cpp @@ -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: diff --git a/src/parser.cpp b/src/parser.cpp index b229fcf..4cfbbda 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -10,11 +10,12 @@ #include #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); } } diff --git a/src/procs.cpp b/src/procs.cpp index b2a40ec..bc3e6ae 100644 --- a/src/procs.cpp +++ b/src/procs.cpp @@ -8,8 +8,9 @@ #include #include #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; diff --git a/src/project.cpp b/src/project.cpp new file mode 100644 index 0000000..789bbb9 --- /dev/null +++ b/src/project.cpp @@ -0,0 +1,67 @@ +#include +#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 #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(); }