/**************************************************************************** * dcc project general header * (C) Cristina Cifuentes, Mike van Emmerik ****************************************************************************/ #pragma once #include #include #include "types.h" #include "ast.h" #include "icode.h" #include "locident.h" #include "error.h" #include "graph.h" #include "bundle.h" #include "Procedure.h" #include "BasicBlock.h" typedef llvm::iplist FunctionListType; typedef FunctionListType lFunction; typedef lFunction::iterator ilFunction; /* SYMBOL TABLE */ struct SYM { SYM() : label(0),size(0),flg(0),type(TYPE_UNKNOWN) { } char name[10]; /* New name for this variable */ dword label; /* physical address (20 bit) */ Int size; /* maximum size */ flags32 flg; /* SEG_IMMED, IMPURE, WORD_OFF */ hlType type; /* probable type */ eDuVal duVal; /* DEF, USE, VAL */ }; typedef std::vector SYMTAB; /* CALL GRAPH NODE */ struct CALL_GRAPH { ilFunction proc; /* Pointer to procedure in pProcList */ std::vector outEdges; /* array of out edges */ public: void write(); CALL_GRAPH() : outEdges(0) { } public: void writeNodeCallGraph(Int indIdx); boolT insertCallGraph(ilFunction caller, ilFunction callee); boolT insertCallGraph(Function *caller, ilFunction callee); void insertArc(ilFunction newProc); }; #define NUM_PROCS_DELTA 5 /* delta # procs a proc invokes */ //extern std::list pProcList; extern FunctionListType pProcList; extern CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */ extern bundle cCode; /* Output C procedure's declaration and code */ /* Procedure FLAGS */ enum PROC_FLAGS { PROC_BADINST=0x00000100,/* Proc contains invalid or 386 instruction */ 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 */ PROC_NEAR =0x00010000, /* Proc exits with near return */ PROC_FAR =0x00020000, /* Proc exits with far return */ GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph */ SI_REGVAR =0x00200000, /* SI is used as a stack variable */ 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_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 */ /**** Global variables ****/ extern char *asm1_name, *asm2_name; /* Assembler output filenames */ typedef struct { /* Command line option flags */ unsigned verbose : 1; unsigned VeryVerbose : 1; unsigned asm1 : 1; /* Early disassembly listing */ unsigned asm2 : 1; /* Disassembly listing after restruct */ unsigned Map : 1; unsigned Stats : 1; unsigned Interact : 1; /* Interactive mode */ unsigned Calls : 1; /* Follow register indirect calls */ char filename[80]; /* The input filename */ } OPTION; extern OPTION option; /* Command line options */ extern SYMTAB symtab; /* Global symbol table */ struct PROG /* Loaded program image parameters */ { int16 initCS; int16 initIP; /* These are initial load values */ int16 initSS; /* Probably not of great interest */ int16 initSP; boolT fCOM; /* Flag set if COM program (else EXE)*/ Int cReloc; /* No. of relocation table entries */ dword *relocTable; /* Ptr. to relocation table */ byte *map; /* Memory bitmap ptr */ Int cProcs; /* Number of procedures so far */ Int offMain; /* The offset of the main() proc */ word segMain; /* The segment of the main() proc */ boolT bSigs; /* True if signatures loaded */ Int cbImage; /* Length of image in bytes */ byte *Image; /* Allocated by loader to hold entire * program image */ }; extern PROG prog; /* Loaded program image parameters */ extern std::bitset<32> duReg[30]; /* def/use bits for registers */ //extern dword duReg[30]; /* def/use bits for registers */ extern dword maskDuReg[30]; /* masks off du bits for regs */ /* Registers used by icode instructions */ static constexpr const char *allRegs[21] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "es", "cs", "ss", "ds", "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "tmp"}; /* Memory map states */ #define BM_UNKNOWN 0 /* Unscanned memory */ #define BM_DATA 1 /* Data */ #define BM_CODE 2 /* Code */ #define BM_IMPURE 3 /* Used as Data and Code*/ /* Intermediate instructions statistics */ struct STATS { Int numBBbef; /* number of basic blocks initially */ Int numBBaft; /* number of basic blocks at the end */ Int nOrder; /* n-th order */ Int numLLIcode; /* number of low-level Icode instructions */ Int numHLIcode; /* number of high-level Icode instructions */ Int totalLL; /* total number of low-level Icode insts */ Int totalHL; /* total number of high-level Icod insts */ }; extern STATS stats; /* Icode statistics */ /**** Global function prototypes ****/ void FrontEnd(char *filename, CALL_GRAPH * *); /* frontend.c */ void *allocMem(Int cb); /* frontend.c */ void udm(void); /* udm.c */ void freeCFG(BB * cfg); /* graph.c */ BB * newBB(BB *, Int, Int, byte, Int, Function *); /* graph.c */ void BackEnd(char *filename, CALL_GRAPH *); /* backend.c */ char *cChar(byte c); /* backend.c */ eErrorId scan(dword ip, ICODE * p); /* scanner.c */ void parse (CALL_GRAPH * *); /* parser.c */ Int strSize (byte *, char); /* parser.c */ void disassem(Int pass, Function * pProc); /* disassem.c */ void interactDis(Function * initProc, Int initIC); /* disassem.c */ bool JmpInst(llIcode opcode); /* idioms.c */ queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */ 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); boolT newStkArg (ICODE *, COND_EXPR *, llIcode, Function *); void allocStkArgs (ICODE *, Int); void placeStkArg (ICODE *, COND_EXPR *, Int); void adjustActArgType (COND_EXPR *, hlType, Function *); /* Exported functions from ast.c */ void removeRegFromLong (byte, LOCAL_ID *, COND_EXPR *); std::string walkCondExpr (const COND_EXPR *exp, Function * pProc, Int *); Int hlTypeSize (const COND_EXPR *, Function *); hlType expType (const COND_EXPR *, Function *); bool insertSubTreeReg(COND_EXPR *, COND_EXPR **, byte, LOCAL_ID *); bool insertSubTreeLongReg (COND_EXPR *, COND_EXPR **, Int); /* Exported functions from hlicode.c */ std::string writeCall (Function *, STKFRAME *, Function *, Int *); char *write1HlIcode (HLTYPE, Function *, Int *); char *writeJcond (HLTYPE, Function *, Int *); char *writeJcondInv (HLTYPE, Function *, Int *); Int power2 (Int); void inverseCondOp (COND_EXPR **); /* Exported funcions from locident.c */ boolT checkLongEq (LONG_STKID_TYPE, iICODE, Int, Function *, Assignment &asgn, Int); boolT checkLongRegEq (LONGID_TYPE, iICODE, Int, Function *, COND_EXPR *&, COND_EXPR *&, Int); byte otherLongRegi (byte, Int, LOCAL_ID *); void insertIdx (IDX_ARRAY *, Int);