Added global 'Project' class, and DccFrontend
This commit is contained in:
parent
902a5ec3d8
commit
c2e5ac2694
@ -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
|
||||
|
||||
@ -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
71
include/project.h
Normal 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;
|
||||
15
src/ast.cpp
15
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];
|
||||
|
||||
@ -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 */
|
||||
{
|
||||
|
||||
15
src/dcc.cpp
15
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();
|
||||
|
||||
@ -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,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))
|
||||
{
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
67
src/project.cpp
Normal 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;
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user