This commit is contained in:
nemerle 2014-03-07 19:42:27 +01:00
parent 1c5e1c2fce
commit 50950028e0
39 changed files with 922 additions and 795 deletions

View File

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

View File

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

View File

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

View File

@ -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,10 +113,18 @@ 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 */
@ -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;

View File

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

View File

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

View File

@ -68,17 +68,13 @@ 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;
currNode=nodes.end();
next=0;
} }
void appendNodeInt(queue &pqH, BB *node); void appendNodeInt(queue &pqH, BB *node);
}; };
@ -87,13 +83,9 @@ struct interval
/* 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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
View 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";
}

View File

@ -30,3 +30,8 @@ void JumpTable::pruneEntries(uint16_t cs)
} }
} }
void Function::callingConv(CConv::Type v) {
m_call_conv=CConv::create(v);
}

View File

@ -18,6 +18,7 @@ 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)
{ {

View File

@ -134,7 +134,6 @@ 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";
} }
@ -142,9 +141,7 @@ string GlobalVariable::walkCondExpr(Function *, int *) const
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;
} }

View File

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

View File

@ -251,13 +251,7 @@ void Function::writeProcComments(std::ostream &ostr)
} }
/* 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))
{ {

View File

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

View File

@ -15,23 +15,32 @@
#include <boost/assign.hpp> #include <boost/assign.hpp>
#include "dcc.h" #include "dcc.h"
#include "project.h"
using namespace boost; using namespace boost;
using namespace boost::adaptors; using namespace boost::adaptors;
struct ExpStack struct ExpStack
{ {
Function *func;
typedef std::list<Expr *> EXP_STK; typedef std::list<Expr *> EXP_STK;
EXP_STK expStk; /* local expression stack */ EXP_STK expStk; /* local expression stack */
void init(); void init(Function *f);
void push(Expr *); void push(Expr *);
Expr * pop(); Expr * pop();
Expr * top() const {
if(!expStk.empty())
return expStk.back();
return nullptr;
}
int numElem(); int numElem();
boolT empty(); bool empty();
void processExpPush(int &numHlIcodes, iICODE picode) void processExpPush(int &numHlIcodes, ICODE &picode)
{ {
push(picode->hlU()->expr()); RegisterNode *rn = dynamic_cast<RegisterNode *>(picode.hlU()->expr());
picode->invalidate(); if(rn)
assert(rn->m_syms==&func->localId);
push(picode.hlU()->expr());
picode.invalidate();
numHlIcodes--; numHlIcodes--;
} }
@ -42,8 +51,9 @@ struct ExpStack
/* Reinitalizes the expression stack (expStk) to NULL, by freeing all the /* Reinitalizes the expression stack (expStk) to NULL, by freeing all the
* space allocated (if any). */ * space allocated (if any). */
void ExpStack::init() void ExpStack::init(Function *f)
{ {
func=f;
expStk.clear(); expStk.clear();
} }
@ -60,7 +70,7 @@ void ExpStack::push(Expr *expr)
Expr *ExpStack::pop() Expr *ExpStack::pop()
{ {
if(expStk.empty()) if(expStk.empty())
return expStk.back(); return nullptr;
Expr *topExp = expStk.back(); Expr *topExp = expStk.back();
expStk.pop_back(); expStk.pop_back();
return topExp; return topExp;
@ -73,7 +83,7 @@ int ExpStack::numElem()
} }
/* Returns whether the expression stack is empty or not */ /* Returns whether the expression stack is empty or not */
boolT ExpStack::empty() bool ExpStack::empty()
{ {
return expStk.empty(); return expStk.empty();
} }
@ -119,7 +129,7 @@ void Function::elimCondCodes ()
uint8_t use; /* Used flags bit vector */ uint8_t use; /* Used flags bit vector */
uint8_t def; /* Defined flags bit vector */ uint8_t def; /* Defined flags bit vector */
boolT notSup; /* Use/def combination not supported */ bool notSup; /* Use/def combination not supported */
Expr *rhs; /* Source operand */ Expr *rhs; /* Source operand */
Expr *lhs; /* Destination operand */ Expr *lhs; /* Destination operand */
BinaryOperator *_expr; /* Boolean expression */ BinaryOperator *_expr; /* Boolean expression */
@ -148,42 +158,42 @@ void Function::elimCondCodes ()
if ((use & def) != use) if ((use & def) != use)
continue; continue;
notSup = false; notSup = false;
LLOperand *dest_ll = defAt->ll()->get(DST); LLOperand *dest_ll = defIcode.ll()->get(DST);
LLOperand *src_ll = defAt->ll()->get(SRC); LLOperand *src_ll = defIcode.ll()->get(SRC);
if ((useAtOp >= iJB) && (useAtOp <= iJNS)) if ((useAtOp >= iJB) && (useAtOp <= iJNS))
{ {
iICODE befDefAt = (++riICODE(defAt)).base(); iICODE befDefAt = (++riICODE(defAt)).base();
switch (defAt->ll()->getOpcode()) switch (defIcode.ll()->getOpcode())
{ {
case iCMP: case iCMP:
rhs = srcIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE); rhs = srcIdent (*defIcode.ll(), this, befDefAt,*useAt, eUSE);
lhs = dstIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE); lhs = dstIdent (*defIcode.ll(), this, befDefAt,*useAt, eUSE);
break; break;
case iOR: case iOR:
lhs = defAt->hl()->asgn.lhs()->clone(); lhs = defIcode.hl()->asgn.lhs()->clone();
useAt->copyDU(*defAt, eUSE, eDEF); useAt->copyDU(*defAt, eUSE, eDEF);
//if (defAt->ll()->testFlags(B)) //if (defAt->ll()->testFlags(B))
rhs = new Constant(0, dest_ll->byteWidth()); rhs = new Constant(0, dest_ll->byteWidth());
break; break;
case iTEST: case iTEST:
rhs = srcIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE); rhs = srcIdent (*defIcode.ll(),this, befDefAt,*useAt, eUSE);
lhs = dstIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE); lhs = dstIdent (*defIcode.ll(),this, befDefAt,*useAt, eUSE);
lhs = BinaryOperator::And(lhs, rhs); lhs = BinaryOperator::And(lhs, rhs);
// if (defAt->ll()->testFlags(B)) // if (defAt->ll()->testFlags(B))
rhs = new Constant(0, dest_ll->byteWidth()); rhs = new Constant(0, dest_ll->byteWidth());
break; break;
case iINC: case iINC:
case iDEC: //WARNING: verbatim copy from iOR needs fixing ? case iDEC: //WARNING: verbatim copy from iOR needs fixing ?
lhs = defAt->hl()->asgn.lhs()->clone(); lhs = defIcode.hl()->asgn.lhs()->clone();
useAt->copyDU(*defAt, eUSE, eDEF); useAt->copyDU(*defAt, eUSE, eDEF);
rhs = new Constant(0, dest_ll->byteWidth()); rhs = new Constant(0, dest_ll->byteWidth());
break; break;
default: default:
notSup = true; notSup = true;
std::cout << hex<<defAt->loc_ip; std::cout << hex<<defIcode.loc_ip;
reportError (JX_NOT_DEF, defAt->ll()->getOpcode()); reportError (JX_NOT_DEF, defIcode.ll()->getOpcode());
flg |= PROC_ASM; /* generate asm */ flg |= PROC_ASM; /* generate asm */
} }
if (! notSup) if (! notSup)
@ -285,7 +295,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
; ;
LivenessSet prevLiveOut, /* previous live out */ LivenessSet prevLiveOut, /* previous live out */
prevLiveIn; /* previous live in */ prevLiveIn; /* previous live in */
boolT change; /* is there change in the live sets?*/ bool change; /* is there change in the live sets?*/
/* liveOut for this procedure */ /* liveOut for this procedure */
liveOut = in_liveOut; liveOut = in_liveOut;
@ -411,18 +421,18 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
if (distance(start_at,end())>1) /* several instructions */ if (distance(start_at,end())>1) /* several instructions */
{ {
iICODE ticode=end(); iICODE ticode=end();
// Only check uses of HIGH_LEVEL icodes
auto hl_range=make_iterator_range(start_at,end()) | filtered(ICODE::select_high_level); auto hl_range=make_iterator_range(start_at,end()) | filtered(ICODE::select_high_level);
auto checked_icode=hl_range.begin(); auto checked_icode=hl_range.begin();
++checked_icode; ++checked_icode;
for (; checked_icode != hl_range.end(); checked_icode++) for (; checked_icode != hl_range.end(); ++checked_icode)
{ {
if (checked_icode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes ICODE &ic(*checked_icode);
continue;
/* if used, get icode index */ /* if used, get icode index */
if ( checked_icode->du.use.testRegAndSubregs(regi) ) if ( ic.du.use.testRegAndSubregs(regi) )
start_at->du1.recordUse(defRegIdx,checked_icode.base()); start_at->du1.recordUse(defRegIdx,checked_icode.base());
/* if defined, stop finding uses for this reg */ /* if defined, stop finding uses for this reg */
if (checked_icode->du.def.testRegAndSubregs(regi)) if (ic.du.def.testRegAndSubregs(regi))
{ {
ticode=checked_icode.base(); ticode=checked_icode.base();
break; break;
@ -449,9 +459,9 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
* on optimized code. */ * on optimized code. */
void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode) void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
{ {
if ((picode.hl()->opcode == HLI_CALL) && if (!((picode.hl()->opcode == HLI_CALL) && (picode.hl()->call.proc->flg & PROC_IS_FUNC)))
(picode.hl()->call.proc->flg & PROC_IS_FUNC)) return;
{
BB *tbb = this->edges[0].BBptr; BB *tbb = this->edges[0].BBptr;
auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level); auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level);
for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter) for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter)
@ -470,7 +480,6 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
if ( picode.du1.used(defRegIdx) && tbb->liveOut.testRegAndSubregs(regi)) if ( picode.du1.used(defRegIdx) && tbb->liveOut.testRegAndSubregs(regi))
picode.du.lastDefRegi.addReg(regi); picode.du.lastDefRegi.addReg(regi);
} }
}
/* If not used within this bb or in successors of this /* If not used within this bb or in successors of this
* bb (ie. not in liveOut), then register is useless, * bb (ie. not in liveOut), then register is useless,
@ -511,8 +520,7 @@ void BB::genDU1()
* Note that register variables should not be considered registers. * Note that register variables should not be considered registers.
*/ */
assert(nullptr!=Parent); assert(nullptr!=Parent);
ICODE::TypeFilter<HIGH_LEVEL> select_high_level; auto all_high_levels = instructions | filtered(ICODE::select_high_level);
auto all_high_levels = instructions | filtered(select_high_level);
for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode) for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode)
{ {
ICODE &ic = *picode; ICODE &ic = *picode;
@ -625,7 +633,6 @@ static void forwardSubsLong (int longIdx, Expr *_exp, iICODE picode, iICODE tico
} }
} }
/* Returns whether the elements of the expression rhs are all x-clear from /* Returns whether the elements of the expression rhs are all x-clear from
* instruction f up to instruction t. */ * instruction f up to instruction t. */
bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs) bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
@ -647,59 +654,89 @@ bool BinaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCA
} }
bool AstIdent::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId) bool AstIdent::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)
{ {
if (ident.idType == REGISTER) if (ident.idType != REGISTER)
{
assert(false);
}
else
return true; return true;
assert(false);
return false;
} }
/* Checks the type of the formal argument as against to the actual argument, /** Checks the type of the formal argument as against to the actual argument,
* whenever possible, and then places the actual argument on the procedure's whenever possible, and then places the actual argument on the procedure's
* argument list. */ argument list.
/// @returns the type size of the stored Arg @returns the type size of the stored Arg
static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t numArgs) */
int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE * picode, size_t numArgs)
{ {
Expr *_exp; Expr *_exp;
bool res; bool res;
int size_of_arg=0;
PROG &prog(Project::get()->prog);
/* if (numArgs == 0) /* if (numArgs == 0)
return; */ return; */
assert(pProc==g_exp_stk.func);
_exp = g_exp_stk.pop(); _exp = g_exp_stk.pop();
if (pp->flg & PROC_ISLIB) /* library function */ if (callee->flg & PROC_ISLIB) /* library function */
{ {
if (pp->args.numArgs > 0) if (callee->args.numArgs > 0)
{ {
if (pp->flg & PROC_VARARG) if (callee->getFunctionType()->isVarArg())
{ {
if (numArgs < pp->args.size()) if (numArgs < callee->args.size()) {
_exp = pProc->adjustActArgType (_exp, pp->args[numArgs].type); if(_exp==nullptr)
} fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
else else
_exp = pProc->adjustActArgType (_exp, pp->args[numArgs].type); _exp = pProc->adjustActArgType (_exp, callee->args[numArgs].type);
}
}
else {
if(numArgs<callee->args.size()) {
if(prog.addressingMode=='l') {
if((callee->args[numArgs].type==TYPE_STR)||(callee->args[numArgs].type==TYPE_PTR)) {
RegisterNode *rn = dynamic_cast<RegisterNode *>(g_exp_stk.top());
AstIdent *idn = dynamic_cast<AstIdent *>(g_exp_stk.top());
if(rn) {
const ID &_id(pProc->localId.id_arr[rn->regiIdx]);
assert(&pProc->localId==rn->m_syms);
if(_id.id.regi==rDS) {
g_exp_stk.pop(); // pop segment
size_of_arg += 2;
}
} else if(idn) {
Expr *tmp1 = new Constant(2,1);
Expr *tmp2 = BinaryOperator::createSHL(_exp,tmp1);
_exp = BinaryOperator::CreateAdd(g_exp_stk.top(),tmp2);
g_exp_stk.pop(); // pop segment
size_of_arg += 2;
}
}
}
_exp = pProc->adjustActArgType (_exp, callee->args[numArgs].type);
} else {
fprintf(stderr,"processCArg tried to query non existent arg\n");
}
}
} }
} }
else /* user function */ else /* user function */
{ {
if (pp->args.numArgs > 0) if (callee->args.numArgs > 0)
{ {
if(_exp==nullptr) if(_exp==nullptr)
fprintf(stderr,"Would try to adjustForArgType with null _exp\n"); fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
else else
pp->args.adjustForArgType (numArgs, _exp->expType (pProc)); callee->args.adjustForArgType (numArgs, _exp->expType (pProc));
} }
} }
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc); res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc);
/* Do not update the size of k if the expression was a segment register /* Do not update the size of k if the expression was a segment register
* in a near call */ * in a near call */
if (res == false) if (res == false)
{ {
if(_exp==nullptr) if(_exp==nullptr)
return 2; return 2+size_of_arg;
return _exp->hlTypeSize (pProc); return _exp->hlTypeSize (pProc)+size_of_arg;
} }
return 0; // be default we do not know the size of the argument return 0; // be default we do not know the size of the argument
} }
@ -709,7 +746,7 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t
* For HLI_CALL hlIcodes, places the arguments in the argument list. */ * For HLI_CALL hlIcodes, places the arguments in the argument list. */
void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const
{ {
boolT res; bool res;
HLTYPE &p_hl(*picode->hlU()); HLTYPE &p_hl(*picode->hlU());
HLTYPE &t_hl(*ticode->hlU()); HLTYPE &t_hl(*ticode->hlU());
@ -764,16 +801,39 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
} }
} }
void C_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE picode) {
void Function::processHliCall(Expr *_exp, iICODE picode)
{
Function * pp; Function * pp;
int cb, numArgs; int cb, numArgs;
boolT res;
int k; int k;
pp = picode->hl()->call.proc; pp = picode->hl()->call.proc;
if (pp->flg & CALL_PASCAL) cb = picode->hl()->call.args->cb;
numArgs = 0;
k = 0;
if (cb)
{ {
while ( k < cb )
{
k+=processCArg (pp, func, &(*picode), numArgs);
numArgs++;
}
}
else if ((cb == 0) && picode->ll()->testFlags(REST_STK))
{
while (! g_exp_stk.empty())
{
k+=processCArg (pp, func, &(*picode), numArgs);
numArgs++;
}
}
}
void Pascal_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE picode) {
Function * pp;
int cb, numArgs;
bool res;
int k;
pp = picode->hl()->call.proc;
cb = pp->cbParam; /* fixed # arguments */ cb = pp->cbParam; /* fixed # arguments */
k = 0; k = 0;
numArgs = 0; numArgs = 0;
@ -783,8 +843,8 @@ void Function::processHliCall(Expr *_exp, iICODE picode)
if (pp->flg & PROC_ISLIB) /* library function */ if (pp->flg & PROC_ISLIB) /* library function */
{ {
if (pp->args.numArgs > 0) if (pp->args.numArgs > 0)
_exp = adjustActArgType(_exp, pp->args[numArgs].type); _exp = func->adjustActArgType(_exp, pp->args[numArgs].type);
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), this); res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), func);
} }
else /* user function */ else /* user function */
{ {
@ -794,37 +854,20 @@ void Function::processHliCall(Expr *_exp, iICODE picode)
{ {
fprintf(stderr,"Would try to adjustForArgType with null _exp\n"); fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
} }
pp->args.adjustForArgType (numArgs,_exp->expType (this)); pp->args.adjustForArgType (numArgs,_exp->expType (func));
} }
res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), this); res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), func);
} }
if (res == false) if (res == false)
k += _exp->hlTypeSize (this); k += _exp->hlTypeSize (func);
numArgs++; numArgs++;
} }
} }
else /* CALL_C */
void Function::processHliCall(Expr *_exp, iICODE picode)
{ {
cb = picode->hl()->call.args->cb; Function * pp = picode->hl()->call.proc;
numArgs = 0; pp->callingConv()->processHLI(this,_exp,picode);
k = 0;
if (cb)
{
while ( k < cb )
{
k+=processCArg (pp, this, &(*picode), numArgs);
numArgs++;
}
}
else if ((cb == 0) && picode->ll()->testFlags(REST_STK))
{
while (! g_exp_stk.empty())
{
k+=processCArg (pp, this, &(*picode), numArgs);
numArgs++;
}
}
}
} }
@ -839,6 +882,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
HLTYPE *ti_hl=nullptr; HLTYPE *ti_hl=nullptr;
uint8_t regi; uint8_t regi;
numHlIcodes = 0; numHlIcodes = 0;
assert(&fnc->localId==&locals);
// register(s) to be forward substituted */ // register(s) to be forward substituted */
auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL>()); auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL>());
for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++) for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
@ -1039,7 +1083,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
numHlIcodes--; numHlIcodes--;
break; break;
case HLI_PUSH: case HLI_RET: case HLI_PUSH:
case HLI_RET:
ticode->hlU()->expr( _icHl.call.toAst() ); ticode->hlU()->expr( _icHl.call.toAst() );
picode->invalidate(); picode->invalidate();
numHlIcodes--; numHlIcodes--;
@ -1077,7 +1122,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
* expression stack */ * expression stack */
else if (_icHl.opcode == HLI_PUSH) else if (_icHl.opcode == HLI_PUSH)
{ {
g_exp_stk.processExpPush(numHlIcodes, picode.base()); g_exp_stk.processExpPush(numHlIcodes, *picode);
} }
else if(picode->du1.getNumRegsDef()!=0) else if(picode->du1.getNumRegsDef()!=0)
printf("Num def %d\n",picode->du1.getNumRegsDef()); printf("Num def %d\n",picode->du1.getNumRegsDef());
@ -1109,7 +1154,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
void Function::findExps() void Function::findExps()
{ {
/* Initialize expression stack */ /* Initialize expression stack */
g_exp_stk.init(); g_exp_stk.init(this);
/* Traverse tree in dfsLast order */ /* Traverse tree in dfsLast order */
for(BB *pbb : m_dfsLast | filtered(BB::ValidFunctor())) for(BB *pbb : m_dfsLast | filtered(BB::ValidFunctor()))
{ {

View File

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

View File

@ -82,7 +82,8 @@ TwoWild(uint8_t pat[])
static bool static bool
FourWild(uint8_t pat[]) FourWild(uint8_t pat[])
{ {
TwoWild(pat); if(TwoWild(pat))
return true;
return TwoWild(pat); return TwoWild(pat);
} }

View File

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

View File

@ -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,11 +144,10 @@ 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; psBB = iter2->second;
elem.BBptr = psBB; elem.BBptr = psBB;
psBB->inEdges.push_back((BB *)nullptr); psBB->inEdges.push_back((BB *)nullptr);
} }
@ -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();
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,62 +94,11 @@ 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)
/* FollowCtrl - Given an initial procedure, state information and symbol table
* builds a list of procedures reachable from the initial procedure
* using a depth first search. */
void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
{
PROG &prog(Project::get()->prog);
ICODE _Icode, *pIcode; /* This gets copied to pProc->Icode[] later */
ICODE eIcode; /* extra icodes for iDIV, iIDIV, iXCHG */
SYM * psym;
uint32_t offset;
eErrorId err;
bool done = false;
SYMTAB &global_symbol_table(Project::get()->symtab);
if (name.find("chkstk") != string::npos)
{
// Danger! Dcc will likely fall over in this code.
// So we act as though we have done with this proc
// pProc->flg &= ~TERMINATES; // Not sure about this
done = true;
// And mark it as a library function, so structure() won't choke on it
flg |= PROC_ISLIB;
return;
}
if (option.VeryVerbose)
{
printf("Parsing proc %s at %X\n", name.c_str(), pstate->IP);
}
while (! done && ! (err = scan(pstate->IP, _Icode)))
{
LLInst *ll = _Icode.ll();
pstate->IP += (uint32_t)ll->numBytes;
setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes);
process_operands(_Icode,pstate);
/* Keep track of interesting instruction flags in procedure */
flg |= (ll->getFlag() & (NOT_HLL | FLOAT_OP));
/* Check if this instruction has already been parsed */
iICODE labLoc = Icode.labelSrch(ll->label);
if (Icode.end()!=labLoc)
{ /* Synthetic jump */
_Icode.type = LOW_LEVEL;
ll->set(iJMP,I | SYNTHETIC | NO_OPS);
ll->replaceSrc(LLOperand::CreateImm2(labLoc->ll()->GetLlLabel()));
ll->label = SynthLab++;
}
/* Copy Icode to Proc */
if ((_Icode.ll()->getOpcode() == iDIV) || (_Icode.ll()->getOpcode() == iIDIV))
{ {
/* MOV rTMP, reg */ /* MOV rTMP, reg */
eIcode = ICODE();
ICODE eIcode = ICODE();
eIcode.type = LOW_LEVEL; eIcode.type = LOW_LEVEL;
eIcode.ll()->set(iMOV,0,rTMP); eIcode.ll()->set(iMOV,0,rTMP);
@ -175,14 +129,14 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
eIcode.ll()->replaceSrc(_Icode.ll()->src()); eIcode.ll()->replaceSrc(_Icode.ll()->src());
eIcode.du = _Icode.du; eIcode.du = _Icode.du;
eIcode.ll()->label = SynthLab++; eIcode.ll()->label = SynthLab++;
pIcode = Icode.addIcode(&eIcode); return Icode.addIcode(&eIcode);
} }
else if (_Icode.ll()->getOpcode() == iXCHG) ICODE *Function::translate_XCHG(LLInst *ll,ICODE &_Icode)
{ {
/* MOV rTMP, regDst */ /* MOV rTMP, regDst */
eIcode = ICODE(); ICODE eIcode;
eIcode.type = LOW_LEVEL; eIcode.type = LOW_LEVEL;
eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,_Icode.ll()->m_dst); eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,ll->m_dst);
eIcode.setRegDU( rTMP, eDEF); eIcode.setRegDU( rTMP, eDEF);
if(eIcode.ll()->src().getReg2()) if(eIcode.ll()->src().getReg2())
{ {
@ -191,11 +145,11 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
if((srcreg>=rAL) && (srcreg<=rBH)) if((srcreg>=rAL) && (srcreg<=rBH))
eIcode.ll()->setFlags( B ); eIcode.ll()->setFlags( B );
} }
eIcode.ll()->label = _Icode.ll()->label; eIcode.ll()->label = ll->label;
Icode.addIcode(&eIcode); Icode.addIcode(&eIcode);
/* MOV regDst, regSrc */ /* MOV regDst, regSrc */
_Icode.ll()->set(iMOV,SYNTHETIC|_Icode.ll()->getFlag()); ll->set(iMOV,SYNTHETIC|ll->getFlag());
Icode.addIcode(&_Icode); Icode.addIcode(&_Icode);
ll->setOpcode(iXCHG); /* for next case */ ll->setOpcode(iXCHG); /* for next case */
@ -213,8 +167,65 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
eIcode.ll()->replaceSrc(rTMP); eIcode.ll()->replaceSrc(rTMP);
eIcode.setRegDU( rTMP, eUSE); eIcode.setRegDU( rTMP, eUSE);
eIcode.ll()->label = SynthLab++; eIcode.ll()->label = SynthLab++;
pIcode = Icode.addIcode(&eIcode); return Icode.addIcode(&eIcode);
} }
/** FollowCtrl - Given an initial procedure, state information and symbol table
* builds a list of procedures reachable from the initial procedure
* using a depth first search. */
void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
{
PROG &prog(Project::get()->prog);
ICODE _Icode, *pIcode; /* This gets copied to pProc->Icode[] later */
SYM * psym;
uint32_t offset;
eErrorId err;
bool done = false;
SYMTAB &global_symbol_table(Project::get()->symtab);
if (name.find("chkstk") != string::npos)
{
// Danger! Dcc will likely fall over in this code.
// So we act as though we have done with this proc
// pProc->flg &= ~TERMINATES; // Not sure about this
done = true;
// And mark it as a library function, so structure() won't choke on it
flg |= PROC_ISLIB;
return;
}
if (option.VeryVerbose)
{
printf("Parsing proc %s at %X\n", name.c_str(), pstate->IP);
}
while (! done )
{
err = scan(pstate->IP, _Icode);
if(err)
break;
LLInst *ll = _Icode.ll();
pstate->IP += (uint32_t)ll->numBytes;
setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes);
process_operands(_Icode,pstate);
/* Keep track of interesting instruction flags in procedure */
flg |= (ll->getFlag() & (NOT_HLL | FLOAT_OP));
/* Check if this instruction has already been parsed */
iICODE labLoc = Icode.labelSrch(ll->label);
if (Icode.end()!=labLoc)
{ /* Synthetic jump */
_Icode.type = LOW_LEVEL;
ll->set(iJMP,I | SYNTHETIC | NO_OPS);
ll->replaceSrc(LLOperand::CreateImm2(labLoc->ll()->GetLlLabel()));
ll->label = SynthLab++;
}
/* Copy Icode to Proc */
if ((ll->getOpcode() == iDIV) || (ll->getOpcode() == iIDIV))
pIcode = translate_DIV(ll, _Icode);
else if (_Icode.ll()->getOpcode() == iXCHG)
pIcode = translate_XCHG(ll, _Icode);
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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -842,9 +842,9 @@ 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);

View File

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