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/parser.cpp
src/perfhlib.cpp src/perfhlib.cpp
src/procs.cpp src/procs.cpp
src/project.cpp
src/proplong.cpp src/proplong.cpp
src/reducible.cpp src/reducible.cpp
src/scanner.cpp src/scanner.cpp
@ -87,6 +88,7 @@ set(dcc_HEADERS
include/idioms/xor_idioms.h include/idioms/xor_idioms.h
include/locident.h include/locident.h
include/perfhlib.h include/perfhlib.h
include/project.h
include/scanner.h include/scanner.h
include/state.h include/state.h
include/symtab.h include/symtab.h

View File

@ -20,7 +20,7 @@
#include "bundle.h" #include "bundle.h"
#include "Procedure.h" #include "Procedure.h"
#include "BasicBlock.h" #include "BasicBlock.h"
struct Project;
/* CALL GRAPH NODE */ /* CALL GRAPH NODE */
struct CALL_GRAPH struct CALL_GRAPH
{ {
@ -60,7 +60,6 @@ typedef struct { /* Command line option flags */
} OPTION; } OPTION;
extern OPTION option; /* Command line options */ extern OPTION option; /* Command line options */
extern SYMTAB symtab; /* Global symbol table */
struct PROG /* Loaded program image parameters */ struct PROG /* Loaded program image parameters */
{ {
@ -111,8 +110,17 @@ extern STATS stats; /* Icode statistics */
/**** Global function prototypes ****/ /**** Global function prototypes ****/
class DccFrontend
void FrontEnd(char *filename, CALL_GRAPH * *); /* frontend.c */ {
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 udm(void); /* udm.c */
void freeCFG(BB * cfg); /* graph.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 "types.h"
#include "dcc.h" #include "dcc.h"
#include "machine_x86.h" #include "machine_x86.h"
#include "project.h"
extern Project g_proj;
using namespace std; using namespace std;
// Conditional operator symbols in C. Index by condOp enumeration type // Conditional operator symbols in C. Index by condOp enumeration type
static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ", static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
@ -116,15 +118,12 @@ COND_EXPR *GlobalVariable::Create(int16_t segValue, int16_t off)
{ {
COND_EXPR *newExp; COND_EXPR *newExp;
uint32_t adr; uint32_t adr;
size_t i;
newExp = new COND_EXPR(IDENTIFIER); newExp = new COND_EXPR(IDENTIFIER);
newExp->expr.ident.idType = GLOB_VAR; newExp->expr.ident.idType = GLOB_VAR;
adr = opAdr(segValue, off); adr = opAdr(segValue, off);
for (i = 0; i < symtab.size(); i++) auto i=g_proj.getSymIdxByAdd(adr);
if (symtab[i].label == adr) if ( not g_proj.validSymIdx(i) )
break;
if (i == symtab.size())
{ {
printf ("Error, glob var not found in symtab\n"); printf ("Error, glob var not found in symtab\n");
delete newExp; delete newExp;
@ -478,7 +477,7 @@ int hlTypeSize (const COND_EXPR *expr, Function * pproc)
switch (expr->expr.ident.idType) switch (expr->expr.ident.idType)
{ {
case GLOB_VAR: case GLOB_VAR:
return (symtab[expr->expr.ident.idNode.globIdx].size); return (g_proj.symbolSize(expr->expr.ident.idNode.globIdx));
case REGISTER: case REGISTER:
if (expr->expr.ident.regiType == BYTE_REG) if (expr->expr.ident.regiType == BYTE_REG)
return (1); return (1);
@ -541,7 +540,7 @@ hlType expType (const COND_EXPR *expr, Function * pproc)
switch (expr->expr.ident.idType) switch (expr->expr.ident.idType)
{ {
case GLOB_VAR: case GLOB_VAR:
return (symtab[expr->expr.ident.idNode.globIdx].type); return g_proj.symbolType(expr->expr.ident.idNode.globIdx);
case REGISTER: case REGISTER:
if (expr->expr.ident.regiType == BYTE_REG) if (expr->expr.ident.regiType == BYTE_REG)
return (TYPE_BYTE_SIGN); return (TYPE_BYTE_SIGN);
@ -700,7 +699,7 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
switch (expr->expr.ident.idType) switch (expr->expr.ident.idType)
{ {
case GLOB_VAR: case GLOB_VAR:
o << symtab[expr->expr.ident.idNode.globIdx].name; o << g_proj.symtab[expr->expr.ident.idNode.globIdx].name;
break; break;
case REGISTER: case REGISTER:
id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx]; id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx];

View File

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

View File

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

View File

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

View File

@ -7,7 +7,8 @@
#include <string.h> #include <string.h>
#include <malloc.h> /* For free() */ #include <malloc.h> /* For free() */
#include "graph.h" #include "graph.h"
#include "project.h"
extern Project g_proj;
//static BB * rmJMP(Function * pProc, int marker, BB * pBB); //static BB * rmJMP(Function * pProc, int marker, BB * pBB);
static void mergeFallThrough(Function * pProc, BB * pBB); static void mergeFallThrough(Function * pProc, BB * pBB);
static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, int *first, int *last); 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)) if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF))
continue; continue;
assert(icod.ll()->caseTbl.numEntries<symtab.size()); //assert that case tbl has less entries then symbol table ????
psym = &symtab[icod.ll()->caseTbl.numEntries]; //WARNING: Case entries are held in symbol table !
for (int c = (int)psym->label; c < (int)psym->label+psym->size; c++) 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)) 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); rhs = COND_EXPR::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
lhs = COND_EXPR::id (*pIcode->ll(), DST, this, i, *pIcode, NONE); lhs = COND_EXPR::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
} }
switch (ll->getOpcode()) switch (ll->getOpcode())
{ {
case iADD: case iADD:

View File

@ -10,11 +10,12 @@
#include <algorithm> #include <algorithm>
#include "dcc.h" #include "dcc.h"
#include "project.h"
using namespace std; using namespace std;
extern Project g_proj;
//static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate); //static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate);
static boolT process_JMP (ICODE * pIcode, STATE * pstate, CALL_GRAPH * pcallGraph); static boolT process_JMP (ICODE * pIcode, STATE * pstate, CALL_GRAPH * pcallGraph);
static void setBits(int16_t type, uint32_t start, uint32_t len); 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 void process_MOV(LLInst &ll, STATE * pstate);
static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag); static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag);
void interactDis(Function * initProc, int ic); 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 /* Parses the program, builds the call graph, and returns the list of
* procedures found */ * procedures found */
void parse (CALL_GRAPH * *pcallGraph) void DccFrontend::parse(Project &proj)
{ {
STATE state; STATE state;
@ -45,11 +46,12 @@ void parse (CALL_GRAPH * *pcallGraph)
SynthLab = SYNTHESIZED_MIN; SynthLab = SYNTHESIZED_MIN;
// default-construct a Function object ! // 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 /* Check for special settings of initial state, based on idioms of the
startup code */ startup code */
state.checkStartup(); state.checkStartup();
Function &start_proc(pProcList.front()); Function &start_proc(proj.pProcList.front());
/* Make a struct for the initial procedure */ /* Make a struct for the initial procedure */
if (prog.offMain != -1) if (prog.offMain != -1)
{ {
@ -71,37 +73,20 @@ void parse (CALL_GRAPH * *pcallGraph)
start_proc.state = state; start_proc.state = state;
/* Set up call graph initial node */ /* Set up call graph initial node */
*pcallGraph = new CALL_GRAPH; proj.callGraph = new CALL_GRAPH;
(*pcallGraph)->proc = pProcList.begin(); proj.callGraph->proc = proj.pProcList.begin();
/* This proc needs to be called to set things up for LibCheck(), which /* 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 */ checks a proc to see if it is a know C (etc) library */
SetupLibCheck(); SetupLibCheck();
//ERROR: proj and g_proj are 'live' at this point !
/* Recursively build entire procedure list */ /* 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() */ /* This proc needs to be called to clean things up from SetupLibCheck() */
CleanupLibCheck(); 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. /* Returns the size of the string pointed by sym and delimited by delim.
* Size includes delimiter. */ * Size includes delimiter. */
int strSize (uint8_t *sym, char delim) int strSize (uint8_t *sym, char delim)
@ -123,7 +108,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
uint32_t offset; uint32_t offset;
eErrorId err; eErrorId err;
boolT done = false; boolT done = false;
SYMTAB &global_symbol_table(g_proj.symtab);
if (name.find("chkstk") != string::npos) if (name.find("chkstk") != string::npos)
{ {
// Danger! Dcc will likely fall over in this code. // Danger! Dcc will likely fall over in this code.
@ -332,7 +317,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
size = prog.fCOM ? size = prog.fCOM ?
strSize (&prog.Image[operand], '$') : strSize (&prog.Image[operand], '$') :
strSize (&prog.Image[operand], '$'); // + 0x100 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])) 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)) if (pIcode.ll()->testFlags(I))
{ {
/* Search procedure list for one with appropriate entry point */ /* Search procedure list for one with appropriate entry point */
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(), ilFunction iter = g_proj.findByEntry(pIcode.ll()->src.op());
[pIcode](const Function &f) ->
bool { return f.procEntry==pIcode.ll()->src.op(); });
/* Create a new procedure node and save copy of the state */ /* 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()); iter = g_proj.createFunction();
Function &x(pProcList.back()); Function &x(*iter);
iter = (++pProcList.rbegin()).base();
x.procEntry = pIcode.ll()->src.op(); x.procEntry = pIcode.ll()->src.op();
LibCheck(x); 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 */ /* A library function. No need to do any more to it */
pcallGraph->insertCallGraph (this, iter); pcallGraph->insertCallGraph (this, iter);
iter = (++pProcList.rbegin()).base(); //iter = (++pProcList.rbegin()).base();
last_insn.ll()->src.proc.proc = &x; last_insn.ll()->src.proc.proc = &x;
return false; return false;
} }
@ -647,7 +629,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
} }
else else
pcallGraph->insertCallGraph (this, iter); g_proj.callGraph->insertCallGraph (this, iter);
last_insn.ll()->src.proc.proc = &(*iter); // ^ target proc 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 */ if (pm->segValue) /* there is a value in the seg field */
{ {
operand = opAdr (pm->segValue, pm->off); 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 */ else if (pstate->f[pm->seg]) /* new value */
{ {
pm->segValue = pstate->r[pm->seg]; pm->segValue = pstate->r[pm->seg];
operand = opAdr(pm->segValue, pm->off); 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 */ /* Flag new memory locations that are segment values */
if (created_new) 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; LLOperand * pm = (d == SRC)? &pIcode.ll()->src: &pIcode.ll()->dst;
SYM * psym; 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 */ 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); setBits (BM_DATA, psym->label, (uint32_t)size);
pIcode.ll()->setFlags(SYM_USE); 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); setBits(BM_DATA, psym->label, (uint32_t)size);
pIcode.ll()->setFlags(SYM_DEF); 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 <cstring>
#include <cassert> #include <cassert>
#include "dcc.h" #include "dcc.h"
#include "project.h"
extern Project g_proj;
/* Static indentation buffer */ /* Static indentation buffer */
static constexpr int indSize=81; /* size of indentation buffer; max 20 */ static constexpr int indSize=81; /* size of indentation buffer; max 20 */
static char indentBuf[indSize] = static char indentBuf[indSize] =
@ -60,10 +61,7 @@ bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee) bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
{ {
auto iter = std::find_if(pProcList.begin(),pProcList.end(), return insertCallGraph(g_proj.funcIter(caller),callee);
[caller](const Function &f)->bool {return caller==&f;});
assert(iter!=pProcList.end());
return insertCallGraph(iter,callee);
} }
@ -99,7 +97,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
COND_EXPR *lhs; COND_EXPR *lhs;
STKFRAME * call_args_stackframe, *target_stackframe; STKFRAME * call_args_stackframe, *target_stackframe;
ID *id; ID *id;
int i, tidx; int tidx;
boolT regExist; boolT regExist;
condId type; condId type;
Function * tproc; 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 <stdio.h>
#include "dcc.h" #include "dcc.h"
#include "disassem.h" #include "disassem.h"
#include "project.h"
extern Project g_proj;
static void displayCFG(Function * pProc); static void displayCFG(Function * pProc);
static void displayDfs(BB * pBB); static void displayDfs(BB * pBB);
@ -71,7 +73,7 @@ void udm(void)
/* Build the control flow graph, find idioms, and convert low-level /* Build the control flow graph, find idioms, and convert low-level
* icodes to high-level ones */ * icodes to high-level ones */
Disassembler ds(2); 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); iter->buildCFG(ds);
} }
@ -81,10 +83,10 @@ void udm(void)
* and intermediate instructions. Find expressions by forward * and intermediate instructions. Find expressions by forward
* substitution algorithm */ * substitution algorithm */
std::bitset<32> live_regs; std::bitset<32> live_regs;
pProcList.front().dataFlow (live_regs); g_proj.pProcList.front().dataFlow (live_regs);
/* Control flow analysis - structuring algorithm */ /* 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(); iter->controlFlowAnalysis();
} }