diff --git a/CMakeLists.txt b/CMakeLists.txt index 60d6cd4..9140cee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ set(dcc_LIB_SOURCES src/symtab.cpp src/udm.cpp src/BasicBlock.cpp + src/CallConvention.cpp ) set(dcc_SOURCES src/dcc.cpp @@ -108,6 +109,8 @@ set(dcc_HEADERS include/Procedure.h include/StackFrame.h include/BasicBlock.h + include/CallConvention.h + ) SOURCE_GROUP(Source FILES ${dcc_SOURCES}) 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_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) ADD_SUBDIRECTORY(src) endif() diff --git a/include/BasicBlock.h b/include/BasicBlock.h index 653fe46..bf4e56c 100644 --- a/include/BasicBlock.h +++ b/include/BasicBlock.h @@ -37,7 +37,7 @@ private: inEdges(0), edges(0),beenOnH(0),inEdgeCount(0),reachingInt(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) { @@ -90,7 +90,7 @@ public: int dfsLastNum; /* DFS #: last visit of node */ int immedDom; /* Immediate dominator (dfsLast index) */ 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 */ size_t numBackEdges; /* # of back edges */ int loopHead; /* most nested loop head to which this node belongs (dfsLast) */ @@ -101,7 +101,7 @@ public: 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 * 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 mergeFallThrough(CIcodeRec &Icode); void dfsNumbering(std::vector &dfsLast, int *first, int *last); diff --git a/include/BinaryImage.h b/include/BinaryImage.h index ec35af2..4ecd86f 100644 --- a/include/BinaryImage.h +++ b/include/BinaryImage.h @@ -17,5 +17,6 @@ struct PROG /* Loaded program image parameters */ int cbImage; /* Length of image in bytes */ const uint8_t *image() const {return Imagez;} uint8_t * Imagez; /* Allocated by loader to hold entire program image */ + int addressingMode; }; diff --git a/include/CallConvention.h b/include/CallConvention.h new file mode 100644 index 0000000..b46b2c3 --- /dev/null +++ b/include/CallConvention.h @@ -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 &); +}; diff --git a/include/Procedure.h b/include/Procedure.h index ff361ea..d88da04 100644 --- a/include/Procedure.h +++ b/include/Procedure.h @@ -1,12 +1,14 @@ #pragma once #include -#include +//#include #include +#include #include "BasicBlock.h" #include "locident.h" #include "state.h" #include "icode.h" #include "StackFrame.h" +#include "CallConvention.h" /* PROCEDURE NODE */ struct CALL_GRAPH; struct Expr; @@ -15,9 +17,7 @@ struct Function; struct CALL_GRAPH; struct PROG; -typedef llvm::iplist FunctionListType; -typedef FunctionListType lFunction; -typedef lFunction::iterator ilFunction; +struct Function; namespace llvm { @@ -49,9 +49,9 @@ enum PROC_FLAGS PROC_IJMP =0x00000200,/* Proc incomplete due to indirect jmp */ PROC_ICALL =0x00000400, /* Proc incomplete due to indirect call */ PROC_HLL =0x00001000, /* Proc is likely to be from a HLL */ - CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */ - CALL_C =0x00004000, /* Proc uses C calling convention */ - CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */ +// CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */ +// CALL_C =0x00004000, /* Proc uses C calling convention */ +// CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */ PROC_NEAR =0x00010000, /* Proc exits with near return */ PROC_FAR =0x00020000, /* Proc exits with far return */ 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 */ PROC_IS_FUNC=0x00800000, /* Proc is a function */ 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_RUNTIME=0x08000000, /* Proc is part of the runtime support */ PROC_ISLIB =0x10000000, /* Proc is a library function */ PROC_ASM =0x20000000, /* Proc is an intrinsic assembler routine */ 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 { - bool m_vararg; + bool m_vararg=false; bool isVarArg() const {return m_vararg;} }; struct Assignment @@ -113,16 +113,24 @@ struct Function : public llvm::ilist_node // BasicBlock iterators... typedef BasicBlockListType::iterator iterator; typedef BasicBlockListType::const_iterator const_iterator; -private: +protected: 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: + FunctionType * type; + CConv * m_call_conv; uint32_t procEntry; /* label number */ std::string name; /* Meaningful name for this proc */ STATE state; /* Entry state */ int depth; /* Depth at which we found it - for printing */ - uint32_t flg; /* Combination of Icode & Proc flags */ - int16_t cbParam; /* Probable no. of bytes of parameters */ + uint32_t flg; /* Combination of Icode & Proc flags */ + int16_t cbParam; /* Probable no. of bytes of parameters */ STKFRAME args; /* Array of arguments */ LOCAL_ID localId; /* Local identifiers */ ID retVal; /* Return value - identifier */ @@ -130,10 +138,8 @@ public: /* Icodes and control flow graph */ CIcodeRec Icode; /* Object with ICODE records */ FunctionCfg m_actual_cfg; - std::list m_cfg; /* Ptr. to BB list/CFG */ std::vector m_dfsLast; - std::list heldBBs; - //BB * *dfsLast; /* Array of pointers to BBs in dfsLast + std::map m_ip_to_bb; // * (reverse postorder) order */ size_t numBBs; /* Number of BBs in the graph cfg */ bool hasCase; /* Procedure has a case node */ @@ -143,18 +149,23 @@ public: LivenessSet liveOut; /* Registers that may be used in successors */ 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), - hasCase(false),liveAnal(0)//,next(0),prev(0) - { + virtual ~Function() { + delete type; } 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); r->name = nm; 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 isLibrary() const { return (flg & PROC_ISLIB)!=0;} void compoundCond(); @@ -172,7 +183,7 @@ public: void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate); void process_operands(ICODE &pIcode, STATE *pstate); 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 codeGen(std::ostream &fs); void mergeFallThrough(BB *pBB); @@ -191,6 +202,8 @@ public: Expr * adjustActArgType(Expr *_exp, hlType forType); std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc); void processDosInt(STATE *pstate, PROG &prog, bool done); + ICODE *translate_DIV(LLInst *ll, ICODE &_Icode); + ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode); protected: void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table); bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate); @@ -218,6 +231,28 @@ protected: void findIdioms(); void propLong(); void genLiveKtes(); - uint8_t findDerivedSeq (derSeq &derivedGi); + bool findDerivedSeq(derSeq &derivedGi); bool nextOrderGraph(derSeq &derivedGi); }; +namespace llvm { +template<> struct ilist_traits + : public ilist_default_traits { + + // createSentinel is used to get hold of the node that marks the end of the + // list... (same trick used here as in ilist_traits) + typename ::Function *createSentinel() const { + return static_cast(&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 Sentinel; +}; +} +typedef llvm::iplist FunctionListType; +typedef FunctionListType lFunction; +typedef lFunction::iterator ilFunction; diff --git a/include/ast.h b/include/ast.h index d745105..6ba45a2 100644 --- a/include/ast.h +++ b/include/ast.h @@ -51,7 +51,8 @@ public: { } - virtual ~Expr(); + /** Recursively deallocates the abstract syntax tree rooted at *exp */ + virtual ~Expr() {} public: virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0; 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); delete m_lhs; delete m_rhs; + m_lhs=m_rhs=nullptr; } static BinaryOperator *Create(condOp o,Expr *l,Expr *r) { @@ -132,21 +134,28 @@ struct BinaryOperator : public Expr } 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) { - return new BinaryOperator(AND,l,r); + return Create(AND,l,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) { - 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); virtual Expr *inverse() const; virtual Expr *clone() const; @@ -281,20 +290,22 @@ struct FuncNode : public AstIdent }; struct RegisterNode : public AstIdent { + const LOCAL_ID *m_syms; regType regiType; /* for REGISTER only */ int regiIdx; /* index into localId, REGISTER */ 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); regiType = reg_type; regiIdx = idx; } 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 { return new RegisterNode(*this); diff --git a/include/dcc.h b/include/dcc.h index 7ffbff8..390b795 100644 --- a/include/dcc.h +++ b/include/dcc.h @@ -101,8 +101,6 @@ void SetupLibCheck(void); /* chklib.c */ void CleanupLibCheck(void); /* chklib.c */ bool LibCheck(Function &p); /* chklib.c */ -/* Exported functions from procs.c */ -boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction); /* Exported functions from hlicode.c */ const char *writeJcond(const HLTYPE &, Function *, int *); diff --git a/include/graph.h b/include/graph.h index 8923855..d10df9f 100644 --- a/include/graph.h +++ b/include/graph.h @@ -68,32 +68,24 @@ typedef std::list queue; struct interval { - uint8_t numInt; /* # of the interval */ - uint8_t numOutEdges; /* Number of out edges */ + uint8_t numInt=0; /* # of the interval */ + uint8_t numOutEdges=0; /* Number of out edges */ queue nodes; /* Nodes of the interval*/ queue::iterator currNode; /* Current node */ - interval *next; /* Next interval */ - BB *firstOfInt(); - interval() - { - numInt=numOutEdges=0; - currNode=nodes.end(); - next=0; - } - void appendNodeInt(queue &pqH, BB *node); + interval * next=0; /* Next interval */ + BB * firstOfInt(); + interval() : currNode(nodes.end()){ + } + void appendNodeInt(queue &pqH, BB *node); }; /* Derived Sequence structure */ struct derSeq_Entry { - BB * Gi; /* Graph pointer */ + BB * Gi=nullptr; /* Graph pointer */ std::list m_intervals; - interval * Ii; /* Interval list of Gi */ - derSeq_Entry() : Gi(0),Ii(0) - { - - } + interval * Ii=nullptr; /* Interval list of Gi */ ~derSeq_Entry(); public: void findIntervals(Function *c); diff --git a/include/icode.h b/include/icode.h index 6d5d761..c1ae718 100644 --- a/include/icode.h +++ b/include/icode.h @@ -18,6 +18,7 @@ #include "libdis.h" #include "Enums.h" #include "state.h" // State depends on INDEXBASE, but later need STATE +#include "CallConvention.h" //enum condId; @@ -307,7 +308,7 @@ struct 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;} void setImmediate(bool x) { immed=x;} bool compound() const {return is_compound;} // dx:ax pair diff --git a/include/locident.h b/include/locident.h index 4d544af..d1a1533 100644 --- a/include/locident.h +++ b/include/locident.h @@ -101,7 +101,7 @@ public: char macro[10]; /* Macro for this identifier */ std::string name; /* Identifier's name */ union ID_UNION { /* Different types of identifiers */ - friend class ID; + friend struct ID; protected: LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */ public: @@ -118,27 +118,27 @@ public: } longKte; ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/} } id; - LONGID_TYPE &longId() {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;} - const LONG_STKID_TYPE &longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;} - ID(); - ID(hlType t, frameType f); - ID(hlType t, const LONGID_TYPE &s); - ID(hlType t, const LONG_STKID_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);} - uint16_t typeBitsize() const - { - return TypeContainer::typeSize(type)*8; - } - bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); } - void setLocalName(int i) - { - char buf[32]; - sprintf (buf, "loc%d", i); - name=buf; - } + LONGID_TYPE & longId() {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;} + const LONG_STKID_TYPE & longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;} + ID(); + ID(hlType t, frameType f); + ID(hlType t, const LONGID_TYPE &s); + ID(hlType t, const LONG_STKID_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);} + uint16_t typeBitsize() const + { + return TypeContainer::typeSize(type)*8; + } + bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); } + void setLocalName(int i) + { + char buf[32]; + sprintf (buf, "loc%d", i); + name=buf; + } }; struct LOCAL_ID diff --git a/include/project.h b/include/project.h index 15a7b5b..32380d6 100644 --- a/include/project.h +++ b/include/project.h @@ -46,7 +46,7 @@ public: const std::string &binary_path() const {return m_fname;} ilFunction funcIter(Function *to_find); ilFunction findByEntry(uint32_t entry); - ilFunction createFunction(); + ilFunction createFunction(FunctionType *f,const std::string &name); bool valid(ilFunction iter); int getSymIdxByAdd(uint32_t adr); diff --git a/include/symtab.h b/include/symtab.h index b29363d..ed697e3 100644 --- a/include/symtab.h +++ b/include/symtab.h @@ -112,6 +112,6 @@ constexpr int NUM_TABLE_TYPES = int(Comment)+1; /* Number of entries: must be la void createSymTables(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 */ diff --git a/include/types.h b/include/types.h index d81dd8d..71c0c36 100644 --- a/include/types.h +++ b/include/types.h @@ -12,10 +12,6 @@ #define MAX 0x7FFFFFFF /* 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 */ @@ -29,12 +25,12 @@ typedef unsigned char boolT; /* 8 bits */ // 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 //#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 */ /* 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 */ #define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1))) diff --git a/src/BasicBlock.cpp b/src/BasicBlock.cpp index 6d86a61..10f182f 100644 --- a/src/BasicBlock.cpp +++ b/src/BasicBlock.cpp @@ -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 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; 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->latchNode= pnewBB->loopFollow = NO_NODE; pnewBB->instructions = r; - + int addr = pnewBB->begin()->loc_ip; /* Mark the basic block to which the icodes belong to, but only for * real code basic blocks (ie. not interval bbs) */ if(parent) { //setInBB should automatically handle if our range is empty 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); pnewBB->Parent = parent; } @@ -48,7 +50,7 @@ BB *BB::Create(const rCODE &r,uint8_t _nodeType, Function *parent) BB *BB::CreateIntervalBB(Function *parent) { 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", diff --git a/src/CallConvention.cpp b/src/CallConvention.cpp new file mode 100644 index 0000000..dad4a8c --- /dev/null +++ b/src/CallConvention.cpp @@ -0,0 +1,36 @@ +#include +#include +#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"; +} diff --git a/src/Procedure.cpp b/src/Procedure.cpp index 492e5dc..536e353 100644 --- a/src/Procedure.cpp +++ b/src/Procedure.cpp @@ -30,3 +30,8 @@ void JumpTable::pruneEntries(uint16_t cs) } } + + +void Function::callingConv(CConv::Type v) { + m_call_conv=CConv::create(v); +} diff --git a/src/RegisterNode.cpp b/src/RegisterNode.cpp index 2cf9700..3041c4d 100644 --- a/src/RegisterNode.cpp +++ b/src/RegisterNode.cpp @@ -16,8 +16,9 @@ #include "project.h" using namespace std; 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); hlType type_sel; regType reg_type; @@ -59,6 +60,7 @@ string RegisterNode::walkCondExpr(Function *pProc, int *numLoc) const std::ostringstream codeOut; std::ostringstream o; + assert(&pProc->localId==m_syms); ID *id = &pProc->localId.id_arr[regiIdx]; if (id->name[0] == '\0') /* no name */ { @@ -83,8 +85,6 @@ int RegisterNode::hlTypeSize(Function *) const return (2); } - - hlType RegisterNode::expType(Function *pproc) const { 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) { + assert(locsym==m_syms); eReg treeReg = locsym->id_arr[regiIdx].id.regi; if (treeReg == regi) /* uint16_t reg */ { @@ -104,6 +105,7 @@ Expr *RegisterNode::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *loc { return _expr; } + return nullptr; } bool RegisterNode::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId) { diff --git a/src/ast.cpp b/src/ast.cpp index 90ad961..c1dd306 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -89,9 +89,9 @@ void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu) break; case eUSE: if (duDu == eDEF) - du.use=duIcode.du.def; + du.use = duIcode.du.def; else - du.use =duIcode.du.use; + du.use = duIcode.du.use; break; case USE_DEF: du = duIcode.du; @@ -134,17 +134,14 @@ string GlobalVariable::walkCondExpr(Function *, int *) const { if(valid) return Project::get()->symtab[globIdx].name; - else - return "INVALID GlobalVariable"; + return "INVALID GlobalVariable"; } /* Returns an identifier conditional expression node of type LOCAL_VAR */ AstIdent *AstIdent::Loc(int off, LOCAL_ID *localId) { size_t i; - AstIdent *newExp; - - newExp = new AstIdent(); + AstIdent *newExp = new AstIdent(); newExp->ident.idType = LOCAL_VAR; 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. */ AstIdent *AstIdent::LongIdx (int idx) { - AstIdent *newExp = new AstIdent(); + AstIdent *newExp = new AstIdent; newExp->ident.idType = LONG_VAR; newExp->ident.idNode.longIdx = idx; return (newExp); @@ -222,7 +219,6 @@ AstIdent *AstIdent::String(uint32_t idx) /* 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) { - int idx; AstIdent *newExp; /* Check for long constant and save it as a constant expression */ if ((sd == SRC) && pIcode->ll()->testFlags(I)) /* constant */ @@ -275,10 +271,10 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_) break; } 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; 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; default: fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type); @@ -826,18 +822,14 @@ Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx) 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 * node. Returns the copy. */ Expr *BinaryOperator::clone() const { - BinaryOperator* newExp=new BinaryOperator(m_op); /* Expression node copy */ - newExp->m_lhs = m_lhs->clone(); - newExp->m_rhs = m_rhs->clone(); - return newExp; + /* Expression node copy */ + return new BinaryOperator(m_op,m_lhs->clone(),m_rhs->clone()); } Expr *BinaryOperator::inverse() const @@ -878,15 +870,13 @@ Expr *AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId) { otherRegi = otherLongRegi (regi, ident.idNode.longIdx, locId); 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; } eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl) { - ID *id; - - id = &locTbl->id_arr[idx]; + ID *id = &locTbl->id_arr[idx]; if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) || (id->type == TYPE_LONG_UNSIGN))) { @@ -933,6 +923,3 @@ hlType FuncNode::expType(Function *) const { return call.proc->retVal.type; } - - - diff --git a/src/chklib.cpp b/src/chklib.cpp index 766b266..ca45627 100644 --- a/src/chklib.cpp +++ b/src/chklib.cpp @@ -74,7 +74,7 @@ void checkHeap(char *msg); /* For debugging */ 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); /* * * * * * * * * * * * * * * *\ @@ -477,6 +477,7 @@ bool LibCheck(Function & pProc) if ((numFunc == 0) || (i=searchPList(ht[h].htSym)) != NIL) { pProc.flg |= PROC_ISLIB; /* It's a lib function */ + pProc.callingConv(CConv::C); if (i != NIL) { /* 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 ***/ } } - if (pFunc[i].bVararg) - pProc.flg |= PROC_VARARG; + pProc.getFunctionType()->m_vararg = pFunc[i].bVararg; } } else if (i == NIL) @@ -532,7 +532,7 @@ bool LibCheck(Function & pProc) 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 -void -readFileSection(uint16_t* p, int len, FILE* f) +void readFileSection(uint16_t* p, int len, FILE* f) { 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 for the pattern that is used up by the WILD uint8_t, tough - it will match with 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 i, j; @@ -763,7 +762,7 @@ void STATE::checkStartup() } printf("Model: %c\n", chModel); - + prog.addressingMode = chModel; /* Now decide the compiler vendor and version number */ if (memcmp(&prog.image()[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0) @@ -953,8 +952,7 @@ void readProtoFile(void) } -int -searchPList(char *name) +int searchPList(char *name) { /* Search through the symbol names for the name */ /* Use binary search */ @@ -991,10 +989,7 @@ searchPList(char *name) { return mn; /* Found! */ } - else - { - return NIL; - } + return NIL; } diff --git a/src/comwrite.cpp b/src/comwrite.cpp index b38476e..e98b346 100644 --- a/src/comwrite.cpp +++ b/src/comwrite.cpp @@ -164,17 +164,17 @@ void LLInst::writeIntComment (std::ostringstream &s) { switch (m_dst.off) { - case 0x01 : - s << "Print spooler"; - break; - case 0x02: - s << "Assign"; - break; - case 0x10: - s << "Share"; - break; - case 0xB7: - s << "Append"; + case 0x01 : + s << "Print spooler"; + break; + case 0x02: + s << "Assign"; + break; + case 0x10: + s << "Share"; + break; + case 0xB7: + s << "Append"; } } else @@ -235,29 +235,23 @@ void Function::writeProcComments(std::ostream &ostr) ostr << " * Untranslatable routine. Assembler provided.\n"; if (this->flg & PROC_IS_FUNC) switch (this->retVal.type) { // TODO: Functions return value in various regs - case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: - ostr << " * Return value in register al.\n"; - break; - case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: - ostr << " * Return value in register ax.\n"; - break; - case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: - ostr << " * Return value in registers dx:ax.\n"; - break; - default: - fprintf(stderr,"Unknown retval type %d",this->retVal.type); - break; + case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: + ostr << " * Return value in register al.\n"; + break; + case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: + ostr << " * Return value in register ax.\n"; + break; + case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: + ostr << " * Return value in registers dx:ax.\n"; + break; + default: + fprintf(stderr,"Unknown retval type %d",this->retVal.type); + break; } /* eos */ } /* Calling convention */ - if (this->flg & CALL_PASCAL) - 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"; - + callingConv()->writeComments(ostr); /* Other flags */ if (this->flg & (PROC_BADINST | PROC_IJMP)) { diff --git a/src/control.cpp b/src/control.cpp index 749ff92..7c2c62b 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -105,7 +105,7 @@ static void freeList (nodeList &l) /* 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(); } diff --git a/src/dataflow.cpp b/src/dataflow.cpp index fa18f6f..75c1fb9 100644 --- a/src/dataflow.cpp +++ b/src/dataflow.cpp @@ -15,23 +15,32 @@ #include #include "dcc.h" - +#include "project.h" using namespace boost; using namespace boost::adaptors; struct ExpStack { + Function *func; typedef std::list EXP_STK; EXP_STK expStk; /* local expression stack */ - void init(); + void init(Function *f); void push(Expr *); - Expr * pop(); + Expr * pop(); + Expr * top() const { + if(!expStk.empty()) + return expStk.back(); + return nullptr; + } int numElem(); - boolT empty(); - void processExpPush(int &numHlIcodes, iICODE picode) + bool empty(); + void processExpPush(int &numHlIcodes, ICODE &picode) { - push(picode->hlU()->expr()); - picode->invalidate(); + RegisterNode *rn = dynamic_cast(picode.hlU()->expr()); + if(rn) + assert(rn->m_syms==&func->localId); + push(picode.hlU()->expr()); + picode.invalidate(); numHlIcodes--; } @@ -42,8 +51,9 @@ struct ExpStack /* Reinitalizes the expression stack (expStk) to NULL, by freeing all the * space allocated (if any). */ -void ExpStack::init() +void ExpStack::init(Function *f) { + func=f; expStk.clear(); } @@ -60,7 +70,7 @@ void ExpStack::push(Expr *expr) Expr *ExpStack::pop() { if(expStk.empty()) - return expStk.back(); + return nullptr; Expr *topExp = expStk.back(); expStk.pop_back(); return topExp; @@ -73,7 +83,7 @@ int ExpStack::numElem() } /* Returns whether the expression stack is empty or not */ -boolT ExpStack::empty() +bool ExpStack::empty() { return expStk.empty(); } @@ -119,7 +129,7 @@ void Function::elimCondCodes () uint8_t use; /* Used 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 *lhs; /* Destination operand */ BinaryOperator *_expr; /* Boolean expression */ @@ -148,43 +158,43 @@ void Function::elimCondCodes () if ((use & def) != use) continue; notSup = false; - LLOperand *dest_ll = defAt->ll()->get(DST); - LLOperand *src_ll = defAt->ll()->get(SRC); + LLOperand *dest_ll = defIcode.ll()->get(DST); + LLOperand *src_ll = defIcode.ll()->get(SRC); if ((useAtOp >= iJB) && (useAtOp <= iJNS)) { iICODE befDefAt = (++riICODE(defAt)).base(); - switch (defAt->ll()->getOpcode()) + switch (defIcode.ll()->getOpcode()) { - case iCMP: - rhs = srcIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE); - lhs = dstIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE); - break; + case iCMP: + rhs = srcIdent (*defIcode.ll(), this, befDefAt,*useAt, eUSE); + lhs = dstIdent (*defIcode.ll(), this, befDefAt,*useAt, eUSE); + break; - case iOR: - lhs = defAt->hl()->asgn.lhs()->clone(); - useAt->copyDU(*defAt, eUSE, eDEF); - //if (defAt->ll()->testFlags(B)) - rhs = new Constant(0, dest_ll->byteWidth()); - break; + case iOR: + lhs = defIcode.hl()->asgn.lhs()->clone(); + useAt->copyDU(*defAt, eUSE, eDEF); + //if (defAt->ll()->testFlags(B)) + rhs = new Constant(0, dest_ll->byteWidth()); + break; - case iTEST: - rhs = srcIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE); - lhs = dstIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE); - lhs = BinaryOperator::And(lhs, rhs); -// if (defAt->ll()->testFlags(B)) - rhs = new Constant(0, dest_ll->byteWidth()); - break; - case iINC: - case iDEC: //WARNING: verbatim copy from iOR needs fixing ? - lhs = defAt->hl()->asgn.lhs()->clone(); - useAt->copyDU(*defAt, eUSE, eDEF); - rhs = new Constant(0, dest_ll->byteWidth()); - break; - default: - notSup = true; - std::cout << hex<loc_ip; - reportError (JX_NOT_DEF, defAt->ll()->getOpcode()); - flg |= PROC_ASM; /* generate asm */ + case iTEST: + rhs = srcIdent (*defIcode.ll(),this, befDefAt,*useAt, eUSE); + lhs = dstIdent (*defIcode.ll(),this, befDefAt,*useAt, eUSE); + lhs = BinaryOperator::And(lhs, rhs); + // if (defAt->ll()->testFlags(B)) + rhs = new Constant(0, dest_ll->byteWidth()); + break; + case iINC: + case iDEC: //WARNING: verbatim copy from iOR needs fixing ? + lhs = defIcode.hl()->asgn.lhs()->clone(); + useAt->copyDU(*defAt, eUSE, eDEF); + rhs = new Constant(0, dest_ll->byteWidth()); + break; + default: + notSup = true; + std::cout << hex<getOpcode()); + flg |= PROC_ASM; /* generate asm */ } if (! notSup) { @@ -285,7 +295,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut) ; LivenessSet prevLiveOut, /* previous live out */ 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 = in_liveOut; @@ -353,17 +363,17 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut) if ((! (pcallee->flg & PROC_ISLIB)) || ( pbb->liveOut.any() )) { switch (pcallee->retVal.type) { - case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: - ticode.du1.setDef(rAX).addDef(rDX); - //TODO: use Calling convention to properly set regs here - break; - case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: - case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: - ticode.du1.setDef(rAX); - break; - default: - ticode.du1 = ICODE::DU1(); // was .numRegsDef = 0 - //fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type); + case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: + ticode.du1.setDef(rAX).addDef(rDX); + //TODO: use Calling convention to properly set regs here + break; + case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: + case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: + ticode.du1.setDef(rAX); + break; + default: + ticode.du1 = ICODE::DU1(); // was .numRegsDef = 0 + //fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type); } /*eos*/ /* Propagate def/use results to calling icode */ @@ -411,18 +421,18 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at) if (distance(start_at,end())>1) /* several instructions */ { 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 checked_icode=hl_range.begin(); ++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 - continue; + ICODE &ic(*checked_icode); /* 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()); /* 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(); break; @@ -449,27 +459,26 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at) * on optimized code. */ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode) { - if ((picode.hl()->opcode == HLI_CALL) && - (picode.hl()->call.proc->flg & PROC_IS_FUNC)) - { - BB *tbb = this->edges[0].BBptr; - auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level); - for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter) - { - /* if used, get icode index */ - if ( iter->du.use.testRegAndSubregs(regi) ) - picode.du1.recordUse(defRegIdx,iter.base()); - /* if defined, stop finding uses for this reg */ - if (iter->du.def.testRegAndSubregs(regi)) - break; - } + if (!((picode.hl()->opcode == HLI_CALL) && (picode.hl()->call.proc->flg & PROC_IS_FUNC))) + return; - /* if not used in this basic block, check if the - * register is live out, if so, make it the last - * definition of this register */ - if ( picode.du1.used(defRegIdx) && tbb->liveOut.testRegAndSubregs(regi)) - picode.du.lastDefRegi.addReg(regi); + BB *tbb = this->edges[0].BBptr; + auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level); + for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter) + { + /* if used, get icode index */ + if ( iter->du.use.testRegAndSubregs(regi) ) + picode.du1.recordUse(defRegIdx,iter.base()); + /* if defined, stop finding uses for this reg */ + if (iter->du.def.testRegAndSubregs(regi)) + break; } + + /* if not used in this basic block, check if the + * register is live out, if so, make it the last + * definition of this register */ + if ( picode.du1.used(defRegIdx) && tbb->liveOut.testRegAndSubregs(regi)) + picode.du.lastDefRegi.addReg(regi); } /* If not used within this bb or in successors of this @@ -511,8 +520,7 @@ void BB::genDU1() * Note that register variables should not be considered registers. */ assert(nullptr!=Parent); - ICODE::TypeFilter select_high_level; - auto all_high_levels = instructions | filtered(select_high_level); + auto all_high_levels = instructions | filtered(ICODE::select_high_level); for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++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 * instruction f up to instruction t. */ 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) { - if (ident.idType == REGISTER) - { - assert(false); - } - else + if (ident.idType != REGISTER) return true; - + assert(false); + return false; } -/* 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 - * argument list. */ -/// @returns the type size of the stored Arg -static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t numArgs) +/** 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 + argument list. + @returns the type size of the stored Arg +*/ +int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE * picode, size_t numArgs) { Expr *_exp; bool res; + int size_of_arg=0; + PROG &prog(Project::get()->prog); + /* if (numArgs == 0) return; */ - + assert(pProc==g_exp_stk.func); _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()) - _exp = pProc->adjustActArgType (_exp, pp->args[numArgs].type); + if (numArgs < callee->args.size()) { + if(_exp==nullptr) + fprintf(stderr,"Would try to adjustForArgType with null _exp\n"); + else + _exp = pProc->adjustActArgType (_exp, callee->args[numArgs].type); + } + } + else { + if(numArgsargs.size()) { + if(prog.addressingMode=='l') { + if((callee->args[numArgs].type==TYPE_STR)||(callee->args[numArgs].type==TYPE_PTR)) { + RegisterNode *rn = dynamic_cast(g_exp_stk.top()); + AstIdent *idn = dynamic_cast(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 - _exp = pProc->adjustActArgType (_exp, pp->args[numArgs].type); } } else /* user function */ { - if (pp->args.numArgs > 0) + if (callee->args.numArgs > 0) { if(_exp==nullptr) fprintf(stderr,"Would try to adjustForArgType with null _exp\n"); else - pp->args.adjustForArgType (numArgs, _exp->expType (pProc)); + callee->args.adjustForArgType (numArgs, _exp->expType (pProc)); } } res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc); - /* Do not update the size of k if the expression was a segment register * in a near call */ if (res == false) { if(_exp==nullptr) - return 2; - return _exp->hlTypeSize (pProc); + return 2+size_of_arg; + return _exp->hlTypeSize (pProc)+size_of_arg; } return 0; // be default we do not know the size of the argument } @@ -709,122 +746,128 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t * For HLI_CALL hlIcodes, places the arguments in the argument list. */ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const { - boolT res; + bool res; HLTYPE &p_hl(*picode->hlU()); HLTYPE &t_hl(*ticode->hlU()); AstIdent *lhs_ident = dynamic_cast(p_hl.asgn.lhs()); switch (t_hl.opcode) { - case HLI_ASSIGN: + case HLI_ASSIGN: + assert(lhs_ident); + if(isLong) + { + forwardSubsLong (lhs_ident->ident.idNode.longIdx, + p_hl.asgn.rhs, picode,ticode, + &numHlIcodes); + } + else + this->forwardSubs (lhs_ident, p_hl.asgn.rhs, picode, ticode, numHlIcodes); + break; + + case HLI_JCOND: case HLI_PUSH: case HLI_RET: + if(isLong) + { assert(lhs_ident); - if(isLong) - { - forwardSubsLong (lhs_ident->ident.idNode.longIdx, - p_hl.asgn.rhs, picode,ticode, - &numHlIcodes); - } - else - this->forwardSubs (lhs_ident, p_hl.asgn.rhs, picode, ticode, numHlIcodes); - break; - - case HLI_JCOND: case HLI_PUSH: case HLI_RET: - if(isLong) - { - assert(lhs_ident); - res = Expr::insertSubTreeLongReg ( - p_hl.asgn.rhs, - t_hl.exp.v, - lhs_ident->ident.idNode.longIdx); - } - else - { - RegisterNode *lhs_reg = dynamic_cast(p_hl.asgn.lhs()); - assert(lhs_reg); - res = Expr::insertSubTreeReg ( - t_hl.exp.v, - p_hl.asgn.rhs, - id_arr[lhs_reg->regiIdx].id.regi, - this); - } - if (res) - { - picode->invalidate(); - numHlIcodes--; - } - break; - - case HLI_CALL: /* register arguments */ - newRegArg ( picode, ticode); + res = Expr::insertSubTreeLongReg ( + p_hl.asgn.rhs, + t_hl.exp.v, + lhs_ident->ident.idNode.longIdx); + } + else + { + RegisterNode *lhs_reg = dynamic_cast(p_hl.asgn.lhs()); + assert(lhs_reg); + res = Expr::insertSubTreeReg ( + t_hl.exp.v, + p_hl.asgn.rhs, + id_arr[lhs_reg->regiIdx].id.regi, + this); + } + if (res) + { picode->invalidate(); numHlIcodes--; - break; - default: - fprintf(stderr,"unhandled LOCAL_ID::processTargetIcode opcode %d\n",t_hl.opcode); + } + break; + case HLI_CALL: /* register arguments */ + newRegArg ( picode, ticode); + picode->invalidate(); + numHlIcodes--; + break; + default: + fprintf(stderr,"unhandled LOCAL_ID::processTargetIcode opcode %d\n",t_hl.opcode); + + } +} +void C_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE picode) { + Function * pp; + int cb, numArgs; + int k; + pp = picode->hl()->call.proc; + 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 */ + k = 0; + numArgs = 0; + while(kflg & PROC_ISLIB) /* library function */ + { + if (pp->args.numArgs > 0) + _exp = func->adjustActArgType(_exp, pp->args[numArgs].type); + res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), func); + } + else /* user function */ + { + if (pp->args.numArgs >0) + { + if(_exp==nullptr) + { + fprintf(stderr,"Would try to adjustForArgType with null _exp\n"); + } + pp->args.adjustForArgType (numArgs,_exp->expType (func)); + } + res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), func); + } + if (res == false) + k += _exp->hlTypeSize (func); + numArgs++; } } void Function::processHliCall(Expr *_exp, iICODE picode) { - Function * pp; - int cb, numArgs; - boolT res; - int k; - pp = picode->hl()->call.proc; - if (pp->flg & CALL_PASCAL) - { - cb = pp->cbParam; /* fixed # arguments */ - k = 0; - numArgs = 0; - while(kflg & PROC_ISLIB) /* library function */ - { - if (pp->args.numArgs > 0) - _exp = adjustActArgType(_exp, pp->args[numArgs].type); - res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), this); - } - else /* user function */ - { - if (pp->args.numArgs >0) - { - if(_exp==nullptr) - { - fprintf(stderr,"Would try to adjustForArgType with null _exp\n"); - } - pp->args.adjustForArgType (numArgs,_exp->expType (this)); - } - res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), this); - } - if (res == false) - k += _exp->hlTypeSize (this); - numArgs++; - } - } - else /* CALL_C */ - { - cb = picode->hl()->call.args->cb; - numArgs = 0; - 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++; - } - } - } + Function * pp = picode->hl()->call.proc; + pp->callingConv()->processHLI(this,_exp,picode); } @@ -839,6 +882,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) HLTYPE *ti_hl=nullptr; uint8_t regi; numHlIcodes = 0; + assert(&fnc->localId==&locals); // register(s) to be forward substituted */ auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter()); for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++) @@ -859,111 +903,111 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) /* Check if we can forward substitute this register */ switch (_icHl.opcode) { - case HLI_ASSIGN: - /* Replace rhs of current icode into target + case HLI_ASSIGN: + /* Replace rhs of current icode into target * icode expression */ - ticode = picode->du1.idx[0].uses.front(); - if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) && - ((ticode->hl()->opcode != HLI_CALL) && - (ticode->hl()->opcode != HLI_RET))) - continue; + ticode = picode->du1.idx[0].uses.front(); + if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) && + ((ticode->hl()->opcode != HLI_CALL) && + (ticode->hl()->opcode != HLI_RET))) + continue; - if (_icHl.asgn.rhs->xClear (make_iterator_range(picode.base(),picode->du1.idx[0].uses[0]), - end(), locals)) - { - locals.processTargetIcode(picode.base(), numHlIcodes, ticode,false); - } + if (_icHl.asgn.rhs->xClear (make_iterator_range(picode.base(),picode->du1.idx[0].uses[0]), + end(), locals)) + { + locals.processTargetIcode(picode.base(), numHlIcodes, ticode,false); + } + break; + + case HLI_POP: + // TODO: sometimes picode->du1.idx[0].uses.front() points to next basic block ? + // pop X + // lab1: + // call F() <- somehow this is marked as user of POP ? + ticode = picode->du1.idx[0].uses.front(); + ti_hl = ticode->hlU(); + if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) && + ((ti_hl->opcode != HLI_CALL) && + (ti_hl->opcode != HLI_RET))) + continue; + + _exp = g_exp_stk.pop(); /* pop last exp pushed */ + switch (ticode->hl()->opcode) { + case HLI_ASSIGN: + locals.forwardSubs(_icHl.expr(), _exp, picode.base(), ticode, numHlIcodes); break; - case HLI_POP: - // TODO: sometimes picode->du1.idx[0].uses.front() points to next basic block ? - // pop X - // lab1: - // call F() <- somehow this is marked as user of POP ? - ticode = picode->du1.idx[0].uses.front(); - ti_hl = ticode->hlU(); - if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) && - ((ti_hl->opcode != HLI_CALL) && - (ti_hl->opcode != HLI_RET))) - continue; + case HLI_JCOND: case HLI_PUSH: case HLI_RET: + { + RegisterNode *v = dynamic_cast(_icHl.expr()); + assert(v); + res = Expr::insertSubTreeReg (ti_hl->exp.v, + _exp, + locals.id_arr[v->regiIdx].id.regi, + &locals); + if (res) + { + picode->invalidate(); + numHlIcodes--; + } + } + break; - _exp = g_exp_stk.pop(); /* pop last exp pushed */ - switch (ticode->hl()->opcode) { - case HLI_ASSIGN: - locals.forwardSubs(_icHl.expr(), _exp, picode.base(), ticode, numHlIcodes); - break; - - case HLI_JCOND: case HLI_PUSH: case HLI_RET: - { - RegisterNode *v = dynamic_cast(_icHl.expr()); - assert(v); - res = Expr::insertSubTreeReg (ti_hl->exp.v, - _exp, - locals.id_arr[v->regiIdx].id.regi, - &locals); - if (res) - { - picode->invalidate(); - numHlIcodes--; - } - } - break; - - /****case HLI_CALL: // register arguments + /****case HLI_CALL: // register arguments newRegArg (pProc, picode, ticode); picode->invalidate(); numHlIcodes--; break; */ - default: - fprintf(stderr,"unhandled BB::findBBExps target opcode %d\n",ticode->hl()->opcode); + default: + fprintf(stderr,"unhandled BB::findBBExps target opcode %d\n",ticode->hl()->opcode); - } // eos + } // eos + break; + + case HLI_CALL: + ticode = picode->du1.idx[0].uses.front(); + ti_hl = ticode->hlU(); + _retVal = &_icHl.call.proc->retVal; + switch (ti_hl->opcode) + { + case HLI_ASSIGN: + assert(ti_hl->asgn.rhs); + _exp = _icHl.call.toAst(); + res = Expr::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals); + if (! res) + Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals); + //TODO: HERE missing: 2 regs + picode->invalidate(); + numHlIcodes--; break; - case HLI_CALL: - ticode = picode->du1.idx[0].uses.front(); - ti_hl = ticode->hlU(); - _retVal = &_icHl.call.proc->retVal; - switch (ti_hl->opcode) + case HLI_PUSH: case HLI_RET: + ti_hl->expr( _icHl.call.toAst() ); + picode->invalidate(); + numHlIcodes--; + break; + + case HLI_JCOND: + _exp = _icHl.call.toAst(); + res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals); + if (res) /* was substituted */ { - case HLI_ASSIGN: - assert(ti_hl->asgn.rhs); - _exp = _icHl.call.toAst(); - res = Expr::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals); - if (! res) - Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals); - //TODO: HERE missing: 2 regs - picode->invalidate(); - numHlIcodes--; - break; - - case HLI_PUSH: case HLI_RET: - ti_hl->expr( _icHl.call.toAst() ); - picode->invalidate(); - numHlIcodes--; - break; - - case HLI_JCOND: - _exp = _icHl.call.toAst(); - res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals); - if (res) /* was substituted */ - { - picode->invalidate(); - numHlIcodes--; - } - else /* cannot substitute function */ - { - auto lhs = AstIdent::idID(_retVal,&locals,picode.base()); - picode->setAsgn(lhs, _exp); - } - break; - default: - fprintf(stderr,"unhandled BB::findBBExps HLI_CALL target opcode %d\n",ti_hl->opcode); - } /* eos */ + picode->invalidate(); + numHlIcodes--; + } + else /* cannot substitute function */ + { + auto lhs = AstIdent::idID(_retVal,&locals,picode.base()); + picode->setAsgn(lhs, _exp); + } break; default: - fprintf(stderr,"BB::findBBExps Unhandled HLI %d\n",_icHl.opcode); + fprintf(stderr,"unhandled BB::findBBExps HLI_CALL target opcode %d\n",ti_hl->opcode); + } /* eos */ + break; + default: + fprintf(stderr,"BB::findBBExps Unhandled HLI %d\n",_icHl.opcode); } /* eos */ } } @@ -977,97 +1021,98 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) switch (_icHl.opcode) { - case HLI_ASSIGN: - /* Replace rhs of current icode into target + case HLI_ASSIGN: + /* Replace rhs of current icode into target * icode expression */ - if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) - { - ticode = picode->du1.idx[0].uses.front(); - if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) && - ((ticode->hl()->opcode != HLI_CALL) && - (ticode->hl()->opcode != HLI_RET))) - continue; - locals.processTargetIcode(picode.base(), numHlIcodes, ticode,true); - } - break; - - case HLI_POP: - if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) - { - ticode = picode->du1.idx[0].uses.front(); - if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) && - ((ticode->hl()->opcode != HLI_CALL) && - (ticode->hl()->opcode != HLI_RET))) - continue; - - _exp = g_exp_stk.pop(); /* pop last exp pushed */ - switch (ticode->hl()->opcode) { - case HLI_ASSIGN: - forwardSubsLong (dynamic_cast(_icHl.expr())->ident.idNode.longIdx, - _exp, picode.base(), ticode, &numHlIcodes); - break; - case HLI_JCOND: case HLI_PUSH: - res = Expr::insertSubTreeLongReg (_exp, - ticode->hlU()->exp.v, - dynamic_cast(_icHl.asgn.lhs())->ident.idNode.longIdx); - if (res) - { - picode->invalidate(); - numHlIcodes--; - } - break; - case HLI_CALL: /*** missing ***/ - break; - default: - fprintf(stderr,"BB::findBBExps Unhandled target op %d\n",ticode->hl()->opcode); - } /* eos */ - } - break; - - case HLI_CALL: /* check for function return */ + if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) + { ticode = picode->du1.idx[0].uses.front(); - switch (ticode->hl()->opcode) - { - case HLI_ASSIGN: - _exp = _icHl.call.toAst(); - ticode->hlU()->asgn.lhs( - AstIdent::Long(&locals, DST, - ticode,HIGH_FIRST, picode.base(), - eDEF, *(++iICODE(ticode))->ll())); - ticode->hlU()->asgn.rhs = _exp; + if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) && + ((ticode->hl()->opcode != HLI_CALL) && + (ticode->hl()->opcode != HLI_RET))) + continue; + locals.processTargetIcode(picode.base(), numHlIcodes, ticode,true); + } + break; + + case HLI_POP: + if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) + { + ticode = picode->du1.idx[0].uses.front(); + if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) && + ((ticode->hl()->opcode != HLI_CALL) && + (ticode->hl()->opcode != HLI_RET))) + continue; + + _exp = g_exp_stk.pop(); /* pop last exp pushed */ + switch (ticode->hl()->opcode) { + case HLI_ASSIGN: + forwardSubsLong (dynamic_cast(_icHl.expr())->ident.idNode.longIdx, + _exp, picode.base(), ticode, &numHlIcodes); + break; + case HLI_JCOND: case HLI_PUSH: + res = Expr::insertSubTreeLongReg (_exp, + ticode->hlU()->exp.v, + dynamic_cast(_icHl.asgn.lhs())->ident.idNode.longIdx); + if (res) + { picode->invalidate(); numHlIcodes--; - break; - - case HLI_PUSH: case HLI_RET: - ticode->hlU()->expr( _icHl.call.toAst() ); - picode->invalidate(); - numHlIcodes--; - break; - - case HLI_JCOND: - _exp = _icHl.call.toAst(); - _retVal = &picode->hl()->call.proc->retVal; - res = Expr::insertSubTreeLongReg (_exp, - ticode->hlU()->exp.v, - locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base())); - if (res) /* was substituted */ - { - picode->invalidate(); - numHlIcodes--; - } - else /* cannot substitute function */ - { - auto lhs = locals.createId(_retVal,picode.base()); - picode->setAsgn(lhs, _exp); - } - break; - default: - fprintf(stderr,"BB::findBBExps Unhandled target op %d\n",ticode->hl()->opcode); + } + break; + case HLI_CALL: /*** missing ***/ + break; + default: + fprintf(stderr,"BB::findBBExps Unhandled target op %d\n",ticode->hl()->opcode); } /* eos */ + } + break; + + case HLI_CALL: /* check for function return */ + ticode = picode->du1.idx[0].uses.front(); + switch (ticode->hl()->opcode) + { + case HLI_ASSIGN: + _exp = _icHl.call.toAst(); + ticode->hlU()->asgn.lhs( + AstIdent::Long(&locals, DST, + ticode,HIGH_FIRST, picode.base(), + eDEF, *(++iICODE(ticode))->ll())); + ticode->hlU()->asgn.rhs = _exp; + picode->invalidate(); + numHlIcodes--; + break; + + case HLI_PUSH: + case HLI_RET: + ticode->hlU()->expr( _icHl.call.toAst() ); + picode->invalidate(); + numHlIcodes--; + break; + + case HLI_JCOND: + _exp = _icHl.call.toAst(); + _retVal = &picode->hl()->call.proc->retVal; + res = Expr::insertSubTreeLongReg (_exp, + ticode->hlU()->exp.v, + locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base())); + if (res) /* was substituted */ + { + picode->invalidate(); + numHlIcodes--; + } + else /* cannot substitute function */ + { + auto lhs = locals.createId(_retVal,picode.base()); + picode->setAsgn(lhs, _exp); + } break; default: - fprintf(stderr,"BB::findBBExps Unhandled HLI %d\n",_icHl.opcode); + fprintf(stderr,"BB::findBBExps Unhandled target op %d\n",ticode->hl()->opcode); + } /* eos */ + break; + default: + fprintf(stderr,"BB::findBBExps Unhandled HLI %d\n",_icHl.opcode); } /* eos */ } @@ -1077,7 +1122,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) * expression stack */ 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) printf("Num def %d\n",picode->du1.getNumRegsDef()); @@ -1109,7 +1154,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) void Function::findExps() { /* Initialize expression stack */ - g_exp_stk.init(); + g_exp_stk.init(this); /* Traverse tree in dfsLast order */ for(BB *pbb : m_dfsLast | filtered(BB::ValidFunctor())) { diff --git a/src/disassem.cpp b/src/disassem.cpp index 3e23f1f..0baba18 100644 --- a/src/disassem.cpp +++ b/src/disassem.cpp @@ -77,14 +77,14 @@ static char *strHex(uint32_t d); //static int checkScanned(uint32_t pcCur); //static void setProc(Function * proc); //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 CIcodeRec pc; static int cb, j, numIcode, allocIcode; static map pl; static uint32_t nextInst; -static boolT fImpure; +static bool fImpure; //static int g_lab; static Function * pProc; /* Points to current proc struct */ diff --git a/src/fixwild.cpp b/src/fixwild.cpp index c223e99..7c91d15 100644 --- a/src/fixwild.cpp +++ b/src/fixwild.cpp @@ -82,8 +82,9 @@ TwoWild(uint8_t pat[]) static bool FourWild(uint8_t pat[]) { - TwoWild(pat); - return TwoWild(pat); + if(TwoWild(pat)) + return true; + return TwoWild(pat); } /* 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; else pc += 1; continue; - + } case 0xB0: /* B0 - BF */ { diff --git a/src/frontend.cpp b/src/frontend.cpp index f0d66bf..677ff68 100644 --- a/src/frontend.cpp +++ b/src/frontend.cpp @@ -223,8 +223,8 @@ void DccFrontend::LoadImage(Project &proj) { fatalError(CANNOT_READ, proj.binary_path().c_str()); } - - if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) { + prog.fCOM = (header.sigLo != 0x4D || header.sigHi != 0x5A); + if (! prog.fCOM ) { /* Read rest of header */ fseek(fp, 0, SEEK_SET); 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 -* purposes it doesn't really matter where in real memory -* the program would end up. EXE programs can't really rely on -* their load location so setting the PSP segment to 0 is fine. -* Certainly programs that prod around in DOS or BIOS are going -* to have to load DS from a constant so it'll be pretty -* obvious. -*/ + * purposes it doesn't really matter where in real memory + * the program would end up. EXE programs can't really rely on + * their load location so setting the PSP segment to 0 is fine. + * Certainly programs that prod around in DOS or BIOS are going + * to have to load DS from a constant so it'll be pretty + * obvious. + */ prog.initCS = (int16_t)LH(&header.initCS) + EXE_RELOCATION; prog.initIP = (int16_t)LH(&header.initIP); prog.initSS = (int16_t)LH(&header.initSS) + EXE_RELOCATION; diff --git a/src/graph.cpp b/src/graph.cpp index ea653bc..2e3041d 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -62,69 +62,69 @@ void Function::createCFG() } else switch (ll->getOpcode()) { - case iJB: case iJBE: case iJAE: case iJA: - case iJL: case iJLE: case iJGE: case iJG: - case iJE: case iJNE: case iJS: case iJNS: - case iJO: case iJNO: case iJP: case iJNP: - case iJCXZ: - pBB = BB::Create(current_range, TWO_BRANCH, this); + case iJB: case iJBE: case iJAE: case iJA: + case iJL: case iJLE: case iJGE: case iJG: + case iJE: case iJNE: case iJS: case iJNS: + case iJO: case iJNO: case iJP: case iJNP: + case iJCXZ: + pBB = BB::Create(current_range, TWO_BRANCH, this); CondJumps: - pBB->addOutEdge(nextIcode->loc_ip); - /* This is checking for jumps off into nowhere */ - if ( not ll->testFlags(NO_LABEL) ) - pBB->addOutEdge(ll->src().getImm2()); - break; + pBB->addOutEdge(nextIcode->loc_ip); + /* This is checking for jumps off into nowhere */ + if ( not ll->testFlags(NO_LABEL) ) + pBB->addOutEdge(ll->src().getImm2()); + break; - case iLOOP: case iLOOPE: case iLOOPNE: - pBB = BB::Create(current_range, LOOP_NODE, this); - goto CondJumps; + case iLOOP: case iLOOPE: case iLOOPNE: + pBB = BB::Create(current_range, LOOP_NODE, this); + goto CondJumps; - case iJMPF: case iJMP: - 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: + case iJMPF: case iJMP: + if (ll->testFlags(SWITCH)) { - 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; + 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 iRET: case iRETF: - pBB = BB::Create(current_range, RETURN_NODE, this); - break; + case iCALLF: case iCALL: + { + 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: - /* Check for exit to DOS */ - if ( ll->testFlags(TERMINATES) ) + case iRET: case iRETF: + pBB = BB::Create(current_range, RETURN_NODE, this); + 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()) - { - if (nextIcode->ll()->testFlags(TARGET | CASE)) - { - pBB = BB::Create(current_range, FALL_NODE, this); - pBB->addOutEdge(nextIcode->loc_ip); - } - } - break; + } + break; } if(pBB!=nullptr) // created a new Basic block { @@ -133,11 +133,9 @@ CondJumps: current_range=make_iterator_range(nextIcode,nextIcode); } } - auto iter=heldBBs.begin(); - /* Convert list of BBs into a graph */ - for (; iter!=heldBBs.end(); ++iter) + for (auto pr : m_ip_to_bb) { - pBB = *iter; + BB* pBB=pr.second; for (auto & elem : pBB->edges) { int32_t ip = elem.ip; @@ -146,16 +144,15 @@ CondJumps: fatalError (INVALID_SYNTHETIC_BB); return; } - auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(), - [ip](BB *psBB)->bool {return psBB->begin()->loc_ip==ip;}); - if(iter2==heldBBs.end()) - fatalError(NO_BB, ip, name.c_str()); - psBB = *iter2; - elem.BBptr = psBB; - psBB->inEdges.push_back((BB *)nullptr); + auto iter2=m_ip_to_bb.find(ip); + if(iter2==m_ip_to_bb.end()) + fatalError(NO_BB, ip, name.c_str()); + psBB = iter2->second; + elem.BBptr = psBB; + psBB->inEdges.push_back((BB *)nullptr); + } } } -} void Function::markImpure() { @@ -181,21 +178,16 @@ void Function::markImpure() } - - -/***************************************************************************** - * newBB - Allocate new BB and link to end of list - *****************************************************************************/ - /***************************************************************************** * freeCFG - Deallocates a cfg ****************************************************************************/ 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) {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; - back().ll()->setFlags(NO_CODE); - back().invalidate(); - nodeType = FALL_NODE; - //instructions.advance_end(-1); //TODO: causes creation of empty BB + + nodeType = pChild->nodeType; + instructions = boost::make_iterator_range(begin(),pChild->end()); + 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 */ - if (pChild->inEdges.size() != 1) - break; + traversed = DFS_MERGE; - nodeType = pChild->nodeType; - instructions = boost::make_iterator_range(begin(),pChild->end()); - pChild->front().ll()->clrFlags(TARGET); - edges.swap(pChild->edges); - - 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); -} + /* Process all out edges recursively */ + for (auto & elem : edges) + { + if (elem.BBptr->traversed != DFS_MERGE) + elem.BBptr->mergeFallThrough(Icode); + } } diff --git a/src/icode.cpp b/src/icode.cpp index d8cfffc..8134054 100644 --- a/src/icode.cpp +++ b/src/icode.cpp @@ -89,11 +89,11 @@ bool LLOperand::isReg() const { 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.cb = param_count; - proc.proc->flg |= call_conv; + proc.proc->callingConv(call_conv); } void HLTYPE::setCall(Function *proc) { diff --git a/src/idioms.cpp b/src/idioms.cpp index d39b2ef..e0e1f8a 100644 --- a/src/idioms.cpp +++ b/src/idioms.cpp @@ -211,7 +211,7 @@ void Function::findIdioms() if (cbParam != delta) { cbParam = delta; - flg |= (CALL_MASK & CALL_UNKNOWN); + callingConv(CConv::UNKNOWN); } } } diff --git a/src/idioms/call_idioms.cpp b/src/idioms/call_idioms.cpp index 784304c..9267a85 100644 --- a/src/idioms/call_idioms.cpp +++ b/src/idioms/call_idioms.cpp @@ -38,7 +38,7 @@ int Idiom3::action() { 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 { @@ -96,7 +96,7 @@ int Idiom17::action() { 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; idxinvalidate(); diff --git a/src/idioms/epilogue_idioms.cpp b/src/idioms/epilogue_idioms.cpp index 3218e60..eb00390 100644 --- a/src/idioms/epilogue_idioms.cpp +++ b/src/idioms/epilogue_idioms.cpp @@ -146,7 +146,7 @@ int Idiom4::action() if(m_param_count) { m_func->cbParam = (int16_t)m_param_count; - m_func->flg |= CALL_PASCAL; + m_func->callingConv(CConv::PASCAL); } return 1; } diff --git a/src/locident.cpp b/src/locident.cpp index c5e444a..6207d66 100644 --- a/src/locident.cpp +++ b/src/locident.cpp @@ -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)); } -ID::ID(hlType t, const LONGGLB_TYPE &s) +ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false) { macro[0]=0; 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)) return (idx); } - + printf("%d",t); /* Not in the table, create new identifier */ id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL))); return (id_arr.size() - 1); diff --git a/src/parser.cpp b/src/parser.cpp index 678de4e..9dfaccf 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -39,42 +39,47 @@ void DccFrontend::parse(Project &proj) SynthLab = SYNTHESIZED_MIN; // default-construct a Function object ! - /*auto func = */proj.createFunction(); + /*auto func = */; /* Check for special settings of initial state, based on idioms of the startup code */ state.checkStartup(); - Function &start_proc(proj.pProcList.front()); + Function *start_proc; /* Make a struct for the initial procedure */ 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 */ - start_proc.procEntry = prog.offMain; + start_proc->procEntry = prog.offMain; /* In medium and large models, the segment of main may (will?) not be the same as the initial CS segment (of the startup code) */ state.setState(rCS, prog.segMain); - start_proc.name = "main"; state.IP = prog.offMain; } else { + start_proc = proj.createFunction(0,"start"); /* 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 */ - start_proc.state = state; + start_proc->state = state; /* Set up call graph initial node */ 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 checks a proc to see if it is a know C (etc) library */ 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 */ - 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() */ 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); 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 * 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; @@ -119,8 +197,11 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) 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(); pstate->IP += (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 */ - if ((_Icode.ll()->getOpcode() == iDIV) || (_Icode.ll()->getOpcode() == iIDIV)) - { - /* 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); - } + if ((ll->getOpcode() == iDIV) || (ll->getOpcode() == iIDIV)) + pIcode = translate_DIV(ll, _Icode); else if (_Icode.ll()->getOpcode() == iXCHG) - { - /* 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); - } + pIcode = translate_XCHG(ll, _Icode); else pIcode = Icode.addIcode(&_Icode); @@ -230,7 +241,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) STATE StCopy; int ip = Icode.size()-1; /* Index of this jump */ ICODE &prev(*(++Icode.rbegin())); /* Previous icode */ - boolT fBranch = false; + bool fBranch = false; pstate->JCond.regi = 0; @@ -298,7 +309,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) //Icode.GetIcode(Icode.GetNumIcodes() - 1)-> /* Program termination: int21h, fn 00h, 31h, 4Ch */ - done = (boolT)(funcNum == 0x00 || funcNum == 0x31 || + done = (bool)(funcNum == 0x00 || funcNum == 0x31 || funcNum == 0x4C); /* 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]; } else /* Program termination: int20h, int27h */ - done = (boolT)(ll->src().getImm2() == 0x20 || - ll->src().getImm2() == 0x27); + done = (ll->src().getImm2() == 0x20 || ll->src().getImm2() == 0x27); if (done) pIcode->ll()->setFlags(TERMINATES); 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 * 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); ICODE &last_insn(Icode.back()); STATE localState; /* Local copy of the machine state */ uint32_t off; - boolT indirect; - /* For Indirect Calls, find the function address */ - indirect = false; + bool indirect = false; //pIcode.ll()->immed.proc.proc=fakeproc; 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 */ if ( not Project::get()->valid(iter) ) { - iter = Project::get()->createFunction(); + iter = Project::get()->createFunction(0,""); Function &x(*iter); x.procEntry = pIcode.ll()->src().getImm2(); LibCheck(x); @@ -1120,13 +1128,13 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate) break; 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.du1.addDef(r); cb = 4; // fallthrough - } + } case iMOV: use(SRC, 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.du1.addDef(rCX); case iLODS: - { + { eReg r = (cb==2)? rAX: rAL; pIcode.du.addDefinedAndUsed(rSI); pIcode.du1.addDef(rSI); pIcode.du.def.addReg(r); pIcode.du1.addDef(r); pIcode.du.use.addReg(sseg); - } + } break; case iREP_OUTS: pIcode.du.addDefinedAndUsed(rCX); diff --git a/src/perfhlib.cpp b/src/perfhlib.cpp index c08ceb5..598a34a 100644 --- a/src/perfhlib.cpp +++ b/src/perfhlib.cpp @@ -24,9 +24,7 @@ static short *g; /* g[] */ //static void duplicateKeys(int v1, int v2); PatternHasher g_pattern_hasher; -void -PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin, - int _NumVert) +void 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 passing all these (or defererencing pointers) for every call to hash() diff --git a/src/procs.cpp b/src/procs.cpp index 0b85f6a..e083573 100644 --- a/src/procs.cpp +++ b/src/procs.cpp @@ -112,6 +112,10 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const RegisterNode *lhs_reg = dynamic_cast(lhs); assert(lhs); type = lhs->ident.type(); + if(type==REGISTER) + assert(lhs_reg); + if(type==LONG_VAR) + assert(!lhs_reg); if (lhs_reg) { 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 (regL < rAL) - { - newsym.type = TYPE_WORD_SIGN; - newsym.regs = new RegisterNode(tidx, WORD_REG); - } - else - { - newsym.type = TYPE_BYTE_SIGN; - newsym.regs = new RegisterNode(tidx, BYTE_REG); - } + regType rType = WORD_REG; + if (regL >= rAL) + rType = BYTE_REG; + newsym.type = (regL < rAL) ? TYPE_WORD_SIGN : TYPE_BYTE_SIGN; + newsym.regs = new RegisterNode(tidx, rType,this); tproc->localId.id_arr[tidx].name = newsym.name; } 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; if ((regi >= rES) && (regi <= rDS)) { - if (opcode == iCALLF) - return false; - else - return true; + return (opcode == iCALLF) ? false : true; } } @@ -312,7 +308,7 @@ Expr *Function::adjustActArgType (Expr *_exp, hlType forType) case TYPE_PTR: /* It's a pointer to a char rather than a pointer to - * an integer */ + * an integer */ /***HERE - modify the type ****/ break; diff --git a/src/project.cpp b/src/project.cpp index 7fc8364..0140292 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -53,9 +53,9 @@ ilFunction Project::findByEntry(uint32_t entry) 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(); } diff --git a/src/proplong.cpp b/src/proplong.cpp index 1ff9dc1..c1782f5 100644 --- a/src/proplong.cpp +++ b/src/proplong.cpp @@ -13,7 +13,7 @@ /* Returns whether the given icode opcode is within the range of valid * high-level conditional jump icodes (iJB..iJG) */ -static boolT isJCond (llIcode opcode) +static bool isJCond (llIcode opcode) { if ((opcode >= iJB) && (opcode <= iJG)) 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 */ -static boolT isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off) +static bool isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off) { iICODE initial_icode=pIcode; if(distance(pIcode,pEnd)<4) diff --git a/src/reducible.cpp b/src/reducible.cpp index 6d15260..535f720 100644 --- a/src/reducible.cpp +++ b/src/reducible.cpp @@ -104,7 +104,7 @@ void derSeq_Entry::findIntervals (Function *c) *header, /* Current interval's header node */ *succ; /* Successor basic block */ 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} */ Gi->beenOnH = true; @@ -304,13 +304,11 @@ bool Function::nextOrderGraph (derSeq &derivedGi) /* Finds the derived sequence of the graph derivedG->Gi (ie. cfg). * Constructs the n-th order graph and places all the intermediate graphs * 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(); assert(iter!=derivedGi.end()); - Gi = iter->Gi; + BB *Gi = iter->Gi; /* Current derived sequence graph */ while (! trivialGraph (Gi)) { /* Find the intervals of Gi and place them in derivedGi->Ii */ diff --git a/src/scanner.cpp b/src/scanner.cpp index 1dd0478..0b30c97 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -842,10 +842,10 @@ static void trans(int i) (llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0 }; LLInst *ll = pIcode->ll(); - if(transTable[REG(*pInst)]==iPUSH) { - printf("es"); - } - if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */ +// if(transTable[REG(*pInst)]==iPUSH) { +// printf("es"); +// } + if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */ ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */ rm(i); ll->replaceSrc( pIcode->ll()->m_dst ); diff --git a/src/symtab.cpp b/src/symtab.cpp index 2f05111..089a744 100644 --- a/src/symtab.cpp +++ b/src/symtab.cpp @@ -133,7 +133,7 @@ void destroySymTables(void) } /* 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 }