Pre-qt5
This commit is contained in:
parent
1c5e1c2fce
commit
50950028e0
@ -73,6 +73,7 @@ set(dcc_LIB_SOURCES
|
|||||||
src/symtab.cpp
|
src/symtab.cpp
|
||||||
src/udm.cpp
|
src/udm.cpp
|
||||||
src/BasicBlock.cpp
|
src/BasicBlock.cpp
|
||||||
|
src/CallConvention.cpp
|
||||||
)
|
)
|
||||||
set(dcc_SOURCES
|
set(dcc_SOURCES
|
||||||
src/dcc.cpp
|
src/dcc.cpp
|
||||||
@ -108,6 +109,8 @@ set(dcc_HEADERS
|
|||||||
include/Procedure.h
|
include/Procedure.h
|
||||||
include/StackFrame.h
|
include/StackFrame.h
|
||||||
include/BasicBlock.h
|
include/BasicBlock.h
|
||||||
|
include/CallConvention.h
|
||||||
|
|
||||||
)
|
)
|
||||||
SOURCE_GROUP(Source FILES ${dcc_SOURCES})
|
SOURCE_GROUP(Source FILES ${dcc_SOURCES})
|
||||||
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
||||||
@ -117,7 +120,7 @@ ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
|
|||||||
|
|
||||||
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
||||||
ADD_DEPENDENCIES(dcc_original dcc_lib)
|
ADD_DEPENDENCIES(dcc_original dcc_lib)
|
||||||
TARGET_LINK_LIBRARIES(dcc_original dcc_lib disasm_s ${REQ_LLVM_LIBRARIES} ncurses)
|
TARGET_LINK_LIBRARIES(dcc_original LLVMSupport dcc_lib disasm_s ${REQ_LLVM_LIBRARIES} LLVMSupport)
|
||||||
if(dcc_build_tests)
|
if(dcc_build_tests)
|
||||||
ADD_SUBDIRECTORY(src)
|
ADD_SUBDIRECTORY(src)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -37,7 +37,7 @@ private:
|
|||||||
inEdges(0),
|
inEdges(0),
|
||||||
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
|
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
|
||||||
inInterval(0),correspInt(0),
|
inInterval(0),correspInt(0),
|
||||||
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0),
|
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(NO_TYPE),latchNode(0),
|
||||||
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
|
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ public:
|
|||||||
int dfsLastNum; /* DFS #: last visit of node */
|
int dfsLastNum; /* DFS #: last visit of node */
|
||||||
int immedDom; /* Immediate dominator (dfsLast index) */
|
int immedDom; /* Immediate dominator (dfsLast index) */
|
||||||
int ifFollow; /* node that ends the if */
|
int ifFollow; /* node that ends the if */
|
||||||
int loopType; /* Type of loop (if any) */
|
eNodeHeaderType loopType; /* Type of loop (if any) */
|
||||||
int latchNode; /* latching node of the loop */
|
int latchNode; /* latching node of the loop */
|
||||||
size_t numBackEdges; /* # of back edges */
|
size_t numBackEdges; /* # of back edges */
|
||||||
int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
|
int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
|
||||||
@ -101,7 +101,7 @@ public:
|
|||||||
int index; /* Index, used in several ways */
|
int index; /* Index, used in several ways */
|
||||||
static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
|
static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
|
||||||
static BB * CreateIntervalBB(Function *parent);
|
static BB * CreateIntervalBB(Function *parent);
|
||||||
static BB * Create(const rCODE &r, uint8_t _nodeType, Function *parent);
|
static BB * Create(const rCODE &r, eBBKind _nodeType, Function *parent);
|
||||||
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
|
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
|
||||||
void mergeFallThrough(CIcodeRec &Icode);
|
void mergeFallThrough(CIcodeRec &Icode);
|
||||||
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
|
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
|
||||||
|
|||||||
@ -17,5 +17,6 @@ struct PROG /* Loaded program image parameters */
|
|||||||
int cbImage; /* Length of image in bytes */
|
int cbImage; /* Length of image in bytes */
|
||||||
const uint8_t *image() const {return Imagez;}
|
const uint8_t *image() const {return Imagez;}
|
||||||
uint8_t * Imagez; /* Allocated by loader to hold entire program image */
|
uint8_t * Imagez; /* Allocated by loader to hold entire program image */
|
||||||
|
int addressingMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
31
include/CallConvention.h
Normal file
31
include/CallConvention.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ast.h"
|
||||||
|
|
||||||
|
struct CConv {
|
||||||
|
enum Type {
|
||||||
|
UNKNOWN=0,
|
||||||
|
C,
|
||||||
|
PASCAL
|
||||||
|
};
|
||||||
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
|
||||||
|
virtual void writeComments(std::ostream &)=0;
|
||||||
|
static CConv * create(Type v);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct C_CallingConvention : public CConv {
|
||||||
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
||||||
|
virtual void writeComments(std::ostream &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int processCArg(Function *callee, Function *pProc, ICODE *picode, size_t numArgs);
|
||||||
|
};
|
||||||
|
struct Pascal_CallingConvention : public CConv {
|
||||||
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
||||||
|
virtual void writeComments(std::ostream &);
|
||||||
|
};
|
||||||
|
struct Unknown_CallingConvention : public CConv {
|
||||||
|
void processHLI(Function *func, Expr *_exp, iICODE picode) {}
|
||||||
|
virtual void writeComments(std::ostream &);
|
||||||
|
};
|
||||||
@ -1,12 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <llvm/ADT/ilist.h>
|
#include <llvm/ADT/ilist.h>
|
||||||
#include <llvm/ADT/ilist_node.h>
|
//#include <llvm/ADT/ilist_node.h>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
#include <map>
|
||||||
#include "BasicBlock.h"
|
#include "BasicBlock.h"
|
||||||
#include "locident.h"
|
#include "locident.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
#include "StackFrame.h"
|
#include "StackFrame.h"
|
||||||
|
#include "CallConvention.h"
|
||||||
/* PROCEDURE NODE */
|
/* PROCEDURE NODE */
|
||||||
struct CALL_GRAPH;
|
struct CALL_GRAPH;
|
||||||
struct Expr;
|
struct Expr;
|
||||||
@ -15,9 +17,7 @@ struct Function;
|
|||||||
struct CALL_GRAPH;
|
struct CALL_GRAPH;
|
||||||
struct PROG;
|
struct PROG;
|
||||||
|
|
||||||
typedef llvm::iplist<Function> FunctionListType;
|
struct Function;
|
||||||
typedef FunctionListType lFunction;
|
|
||||||
typedef lFunction::iterator ilFunction;
|
|
||||||
|
|
||||||
namespace llvm
|
namespace llvm
|
||||||
{
|
{
|
||||||
@ -49,9 +49,9 @@ enum PROC_FLAGS
|
|||||||
PROC_IJMP =0x00000200,/* Proc incomplete due to indirect jmp */
|
PROC_IJMP =0x00000200,/* Proc incomplete due to indirect jmp */
|
||||||
PROC_ICALL =0x00000400, /* Proc incomplete due to indirect call */
|
PROC_ICALL =0x00000400, /* Proc incomplete due to indirect call */
|
||||||
PROC_HLL =0x00001000, /* Proc is likely to be from a HLL */
|
PROC_HLL =0x00001000, /* Proc is likely to be from a HLL */
|
||||||
CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */
|
// CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */
|
||||||
CALL_C =0x00004000, /* Proc uses C calling convention */
|
// CALL_C =0x00004000, /* Proc uses C calling convention */
|
||||||
CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */
|
// CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */
|
||||||
PROC_NEAR =0x00010000, /* Proc exits with near return */
|
PROC_NEAR =0x00010000, /* Proc exits with near return */
|
||||||
PROC_FAR =0x00020000, /* Proc exits with far return */
|
PROC_FAR =0x00020000, /* Proc exits with far return */
|
||||||
GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph */
|
GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph */
|
||||||
@ -59,18 +59,18 @@ enum PROC_FLAGS
|
|||||||
DI_REGVAR =0x00400000, /* DI is used as a stack variable */
|
DI_REGVAR =0x00400000, /* DI is used as a stack variable */
|
||||||
PROC_IS_FUNC=0x00800000, /* Proc is a function */
|
PROC_IS_FUNC=0x00800000, /* Proc is a function */
|
||||||
REG_ARGS =0x01000000, /* Proc has registers as arguments */
|
REG_ARGS =0x01000000, /* Proc has registers as arguments */
|
||||||
PROC_VARARG =0x02000000, /* Proc has variable arguments */
|
// PROC_VARARG =0x02000000, /* Proc has variable arguments */
|
||||||
PROC_OUTPUT =0x04000000, /* C for this proc has been output */
|
PROC_OUTPUT =0x04000000, /* C for this proc has been output */
|
||||||
PROC_RUNTIME=0x08000000, /* Proc is part of the runtime support */
|
PROC_RUNTIME=0x08000000, /* Proc is part of the runtime support */
|
||||||
PROC_ISLIB =0x10000000, /* Proc is a library function */
|
PROC_ISLIB =0x10000000, /* Proc is a library function */
|
||||||
PROC_ASM =0x20000000, /* Proc is an intrinsic assembler routine */
|
PROC_ASM =0x20000000, /* Proc is an intrinsic assembler routine */
|
||||||
PROC_IS_HLL =0x40000000 /* Proc has HLL prolog code */
|
PROC_IS_HLL =0x40000000 /* Proc has HLL prolog code */
|
||||||
#define CALL_MASK 0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL */
|
//#define CALL_MASK 0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionType
|
struct FunctionType
|
||||||
{
|
{
|
||||||
bool m_vararg;
|
bool m_vararg=false;
|
||||||
bool isVarArg() const {return m_vararg;}
|
bool isVarArg() const {return m_vararg;}
|
||||||
};
|
};
|
||||||
struct Assignment
|
struct Assignment
|
||||||
@ -113,16 +113,24 @@ struct Function : public llvm::ilist_node<Function>
|
|||||||
// BasicBlock iterators...
|
// BasicBlock iterators...
|
||||||
typedef BasicBlockListType::iterator iterator;
|
typedef BasicBlockListType::iterator iterator;
|
||||||
typedef BasicBlockListType::const_iterator const_iterator;
|
typedef BasicBlockListType::const_iterator const_iterator;
|
||||||
private:
|
protected:
|
||||||
BasicBlockListType BasicBlocks; ///< The basic blocks
|
BasicBlockListType BasicBlocks; ///< The basic blocks
|
||||||
|
Function(FunctionType */*ty*/) : procEntry(0),depth(0),flg(0),cbParam(0),m_dfsLast(0),numBBs(0),
|
||||||
|
hasCase(false),liveAnal(0)
|
||||||
|
{
|
||||||
|
type = new FunctionType;
|
||||||
|
callingConv(CConv::UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
FunctionType * type;
|
||||||
|
CConv * m_call_conv;
|
||||||
uint32_t procEntry; /* label number */
|
uint32_t procEntry; /* label number */
|
||||||
std::string name; /* Meaningful name for this proc */
|
std::string name; /* Meaningful name for this proc */
|
||||||
STATE state; /* Entry state */
|
STATE state; /* Entry state */
|
||||||
int depth; /* Depth at which we found it - for printing */
|
int depth; /* Depth at which we found it - for printing */
|
||||||
uint32_t flg; /* Combination of Icode & Proc flags */
|
uint32_t flg; /* Combination of Icode & Proc flags */
|
||||||
int16_t cbParam; /* Probable no. of bytes of parameters */
|
int16_t cbParam; /* Probable no. of bytes of parameters */
|
||||||
STKFRAME args; /* Array of arguments */
|
STKFRAME args; /* Array of arguments */
|
||||||
LOCAL_ID localId; /* Local identifiers */
|
LOCAL_ID localId; /* Local identifiers */
|
||||||
ID retVal; /* Return value - identifier */
|
ID retVal; /* Return value - identifier */
|
||||||
@ -130,10 +138,8 @@ public:
|
|||||||
/* Icodes and control flow graph */
|
/* Icodes and control flow graph */
|
||||||
CIcodeRec Icode; /* Object with ICODE records */
|
CIcodeRec Icode; /* Object with ICODE records */
|
||||||
FunctionCfg m_actual_cfg;
|
FunctionCfg m_actual_cfg;
|
||||||
std::list<BB*> m_cfg; /* Ptr. to BB list/CFG */
|
|
||||||
std::vector<BB*> m_dfsLast;
|
std::vector<BB*> m_dfsLast;
|
||||||
std::list<BB*> heldBBs;
|
std::map<int,BB*> m_ip_to_bb;
|
||||||
//BB * *dfsLast; /* Array of pointers to BBs in dfsLast
|
|
||||||
// * (reverse postorder) order */
|
// * (reverse postorder) order */
|
||||||
size_t numBBs; /* Number of BBs in the graph cfg */
|
size_t numBBs; /* Number of BBs in the graph cfg */
|
||||||
bool hasCase; /* Procedure has a case node */
|
bool hasCase; /* Procedure has a case node */
|
||||||
@ -143,18 +149,23 @@ public:
|
|||||||
LivenessSet liveOut; /* Registers that may be used in successors */
|
LivenessSet liveOut; /* Registers that may be used in successors */
|
||||||
bool liveAnal; /* Procedure has been analysed already */
|
bool liveAnal; /* Procedure has been analysed already */
|
||||||
|
|
||||||
Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
|
virtual ~Function() {
|
||||||
hasCase(false),liveAnal(0)//,next(0),prev(0)
|
delete type;
|
||||||
{
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static Function *Create(void *ty=0,int /*Linkage*/=0,const std::string &nm="",void */*module*/=0)
|
static Function *Create(FunctionType *ty=0,int /*Linkage*/=0,const std::string &nm="",void */*module*/=0)
|
||||||
{
|
{
|
||||||
Function *r=new Function(ty);
|
Function *r=new Function(ty);
|
||||||
r->name = nm;
|
r->name = nm;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;}
|
FunctionType *getFunctionType() const {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
CConv *callingConv() const { return m_call_conv;}
|
||||||
|
void callingConv(CConv::Type v);
|
||||||
|
|
||||||
|
// bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;}
|
||||||
bool hasRegArgs() const { return (flg & REG_ARGS)!=0;}
|
bool hasRegArgs() const { return (flg & REG_ARGS)!=0;}
|
||||||
bool isLibrary() const { return (flg & PROC_ISLIB)!=0;}
|
bool isLibrary() const { return (flg & PROC_ISLIB)!=0;}
|
||||||
void compoundCond();
|
void compoundCond();
|
||||||
@ -172,7 +183,7 @@ public:
|
|||||||
void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
|
void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
void process_operands(ICODE &pIcode, STATE *pstate);
|
void process_operands(ICODE &pIcode, STATE *pstate);
|
||||||
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
||||||
boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
void freeCFG();
|
void freeCFG();
|
||||||
void codeGen(std::ostream &fs);
|
void codeGen(std::ostream &fs);
|
||||||
void mergeFallThrough(BB *pBB);
|
void mergeFallThrough(BB *pBB);
|
||||||
@ -191,6 +202,8 @@ public:
|
|||||||
Expr * adjustActArgType(Expr *_exp, hlType forType);
|
Expr * adjustActArgType(Expr *_exp, hlType forType);
|
||||||
std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc);
|
std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc);
|
||||||
void processDosInt(STATE *pstate, PROG &prog, bool done);
|
void processDosInt(STATE *pstate, PROG &prog, bool done);
|
||||||
|
ICODE *translate_DIV(LLInst *ll, ICODE &_Icode);
|
||||||
|
ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode);
|
||||||
protected:
|
protected:
|
||||||
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
|
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
|
||||||
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
@ -218,6 +231,28 @@ protected:
|
|||||||
void findIdioms();
|
void findIdioms();
|
||||||
void propLong();
|
void propLong();
|
||||||
void genLiveKtes();
|
void genLiveKtes();
|
||||||
uint8_t findDerivedSeq (derSeq &derivedGi);
|
bool findDerivedSeq(derSeq &derivedGi);
|
||||||
bool nextOrderGraph(derSeq &derivedGi);
|
bool nextOrderGraph(derSeq &derivedGi);
|
||||||
};
|
};
|
||||||
|
namespace llvm {
|
||||||
|
template<> struct ilist_traits<typename ::Function>
|
||||||
|
: public ilist_default_traits<typename ::Function> {
|
||||||
|
|
||||||
|
// createSentinel is used to get hold of the node that marks the end of the
|
||||||
|
// list... (same trick used here as in ilist_traits<Instruction>)
|
||||||
|
typename ::Function *createSentinel() const {
|
||||||
|
return static_cast<typename ::Function*>(&Sentinel);
|
||||||
|
}
|
||||||
|
static void destroySentinel(typename ::Function*) {}
|
||||||
|
|
||||||
|
typename ::Function *provideInitialHead() const { return createSentinel(); }
|
||||||
|
typename ::Function *ensureHead(::Function*) const { return createSentinel(); }
|
||||||
|
static void noteHead(typename ::Function*, typename ::Function*) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable ilist_node<typename ::Function> Sentinel;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
typedef llvm::iplist<Function> FunctionListType;
|
||||||
|
typedef FunctionListType lFunction;
|
||||||
|
typedef lFunction::iterator ilFunction;
|
||||||
|
|||||||
@ -51,7 +51,8 @@ public:
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual ~Expr();
|
/** Recursively deallocates the abstract syntax tree rooted at *exp */
|
||||||
|
virtual ~Expr() {}
|
||||||
public:
|
public:
|
||||||
virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
|
virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
|
||||||
virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
|
virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
|
||||||
@ -122,6 +123,7 @@ struct BinaryOperator : public Expr
|
|||||||
assert(m_lhs!=m_rhs || m_lhs==nullptr);
|
assert(m_lhs!=m_rhs || m_lhs==nullptr);
|
||||||
delete m_lhs;
|
delete m_lhs;
|
||||||
delete m_rhs;
|
delete m_rhs;
|
||||||
|
m_lhs=m_rhs=nullptr;
|
||||||
}
|
}
|
||||||
static BinaryOperator *Create(condOp o,Expr *l,Expr *r)
|
static BinaryOperator *Create(condOp o,Expr *l,Expr *r)
|
||||||
{
|
{
|
||||||
@ -132,21 +134,28 @@ struct BinaryOperator : public Expr
|
|||||||
}
|
}
|
||||||
static BinaryOperator *LogicAnd(Expr *l,Expr *r)
|
static BinaryOperator *LogicAnd(Expr *l,Expr *r)
|
||||||
{
|
{
|
||||||
return new BinaryOperator(DBL_AND,l,r);
|
return Create(DBL_AND,l,r);
|
||||||
|
}
|
||||||
|
static BinaryOperator *createSHL(Expr *l,Expr *r)
|
||||||
|
{
|
||||||
|
return Create(SHL,l,r);
|
||||||
}
|
}
|
||||||
static BinaryOperator *And(Expr *l,Expr *r)
|
static BinaryOperator *And(Expr *l,Expr *r)
|
||||||
{
|
{
|
||||||
return new BinaryOperator(AND,l,r);
|
return Create(AND,l,r);
|
||||||
}
|
}
|
||||||
static BinaryOperator *Or(Expr *l,Expr *r)
|
static BinaryOperator *Or(Expr *l,Expr *r)
|
||||||
{
|
{
|
||||||
return new BinaryOperator(OR,l,r);
|
return Create(OR,l,r);
|
||||||
}
|
}
|
||||||
static BinaryOperator *LogicOr(Expr *l,Expr *r)
|
static BinaryOperator *LogicOr(Expr *l,Expr *r)
|
||||||
{
|
{
|
||||||
return new BinaryOperator(DBL_OR,l,r);
|
return Create(DBL_OR,l,r);
|
||||||
|
}
|
||||||
|
static BinaryOperator *CreateAdd(Expr *l,Expr *r) {
|
||||||
|
return Create(ADD,l,r);
|
||||||
|
|
||||||
}
|
}
|
||||||
static BinaryOperator *CreateAdd(Expr *l,Expr *r);
|
|
||||||
void changeBoolOp(condOp newOp);
|
void changeBoolOp(condOp newOp);
|
||||||
virtual Expr *inverse() const;
|
virtual Expr *inverse() const;
|
||||||
virtual Expr *clone() const;
|
virtual Expr *clone() const;
|
||||||
@ -281,20 +290,22 @@ struct FuncNode : public AstIdent
|
|||||||
};
|
};
|
||||||
struct RegisterNode : public AstIdent
|
struct RegisterNode : public AstIdent
|
||||||
{
|
{
|
||||||
|
const LOCAL_ID *m_syms;
|
||||||
regType regiType; /* for REGISTER only */
|
regType regiType; /* for REGISTER only */
|
||||||
int regiIdx; /* index into localId, REGISTER */
|
int regiIdx; /* index into localId, REGISTER */
|
||||||
|
|
||||||
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
|
|
||||||
RegisterNode(int idx, regType reg_type)
|
RegisterNode(int idx, regType reg_type,const LOCAL_ID *syms)
|
||||||
{
|
{
|
||||||
|
m_syms= syms;
|
||||||
ident.type(REGISTER);
|
ident.type(REGISTER);
|
||||||
regiType = reg_type;
|
regiType = reg_type;
|
||||||
regiIdx = idx;
|
regiIdx = idx;
|
||||||
}
|
}
|
||||||
RegisterNode(const LLOperand &, LOCAL_ID *locsym);
|
RegisterNode(const LLOperand &, LOCAL_ID *locsym);
|
||||||
|
|
||||||
RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
|
//RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
|
||||||
virtual Expr *clone() const
|
virtual Expr *clone() const
|
||||||
{
|
{
|
||||||
return new RegisterNode(*this);
|
return new RegisterNode(*this);
|
||||||
|
|||||||
@ -101,8 +101,6 @@ void SetupLibCheck(void); /* chklib.c */
|
|||||||
void CleanupLibCheck(void); /* chklib.c */
|
void CleanupLibCheck(void); /* chklib.c */
|
||||||
bool LibCheck(Function &p); /* chklib.c */
|
bool LibCheck(Function &p); /* chklib.c */
|
||||||
|
|
||||||
/* Exported functions from procs.c */
|
|
||||||
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
|
|
||||||
|
|
||||||
/* Exported functions from hlicode.c */
|
/* Exported functions from hlicode.c */
|
||||||
const char *writeJcond(const HLTYPE &, Function *, int *);
|
const char *writeJcond(const HLTYPE &, Function *, int *);
|
||||||
|
|||||||
@ -68,32 +68,24 @@ typedef std::list<BB *> queue;
|
|||||||
|
|
||||||
struct interval
|
struct interval
|
||||||
{
|
{
|
||||||
uint8_t numInt; /* # of the interval */
|
uint8_t numInt=0; /* # of the interval */
|
||||||
uint8_t numOutEdges; /* Number of out edges */
|
uint8_t numOutEdges=0; /* Number of out edges */
|
||||||
queue nodes; /* Nodes of the interval*/
|
queue nodes; /* Nodes of the interval*/
|
||||||
queue::iterator currNode; /* Current node */
|
queue::iterator currNode; /* Current node */
|
||||||
interval *next; /* Next interval */
|
interval * next=0; /* Next interval */
|
||||||
BB *firstOfInt();
|
BB * firstOfInt();
|
||||||
interval()
|
interval() : currNode(nodes.end()){
|
||||||
{
|
}
|
||||||
numInt=numOutEdges=0;
|
void appendNodeInt(queue &pqH, BB *node);
|
||||||
currNode=nodes.end();
|
|
||||||
next=0;
|
|
||||||
}
|
|
||||||
void appendNodeInt(queue &pqH, BB *node);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Derived Sequence structure */
|
/* Derived Sequence structure */
|
||||||
struct derSeq_Entry
|
struct derSeq_Entry
|
||||||
{
|
{
|
||||||
BB * Gi; /* Graph pointer */
|
BB * Gi=nullptr; /* Graph pointer */
|
||||||
std::list<interval *> m_intervals;
|
std::list<interval *> m_intervals;
|
||||||
interval * Ii; /* Interval list of Gi */
|
interval * Ii=nullptr; /* Interval list of Gi */
|
||||||
derSeq_Entry() : Gi(0),Ii(0)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
~derSeq_Entry();
|
~derSeq_Entry();
|
||||||
public:
|
public:
|
||||||
void findIntervals(Function *c);
|
void findIntervals(Function *c);
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "libdis.h"
|
#include "libdis.h"
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
||||||
|
#include "CallConvention.h"
|
||||||
|
|
||||||
//enum condId;
|
//enum condId;
|
||||||
|
|
||||||
@ -307,7 +308,7 @@ struct LLOperand
|
|||||||
{
|
{
|
||||||
return not (*this == LLOperand());
|
return not (*this == LLOperand());
|
||||||
}
|
}
|
||||||
void addProcInformation(int param_count,uint32_t call_conv);
|
void addProcInformation(int param_count, CConv::Type call_conv);
|
||||||
bool isImmediate() const { return immed;}
|
bool isImmediate() const { return immed;}
|
||||||
void setImmediate(bool x) { immed=x;}
|
void setImmediate(bool x) { immed=x;}
|
||||||
bool compound() const {return is_compound;} // dx:ax pair
|
bool compound() const {return is_compound;} // dx:ax pair
|
||||||
|
|||||||
@ -101,7 +101,7 @@ public:
|
|||||||
char macro[10]; /* Macro for this identifier */
|
char macro[10]; /* Macro for this identifier */
|
||||||
std::string name; /* Identifier's name */
|
std::string name; /* Identifier's name */
|
||||||
union ID_UNION { /* Different types of identifiers */
|
union ID_UNION { /* Different types of identifiers */
|
||||||
friend class ID;
|
friend struct ID;
|
||||||
protected:
|
protected:
|
||||||
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
|
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
|
||||||
public:
|
public:
|
||||||
@ -118,27 +118,27 @@ public:
|
|||||||
} longKte;
|
} longKte;
|
||||||
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
|
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
|
||||||
} id;
|
} id;
|
||||||
LONGID_TYPE &longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
|
LONGID_TYPE & longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
|
||||||
const LONGID_TYPE &longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
|
const LONGID_TYPE & longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
|
||||||
LONG_STKID_TYPE &longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
|
LONG_STKID_TYPE & longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
|
||||||
const LONG_STKID_TYPE &longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
|
const LONG_STKID_TYPE & longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
|
||||||
ID();
|
ID();
|
||||||
ID(hlType t, frameType f);
|
ID(hlType t, frameType f);
|
||||||
ID(hlType t, const LONGID_TYPE &s);
|
ID(hlType t, const LONGID_TYPE &s);
|
||||||
ID(hlType t, const LONG_STKID_TYPE &s);
|
ID(hlType t, const LONG_STKID_TYPE &s);
|
||||||
ID(hlType t, const LONGGLB_TYPE &s);
|
ID(hlType t, const LONGGLB_TYPE &s);
|
||||||
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
|
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
|
||||||
uint16_t typeBitsize() const
|
uint16_t typeBitsize() const
|
||||||
{
|
{
|
||||||
return TypeContainer::typeSize(type)*8;
|
return TypeContainer::typeSize(type)*8;
|
||||||
}
|
}
|
||||||
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
|
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
|
||||||
void setLocalName(int i)
|
void setLocalName(int i)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
sprintf (buf, "loc%d", i);
|
sprintf (buf, "loc%d", i);
|
||||||
name=buf;
|
name=buf;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LOCAL_ID
|
struct LOCAL_ID
|
||||||
|
|||||||
@ -46,7 +46,7 @@ public:
|
|||||||
const std::string &binary_path() const {return m_fname;}
|
const std::string &binary_path() const {return m_fname;}
|
||||||
ilFunction funcIter(Function *to_find);
|
ilFunction funcIter(Function *to_find);
|
||||||
ilFunction findByEntry(uint32_t entry);
|
ilFunction findByEntry(uint32_t entry);
|
||||||
ilFunction createFunction();
|
ilFunction createFunction(FunctionType *f,const std::string &name);
|
||||||
bool valid(ilFunction iter);
|
bool valid(ilFunction iter);
|
||||||
|
|
||||||
int getSymIdxByAdd(uint32_t adr);
|
int getSymIdxByAdd(uint32_t adr);
|
||||||
|
|||||||
@ -112,6 +112,6 @@ constexpr int NUM_TABLE_TYPES = int(Comment)+1; /* Number of entries: must be la
|
|||||||
|
|
||||||
void createSymTables(void);
|
void createSymTables(void);
|
||||||
void destroySymTables(void);
|
void destroySymTables(void);
|
||||||
boolT readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc);
|
bool readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc);
|
||||||
void selectTable(tableType); /* Select a particular table */
|
void selectTable(tableType); /* Select a particular table */
|
||||||
|
|
||||||
|
|||||||
@ -12,10 +12,6 @@
|
|||||||
#define MAX 0x7FFFFFFF
|
#define MAX 0x7FFFFFFF
|
||||||
|
|
||||||
/* Type definitions used in the program */
|
/* Type definitions used in the program */
|
||||||
typedef unsigned char byte; /* 8 bits */
|
|
||||||
typedef unsigned short word;/* 16 bits */
|
|
||||||
typedef short int16; /* 16 bits */
|
|
||||||
typedef unsigned char boolT; /* 8 bits */
|
|
||||||
|
|
||||||
#define SYNTHESIZED_MIN 0x100000 /* Synthesized labs use bits 21..32 */
|
#define SYNTHESIZED_MIN 0x100000 /* Synthesized labs use bits 21..32 */
|
||||||
|
|
||||||
@ -29,12 +25,12 @@ typedef unsigned char boolT; /* 8 bits */
|
|||||||
// Macro reads a LH word from the image regardless of host convention
|
// Macro reads a LH word from the image regardless of host convention
|
||||||
// Returns a 16 bit quantity, e.g. C000 is read into an Int as C000
|
// Returns a 16 bit quantity, e.g. C000 is read into an Int as C000
|
||||||
//#define LH(p) ((int16)((byte *)(p))[0] + ((int16)((byte *)(p))[1] << 8))
|
//#define LH(p) ((int16)((byte *)(p))[0] + ((int16)((byte *)(p))[1] << 8))
|
||||||
#define LH(p) ((word)((byte *)(p))[0] + ((word)((byte *)(p))[1] << 8))
|
#define LH(p) ((uint16_t)((uint8_t *)(p))[0] + ((uint16_t)((uint8_t *)(p))[1] << 8))
|
||||||
|
|
||||||
|
|
||||||
/* Macro reads a LH word from the image regardless of host convention */
|
/* Macro reads a LH word from the image regardless of host convention */
|
||||||
/* Returns a signed quantity, e.g. C000 is read into an Int as FFFFC000 */
|
/* Returns a signed quantity, e.g. C000 is read into an Int as FFFFC000 */
|
||||||
#define LH_SIGNED(p) (((byte *)(p))[0] + (((char *)(p))[1] << 8))
|
#define LH_SIGNED(p) (((uint8_t *)(p))[0] + (((char *)(p))[1] << 8))
|
||||||
|
|
||||||
/* Macro tests bit b for type t in prog.map */
|
/* Macro tests bit b for type t in prog.map */
|
||||||
#define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))
|
#define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))
|
||||||
|
|||||||
@ -19,7 +19,7 @@ BB *BB::Create(void */*ctx*/, const string &/*s*/, Function *parent, BB */*inser
|
|||||||
* @arg start - basic block starts here, might be parent->Icode.end()
|
* @arg start - basic block starts here, might be parent->Icode.end()
|
||||||
* @arg fin - last of basic block's instructions
|
* @arg fin - last of basic block's instructions
|
||||||
*/
|
*/
|
||||||
BB *BB::Create(const rCODE &r,uint8_t _nodeType, Function *parent)
|
BB *BB::Create(const rCODE &r,eBBKind _nodeType, Function *parent)
|
||||||
{
|
{
|
||||||
BB* pnewBB;
|
BB* pnewBB;
|
||||||
pnewBB = new BB;
|
pnewBB = new BB;
|
||||||
@ -28,14 +28,16 @@ BB *BB::Create(const rCODE &r,uint8_t _nodeType, Function *parent)
|
|||||||
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
|
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
|
||||||
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
|
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
|
||||||
pnewBB->instructions = r;
|
pnewBB->instructions = r;
|
||||||
|
int addr = pnewBB->begin()->loc_ip;
|
||||||
/* Mark the basic block to which the icodes belong to, but only for
|
/* Mark the basic block to which the icodes belong to, but only for
|
||||||
* real code basic blocks (ie. not interval bbs) */
|
* real code basic blocks (ie. not interval bbs) */
|
||||||
if(parent)
|
if(parent)
|
||||||
{
|
{
|
||||||
//setInBB should automatically handle if our range is empty
|
//setInBB should automatically handle if our range is empty
|
||||||
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
|
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
|
||||||
parent->heldBBs.push_back(pnewBB);
|
|
||||||
|
assert(parent->m_ip_to_bb.find(addr)==parent->m_ip_to_bb.end());
|
||||||
|
parent->m_ip_to_bb[addr] = pnewBB;
|
||||||
parent->m_actual_cfg.push_back(pnewBB);
|
parent->m_actual_cfg.push_back(pnewBB);
|
||||||
pnewBB->Parent = parent;
|
pnewBB->Parent = parent;
|
||||||
}
|
}
|
||||||
@ -48,7 +50,7 @@ BB *BB::Create(const rCODE &r,uint8_t _nodeType, Function *parent)
|
|||||||
BB *BB::CreateIntervalBB(Function *parent)
|
BB *BB::CreateIntervalBB(Function *parent)
|
||||||
{
|
{
|
||||||
iICODE endOfParent = parent->Icode.end();
|
iICODE endOfParent = parent->Icode.end();
|
||||||
return Create(make_iterator_range(endOfParent,endOfParent),INTERVAL_NODE,parent);
|
return Create(make_iterator_range(endOfParent,endOfParent),INTERVAL_NODE,nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
|
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
|
||||||
|
|||||||
36
src/CallConvention.cpp
Normal file
36
src/CallConvention.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include <ostream>
|
||||||
|
#include <cassert>
|
||||||
|
#include "CallConvention.h"
|
||||||
|
|
||||||
|
CConv *CConv::create(Type v)
|
||||||
|
{
|
||||||
|
static C_CallingConvention *c_call = nullptr;
|
||||||
|
static Pascal_CallingConvention *p_call = nullptr;
|
||||||
|
static Unknown_CallingConvention *u_call= nullptr;
|
||||||
|
if(!c_call)
|
||||||
|
c_call = new C_CallingConvention;
|
||||||
|
if(!p_call)
|
||||||
|
p_call = new Pascal_CallingConvention;
|
||||||
|
if(!u_call)
|
||||||
|
u_call = new Unknown_CallingConvention;
|
||||||
|
switch(v) {
|
||||||
|
case UNKNOWN: return u_call;
|
||||||
|
case C: return c_call;
|
||||||
|
case PASCAL: return p_call;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_CallingConvention::writeComments(std::ostream &ostr)
|
||||||
|
{
|
||||||
|
ostr << " * C calling convention.\n";
|
||||||
|
}
|
||||||
|
void Pascal_CallingConvention::writeComments(std::ostream &ostr)
|
||||||
|
{
|
||||||
|
ostr << " * Pascal calling convention.\n";
|
||||||
|
}
|
||||||
|
void Unknown_CallingConvention::writeComments(std::ostream &ostr)
|
||||||
|
{
|
||||||
|
ostr << " * Unknown calling convention.\n";
|
||||||
|
}
|
||||||
@ -30,3 +30,8 @@ void JumpTable::pruneEntries(uint16_t cs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Function::callingConv(CConv::Type v) {
|
||||||
|
m_call_conv=CConv::create(v);
|
||||||
|
}
|
||||||
|
|||||||
@ -16,8 +16,9 @@
|
|||||||
#include "project.h"
|
#include "project.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost::adaptors;
|
using namespace boost::adaptors;
|
||||||
RegisterNode::RegisterNode(const LLOperand &op,LOCAL_ID *locsym)
|
RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym)
|
||||||
{
|
{
|
||||||
|
m_syms = locsym;
|
||||||
ident.type(REGISTER);
|
ident.type(REGISTER);
|
||||||
hlType type_sel;
|
hlType type_sel;
|
||||||
regType reg_type;
|
regType reg_type;
|
||||||
@ -59,6 +60,7 @@ string RegisterNode::walkCondExpr(Function *pProc, int *numLoc) const
|
|||||||
std::ostringstream codeOut;
|
std::ostringstream codeOut;
|
||||||
|
|
||||||
std::ostringstream o;
|
std::ostringstream o;
|
||||||
|
assert(&pProc->localId==m_syms);
|
||||||
ID *id = &pProc->localId.id_arr[regiIdx];
|
ID *id = &pProc->localId.id_arr[regiIdx];
|
||||||
if (id->name[0] == '\0') /* no name */
|
if (id->name[0] == '\0') /* no name */
|
||||||
{
|
{
|
||||||
@ -83,8 +85,6 @@ int RegisterNode::hlTypeSize(Function *) const
|
|||||||
return (2);
|
return (2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
hlType RegisterNode::expType(Function *pproc) const
|
hlType RegisterNode::expType(Function *pproc) const
|
||||||
{
|
{
|
||||||
if (regiType == BYTE_REG)
|
if (regiType == BYTE_REG)
|
||||||
@ -95,6 +95,7 @@ hlType RegisterNode::expType(Function *pproc) const
|
|||||||
|
|
||||||
Expr *RegisterNode::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
|
Expr *RegisterNode::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
|
||||||
{
|
{
|
||||||
|
assert(locsym==m_syms);
|
||||||
eReg treeReg = locsym->id_arr[regiIdx].id.regi;
|
eReg treeReg = locsym->id_arr[regiIdx].id.regi;
|
||||||
if (treeReg == regi) /* uint16_t reg */
|
if (treeReg == regi) /* uint16_t reg */
|
||||||
{
|
{
|
||||||
@ -104,6 +105,7 @@ Expr *RegisterNode::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *loc
|
|||||||
{
|
{
|
||||||
return _expr;
|
return _expr;
|
||||||
}
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
bool RegisterNode::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)
|
bool RegisterNode::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)
|
||||||
{
|
{
|
||||||
|
|||||||
35
src/ast.cpp
35
src/ast.cpp
@ -89,9 +89,9 @@ void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu)
|
|||||||
break;
|
break;
|
||||||
case eUSE:
|
case eUSE:
|
||||||
if (duDu == eDEF)
|
if (duDu == eDEF)
|
||||||
du.use=duIcode.du.def;
|
du.use = duIcode.du.def;
|
||||||
else
|
else
|
||||||
du.use =duIcode.du.use;
|
du.use = duIcode.du.use;
|
||||||
break;
|
break;
|
||||||
case USE_DEF:
|
case USE_DEF:
|
||||||
du = duIcode.du;
|
du = duIcode.du;
|
||||||
@ -134,17 +134,14 @@ string GlobalVariable::walkCondExpr(Function *, int *) const
|
|||||||
{
|
{
|
||||||
if(valid)
|
if(valid)
|
||||||
return Project::get()->symtab[globIdx].name;
|
return Project::get()->symtab[globIdx].name;
|
||||||
else
|
return "INVALID GlobalVariable";
|
||||||
return "INVALID GlobalVariable";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns an identifier conditional expression node of type LOCAL_VAR */
|
/* Returns an identifier conditional expression node of type LOCAL_VAR */
|
||||||
AstIdent *AstIdent::Loc(int off, LOCAL_ID *localId)
|
AstIdent *AstIdent::Loc(int off, LOCAL_ID *localId)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
AstIdent *newExp;
|
AstIdent *newExp = new AstIdent();
|
||||||
|
|
||||||
newExp = new AstIdent();
|
|
||||||
newExp->ident.idType = LOCAL_VAR;
|
newExp->ident.idType = LOCAL_VAR;
|
||||||
for (i = 0; i < localId->csym(); i++)
|
for (i = 0; i < localId->csym(); i++)
|
||||||
{
|
{
|
||||||
@ -204,7 +201,7 @@ string GlobalVariableIdx::walkCondExpr(Function *pProc, int *) const
|
|||||||
* that points to the given index idx. */
|
* that points to the given index idx. */
|
||||||
AstIdent *AstIdent::LongIdx (int idx)
|
AstIdent *AstIdent::LongIdx (int idx)
|
||||||
{
|
{
|
||||||
AstIdent *newExp = new AstIdent();
|
AstIdent *newExp = new AstIdent;
|
||||||
newExp->ident.idType = LONG_VAR;
|
newExp->ident.idType = LONG_VAR;
|
||||||
newExp->ident.idNode.longIdx = idx;
|
newExp->ident.idNode.longIdx = idx;
|
||||||
return (newExp);
|
return (newExp);
|
||||||
@ -222,7 +219,6 @@ AstIdent *AstIdent::String(uint32_t idx)
|
|||||||
/* Returns an identifier conditional expression node of type LONG_VAR */
|
/* Returns an identifier conditional expression node of type LONG_VAR */
|
||||||
AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset)
|
AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
AstIdent *newExp;
|
AstIdent *newExp;
|
||||||
/* Check for long constant and save it as a constant expression */
|
/* Check for long constant and save it as a constant expression */
|
||||||
if ((sd == SRC) && pIcode->ll()->testFlags(I)) /* constant */
|
if ((sd == SRC) && pIcode->ll()->testFlags(I)) /* constant */
|
||||||
@ -275,10 +271,10 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_WORD_SIGN:
|
case TYPE_WORD_SIGN:
|
||||||
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG);
|
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG,locsym);
|
||||||
break;
|
break;
|
||||||
case TYPE_BYTE_SIGN:
|
case TYPE_BYTE_SIGN:
|
||||||
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG);
|
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG,locsym);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type);
|
fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type);
|
||||||
@ -826,18 +822,14 @@ Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recursively deallocates the abstract syntax tree rooted at *exp */
|
|
||||||
Expr::~Expr(){}
|
|
||||||
|
|
||||||
/* Makes a copy of the given expression. Allocates newExp storage for each
|
/* Makes a copy of the given expression. Allocates newExp storage for each
|
||||||
* node. Returns the copy. */
|
* node. Returns the copy. */
|
||||||
|
|
||||||
Expr *BinaryOperator::clone() const
|
Expr *BinaryOperator::clone() const
|
||||||
{
|
{
|
||||||
BinaryOperator* newExp=new BinaryOperator(m_op); /* Expression node copy */
|
/* Expression node copy */
|
||||||
newExp->m_lhs = m_lhs->clone();
|
return new BinaryOperator(m_op,m_lhs->clone(),m_rhs->clone());
|
||||||
newExp->m_rhs = m_rhs->clone();
|
|
||||||
return newExp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr *BinaryOperator::inverse() const
|
Expr *BinaryOperator::inverse() const
|
||||||
@ -878,15 +870,13 @@ Expr *AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId)
|
|||||||
{
|
{
|
||||||
otherRegi = otherLongRegi (regi, ident.idNode.longIdx, locId);
|
otherRegi = otherLongRegi (regi, ident.idNode.longIdx, locId);
|
||||||
delete this;
|
delete this;
|
||||||
return new RegisterNode(locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi),WORD_REG);
|
return new RegisterNode(locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi),WORD_REG,locId);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
||||||
{
|
{
|
||||||
ID *id;
|
ID *id = &locTbl->id_arr[idx];
|
||||||
|
|
||||||
id = &locTbl->id_arr[idx];
|
|
||||||
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
|
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
|
||||||
(id->type == TYPE_LONG_UNSIGN)))
|
(id->type == TYPE_LONG_UNSIGN)))
|
||||||
{
|
{
|
||||||
@ -933,6 +923,3 @@ hlType FuncNode::expType(Function *) const
|
|||||||
{
|
{
|
||||||
return call.proc->retVal.type;
|
return call.proc->retVal.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -74,7 +74,7 @@ void checkHeap(char *msg); /* For debugging */
|
|||||||
|
|
||||||
void fixWildCards(uint8_t pat[]); /* In fixwild.c */
|
void fixWildCards(uint8_t pat[]); /* In fixwild.c */
|
||||||
|
|
||||||
static boolT locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern,
|
static bool locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern,
|
||||||
int iPatLen, int *index);
|
int iPatLen, int *index);
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * *\
|
/* * * * * * * * * * * * * * * *\
|
||||||
@ -477,6 +477,7 @@ bool LibCheck(Function & pProc)
|
|||||||
if ((numFunc == 0) || (i=searchPList(ht[h].htSym)) != NIL)
|
if ((numFunc == 0) || (i=searchPList(ht[h].htSym)) != NIL)
|
||||||
{
|
{
|
||||||
pProc.flg |= PROC_ISLIB; /* It's a lib function */
|
pProc.flg |= PROC_ISLIB; /* It's a lib function */
|
||||||
|
pProc.callingConv(CConv::C);
|
||||||
if (i != NIL)
|
if (i != NIL)
|
||||||
{
|
{
|
||||||
/* Allocate space for the arg struct, and copy the hlType to
|
/* Allocate space for the arg struct, and copy the hlType to
|
||||||
@ -511,8 +512,7 @@ bool LibCheck(Function & pProc)
|
|||||||
/*** other types are not considered yet ***/
|
/*** other types are not considered yet ***/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pFunc[i].bVararg)
|
pProc.getFunctionType()->m_vararg = pFunc[i].bVararg;
|
||||||
pProc.flg |= PROC_VARARG;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (i == NIL)
|
else if (i == NIL)
|
||||||
@ -532,7 +532,7 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.args.numArgs = 0; /* With no args */
|
pProc.args.numArgs = 0; /* With no args */
|
||||||
}
|
}
|
||||||
|
|
||||||
return (boolT)((pProc.flg & PROC_ISLIB) != 0);
|
return (bool)((pProc.flg & PROC_ISLIB) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -565,8 +565,7 @@ readFileShort(FILE *f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read a section of the file, considering endian issues
|
// Read a section of the file, considering endian issues
|
||||||
void
|
void readFileSection(uint16_t* p, int len, FILE* f)
|
||||||
readFileSection(uint16_t* p, int len, FILE* f)
|
|
||||||
{
|
{
|
||||||
for (int i=0; i < len; i += 2)
|
for (int i=0; i < len; i += 2)
|
||||||
{
|
{
|
||||||
@ -589,7 +588,7 @@ void dispKey(int /*i*/)
|
|||||||
iPatLen). The pattern can contain wild bytes; if you really want to match
|
iPatLen). The pattern can contain wild bytes; if you really want to match
|
||||||
for the pattern that is used up by the WILD uint8_t, tough - it will match with
|
for the pattern that is used up by the WILD uint8_t, tough - it will match with
|
||||||
everything else as well. */
|
everything else as well. */
|
||||||
static boolT locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen,
|
static bool locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen,
|
||||||
int *index)
|
int *index)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -763,7 +762,7 @@ void STATE::checkStartup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Model: %c\n", chModel);
|
printf("Model: %c\n", chModel);
|
||||||
|
prog.addressingMode = chModel;
|
||||||
|
|
||||||
/* Now decide the compiler vendor and version number */
|
/* Now decide the compiler vendor and version number */
|
||||||
if (memcmp(&prog.image()[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0)
|
if (memcmp(&prog.image()[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0)
|
||||||
@ -953,8 +952,7 @@ void readProtoFile(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int searchPList(char *name)
|
||||||
searchPList(char *name)
|
|
||||||
{
|
{
|
||||||
/* Search through the symbol names for the name */
|
/* Search through the symbol names for the name */
|
||||||
/* Use binary search */
|
/* Use binary search */
|
||||||
@ -991,10 +989,7 @@ searchPList(char *name)
|
|||||||
{
|
{
|
||||||
return mn; /* Found! */
|
return mn; /* Found! */
|
||||||
}
|
}
|
||||||
else
|
return NIL;
|
||||||
{
|
|
||||||
return NIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -164,17 +164,17 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
|||||||
{
|
{
|
||||||
switch (m_dst.off)
|
switch (m_dst.off)
|
||||||
{
|
{
|
||||||
case 0x01 :
|
case 0x01 :
|
||||||
s << "Print spooler";
|
s << "Print spooler";
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
s << "Assign";
|
s << "Assign";
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
s << "Share";
|
s << "Share";
|
||||||
break;
|
break;
|
||||||
case 0xB7:
|
case 0xB7:
|
||||||
s << "Append";
|
s << "Append";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -235,29 +235,23 @@ void Function::writeProcComments(std::ostream &ostr)
|
|||||||
ostr << " * Untranslatable routine. Assembler provided.\n";
|
ostr << " * Untranslatable routine. Assembler provided.\n";
|
||||||
if (this->flg & PROC_IS_FUNC)
|
if (this->flg & PROC_IS_FUNC)
|
||||||
switch (this->retVal.type) { // TODO: Functions return value in various regs
|
switch (this->retVal.type) { // TODO: Functions return value in various regs
|
||||||
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
||||||
ostr << " * Return value in register al.\n";
|
ostr << " * Return value in register al.\n";
|
||||||
break;
|
break;
|
||||||
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
||||||
ostr << " * Return value in register ax.\n";
|
ostr << " * Return value in register ax.\n";
|
||||||
break;
|
break;
|
||||||
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
||||||
ostr << " * Return value in registers dx:ax.\n";
|
ostr << " * Return value in registers dx:ax.\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"Unknown retval type %d",this->retVal.type);
|
fprintf(stderr,"Unknown retval type %d",this->retVal.type);
|
||||||
break;
|
break;
|
||||||
} /* eos */
|
} /* eos */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calling convention */
|
/* Calling convention */
|
||||||
if (this->flg & CALL_PASCAL)
|
callingConv()->writeComments(ostr);
|
||||||
ostr << " * Pascal calling convention.\n";
|
|
||||||
else if (this->flg & CALL_C)
|
|
||||||
ostr << " * C calling convention.\n";
|
|
||||||
else if (this->flg & CALL_UNKNOWN)
|
|
||||||
ostr << " * Unknown calling convention.\n";
|
|
||||||
|
|
||||||
/* Other flags */
|
/* Other flags */
|
||||||
if (this->flg & (PROC_BADINST | PROC_IJMP))
|
if (this->flg & (PROC_BADINST | PROC_IJMP))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -105,7 +105,7 @@ static void freeList (nodeList &l)
|
|||||||
|
|
||||||
|
|
||||||
/* Returns whether the node n belongs to the queue list q. */
|
/* Returns whether the node n belongs to the queue list q. */
|
||||||
static boolT inInt(BB * n, queue &q)
|
static bool inInt(BB * n, queue &q)
|
||||||
{
|
{
|
||||||
return std::find(q.begin(),q.end(),n)!=q.end();
|
return std::find(q.begin(),q.end(),n)!=q.end();
|
||||||
}
|
}
|
||||||
|
|||||||
807
src/dataflow.cpp
807
src/dataflow.cpp
File diff suppressed because it is too large
Load Diff
@ -77,14 +77,14 @@ static char *strHex(uint32_t d);
|
|||||||
//static int checkScanned(uint32_t pcCur);
|
//static int checkScanned(uint32_t pcCur);
|
||||||
//static void setProc(Function * proc);
|
//static void setProc(Function * proc);
|
||||||
//static void dispData(uint16_t dataSeg);
|
//static void dispData(uint16_t dataSeg);
|
||||||
boolT callArg(uint16_t off, char *temp); /* Check for procedure name */
|
bool callArg(uint16_t off, char *temp); /* Check for procedure name */
|
||||||
|
|
||||||
//static FILE *dis_g_fp;
|
//static FILE *dis_g_fp;
|
||||||
static CIcodeRec pc;
|
static CIcodeRec pc;
|
||||||
static int cb, j, numIcode, allocIcode;
|
static int cb, j, numIcode, allocIcode;
|
||||||
static map<int,int> pl;
|
static map<int,int> pl;
|
||||||
static uint32_t nextInst;
|
static uint32_t nextInst;
|
||||||
static boolT fImpure;
|
static bool fImpure;
|
||||||
//static int g_lab;
|
//static int g_lab;
|
||||||
static Function * pProc; /* Points to current proc struct */
|
static Function * pProc; /* Points to current proc struct */
|
||||||
|
|
||||||
|
|||||||
@ -82,8 +82,9 @@ TwoWild(uint8_t pat[])
|
|||||||
static bool
|
static bool
|
||||||
FourWild(uint8_t pat[])
|
FourWild(uint8_t pat[])
|
||||||
{
|
{
|
||||||
TwoWild(pat);
|
if(TwoWild(pat))
|
||||||
return TwoWild(pat);
|
return true;
|
||||||
|
return TwoWild(pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chop from the current point by wiping with zeroes. Can't rely on anything
|
/* Chop from the current point by wiping with zeroes. Can't rely on anything
|
||||||
@ -338,7 +339,7 @@ void fixWildCards(uint8_t pat[])
|
|||||||
if (op & 1) pc += 2;
|
if (op & 1) pc += 2;
|
||||||
else pc += 1;
|
else pc += 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
case 0xB0: /* B0 - BF */
|
case 0xB0: /* B0 - BF */
|
||||||
{
|
{
|
||||||
|
|||||||
@ -223,8 +223,8 @@ void DccFrontend::LoadImage(Project &proj)
|
|||||||
{
|
{
|
||||||
fatalError(CANNOT_READ, proj.binary_path().c_str());
|
fatalError(CANNOT_READ, proj.binary_path().c_str());
|
||||||
}
|
}
|
||||||
|
prog.fCOM = (header.sigLo != 0x4D || header.sigHi != 0x5A);
|
||||||
if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) {
|
if (! prog.fCOM ) {
|
||||||
/* Read rest of header */
|
/* Read rest of header */
|
||||||
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)
|
||||||
@ -250,13 +250,13 @@ void DccFrontend::LoadImage(Project &proj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We quietly ignore minAlloc and maxAlloc since for our
|
/* We quietly ignore minAlloc and maxAlloc since for our
|
||||||
* purposes it doesn't really matter where in real memory
|
* purposes it doesn't really matter where in real memory
|
||||||
* the program would end up. EXE programs can't really rely on
|
* the program would end up. EXE programs can't really rely on
|
||||||
* their load location so setting the PSP segment to 0 is fine.
|
* their load location so setting the PSP segment to 0 is fine.
|
||||||
* Certainly programs that prod around in DOS or BIOS are going
|
* Certainly programs that prod around in DOS or BIOS are going
|
||||||
* to have to load DS from a constant so it'll be pretty
|
* to have to load DS from a constant so it'll be pretty
|
||||||
* obvious.
|
* obvious.
|
||||||
*/
|
*/
|
||||||
prog.initCS = (int16_t)LH(&header.initCS) + EXE_RELOCATION;
|
prog.initCS = (int16_t)LH(&header.initCS) + EXE_RELOCATION;
|
||||||
prog.initIP = (int16_t)LH(&header.initIP);
|
prog.initIP = (int16_t)LH(&header.initIP);
|
||||||
prog.initSS = (int16_t)LH(&header.initSS) + EXE_RELOCATION;
|
prog.initSS = (int16_t)LH(&header.initSS) + EXE_RELOCATION;
|
||||||
|
|||||||
188
src/graph.cpp
188
src/graph.cpp
@ -62,69 +62,69 @@ void Function::createCFG()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
switch (ll->getOpcode()) {
|
switch (ll->getOpcode()) {
|
||||||
case iJB: case iJBE: case iJAE: case iJA:
|
case iJB: case iJBE: case iJAE: case iJA:
|
||||||
case iJL: case iJLE: case iJGE: case iJG:
|
case iJL: case iJLE: case iJGE: case iJG:
|
||||||
case iJE: case iJNE: case iJS: case iJNS:
|
case iJE: case iJNE: case iJS: case iJNS:
|
||||||
case iJO: case iJNO: case iJP: case iJNP:
|
case iJO: case iJNO: case iJP: case iJNP:
|
||||||
case iJCXZ:
|
case iJCXZ:
|
||||||
pBB = BB::Create(current_range, TWO_BRANCH, this);
|
pBB = BB::Create(current_range, TWO_BRANCH, this);
|
||||||
CondJumps:
|
CondJumps:
|
||||||
pBB->addOutEdge(nextIcode->loc_ip);
|
pBB->addOutEdge(nextIcode->loc_ip);
|
||||||
/* This is checking for jumps off into nowhere */
|
/* This is checking for jumps off into nowhere */
|
||||||
if ( not ll->testFlags(NO_LABEL) )
|
if ( not ll->testFlags(NO_LABEL) )
|
||||||
pBB->addOutEdge(ll->src().getImm2());
|
pBB->addOutEdge(ll->src().getImm2());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iLOOP: case iLOOPE: case iLOOPNE:
|
case iLOOP: case iLOOPE: case iLOOPNE:
|
||||||
pBB = BB::Create(current_range, LOOP_NODE, this);
|
pBB = BB::Create(current_range, LOOP_NODE, this);
|
||||||
goto CondJumps;
|
goto CondJumps;
|
||||||
|
|
||||||
case iJMPF: case iJMP:
|
case iJMPF: case iJMP:
|
||||||
if (ll->testFlags(SWITCH))
|
if (ll->testFlags(SWITCH))
|
||||||
{
|
|
||||||
pBB = BB::Create(current_range, MULTI_BRANCH, this);
|
|
||||||
for (auto & elem : ll->caseTbl2)
|
|
||||||
pBB->addOutEdge(elem);
|
|
||||||
hasCase = true;
|
|
||||||
}
|
|
||||||
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
|
|
||||||
{
|
|
||||||
pBB = BB::Create(current_range, ONE_BRANCH, this);
|
|
||||||
pBB->addOutEdge(ll->src().getImm2());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pBB = BB::Create(current_range, NOWHERE_NODE, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case iCALLF: case iCALL:
|
|
||||||
{
|
{
|
||||||
Function * p = ll->src().proc.proc;
|
pBB = BB::Create(current_range, MULTI_BRANCH, this);
|
||||||
pBB = BB::Create(current_range, CALL_NODE, this);
|
for (auto & elem : ll->caseTbl2)
|
||||||
if (p && not ((p->flg) & TERMINATES) )
|
pBB->addOutEdge(elem);
|
||||||
pBB->addOutEdge(nextIcode->loc_ip);
|
hasCase = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
|
||||||
|
{
|
||||||
|
pBB = BB::Create(current_range, ONE_BRANCH, this);
|
||||||
|
pBB->addOutEdge(ll->src().getImm2());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pBB = BB::Create(current_range, NOWHERE_NODE, this);
|
||||||
|
break;
|
||||||
|
|
||||||
case iRET: case iRETF:
|
case iCALLF: case iCALL:
|
||||||
pBB = BB::Create(current_range, RETURN_NODE, this);
|
{
|
||||||
break;
|
Function * p = ll->src().proc.proc;
|
||||||
|
pBB = BB::Create(current_range, CALL_NODE, this);
|
||||||
|
if (p && not ((p->flg) & TERMINATES) )
|
||||||
|
pBB->addOutEdge(nextIcode->loc_ip);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
case iRET: case iRETF:
|
||||||
/* Check for exit to DOS */
|
pBB = BB::Create(current_range, RETURN_NODE, this);
|
||||||
if ( ll->testFlags(TERMINATES) )
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Check for exit to DOS */
|
||||||
|
if ( ll->testFlags(TERMINATES) )
|
||||||
|
{
|
||||||
|
pBB = BB::Create(current_range, TERMINATE_NODE, this);
|
||||||
|
}
|
||||||
|
/* Check for a fall through */
|
||||||
|
else if (nextIcode != Icode.end())
|
||||||
|
{
|
||||||
|
if (nextIcode->ll()->testFlags(TARGET | CASE))
|
||||||
{
|
{
|
||||||
pBB = BB::Create(current_range, TERMINATE_NODE, this);
|
pBB = BB::Create(current_range, FALL_NODE, this);
|
||||||
|
pBB->addOutEdge(nextIcode->loc_ip);
|
||||||
}
|
}
|
||||||
/* Check for a fall through */
|
}
|
||||||
else if (nextIcode != Icode.end())
|
break;
|
||||||
{
|
|
||||||
if (nextIcode->ll()->testFlags(TARGET | CASE))
|
|
||||||
{
|
|
||||||
pBB = BB::Create(current_range, FALL_NODE, this);
|
|
||||||
pBB->addOutEdge(nextIcode->loc_ip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if(pBB!=nullptr) // created a new Basic block
|
if(pBB!=nullptr) // created a new Basic block
|
||||||
{
|
{
|
||||||
@ -133,11 +133,9 @@ CondJumps:
|
|||||||
current_range=make_iterator_range(nextIcode,nextIcode);
|
current_range=make_iterator_range(nextIcode,nextIcode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto iter=heldBBs.begin();
|
for (auto pr : m_ip_to_bb)
|
||||||
/* Convert list of BBs into a graph */
|
|
||||||
for (; iter!=heldBBs.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
pBB = *iter;
|
BB* pBB=pr.second;
|
||||||
for (auto & elem : pBB->edges)
|
for (auto & elem : pBB->edges)
|
||||||
{
|
{
|
||||||
int32_t ip = elem.ip;
|
int32_t ip = elem.ip;
|
||||||
@ -146,16 +144,15 @@ CondJumps:
|
|||||||
fatalError (INVALID_SYNTHETIC_BB);
|
fatalError (INVALID_SYNTHETIC_BB);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(),
|
auto iter2=m_ip_to_bb.find(ip);
|
||||||
[ip](BB *psBB)->bool {return psBB->begin()->loc_ip==ip;});
|
if(iter2==m_ip_to_bb.end())
|
||||||
if(iter2==heldBBs.end())
|
fatalError(NO_BB, ip, name.c_str());
|
||||||
fatalError(NO_BB, ip, name.c_str());
|
psBB = iter2->second;
|
||||||
psBB = *iter2;
|
elem.BBptr = psBB;
|
||||||
elem.BBptr = psBB;
|
psBB->inEdges.push_back((BB *)nullptr);
|
||||||
psBB->inEdges.push_back((BB *)nullptr);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Function::markImpure()
|
void Function::markImpure()
|
||||||
{
|
{
|
||||||
@ -181,21 +178,16 @@ void Function::markImpure()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* newBB - Allocate new BB and link to end of list
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* freeCFG - Deallocates a cfg
|
* freeCFG - Deallocates a cfg
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void Function::freeCFG()
|
void Function::freeCFG()
|
||||||
{
|
{
|
||||||
for(BB *p : heldBBs)
|
for(auto p : m_ip_to_bb)
|
||||||
{
|
{
|
||||||
delete p;
|
delete p.second;
|
||||||
}
|
}
|
||||||
|
m_ip_to_bb.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -338,33 +330,33 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
|
|||||||
auto iter=std::find_if(this->end(),pChild->begin(),[](ICODE &c)
|
auto iter=std::find_if(this->end(),pChild->begin(),[](ICODE &c)
|
||||||
{return not c.ll()->testFlags(NO_CODE);});
|
{return not c.ll()->testFlags(NO_CODE);});
|
||||||
|
|
||||||
if (iter != pChild->begin())
|
if (iter != pChild->begin())
|
||||||
|
break;
|
||||||
|
back().ll()->setFlags(NO_CODE);
|
||||||
|
back().invalidate();
|
||||||
|
nodeType = FALL_NODE;
|
||||||
|
//instructions.advance_end(-1); //TODO: causes creation of empty BB
|
||||||
|
}
|
||||||
|
/* If there's no other edges into child can merge */
|
||||||
|
if (pChild->inEdges.size() != 1)
|
||||||
break;
|
break;
|
||||||
back().ll()->setFlags(NO_CODE);
|
|
||||||
back().invalidate();
|
nodeType = pChild->nodeType;
|
||||||
nodeType = FALL_NODE;
|
instructions = boost::make_iterator_range(begin(),pChild->end());
|
||||||
//instructions.advance_end(-1); //TODO: causes creation of empty BB
|
pChild->front().ll()->clrFlags(TARGET);
|
||||||
|
edges.swap(pChild->edges);
|
||||||
|
|
||||||
|
pChild->inEdges.clear();
|
||||||
|
pChild->edges.clear();
|
||||||
}
|
}
|
||||||
/* If there's no other edges into child can merge */
|
traversed = DFS_MERGE;
|
||||||
if (pChild->inEdges.size() != 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
nodeType = pChild->nodeType;
|
/* Process all out edges recursively */
|
||||||
instructions = boost::make_iterator_range(begin(),pChild->end());
|
for (auto & elem : edges)
|
||||||
pChild->front().ll()->clrFlags(TARGET);
|
{
|
||||||
edges.swap(pChild->edges);
|
if (elem.BBptr->traversed != DFS_MERGE)
|
||||||
|
elem.BBptr->mergeFallThrough(Icode);
|
||||||
pChild->inEdges.clear();
|
}
|
||||||
pChild->edges.clear();
|
|
||||||
}
|
|
||||||
traversed = DFS_MERGE;
|
|
||||||
|
|
||||||
/* Process all out edges recursively */
|
|
||||||
for (auto & elem : edges)
|
|
||||||
{
|
|
||||||
if (elem.BBptr->traversed != DFS_MERGE)
|
|
||||||
elem.BBptr->mergeFallThrough(Icode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -89,11 +89,11 @@ bool LLOperand::isReg() const
|
|||||||
{
|
{
|
||||||
return (regi>=rAX) && (regi<=rTMP);
|
return (regi>=rAX) && (regi<=rTMP);
|
||||||
}
|
}
|
||||||
void LLOperand::addProcInformation(int param_count, uint32_t call_conv)
|
void LLOperand::addProcInformation(int param_count, CConv::Type call_conv)
|
||||||
{
|
{
|
||||||
proc.proc->cbParam = (int16_t)param_count;
|
proc.proc->cbParam = (int16_t)param_count;
|
||||||
proc.cb = param_count;
|
proc.cb = param_count;
|
||||||
proc.proc->flg |= call_conv;
|
proc.proc->callingConv(call_conv);
|
||||||
}
|
}
|
||||||
void HLTYPE::setCall(Function *proc)
|
void HLTYPE::setCall(Function *proc)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -211,7 +211,7 @@ void Function::findIdioms()
|
|||||||
if (cbParam != delta)
|
if (cbParam != delta)
|
||||||
{
|
{
|
||||||
cbParam = delta;
|
cbParam = delta;
|
||||||
flg |= (CALL_MASK & CALL_UNKNOWN);
|
callingConv(CConv::UNKNOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ int Idiom3::action()
|
|||||||
{
|
{
|
||||||
if (m_icodes[0]->ll()->testFlags(I) )
|
if (m_icodes[0]->ll()->testFlags(I) )
|
||||||
{
|
{
|
||||||
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CALL_C);
|
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@ int Idiom17::action()
|
|||||||
{
|
{
|
||||||
if (m_icodes[0]->ll()->testFlags(I))
|
if (m_icodes[0]->ll()->testFlags(I))
|
||||||
{
|
{
|
||||||
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CALL_C);
|
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
|
||||||
for(size_t idx=1; idx<m_icodes.size(); ++idx)
|
for(size_t idx=1; idx<m_icodes.size(); ++idx)
|
||||||
{
|
{
|
||||||
m_icodes[idx]->invalidate();
|
m_icodes[idx]->invalidate();
|
||||||
|
|||||||
@ -146,7 +146,7 @@ int Idiom4::action()
|
|||||||
if(m_param_count)
|
if(m_param_count)
|
||||||
{
|
{
|
||||||
m_func->cbParam = (int16_t)m_param_count;
|
m_func->cbParam = (int16_t)m_param_count;
|
||||||
m_func->flg |= CALL_PASCAL;
|
m_func->callingConv(CConv::PASCAL);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(fals
|
|||||||
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
||||||
}
|
}
|
||||||
|
|
||||||
ID::ID(hlType t, const LONGGLB_TYPE &s)
|
ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
|
||||||
{
|
{
|
||||||
macro[0]=0;
|
macro[0]=0;
|
||||||
memset(&id,0,sizeof(id));
|
memset(&id,0,sizeof(id));
|
||||||
@ -224,7 +224,7 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
|
|||||||
(id_arr[idx].id.longGlb.offL == offL))
|
(id_arr[idx].id.longGlb.offL == offL))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
printf("%d",t);
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
|
id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
|
||||||
return (id_arr.size() - 1);
|
return (id_arr.size() - 1);
|
||||||
|
|||||||
210
src/parser.cpp
210
src/parser.cpp
@ -39,42 +39,47 @@ void DccFrontend::parse(Project &proj)
|
|||||||
SynthLab = SYNTHESIZED_MIN;
|
SynthLab = SYNTHESIZED_MIN;
|
||||||
|
|
||||||
// default-construct a Function object !
|
// default-construct a Function object !
|
||||||
/*auto func = */proj.createFunction();
|
/*auto func = */;
|
||||||
|
|
||||||
/* 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(proj.pProcList.front());
|
Function *start_proc;
|
||||||
/* Make a struct for the initial procedure */
|
/* Make a struct for the initial procedure */
|
||||||
if (prog.offMain != -1)
|
if (prog.offMain != -1)
|
||||||
{
|
{
|
||||||
|
start_proc = proj.createFunction(0,"main");
|
||||||
|
start_proc->retVal.loc = REG_FRAME;
|
||||||
|
start_proc->retVal.type = TYPE_WORD_SIGN;
|
||||||
|
start_proc->retVal.id.regi = rAX;
|
||||||
/* We know where main() is. Start the flow of control from there */
|
/* We know where main() is. Start the flow of control from there */
|
||||||
start_proc.procEntry = prog.offMain;
|
start_proc->procEntry = prog.offMain;
|
||||||
/* In medium and large models, the segment of main may (will?) not be
|
/* In medium and large models, the segment of main may (will?) not be
|
||||||
the same as the initial CS segment (of the startup code) */
|
the same as the initial CS segment (of the startup code) */
|
||||||
state.setState(rCS, prog.segMain);
|
state.setState(rCS, prog.segMain);
|
||||||
start_proc.name = "main";
|
|
||||||
state.IP = prog.offMain;
|
state.IP = prog.offMain;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
start_proc = proj.createFunction(0,"start");
|
||||||
/* Create initial procedure at program start address */
|
/* Create initial procedure at program start address */
|
||||||
start_proc.name="start";
|
start_proc->procEntry = (uint32_t)state.IP;
|
||||||
start_proc.procEntry = (uint32_t)state.IP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The state info is for the first procedure */
|
/* The state info is for the first procedure */
|
||||||
start_proc.state = state;
|
start_proc->state = state;
|
||||||
|
|
||||||
/* Set up call graph initial node */
|
/* Set up call graph initial node */
|
||||||
proj.callGraph = new CALL_GRAPH;
|
proj.callGraph = new CALL_GRAPH;
|
||||||
proj.callGraph->proc = proj.pProcList.begin();
|
proj.callGraph->proc = start_proc;
|
||||||
|
|
||||||
/* 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 !
|
//BUG: proj and g_proj are 'live' at this point !
|
||||||
|
|
||||||
/* Recursively build entire procedure list */
|
/* Recursively build entire procedure list */
|
||||||
proj.pProcList.front().FollowCtrl (proj.callGraph, &state);
|
start_proc->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();
|
||||||
@ -89,16 +94,89 @@ int strSize (const uint8_t *sym, char delim)
|
|||||||
const uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim);
|
const uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim);
|
||||||
return end_ptr-sym+1;
|
return end_ptr-sym+1;
|
||||||
}
|
}
|
||||||
Function *fakeproc=Function::Create(nullptr,0,"fake");
|
ICODE * Function::translate_DIV(LLInst *ll, ICODE &_Icode)
|
||||||
|
{
|
||||||
|
/* MOV rTMP, reg */
|
||||||
|
|
||||||
/* FollowCtrl - Given an initial procedure, state information and symbol table
|
ICODE eIcode = ICODE();
|
||||||
|
|
||||||
|
eIcode.type = LOW_LEVEL;
|
||||||
|
eIcode.ll()->set(iMOV,0,rTMP);
|
||||||
|
if (ll->testFlags(B) )
|
||||||
|
{
|
||||||
|
eIcode.ll()->setFlags( B );
|
||||||
|
eIcode.ll()->replaceSrc(rAX);
|
||||||
|
}
|
||||||
|
else /* implicit dx:ax */
|
||||||
|
{
|
||||||
|
eIcode.ll()->setFlags( IM_SRC );
|
||||||
|
eIcode.setRegDU( rDX, eUSE);
|
||||||
|
}
|
||||||
|
eIcode.setRegDU( rAX, eUSE);
|
||||||
|
eIcode.setRegDU( rTMP, eDEF);
|
||||||
|
eIcode.ll()->setFlags( SYNTHETIC );
|
||||||
|
/* eIcode.ll()->label = SynthLab++; */
|
||||||
|
eIcode.ll()->label = _Icode.ll()->label;
|
||||||
|
Icode.addIcode(&eIcode);
|
||||||
|
|
||||||
|
/* iDIV, iIDIV */
|
||||||
|
Icode.addIcode(&_Icode);
|
||||||
|
|
||||||
|
/* iMOD */
|
||||||
|
eIcode = ICODE();
|
||||||
|
eIcode.type = LOW_LEVEL;
|
||||||
|
eIcode.ll()->set(iMOD,ll->getFlag() | SYNTHETIC | IM_TMP_DST);
|
||||||
|
eIcode.ll()->replaceSrc(_Icode.ll()->src());
|
||||||
|
eIcode.du = _Icode.du;
|
||||||
|
eIcode.ll()->label = SynthLab++;
|
||||||
|
return Icode.addIcode(&eIcode);
|
||||||
|
}
|
||||||
|
ICODE *Function::translate_XCHG(LLInst *ll,ICODE &_Icode)
|
||||||
|
{
|
||||||
|
/* MOV rTMP, regDst */
|
||||||
|
ICODE eIcode;
|
||||||
|
eIcode.type = LOW_LEVEL;
|
||||||
|
eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,ll->m_dst);
|
||||||
|
eIcode.setRegDU( rTMP, eDEF);
|
||||||
|
if(eIcode.ll()->src().getReg2())
|
||||||
|
{
|
||||||
|
eReg srcreg=eIcode.ll()->src().getReg2();
|
||||||
|
eIcode.setRegDU( srcreg, eUSE);
|
||||||
|
if((srcreg>=rAL) && (srcreg<=rBH))
|
||||||
|
eIcode.ll()->setFlags( B );
|
||||||
|
}
|
||||||
|
eIcode.ll()->label = ll->label;
|
||||||
|
Icode.addIcode(&eIcode);
|
||||||
|
|
||||||
|
/* MOV regDst, regSrc */
|
||||||
|
ll->set(iMOV,SYNTHETIC|ll->getFlag());
|
||||||
|
Icode.addIcode(&_Icode);
|
||||||
|
ll->setOpcode(iXCHG); /* for next case */
|
||||||
|
|
||||||
|
/* MOV regSrc, rTMP */
|
||||||
|
eIcode = ICODE();
|
||||||
|
eIcode.type = LOW_LEVEL;
|
||||||
|
eIcode.ll()->set(iMOV,SYNTHETIC);
|
||||||
|
eIcode.ll()->replaceDst(ll->src());
|
||||||
|
if(eIcode.ll()->m_dst.regi)
|
||||||
|
{
|
||||||
|
if((eIcode.ll()->m_dst.regi>=rAL) && (eIcode.ll()->m_dst.regi<=rBH))
|
||||||
|
eIcode.ll()->setFlags( B );
|
||||||
|
eIcode.setRegDU( eIcode.ll()->m_dst.regi, eDEF);
|
||||||
|
}
|
||||||
|
eIcode.ll()->replaceSrc(rTMP);
|
||||||
|
eIcode.setRegDU( rTMP, eUSE);
|
||||||
|
eIcode.ll()->label = SynthLab++;
|
||||||
|
return Icode.addIcode(&eIcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** FollowCtrl - Given an initial procedure, state information and symbol table
|
||||||
* builds a list of procedures reachable from the initial procedure
|
* builds a list of procedures reachable from the initial procedure
|
||||||
* using a depth first search. */
|
* using a depth first search. */
|
||||||
void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
ICODE _Icode, *pIcode; /* This gets copied to pProc->Icode[] later */
|
ICODE _Icode, *pIcode; /* This gets copied to pProc->Icode[] later */
|
||||||
ICODE eIcode; /* extra icodes for iDIV, iIDIV, iXCHG */
|
|
||||||
SYM * psym;
|
SYM * psym;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
eErrorId err;
|
eErrorId err;
|
||||||
@ -119,8 +197,11 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
printf("Parsing proc %s at %X\n", name.c_str(), pstate->IP);
|
printf("Parsing proc %s at %X\n", name.c_str(), pstate->IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! done && ! (err = scan(pstate->IP, _Icode)))
|
while (! done )
|
||||||
{
|
{
|
||||||
|
err = scan(pstate->IP, _Icode);
|
||||||
|
if(err)
|
||||||
|
break;
|
||||||
LLInst *ll = _Icode.ll();
|
LLInst *ll = _Icode.ll();
|
||||||
pstate->IP += (uint32_t)ll->numBytes;
|
pstate->IP += (uint32_t)ll->numBytes;
|
||||||
setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes);
|
setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes);
|
||||||
@ -141,80 +222,10 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Copy Icode to Proc */
|
/* Copy Icode to Proc */
|
||||||
if ((_Icode.ll()->getOpcode() == iDIV) || (_Icode.ll()->getOpcode() == iIDIV))
|
if ((ll->getOpcode() == iDIV) || (ll->getOpcode() == iIDIV))
|
||||||
{
|
pIcode = translate_DIV(ll, _Icode);
|
||||||
/* MOV rTMP, reg */
|
|
||||||
eIcode = ICODE();
|
|
||||||
|
|
||||||
eIcode.type = LOW_LEVEL;
|
|
||||||
eIcode.ll()->set(iMOV,0,rTMP);
|
|
||||||
if (ll->testFlags(B) )
|
|
||||||
{
|
|
||||||
eIcode.ll()->setFlags( B );
|
|
||||||
eIcode.ll()->replaceSrc(rAX);
|
|
||||||
}
|
|
||||||
else /* implicit dx:ax */
|
|
||||||
{
|
|
||||||
eIcode.ll()->setFlags( IM_SRC );
|
|
||||||
eIcode.setRegDU( rDX, eUSE);
|
|
||||||
}
|
|
||||||
eIcode.setRegDU( rAX, eUSE);
|
|
||||||
eIcode.setRegDU( rTMP, eDEF);
|
|
||||||
eIcode.ll()->setFlags( SYNTHETIC );
|
|
||||||
/* eIcode.ll()->label = SynthLab++; */
|
|
||||||
eIcode.ll()->label = _Icode.ll()->label;
|
|
||||||
Icode.addIcode(&eIcode);
|
|
||||||
|
|
||||||
/* iDIV, iIDIV */
|
|
||||||
Icode.addIcode(&_Icode);
|
|
||||||
|
|
||||||
/* iMOD */
|
|
||||||
eIcode = ICODE();
|
|
||||||
eIcode.type = LOW_LEVEL;
|
|
||||||
eIcode.ll()->set(iMOD,ll->getFlag() | SYNTHETIC | IM_TMP_DST);
|
|
||||||
eIcode.ll()->replaceSrc(_Icode.ll()->src());
|
|
||||||
eIcode.du = _Icode.du;
|
|
||||||
eIcode.ll()->label = SynthLab++;
|
|
||||||
pIcode = Icode.addIcode(&eIcode);
|
|
||||||
}
|
|
||||||
else if (_Icode.ll()->getOpcode() == iXCHG)
|
else if (_Icode.ll()->getOpcode() == iXCHG)
|
||||||
{
|
pIcode = translate_XCHG(ll, _Icode);
|
||||||
/* MOV rTMP, regDst */
|
|
||||||
eIcode = ICODE();
|
|
||||||
eIcode.type = LOW_LEVEL;
|
|
||||||
eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,_Icode.ll()->m_dst);
|
|
||||||
eIcode.setRegDU( rTMP, eDEF);
|
|
||||||
if(eIcode.ll()->src().getReg2())
|
|
||||||
{
|
|
||||||
eReg srcreg=eIcode.ll()->src().getReg2();
|
|
||||||
eIcode.setRegDU( srcreg, eUSE);
|
|
||||||
if((srcreg>=rAL) && (srcreg<=rBH))
|
|
||||||
eIcode.ll()->setFlags( B );
|
|
||||||
}
|
|
||||||
eIcode.ll()->label = _Icode.ll()->label;
|
|
||||||
Icode.addIcode(&eIcode);
|
|
||||||
|
|
||||||
/* MOV regDst, regSrc */
|
|
||||||
_Icode.ll()->set(iMOV,SYNTHETIC|_Icode.ll()->getFlag());
|
|
||||||
Icode.addIcode(&_Icode);
|
|
||||||
ll->setOpcode(iXCHG); /* for next case */
|
|
||||||
|
|
||||||
/* MOV regSrc, rTMP */
|
|
||||||
eIcode = ICODE();
|
|
||||||
eIcode.type = LOW_LEVEL;
|
|
||||||
eIcode.ll()->set(iMOV,SYNTHETIC);
|
|
||||||
eIcode.ll()->replaceDst(ll->src());
|
|
||||||
if(eIcode.ll()->m_dst.regi)
|
|
||||||
{
|
|
||||||
if((eIcode.ll()->m_dst.regi>=rAL) && (eIcode.ll()->m_dst.regi<=rBH))
|
|
||||||
eIcode.ll()->setFlags( B );
|
|
||||||
eIcode.setRegDU( eIcode.ll()->m_dst.regi, eDEF);
|
|
||||||
}
|
|
||||||
eIcode.ll()->replaceSrc(rTMP);
|
|
||||||
eIcode.setRegDU( rTMP, eUSE);
|
|
||||||
eIcode.ll()->label = SynthLab++;
|
|
||||||
pIcode = Icode.addIcode(&eIcode);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
pIcode = Icode.addIcode(&_Icode);
|
pIcode = Icode.addIcode(&_Icode);
|
||||||
|
|
||||||
@ -230,7 +241,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
STATE StCopy;
|
STATE StCopy;
|
||||||
int ip = Icode.size()-1; /* Index of this jump */
|
int ip = Icode.size()-1; /* Index of this jump */
|
||||||
ICODE &prev(*(++Icode.rbegin())); /* Previous icode */
|
ICODE &prev(*(++Icode.rbegin())); /* Previous icode */
|
||||||
boolT fBranch = false;
|
bool fBranch = false;
|
||||||
|
|
||||||
pstate->JCond.regi = 0;
|
pstate->JCond.regi = 0;
|
||||||
|
|
||||||
@ -298,7 +309,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
//Icode.GetIcode(Icode.GetNumIcodes() - 1)->
|
//Icode.GetIcode(Icode.GetNumIcodes() - 1)->
|
||||||
|
|
||||||
/* Program termination: int21h, fn 00h, 31h, 4Ch */
|
/* Program termination: int21h, fn 00h, 31h, 4Ch */
|
||||||
done = (boolT)(funcNum == 0x00 || funcNum == 0x31 ||
|
done = (bool)(funcNum == 0x00 || funcNum == 0x31 ||
|
||||||
funcNum == 0x4C);
|
funcNum == 0x4C);
|
||||||
|
|
||||||
/* String functions: int21h, fn 09h */
|
/* String functions: int21h, fn 09h */
|
||||||
@ -318,8 +329,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
Icode.back().ll()->m_dst.off = pstate->r[rAH];
|
Icode.back().ll()->m_dst.off = pstate->r[rAH];
|
||||||
}
|
}
|
||||||
else /* Program termination: int20h, int27h */
|
else /* Program termination: int20h, int27h */
|
||||||
done = (boolT)(ll->src().getImm2() == 0x20 ||
|
done = (ll->src().getImm2() == 0x20 || ll->src().getImm2() == 0x27);
|
||||||
ll->src().getImm2() == 0x27);
|
|
||||||
if (done)
|
if (done)
|
||||||
pIcode->ll()->setFlags(TERMINATES);
|
pIcode->ll()->setFlags(TERMINATES);
|
||||||
break;
|
break;
|
||||||
@ -546,16 +556,14 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
|
|||||||
* programmer expected it to come back - otherwise surely a JMP would
|
* programmer expected it to come back - otherwise surely a JMP would
|
||||||
* have been used. */
|
* have been used. */
|
||||||
|
|
||||||
boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *pstate)
|
bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
ICODE &last_insn(Icode.back());
|
ICODE &last_insn(Icode.back());
|
||||||
STATE localState; /* Local copy of the machine state */
|
STATE localState; /* Local copy of the machine state */
|
||||||
uint32_t off;
|
uint32_t off;
|
||||||
boolT indirect;
|
|
||||||
|
|
||||||
/* For Indirect Calls, find the function address */
|
/* For Indirect Calls, find the function address */
|
||||||
indirect = false;
|
bool indirect = false;
|
||||||
//pIcode.ll()->immed.proc.proc=fakeproc;
|
//pIcode.ll()->immed.proc.proc=fakeproc;
|
||||||
if ( not pIcode.ll()->testFlags(I) )
|
if ( not pIcode.ll()->testFlags(I) )
|
||||||
{
|
{
|
||||||
@ -618,7 +626,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
|
|||||||
/* Create a new procedure node and save copy of the state */
|
/* Create a new procedure node and save copy of the state */
|
||||||
if ( not Project::get()->valid(iter) )
|
if ( not Project::get()->valid(iter) )
|
||||||
{
|
{
|
||||||
iter = Project::get()->createFunction();
|
iter = Project::get()->createFunction(0,"");
|
||||||
Function &x(*iter);
|
Function &x(*iter);
|
||||||
x.procEntry = pIcode.ll()->src().getImm2();
|
x.procEntry = pIcode.ll()->src().getImm2();
|
||||||
LibCheck(x);
|
LibCheck(x);
|
||||||
@ -1120,13 +1128,13 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iLDS: case iLES:
|
case iLDS: case iLES:
|
||||||
{
|
{
|
||||||
eReg r=((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES);
|
eReg r=((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES);
|
||||||
pIcode.du.def.addReg(r);
|
pIcode.du.def.addReg(r);
|
||||||
pIcode.du1.addDef(r);
|
pIcode.du1.addDef(r);
|
||||||
cb = 4;
|
cb = 4;
|
||||||
// fallthrough
|
// fallthrough
|
||||||
}
|
}
|
||||||
case iMOV:
|
case iMOV:
|
||||||
use(SRC, pIcode, this, pstate, cb);
|
use(SRC, pIcode, this, pstate, cb);
|
||||||
def(DST, pIcode, this, pstate, cb);
|
def(DST, pIcode, this, pstate, cb);
|
||||||
@ -1186,14 +1194,14 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
pIcode.du.addDefinedAndUsed(rCX);
|
pIcode.du.addDefinedAndUsed(rCX);
|
||||||
pIcode.du1.addDef(rCX);
|
pIcode.du1.addDef(rCX);
|
||||||
case iLODS:
|
case iLODS:
|
||||||
{
|
{
|
||||||
eReg r = (cb==2)? rAX: rAL;
|
eReg r = (cb==2)? rAX: rAL;
|
||||||
pIcode.du.addDefinedAndUsed(rSI);
|
pIcode.du.addDefinedAndUsed(rSI);
|
||||||
pIcode.du1.addDef(rSI);
|
pIcode.du1.addDef(rSI);
|
||||||
pIcode.du.def.addReg(r);
|
pIcode.du.def.addReg(r);
|
||||||
pIcode.du1.addDef(r);
|
pIcode.du1.addDef(r);
|
||||||
pIcode.du.use.addReg(sseg);
|
pIcode.du.use.addReg(sseg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case iREP_OUTS:
|
case iREP_OUTS:
|
||||||
pIcode.du.addDefinedAndUsed(rCX);
|
pIcode.du.addDefinedAndUsed(rCX);
|
||||||
|
|||||||
@ -24,9 +24,7 @@ static short *g; /* g[] */
|
|||||||
//static void duplicateKeys(int v1, int v2);
|
//static void duplicateKeys(int v1, int v2);
|
||||||
PatternHasher g_pattern_hasher;
|
PatternHasher g_pattern_hasher;
|
||||||
|
|
||||||
void
|
void PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin, int _NumVert)
|
||||||
PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
|
|
||||||
int _NumVert)
|
|
||||||
{
|
{
|
||||||
/* These parameters are stored in statics so as to obviate the need for
|
/* These parameters are stored in statics so as to obviate the need for
|
||||||
passing all these (or defererencing pointers) for every call to hash()
|
passing all these (or defererencing pointers) for every call to hash()
|
||||||
|
|||||||
@ -112,6 +112,10 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
|
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
|
||||||
assert(lhs);
|
assert(lhs);
|
||||||
type = lhs->ident.type();
|
type = lhs->ident.type();
|
||||||
|
if(type==REGISTER)
|
||||||
|
assert(lhs_reg);
|
||||||
|
if(type==LONG_VAR)
|
||||||
|
assert(!lhs_reg);
|
||||||
if (lhs_reg)
|
if (lhs_reg)
|
||||||
{
|
{
|
||||||
regL = id_arr[lhs_reg->regiIdx].id.regi;
|
regL = id_arr[lhs_reg->regiIdx].id.regi;
|
||||||
@ -163,16 +167,11 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
|
|
||||||
if (type == REGISTER)
|
if (type == REGISTER)
|
||||||
{
|
{
|
||||||
if (regL < rAL)
|
regType rType = WORD_REG;
|
||||||
{
|
if (regL >= rAL)
|
||||||
newsym.type = TYPE_WORD_SIGN;
|
rType = BYTE_REG;
|
||||||
newsym.regs = new RegisterNode(tidx, WORD_REG);
|
newsym.type = (regL < rAL) ? TYPE_WORD_SIGN : TYPE_BYTE_SIGN;
|
||||||
}
|
newsym.regs = new RegisterNode(tidx, rType,this);
|
||||||
else
|
|
||||||
{
|
|
||||||
newsym.type = TYPE_BYTE_SIGN;
|
|
||||||
newsym.regs = new RegisterNode(tidx, BYTE_REG);
|
|
||||||
}
|
|
||||||
tproc->localId.id_arr[tidx].name = newsym.name;
|
tproc->localId.id_arr[tidx].name = newsym.name;
|
||||||
}
|
}
|
||||||
else if (type == LONG_VAR)
|
else if (type == LONG_VAR)
|
||||||
@ -234,10 +233,7 @@ bool CallType::newStkArg(Expr *exp, llIcode opcode, Function * pproc)
|
|||||||
regi = pproc->localId.id_arr[expr->regiIdx].id.regi;
|
regi = pproc->localId.id_arr[expr->regiIdx].id.regi;
|
||||||
if ((regi >= rES) && (regi <= rDS))
|
if ((regi >= rES) && (regi <= rDS))
|
||||||
{
|
{
|
||||||
if (opcode == iCALLF)
|
return (opcode == iCALLF) ? false : true;
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +308,7 @@ Expr *Function::adjustActArgType (Expr *_exp, hlType forType)
|
|||||||
|
|
||||||
case TYPE_PTR:
|
case TYPE_PTR:
|
||||||
/* It's a pointer to a char rather than a pointer to
|
/* It's a pointer to a char rather than a pointer to
|
||||||
* an integer */
|
* an integer */
|
||||||
/***HERE - modify the type ****/
|
/***HERE - modify the type ****/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@ -53,9 +53,9 @@ ilFunction Project::findByEntry(uint32_t entry)
|
|||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ilFunction Project::createFunction()
|
ilFunction Project::createFunction(FunctionType *f,const std::string &name)
|
||||||
{
|
{
|
||||||
pProcList.push_back(Function::Create());
|
pProcList.push_back(Function::Create(f,0,name,0));
|
||||||
return (++pProcList.rbegin()).base();
|
return (++pProcList.rbegin()).base();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
/* Returns whether the given icode opcode is within the range of valid
|
/* Returns whether the given icode opcode is within the range of valid
|
||||||
* high-level conditional jump icodes (iJB..iJG) */
|
* high-level conditional jump icodes (iJB..iJG) */
|
||||||
static boolT isJCond (llIcode opcode)
|
static bool isJCond (llIcode opcode)
|
||||||
{
|
{
|
||||||
if ((opcode >= iJB) && (opcode <= iJG))
|
if ((opcode >= iJB) && (opcode <= iJG))
|
||||||
return true;
|
return true;
|
||||||
@ -59,7 +59,7 @@ static bool isLong23 (BB * pbb, iICODE &off, int *arc)
|
|||||||
|
|
||||||
|
|
||||||
/* Returns whether the conditions for a 2-2 long variable are satisfied */
|
/* Returns whether the conditions for a 2-2 long variable are satisfied */
|
||||||
static boolT isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off)
|
static bool isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off)
|
||||||
{
|
{
|
||||||
iICODE initial_icode=pIcode;
|
iICODE initial_icode=pIcode;
|
||||||
if(distance(pIcode,pEnd)<4)
|
if(distance(pIcode,pEnd)<4)
|
||||||
|
|||||||
@ -104,7 +104,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
*header, /* Current interval's header node */
|
*header, /* Current interval's header node */
|
||||||
*succ; /* Successor basic block */
|
*succ; /* Successor basic block */
|
||||||
queue H; /* Queue of possible header nodes */
|
queue H; /* Queue of possible header nodes */
|
||||||
boolT first = true; /* First pass through the loop */
|
bool first = true; /* First pass through the loop */
|
||||||
|
|
||||||
appendQueue (H, Gi); /* H = {first node of G} */
|
appendQueue (H, Gi); /* H = {first node of G} */
|
||||||
Gi->beenOnH = true;
|
Gi->beenOnH = true;
|
||||||
@ -304,13 +304,11 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
|
|||||||
/* Finds the derived sequence of the graph derivedG->Gi (ie. cfg).
|
/* Finds the derived sequence of the graph derivedG->Gi (ie. cfg).
|
||||||
* Constructs the n-th order graph and places all the intermediate graphs
|
* Constructs the n-th order graph and places all the intermediate graphs
|
||||||
* in the derivedG list sequence. */
|
* in the derivedG list sequence. */
|
||||||
uint8_t Function::findDerivedSeq (derSeq &derivedGi)
|
bool Function::findDerivedSeq (derSeq &derivedGi)
|
||||||
{
|
{
|
||||||
BB *Gi; /* Current derived sequence graph */
|
|
||||||
|
|
||||||
derSeq::iterator iter=derivedGi.begin();
|
derSeq::iterator iter=derivedGi.begin();
|
||||||
assert(iter!=derivedGi.end());
|
assert(iter!=derivedGi.end());
|
||||||
Gi = iter->Gi;
|
BB *Gi = iter->Gi; /* Current derived sequence graph */
|
||||||
while (! trivialGraph (Gi))
|
while (! trivialGraph (Gi))
|
||||||
{
|
{
|
||||||
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
||||||
|
|||||||
@ -842,10 +842,10 @@ static void trans(int i)
|
|||||||
(llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0
|
(llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0
|
||||||
};
|
};
|
||||||
LLInst *ll = pIcode->ll();
|
LLInst *ll = pIcode->ll();
|
||||||
if(transTable[REG(*pInst)]==iPUSH) {
|
// if(transTable[REG(*pInst)]==iPUSH) {
|
||||||
printf("es");
|
// printf("es");
|
||||||
}
|
// }
|
||||||
if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
|
if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
|
||||||
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
|
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
|
||||||
rm(i);
|
rm(i);
|
||||||
ll->replaceSrc( pIcode->ll()->m_dst );
|
ll->replaceSrc( pIcode->ll()->m_dst );
|
||||||
|
|||||||
@ -133,7 +133,7 @@ void destroySymTables(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Using the value, read the symbolic name */
|
/* Using the value, read the symbolic name */
|
||||||
boolT readVal(std::ostringstream &/*symName*/, uint32_t /*symOff*/, Function * /*symProc*/)
|
bool readVal(std::ostringstream &/*symName*/, uint32_t /*symOff*/, Function * /*symProc*/)
|
||||||
{
|
{
|
||||||
return false; // no symbolic names for now
|
return false; // no symbolic names for now
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user