Browse Source

Added global 'Project' class, and DccFrontend

Artur K 12 years ago
parent
commit
c2e5ac2694
13 changed files with 233 additions and 106 deletions
  1. 2 0
      CMakeLists.txt
  2. 12 4
      include/dcc.h
  3. 71 0
      include/project.h
  4. 7 8
      src/ast.cpp
  5. 6 13
      src/backend.cpp
  6. 9 6
      src/dcc.cpp
  7. 19 20
      src/frontend.cpp
  8. 7 4
      src/graph.cpp
  9. 0 1
      src/hlicode.cpp
  10. 24 41
      src/parser.cpp
  11. 4 6
      src/procs.cpp
  12. 67 0
      src/project.cpp
  13. 5 3
      src/udm.cpp

+ 2 - 0
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

+ 12 - 4
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      */

+ 71 - 0
include/project.h

@@ -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;

+ 7 - 8
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];

+ 6 - 13
src/backend.cpp

@@ -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 */
     {

+ 9 - 6
src/dcc.cpp

@@ -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();

+ 19 - 20
src/frontend.cpp

@@ -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 */

+ 7 - 4
src/graph.cpp

@@ -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))
             {

+ 0 - 1
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:

+ 24 - 41
src/parser.cpp

@@ -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);
         }
     }
 

+ 4 - 6
src/procs.cpp

@@ -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 - 0
src/project.cpp

@@ -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;
+}

+ 5 - 3
src/udm.cpp

@@ -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();
     }