This commit is contained in:
Artur K
2011-11-24 20:19:41 +01:00
commit 4c249fe5c4
105 changed files with 21153 additions and 0 deletions

88
include/BasicBlock.h Normal file
View File

@@ -0,0 +1,88 @@
#pragma once
#include <list>
#include <vector>
#include <string>
#include "types.h"
/* Basic block (BB) node definition */
struct Function;
class CIcodeRec;
struct BB;
struct interval;
typedef union
{
dword ip; /* Out edge icode address */
BB * BBptr; /* Out edge pointer to next BB */
interval *intPtr; /* Out edge ptr to next interval*/
} TYPEADR_TYPE;
struct BB
{
protected:
BB(const BB&);
BB() : nodeType(0),traversed(0),start(0),length(0),
numHlIcodes(0),flg(0),
numInEdges(0),inEdges(0),
numOutEdges(0),edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
inInterval(0),correspInt(0),liveUse(0),def(0),liveIn(0),liveOut(0),
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0),
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
{
}
public:
byte nodeType; /* Type of node */
Int traversed; /* Boolean: traversed yet? */
Int start; /* First instruction offset */
Int length; /* No. of instructions this BB */
Int numHlIcodes; /* No. of high-level icodes */
flags32 flg; /* BB flags */
/* In edges and out edges */
Int numInEdges; /* Number of in edges */
std::vector<BB *> inEdges; // does not own held pointers
Int numOutEdges; /* Number of out edges */
std::vector<TYPEADR_TYPE> edges;/* Array of ptrs. to out edges */
/* For interval construction */
Int beenOnH; /* #times been on header list H */
Int inEdgeCount; /* #inEdges (to find intervals) */
BB * reachingInt; /* Reaching interval header */
interval *inInterval; /* Node's interval */
/* For derived sequence construction */
interval *correspInt; /* Corresponding interval in
* derived graph Gi-1 */
/* For live register analysis
* LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b)) */
dword liveUse; /* LiveUse(b) */
dword def; /* Def(b) */
dword liveIn; /* LiveIn(b) */
dword liveOut; /* LiveOut(b) */
/* For structuring analysis */
Int dfsFirstNum; /* DFS #: first visit of node */
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) */
Int latchNode; /* latching node of the loop */
Int numBackEdges; /* # of back edges */
Int loopHead; /* most nested loop head to which
* thcis node belongs (dfsLast) */
Int loopFollow; /* node that follows the loop */
Int caseHead; /* most nested case to which this
node belongs (dfsLast) */
Int caseTail; /* tail node for the case */
Int index; /* Index, used in several ways */
static BB *Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
static BB *Create(Int start, Int ip, byte nodeType, Int numOutEdges, Function * parent);
void writeCode(Int indLevel, Function *pProc, Int *numLoc, Int latchNode, Int ifFollow);
void mergeFallThrough(CIcodeRec &Icode);
void dfsNumbering(std::vector<BB *> &dfsLast, Int *first, Int *last);
void displayDfs();
};

85
include/Enums.h Normal file
View File

@@ -0,0 +1,85 @@
#pragma once
/* Register types */
enum regType
{
BYTE_REG,
WORD_REG
};
enum condId
{
GLOB_VAR, /* global variable */
REGISTER, /* register */
LOCAL_VAR, /* negative disp */
PARAM, /* positive disp */
GLOB_VAR_IDX, /* indexed global variable *//*** should merge w/glob-var*/
CONSTANT, /* constant */
STRING, /* string */
LONG_VAR, /* long variable */
FUNCTION, /* function */
OTHER /* other **** tmp solution */
};
enum condOp
{
/* For conditional expressions */
LESS_EQUAL = 0, /* <= */
LESS, /* < */
EQUAL, /* == */
NOT_EQUAL, /* != */
GREATER, /* > */
GREATER_EQUAL, /* >= */
/* For general expressions */
AND, /* & */
OR, /* | */
XOR, /* ^ */
NOT, /* ~ */ /* 1's complement */
ADD, /* + */
SUB, /* - */
MUL, /* * */
DIV, /* / */
SHR, /* >> */
SHL, /* << */
MOD, /* % */
DBL_AND, /* && */
DBL_OR, /* || */
DUMMY /* */
};
/* LOW_LEVEL operand location: source or destination */
enum opLoc
{
SRC, /* Source operand */
DST, /* Destination operand */
LHS_OP /* Left-hand side operand (for HIGH_LEVEL) */
};
/* Conditional Expression enumeration nodes and operators */
enum condNodeType
{
UNKNOWN_OP=0,
BOOLEAN_OP, /* condOps */
NEGATION, /* not (2's complement) */
ADDRESSOF, /* addressOf (&) */
DEREFERENCE, /* contents of (*) */
IDENTIFIER, /* {register | local | param | constant | global} */
/* The following are only available to C programs */
POST_INC, /* ++ (post increment) */
POST_DEC, /* -- (post decrement) */
PRE_INC, /* ++ (pre increment) */
PRE_DEC /* -- (pre decrement) */
} ;
/* Enumeration to determine whether pIcode points to the high or low part
* of a long number */
enum hlFirst
{
HIGH_FIRST, /* High value is first */
LOW_FIRST /* Low value is first */
};
/* Operand is defined, used or both flag */
enum operDu
{
eDEF=0x10, /* Operand is defined */
eUSE=0x100, /* Operand is used */
USE_DEF, /* Operand is used and defined */
NONE /* No operation is required on this operand */
};

31
include/IdentType.h Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include "ast.h"
#include "types.h"
struct IDENTTYPE
{
condId idType;
regType regiType; /* for REGISTER only */
union _idNode {
Int regiIdx; /* index into localId, REGISTER */
Int globIdx; /* index into symtab for GLOB_VAR */
Int localIdx; /* idx into localId, LOCAL_VAR */
Int paramIdx; /* idx into args symtab, PARAMS */
Int idxGlbIdx; /* idx into localId, GLOB_VAR_IDX */
struct _kte
{ /* for CONSTANT only */
dword kte; /* value of the constant */
byte size; /* #bytes size constant */
} kte;
dword strIdx; /* idx into image, for STRING */
Int longIdx; /* idx into LOCAL_ID table, LONG_VAR*/
struct _call { /* for FUNCTION only */
Function *proc;
STKFRAME *args;
} call;
struct { /* for OTHER; tmp struct */
byte seg; /* segment */
byte regi; /* index mode */
int16 off; /* offset */
} other;
} idNode;
};

77
include/Procedure.h Normal file
View File

@@ -0,0 +1,77 @@
#pragma once
#include "types.h"
#include "ast.h"
#include "icode.h"
#include "locident.h"
#include "error.h"
#include "graph.h"
#include "bundle.h"
#include "StackFrame.h"
/* PROCEDURE NODE */
struct CALL_GRAPH;
struct Function
{
dword procEntry; /* label number */
char name[SYMLEN]; /* Meaningful name for this proc */
STATE state; /* Entry state */
Int depth; /* Depth at which we found it - for printing */
flags32 flg; /* Combination of Icode & Proc flags */
int16 cbParam; /* Probable no. of bytes of parameters */
STKFRAME args; /* Array of arguments */
LOCAL_ID localId; /* Local identifiers */
ID retVal; /* Return value - identifier */
/* Icodes and control flow graph */
CIcodeRec Icode; /* Object with ICODE records */
std::vector<BB*> cfg; /* Ptr. to BB list/CFG */
std::vector<BB*> dfsLast;
std::vector<BB*> heldBBs;
//BB * *dfsLast; /* Array of pointers to BBs in dfsLast
// * (reverse postorder) order */
Int numBBs; /* Number of BBs in the graph cfg */
boolT hasCase; /* Procedure has a case node */
/* For interprocedural live analysis */
dword liveIn; /* Registers used before defined */
dword liveOut; /* Registers that may be used in successors */
boolT liveAnal; /* Procedure has been analysed already */
/* Double-linked list */
// Function *next;
// Function *prev;
public:
Function() : procEntry(0),depth(0),flg(0),cbParam(0),cfg(0),dfsLast(0),numBBs(0),
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
{
memset(name,0,SYMLEN);
}
void compoundCond();
void writeProcComments();
void lowLevelAnalysis();
void bindIcodeOff();
void dataFlow(dword liveOut);
void compressCFG();
void highLevelGen();
void structure(derSeq *derivedG);
derSeq *checkReducibility();
void createCFG();
void markImpure();
void findImmedDom();
void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
void process_operands(ICODE *pIcode, STATE *pstate);
boolT process_JMP(ICODE *pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
boolT process_CALL(ICODE *pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
void displayCFG();
void freeCFG();
void codeGen(std::ostream &fs);
void displayStats();
void mergeFallThrough(BB *pBB);
protected:
void findExps();
void genDU1();
void elimCondCodes();
void liveRegAnalysis(dword in_liveOut);
void findIdioms();
void propLong();
void genLiveKtes();
};

45
include/StackFrame.h Normal file
View File

@@ -0,0 +1,45 @@
#pragma once
#include "types.h"
#include "ast.h"
#include "icode.h"
#include "locident.h"
#include "error.h"
#include "graph.h"
#include "bundle.h"
/* STACK FRAME */
struct STKSYM
{
COND_EXPR *actual; /* Expression tree of actual parameter */
COND_EXPR *regs; /* For register arguments only */
int16 off; /* Immediate off from BP (+:args, -:params) */
byte regOff; /* Offset is a register (e.g. SI, DI) */
Int size; /* Size */
hlType type; /* Probable type */
eDuVal duVal; /* DEF, USE, VAL */
boolT hasMacro; /* This type needs a macro */
char macro[10]; /* Macro name */
char name[10]; /* Name for this symbol/argument */
boolT invalid; /* Boolean: invalid entry in formal arg list*/
STKSYM()
{
memset(this,0,sizeof(STKSYM));
}
};
struct STKFRAME
{
std::vector<STKSYM> sym;
//STKSYM * sym; /* Symbols */
int16 minOff; /* Initial offset in stack frame*/
int16 maxOff; /* Maximum offset in stack frame*/
Int cb; /* Number of bytes in arguments */
Int numArgs; /* No. of arguments in the table*/
void adjustForArgType(Int numArg_, hlType actType_);
STKFRAME() : sym(0),minOff(0),maxOff(0),cb(0),numArgs(0)
{
}
public:
Int getLocVar(Int off);
};

91
include/ast.h Normal file
View File

@@ -0,0 +1,91 @@
/*
* File: ast.h
* Purpose: definition of the abstract syntax tree ADT.
* Date: September 1993
* (C) Cristina Cifuentes
*/
#pragma once
static const int operandSize=20;
#include <cstring>
#include "Enums.h"
/* The following definitions and types define the Conditional Expression
* attributed syntax tree, as defined by the following EBNF:
CondExp ::= CondTerm AND CondTerm | CondTerm
CondTerm ::= (CondFactor op CondFactor)
CondFactor ::= Identifier | ! CondFactor
Identifier ::= globalVar | register | localVar | parameter | constant
op ::= <= | < | = | != | > | >=
*/
/* High-level BOOLEAN conditions for iJB..iJNS icodes */
static const condOp condOpJCond[12] = {LESS, LESS_EQUAL, GREATER_EQUAL, GREATER,
EQUAL, NOT_EQUAL, LESS, GREATER_EQUAL,
LESS_EQUAL, GREATER, GREATER_EQUAL, LESS};
static const condOp invCondOpJCond[12] = {GREATER_EQUAL, GREATER, LESS, LESS_EQUAL,
NOT_EQUAL, EQUAL, GREATER_EQUAL, LESS,
GREATER, LESS_EQUAL, LESS, GREATER_EQUAL};
struct Function;
struct STKFRAME;
struct LOCAL_ID;
struct ICODE;
struct ID;
#include "IdentType.h"
//enum opLoc;
//enum hlFirst;
//enum operDu;
/* Expression data type */
struct COND_EXPR
{
condNodeType type; /* Conditional Expression Node Type */
union _exprNode { /* Different cond expr nodes */
struct /* for BOOLEAN_OP */
{
condOp op;
COND_EXPR *lhs;
COND_EXPR *rhs;
} boolExpr;
COND_EXPR *unaryExp; /* for NEGATION,ADDRESSOF,DEREFERENCE*/
IDENTTYPE ident; /* for IDENTIFIER */
} expr;
public:
static COND_EXPR *idGlob(int16 segValue, int16 off);
static COND_EXPR *idRegIdx(Int idx, regType reg_type);
static COND_EXPR *idKte(dword kte, byte size);
static COND_EXPR *idLoc(Int off, LOCAL_ID *localId);
static COND_EXPR *idReg(byte regi, flags32 icodeFlg, LOCAL_ID *locsym);
static COND_EXPR *idLongIdx(Int idx);
static COND_EXPR *idOther(byte seg, byte regi, int16 off);
static COND_EXPR *idParam(Int off, const STKFRAME *argSymtab);
static COND_EXPR *unary(condNodeType t, COND_EXPR *sub_expr);
static COND_EXPR *idLong(LOCAL_ID *localId, opLoc sd, ICODE *pIcode, hlFirst f, Int ix, operDu du, Int off);
static COND_EXPR *idFunc(Function *pproc, STKFRAME *args);
static COND_EXPR *idID(const ID *retVal, LOCAL_ID *locsym, Int ix);
static COND_EXPR *id(ICODE *pIcode, opLoc sd, Function *pProc, Int i, ICODE *duIcode, operDu du);
static COND_EXPR *boolOp(COND_EXPR *lhs, COND_EXPR *rhs, condOp op);
public:
COND_EXPR *clone();
void release();
void changeBoolOp(condOp newOp);
COND_EXPR(COND_EXPR &other)
{
type=other.type;
expr=other.expr;
}
COND_EXPR()
{
type=UNKNOWN_OP;
memset(&expr,0,sizeof(_exprNode));
}
};
/* Sequence of conditional expression data type */
/*** NOTE: not used at present ****/
//struct SEQ_COND_EXPR
//{
// COND_EXPR *expr;
// struct _condExpSeq *neccxt;
//};

31
include/bundle.h Normal file
View File

@@ -0,0 +1,31 @@
/*****************************************************************************
* Project: dcc
* File: bundle.h
* Purpose: Module to handle the bundle type (array of pointers to strings).
* (C) Cristina Cifuentes
****************************************************************************/
#pragma once
#include <stdio.h>
#include <vector>
#include <string>
typedef std::vector<std::string> strTable;
struct bundle
{
public:
void appendCode(const char *format, ...);
void appendDecl(const char *format, ...);
strTable decl; /* Declarations */
strTable code; /* C code */
};
#define lineSize 360 /* 3 lines in the mean time */
void newBundle (bundle *procCode);
//void appendStrTab (strTable *strTab, const char *format, ...);
Int nextBundleIdx (strTable *strTab);
void addLabelBundle (strTable &strTab, Int idx, Int label);
void writeBundle (std::ostream &ios, bundle procCode);
void freeBundle (bundle *procCode);

219
include/dcc.h Normal file
View File

@@ -0,0 +1,219 @@
/****************************************************************************
* dcc project general header
* (C) Cristina Cifuentes, Mike van Emmerik
****************************************************************************/
#pragma once
#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 std::list<Function> lFunction;
typedef std::list<Function>::iterator ilFunction;
/* SYMBOL TABLE */
struct SYM {
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 */
};
struct SYMTAB
{
Int csym; /* No. of symbols in table */
Int alloc; /* Allocation */
SYM * sym; /* Symbols */
};
/* CALL GRAPH NODE */
struct CALL_GRAPH
{
ilFunction proc; /* Pointer to procedure in pProcList */
std::vector<CALL_GRAPH *> 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<Function> 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=0x000100,/* Proc contains invalid or 386 instruction */
PROC_IJMP =0x000200,/* Proc incomplete due to indirect jmp */
PROC_ICALL =0x000400, /* Proc incomplete due to indirect call */
PROC_HLL=0x001000, /* Proc is likely to be from a HLL */
CALL_PASCAL=0x002000, /* Proc uses Pascal calling convention */
CALL_C=0x004000, /* Proc uses C calling convention */
CALL_UNKNOWN=0x008000, /* Proc uses unknown calling convention */
PROC_NEAR=0x010000, /* Proc exits with near return */
PROC_FAR=0x020000, /* Proc exits with far return */
GRAPH_IRRED=0x100000, /* Proc generates an irreducible graph */
SI_REGVAR=0x200000, /* SI is used as a stack variable */
DI_REGVAR=0x400000, /* DI is used as a stack variable */
PROC_IS_FUNC=0x800000, /* Proc is a function */
REG_ARGS=0x1000000, /* Proc has registers as arguments */
PROC_VARARG=0x2000000, /* Proc has variable arguments */
PROC_OUTPUT=0x4000000, /* C for this proc has been output */
PROC_RUNTIME=0x8000000, /* 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 char condExp[200]; /* Conditional expression buffer */
extern char callBuf[100]; /* Function call buffer */
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 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 *reallocVar(void *p, Int newsize); /* 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 */
Int scan(dword ip, ICODE * p); /* scanner.c */
void parse (CALL_GRAPH * *); /* parser.c */
boolT labelSrch(ICODE * pIc, Int n, dword tg, Int *pIdx); /* parser.c */
Int strSize (byte *, char); /* parser.c */
void disassem(Int pass, Function * pProc); /* disassem.c */
void interactDis(Function * initProc, Int initIC); /* disassem.c */
boolT JmpInst(llIcode opcode); /* idioms.c */
queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */
void SetupLibCheck(void); /* chklib.c */
void CleanupLibCheck(void); /* chklib.c */
boolT LibCheck(Function &p); /* chklib.c */
/* Exported functions from procs.c */
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
void newRegArg (Function *, ICODE *, ICODE *);
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 *);
void copyDU (ICODE *, const ICODE *, operDu, operDu);
boolT insertSubTreeReg (COND_EXPR *, COND_EXPR **, byte, LOCAL_ID *);
boolT insertSubTreeLongReg (COND_EXPR *, COND_EXPR **, Int);
//COND_EXPR *concatExps (SEQ_COND_EXPR *, COND_EXPR *, condNodeType);
void initExpStk();
void pushExpStk (COND_EXPR *);
COND_EXPR *popExpStk();
Int numElemExpStk();
boolT emptyExpStk();
/* Exported functions from hlicode.c */
boolT removeDefRegi (byte, ICODE *, Int, LOCAL_ID *);
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, ICODE *, Int, Int, Function *, COND_EXPR **,COND_EXPR **, Int);
boolT checkLongRegEq (LONGID_TYPE, ICODE *, Int, Int, Function *, COND_EXPR **,COND_EXPR **, Int);
byte otherLongRegi (byte, Int, LOCAL_ID *);
void insertIdx (IDX_ARRAY *, Int);

43
include/disassem.h Normal file
View File

@@ -0,0 +1,43 @@
/****************************************************************************
* dcc project disassembler header
* (C) Mike van Emmerik
****************************************************************************/
/* Definitions for extended keys (first key is zero) */
#define EXT 0x100 /* "Extended" flag */
#ifdef __MSDOS__
#define KEY_DOWN EXT+'P'
#define KEY_LEFT EXT+'K'
#define KEY_UP EXT+'H'
#define KEY_RIGHT EXT+'M'
#define KEY_NPAGE EXT+'Q'
#define KEY_PPAGE EXT+'I'
#endif
#ifdef _CONSOLE
#define KEY_DOWN 0x50 /* Same as keypad scancodes */
#define KEY_LEFT 0x4B
#define KEY_UP 0x48
#define KEY_RIGHT 0x4D
#define KEY_NPAGE 0x51
#define KEY_PPAGE 0x49
#endif
#ifdef __UNIX__
#define KEY_DOWN EXT+'B'
#define KEY_LEFT EXT+'D'
#define KEY_UP EXT+'A'
#define KEY_RIGHT EXT+'C'
#define KEY_NPAGE EXT+'J' /* Enter correct value! */
#define KEY_PPAGE EXT+'K' /* Another guess! */
#endif
/* "Attributes" */
#define A_NORMAL 'N' /* For Dos/Unix */
#define A_REVERSE 'I'
#define A_BOLD 'B'
#define LINES 24
#define COLS 80

77
include/dosdcc.h Normal file
View File

@@ -0,0 +1,77 @@
/***************************************************************************
* File : dosdcc.h
* Purpose : include file for files decompiled by dcc.
* Copyright (c) Cristina Cifuentes - QUT - 1992
**************************************************************************/
/* Type definitions for intel 80x86 architecture */
typedef unsigned int Word; /* 16 bits */
typedef unsigned char Byte; /* 8 bits */
typedef union {
unsigned long dW;
Word wL, wH; /* 2 words */
} Dword; /* 32 bits */
/* Structure to access high and low bits of a Byte or Word variable */
typedef struct {
/* low byte */
Word lowBitWord : 1;
Word filler1 : 6;
Word highBitByte : 1;
/* high byte */
Word lowBitByte : 1;
Word filler2 : 6;
Word highBitWord : 1;
} wordBits;
/* Low and high bits of a Byte or Word variable */
#define lowBit(a) ((wordBits)(a).lowBitWord)
#define highBitByte(a) ((wordBits)(a).highBitByte)
#define lowBitByte(a) ((wordBits)(a).lowBitByte)
#define highBit(a) (sizeof(a) == sizeof(Word) ? \
((wordBits)(a).highBitWord):\
((wordBits)(a).highBitByte))
/* Word register variables */
#define ax regs.x.ax
#define bx regs.x.bx
#define cx regs.x.cx
#define dx regs.x.dx
#define cs regs.x.cs
#define es regs.x.es
#define ds regs.x.ds
#define ss regs.x.ss
#define si regs.x.si
#define di regs.x.di
#define bp regs.x.bp
#define sp regs.x.sp
/* getting rid of all flags */
#define carry regs.x.cflags
#define overF regs.x.flags /***** check *****/
/* Byte register variables */
#define ah regs.h.ah
#define al regs.h.al
#define bh regs.h.bh
#define bl regs.h.bl
#define ch regs.h.ch
#define cl regs.h.cl
#define dh regs.h.dh
#define dl regs.h.dl
/* High and low words of a Dword */
#define highWord(w) (*((Word*)&(w) + 1))
#define lowWord(w) ((Word)(w))
#define MAXByte 0xFF
#define MAXWord 0xFFFF
#define MAXSignByte 0x7F
#define MINSignByte 0x81
#define MAXSignWord 0x7FFF
#define MINSignWord 0x8001

33
include/error.h Normal file
View File

@@ -0,0 +1,33 @@
/*****************************************************************************
* Error codes
* (C) Cristina Cifuentes
****************************************************************************/
#pragma once
/* These definitions refer to errorMessage in error.c */
#define USAGE 0
#define INVALID_ARG 1
#define INVALID_OPCODE 2
#define INVALID_386OP 3
#define FUNNY_SEGOVR 4
#define FUNNY_REP 5
#define CANNOT_OPEN 6
#define CANNOT_READ 7
#define MALLOC_FAILED 8
#define NEWEXE_FORMAT 9
#define NO_BB 10
#define INVALID_SYNTHETIC_BB 11
#define INVALID_INT_BB 12
#define IP_OUT_OF_RANGE 13
#define DEF_NOT_FOUND 14
#define JX_NOT_DEF 15
#define NOT_DEF_USE 16
#define REPEAT_FAIL 17
#define WHILE_FAIL 18
void fatalError(Int errId, ...);
void reportError(Int errId, ...);

99
include/graph.h Normal file
View File

@@ -0,0 +1,99 @@
/*****************************************************************************
* CFG, BB and interval related definitions
* (C) Cristina Cifuentes
****************************************************************************/
#pragma once
#include <list>
#include <vector>
/* Types of basic block nodes */
/* Real basic blocks: type defined according to their out-edges */
enum eBBKind
{
ONE_BRANCH = 0, /* unconditional branch */
TWO_BRANCH = 1, /* conditional branch */
MULTI_BRANCH=2, /* case branch */
FALL_NODE=3, /* fall through */
RETURN_NODE=4, /* procedure/program return */
CALL_NODE=5, /* procedure call */
LOOP_NODE=6, /* loop instruction */
REP_NODE=7, /* repeat instruction */
INTERVAL_NODE=8, /* contains interval list */
TERMINATE_NODE=11, /* Exit to DOS */
NOWHERE_NODE=12 /* No outedges going anywhere */
};
/* Depth-first traversal constants */
enum eDFS
{
DFS_DISP=1, /* Display graph pass */
DFS_MERGE=2, /* Merge nodes pass */
DFS_NUM=3, /* DFS numbering pass */
DFS_CASE=4, /* Case pass */
DFS_ALPHA=5, /* Alpha code generation*/
DFS_JMP=9 /* rmJMP pass - must be largest flag */
};
/* Control flow analysis constants */
enum eNodeHeaderType
{
NO_TYPE=0, /* node is not a loop header*/
WHILE_TYPE=1, /* node is a while header */
REPEAT_TYPE=2, /* node is a repeat header */
ENDLESS_TYPE=3 /* endless loop header */
};
/* Uninitialized values for certain fields */
#define NO_NODE MAX /* node has no associated node */
#define NO_DOM MAX /* node has no dominator */
#define UN_INIT MAX /* uninitialized variable */
#define THEN 0 /* then edge */
#define ELSE 1 /* else edge */
/* Basic Block (BB) flags */
#define INVALID_BB 0x0001 /* BB is not valid any more */
#define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */
struct BB;
/* Interval structure */
typedef std::list<BB *> queue;
struct interval
{
byte numInt; /* # of the interval */
byte numOutEdges; /* 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;
}
};
/* Derived Sequence structure */
struct derSeq_Entry
{
BB * Gi; /* Graph pointer */
interval * Ii; /* Interval list of Gi */
derSeq_Entry() : Gi(0),Ii(0)
{
}
~derSeq_Entry();
public:
void findIntervals();
};
class derSeq : public std::list<derSeq_Entry>
{
public:
void display();
};
void freeDerivedSeq(derSeq &derivedG); /* reducible.c */

36
include/hlicode.h Normal file
View File

@@ -0,0 +1,36 @@
/*
* File: hlIcode.h
* Purpose: module definitions for high-level icodes
* Date: September 1993
*/
/* High level icodes opcodes - def in file icode.h */
/*typedef enum {
HLI_ASSIGN,
INC,
DEC,
HLI_JCOND,
} hlIcode; */
typedef struct {
hlIcode opcode; /* hlIcode opcode */
union { /* different operands */
struct {
COND_EXPR *lhs;
COND_EXPR *rhs;
} asgn; /* for HLI_ASSIGN hlIcode */
COND_EXPR *exp; /* for HLI_JCOND, INC, DEC */
} oper; /* operand */
boolT valid; /* has a valid hlIcode */
} HLICODE;
//typedef struct {
// Int numIcodes; /* No. of hlIcode reocrds written */
// Int numAlloc; /* No. of hlIcode records allocated */
// HLICODE *hlIcode; /* Array of high-level icodes */
//} HLICODEREC;

362
include/icode.h Normal file
View File

@@ -0,0 +1,362 @@
/*****************************************************************************
* I-code related definitions
* (C) Cristina Cifuentes
****************************************************************************/
#pragma once
#include <vector>
#include "Enums.h"
//enum condId;
/* LOW_LEVEL icode flags */
enum eLLFlags
{
B =0x0000001, /* Byte operands (value implicitly used) */
I =0x0000002, /* Immed. source */
NOT_HLL =0x0000004, /* Not HLL inst. */
FLOAT_OP =0x0000008, /* ESC or WAIT */
SEG_IMMED =0x0000010, /* Number is relocated segment value */
IMPURE =0x0000020, /* Instruction modifies code */
WORD_OFF =0x0000040, /* Inst has word offset ie.could be address */
TERMINATES =0x0000080, /* Instruction terminates program */
CASE =0x0000100, /* Label as case part of switch */
SWITCH =0x0000200, /* Treat indirect JMP as switch stmt */
TARGET =0x0000400, /* Jump target */
SYNTHETIC =0x0000800, /* Synthetic jump instruction */
NO_LABEL =0x0001000, /* Immed. jump cannot be linked to a label */
NO_CODE =0x0002000, /* Hole in Icode array */
SYM_USE =0x0004000, /* Instruction uses a symbol */
SYM_DEF =0x0008000, /* Instruction defines a symbol */
NO_SRC =0x0010000, /* Opcode takes no source */
NO_OPS =0x0020000, /* Opcode takes no operands */
IM_OPS =0x0040000, /* Opcode takes implicit operands */
SRC_B =0x0080000, /* Source operand is byte (dest is word) */
#define NO_SRC_B 0xF7FFFF /* Masks off SRC_B */
HLL_LABEL =0x0100000, /* Icode has a high level language label */
IM_DST =0x0200000, /* Implicit DST for opcode (SIGNEX) */
IM_SRC =0x0400000, /* Implicit SRC for opcode (dx:ax) */
IM_TMP_DST =0x0800000, /* Implicit rTMP DST for opcode (DIV/IDIV) */
JMP_ICODE =0x1000000, /* Jmp dest immed.op converted to icode index */
JX_LOOP =0x2000000, /* Cond jump is part of loop conditional exp */
REST_STK =0x4000000 /* Stack needs to be restored after CALL */
};
/* Parser flags */
#define TO_REG 0x000100 /* rm is source */
#define S 0x000200 /* sign extend */
#define OP386 0x000400 /* 386 op-code */
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
#define ICODEMASK 0xFF00FF /* Masks off parser flags */
/* LOW_LEVEL icode, DU flag bits */
#define Cf 1
#define Sf 2
#define Zf 4
#define Df 8
/* Machine registers */
#define rAX 1 /* These are numbered relative to real 8086 */
#define rCX 2
#define rDX 3
#define rBX 4
#define rSP 5
#define rBP 6
#define rSI 7
#define rDI 8
#define rES 9
#define rCS 10
#define rSS 11
#define rDS 12
#define rAL 13
#define rCL 14
#define rDL 15
#define rBL 16
#define rAH 17
#define rCH 18
#define rDH 19
#define rBH 20
#define rTMP 21 /* temp register for DIV/IDIV/MOD */
#define INDEXBASE 22 /* Indexed modes go from INDEXBASE to
* INDEXBASE+7 */
/* Byte and Word registers */
static const char *const byteReg[9] = {"al", "cl", "dl", "bl",
"ah", "ch", "dh", "bh", "tmp" };
static const char *const wordReg[21] = {"ax", "cx", "dx", "bx", "sp", "bp",
"si", "di", "es", "cs", "ss", "ds",
"", "", "", "", "", "", "", "", "tmp"};
#include "state.h" // State depends on INDEXBASE, but later need STATE
/* Types of icodes */
enum icodeType
{
NOT_SCANNED = 0, /* not even scanned yet */
LOW_LEVEL, /* low-level icode */
HIGH_LEVEL /* high-level icode */
};
/* LOW_LEVEL icode opcodes */
enum llIcode
{
iCBW, /* 0 */
iAAA,
iAAD,
iAAM,
iAAS,
iADC,
iADD,
iAND,
iBOUND,
iCALL,
iCALLF, /* 10 */
iCLC,
iCLD,
iCLI,
iCMC,
iCMP,
iCMPS,
iREPNE_CMPS,
iREPE_CMPS,
iDAA,
iDAS, /* 20 */
iDEC,
iDIV,
iENTER,
iESC,
iHLT,
iIDIV,
iIMUL,
iIN,
iINC,
iINS, /* 30 */
iREP_INS,
iINT,
iIRET,
iJB,
iJBE,
iJAE,
iJA,
iJE,
iJNE,
iJL, /* 40 */
iJGE,
iJLE,
iJG,
iJS,
iJNS,
iJO,
iJNO,
iJP,
iJNP,
iJCXZ, /* 50 */
iJMP,
iJMPF,
iLAHF,
iLDS,
iLEA,
iLEAVE,
iLES,
iLOCK,
iLODS,
iREP_LODS, /* 60 */
iLOOP,
iLOOPE,
iLOOPNE,
iMOV, /* 64 */
iMOVS,
iREP_MOVS,
iMUL, /* 67 */
iNEG,
iNOT,
iOR, /* 70 */
iOUT,
iOUTS,
iREP_OUTS,
iPOP,
iPOPA,
iPOPF,
iPUSH,
iPUSHA,
iPUSHF,
iRCL, /* 80 */
iRCR,
iROL,
iROR,
iRET, /* 84 */
iRETF,
iSAHF,
iSAR,
iSHL,
iSHR,
iSBB, /* 90 */
iSCAS,
iREPNE_SCAS,
iREPE_SCAS,
iSIGNEX,
iSTC,
iSTD,
iSTI,
iSTOS,
iREP_STOS,
iSUB, /* 100 */
iTEST,
iWAIT,
iXCHG,
iXLAT,
iXOR,
iINTO,
iNOP,
iREPNE,
iREPE,
iMOD /* 110 */
};
struct BB;
struct Function;
struct STKFRAME;
/* HIGH_LEVEL icodes opcodes */
typedef enum {
HLI_ASSIGN, /* := */
HLI_CALL, /* Call procedure */
HLI_JCOND, /* Conditional jump */
HLI_RET, /* Return from procedure */
/* pseudo high-level icodes */
HLI_POP, /* Pop expression */
HLI_PUSH, /* Push expression */
} hlIcode;
/* Def/use of flags - low 4 bits represent flags */
struct DU
{
byte d;
byte u;
};
/* Def/Use of registers and stack variables */
struct DU_ICODE
{
dword def; /* For Registers: position in dword is reg index*/
dword lastDefRegi;/* Bit set if last def of this register in BB */
dword use; /* For Registers: position in dword is reg index*/
};
/* Definition-use chain for level 1 (within a basic block) */
#define MAX_REGS_DEF 2 /* 2 regs def'd for long-reg vars */
#define MAX_USES 5
struct DU1
{
Int numRegsDef; /* # registers defined by this inst */
byte regi[MAX_REGS_DEF]; /* registers defined by this inst */
Int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
};
/* LOW_LEVEL icode operand record */
struct ICODEMEM
{
byte seg; /* CS, DS, ES, SS */
int16 segValue; /* Value of segment seg during analysis */
byte segOver; /* CS, DS, ES, SS if segment override */
byte regi; /* 0 < regs < INDEXBASE <= index modes */
int16 off; /* memory address offset */
} ;
struct COND_EXPR;
struct HLTYPE
{
hlIcode opcode; /* hlIcode opcode */
union { /* different operands */
struct { /* for HLI_ASSIGN */
COND_EXPR *lhs;
COND_EXPR *rhs;
} asgn;
COND_EXPR *exp; /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
struct { /* for HLI_CALL */
Function *proc;
STKFRAME *args; /* actual arguments */
} call;
} oper; /* operand */
} ;
typedef struct
{
llIcode opcode; /* llIcode instruction */
byte numBytes; /* Number of bytes this instr */
flags32 flg; /* icode flags */
dword label; /* offset in image (20-bit adr) */
ICODEMEM dst; /* destination operand */
ICODEMEM src; /* source operand */
union { /* Source operand if (flg & I) */
dword op; /* idx of immed src op */
struct { /* Call & # actual arg bytes */
Function *proc; /* ^ target proc (for CALL(F))*/
Int cb; /* # actual arg bytes */
} proc;
} immed;
DU flagDU; /* def/use of flags */
struct { /* Case table if op==JMP && !I */
Int numEntries; /* # entries in case table */
dword *entries; /* array of offsets */
} caseTbl;
Int hllLabNum; /* label # for hll codegen */
} LLTYPE;
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */
struct ICODE
{
icodeType type; /* Icode type */
boolT invalid; /* Has no HIGH_LEVEL equivalent */
BB *inBB; /* BB to which this icode belongs */
DU_ICODE du; /* Def/use regs/vars */
DU1 du1; /* du chain 1 */
Int codeIdx; /* Index into cCode.code */
struct IC { /* Different types of icodes */
LLTYPE ll;
HLTYPE hl; /* For HIGH_LEVEL icodes */
};
IC ic;/* intermediate code */
void writeIntComment(char *s);
void setRegDU(byte regi, operDu du_in);
void invalidate();
void newCallHl();
void writeDU(Int idx);
condId idType(opLoc sd);
// HLL setting functions
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs); // set this icode to be an assign
void setUnary(hlIcode op, COND_EXPR *exp);
void setJCond(COND_EXPR *cexp);
int loc_ip; // used by CICodeRec to number ICODEs
};
// This is the icode array object.
// The bulk of this could well be done with a class library
class CIcodeRec : public std::vector<ICODE>
{
public:
CIcodeRec(); // Constructor
~CIcodeRec(); // Destructor
ICODE * addIcode(ICODE *pIcode);
ICODE * GetFirstIcode();
// ICODE * GetNextIcode(ICODE * pCurIcode);
boolT IsValid(ICODE * pCurIcode);
int GetNumIcodes();
void SetInBB(int start, int end, BB* pnewBB);
void SetImmediateOp(int ip, dword dw);
void SetLlFlag(int ip, dword flag);
void ClearLlFlag(int ip, dword flag);
dword GetLlFlag(int ip);
void SetLlInvalid(int ip, boolT fInv);
dword GetLlLabel(int ip);
llIcode GetLlOpcode(int ip);
boolT labelSrch(dword target, Int *pIndex);
ICODE * GetIcode(int ip);
};

130
include/locident.h Normal file
View File

@@ -0,0 +1,130 @@
/*
* File: locIdent.h
* Purpose: High-level local identifier definitions
* Date: October 1993
* (C) Cristina Cifuentes
*/
#pragma once
#include <vector>
#include <algorithm>
/* Type definition */
struct IDX_ARRAY : public std::vector<int>
{
bool inList(int idx)
{
return std::find(begin(),end(),idx)!=end();
}
};
/* Type definitions used in the decompiled program */
typedef enum {
TYPE_UNKNOWN = 0, /* unknown so far */
TYPE_BYTE_SIGN, /* signed byte (8 bits) */
TYPE_BYTE_UNSIGN, /* unsigned byte */
TYPE_WORD_SIGN, /* signed word (16 bits) */
TYPE_WORD_UNSIGN, /* unsigned word (16 bits) */
TYPE_LONG_SIGN, /* signed long (32 bits) */
TYPE_LONG_UNSIGN, /* unsigned long (32 bits) */
TYPE_RECORD, /* record structure */
TYPE_PTR, /* pointer (32 bit ptr) */
TYPE_STR, /* string */
TYPE_CONST, /* constant (any type) */
TYPE_FLOAT, /* floating point */
TYPE_DOUBLE /* double precision float */
} hlType;
static const char *hlTypes[13] = {"", "char", "unsigned char", "int", "unsigned int",
"long", "unsigned long", "record", "int *", "char *",
"", "float", "double"};
typedef enum
{
STK_FRAME, /* For stack vars */
REG_FRAME, /* For register variables */
GLB_FRAME /* For globals */
} frameType;
typedef struct
{
int16 seg; /* segment value */
int16 off; /* offset */
byte regi; /* optional indexed register */
} BWGLB_TYPE;
typedef struct
{ /* For TYPE_LONG_(UN)SIGN on the stack */
Int offH; /* high offset from BP */
Int offL; /* low offset from BP */
} LONG_STKID_TYPE;
typedef struct
{ /* For TYPE_LONG_(UN)SIGN registers */
byte h; /* high register */
byte l; /* low register */
} LONGID_TYPE;
/* ID, LOCAL_ID */
struct ID
{
hlType type; /* Probable type */
boolT illegal;/* Boolean: not a valid field any more */
IDX_ARRAY idx; /* Index into icode array (REG_FRAME only) */
frameType loc; /* Frame location */
boolT hasMacro;/* Identifier requires a macro */
char macro[10];/* Macro for this identifier */
char name[20];/* Identifier's name */
union { /* Different types of identifiers */
byte regi; /* For TYPE_BYTE(WORD)_(UN)SIGN registers */
struct { /* For TYPE_BYTE(WORD)_(UN)SIGN on the stack */
byte regOff; /* register offset (if any) */
Int off; /* offset from BP */
} bwId;
BWGLB_TYPE bwGlb; /* For TYPE_BYTE(WORD)_(UN)SIGN globals */
LONGID_TYPE longId; /* For TYPE_LONG_(UN)SIGN registers */
LONG_STKID_TYPE longStkId;/* For TYPE_LONG_(UN)SIGN on the stack */
struct { /* For TYPE_LONG_(UN)SIGN globals */
int16 seg; /* segment value */
int16 offH; /* offset high */
int16 offL; /* offset low */
byte regi; /* optional indexed register */
} longGlb;
struct { /* For TYPE_LONG_(UN)SIGN constants */
dword h; /* high word */
dword l; /* low word */
} longKte;
} id;
ID()
{
memset(this,0,sizeof(ID));
}
ID(hlType t, frameType f)
{
memset(this,0,sizeof(ID));
type=t;
loc=f;
}
};
struct LOCAL_ID
{
std::vector<ID> id_arr;
public:
LOCAL_ID()
{}
Int newByteWordReg(hlType t, byte regi);
Int newByteWordStk(hlType t, Int off, byte regOff);
Int newIntIdx(int16 seg, int16 off, byte regi, Int ix, hlType t);
Int newLongReg(hlType t, byte regH, byte regL, Int ix);
Int newLong(opLoc sd, ICODE *pIcode, hlFirst f, Int ix, operDu du, Int off);
void newIdent(hlType t, frameType f);
void flagByteWordId(Int off);
void propLongId(byte regL, byte regH, const char *name);
size_t csym() const {return id_arr.size();}
protected:
Int newLongIdx(int16 seg, int16 offH, int16 offL, byte regi, Int ix, hlType t);
Int newLongGlb(int16 seg, int16 offH, int16 offL, Int ix, hlType t);
Int newLongStk(hlType t, Int offH, Int offL);
};

34
include/perfhlib.h Normal file
View File

@@ -0,0 +1,34 @@
/* Perfect hashing function library. Contains functions to generate perfect
hashing functions
* (C) Mike van Emmerik
*/
#define TRUE 1
#define FALSE 0
#define bool unsigned char
#define byte unsigned char
#define word unsigned short
/* Prototypes */
void hashParams(int NumEntry, int EntryLen, int SetSize, char SetMin,
int NumVert); /* Set the parameters for the hash table */
void hashCleanup(void); /* Frees memory allocated by hashParams() */
void map(void); /* Part 1 of creating the tables */
void assign(void); /* Part 2 of creating the tables */
int hash(byte *s); /* Hash the string to an int 0 .. NUMENTRY-1 */
word *readT1(void); /* Returns a pointer to the T1 table */
word *readT2(void); /* Returns a pointer to the T2 table */
word *readG(void); /* Returns a pointer to the g table */
/* The application must provide these functions: */
void getKey(int i, byte **pKeys);/* Set *keys to point to the i+1th key */
void dispKey(int i); /* Display the key */
/* Macro reads a LH word from the image regardless of host convention */
#ifndef LH
#define LH(p) ((int)((byte *)(p))[0] + ((int)((byte *)(p))[1] << 8))
#endif

38
include/scanner.h Normal file
View File

@@ -0,0 +1,38 @@
/* Scanner functions
* (C) Cristina Cifuentes, Jeff Ledermann
*/
#define LH(p) ((int)((byte *)(p))[0] + ((int)((byte *)(p))[1] << 8))
static void rm(Int i);
static void modrm(Int i);
static void segrm(Int i);
static void data1(Int i);
static void data2(Int i);
static void regop(Int i);
static void segop(Int i);
static void strop(Int i);
static void escop(Int i);
static void axImp(Int i);
static void alImp(Int i);
static void axSrcIm(Int i);
static void memImp(Int i);
static void memReg0(Int i);
static void memOnly(Int i);
static void dispM(Int i);
static void dispS(Int i);
static void dispN(Int i);
static void dispF(Int i);
static void prefix(Int i);
static void immed(Int i);
static void shift(Int i);
static void arith(Int i);
static void trans(Int i);
static void const1(Int i);
static void const3(Int i);
static void none1(Int i);
static void none2(Int i);
static void checkInt(Int i);
/* Extracts reg bits from middle of mod-reg-rm byte */
#define REG(x) ((byte)(x & 0x38) >> 3)

28
include/state.h Normal file
View File

@@ -0,0 +1,28 @@
/****************************************************************************
* dcc project header
* (C) Cristina Cifuentes, Mike van Emmerik
****************************************************************************/
/* STATE TABLE */
struct STATE
{
dword IP; /* Offset into Image */
int16 r[INDEXBASE]; /* Value of segs and AX */
byte f[INDEXBASE]; /* True if r[.] has a value */
struct
{ /* For case stmt indexed reg */
byte regi; /* Last conditional jump */
int16 immed; /* Contents of the previous register */
} JCond;
void setState(word reg, int16 value);
public:
void checkStartup();
STATE() : IP(0)
{
JCond.immed=0;
memset(r,0,sizeof(int16)*INDEXBASE);
memset(f,0,sizeof(byte)*INDEXBASE);
}
};

50
include/symtab.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* Symbol table prototypes
* (C) Mike van Emmerik
*/
#pragma once
/* * * * * * * * * * * * * * * * * */
/* Symbol table structs and protos */
/* * * * * * * * * * * * * * * * * */
struct Function;
struct SYMTABLE
{
std::string pSymName; /* Ptr to symbolic name or comment */
dword symOff; /* Symbol image offset */
Function *symProc; /* Procedure pointer */
word preHash; /* Hash value before the modulo */
word postHash; /* Hash value after the modulo */
word nextOvf; /* Next entry this hash bucket, or -1 */
word prevOvf; /* Back link in Ovf chain */
SYMTABLE() : symOff(0),symProc(0) {}
SYMTABLE(dword _sym,Function *_proc) : symOff(_sym),symProc(_proc)
{}
bool operator == (const SYMTABLE &other) const
{
// does not yse pSymName, to ease finding by symOff/symProc combo
// in map<SYMTABLE,X>
return (symOff==other.symOff) && symProc==(other.symProc);
}
};
enum tableType /* The table types */
{
Label=0, /* The label table */
Comment, /* The comment table */
NUM_TABLE_TYPES /* Number of entries: must be last */
};
void createSymTables(void);
void destroySymTables(void);
void enterSym(char *symName, dword symOff, Function *symProc, boolT bSymToo);
boolT readSym (char *symName, dword *pSymOff, Function **pSymProc);
boolT readVal (char *symName, dword symOff, Function *symProc);
void deleteSym(char *symName);
void deleteVal(dword symOff, Function * symProc, boolT bSymToo);
std::string findVal(dword symOff, Function * symProc, word *pIndex);
word symHash(char *name, word *pre);
word valHash(dword off, Function * proc, word *pre);
void selectTable(tableType); /* Select a particular table */
char *addStrTbl(char *pStr); /* Add string to string table */

80
include/types.h Normal file
View File

@@ -0,0 +1,80 @@
/****************************************************************************
* dcc project general header
* (C) Cristina Cifuentes, Mike van Emmerik
****************************************************************************/
#pragma once
#include <stdint.h>
/**** Common definitions and macros ****/
#ifdef __MSDOS__ /* Intel: 16 bit integer */
typedef long Int; /* Int: 0x80000000..0x7FFFFFFF */
typedef unsigned long flags32; /* 32 bits */
typedef unsigned long dword; /* 32 bits */
#define MAX 0x7FFFFFFF
#else /* Unix: 32 bit integer */
typedef int Int; /* Int: 0x80000000..0x7FFFFFFF */
typedef unsigned int flags32; /* 32 bits */
typedef unsigned int dword; /* 32 bits */
#define MAX 0x7FFFFFFF
#endif
/* 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 */
#if defined(__MSDOS__) | defined(WIN32)
#define unlink _unlink // Compiler is picky about non Ansi names
#endif
#define TRUE 1
#define FALSE 0
#define SYNTHESIZED_MIN 0x100000 /* Synthesized labs use bits 21..32 */
/* These are for C library signature detection */
#define SYMLEN 16 /* Length of proc symbols, incl null */
#define PATLEN 23 /* Length of proc patterns */
#define WILD 0xF4 /* The wild byte */
/****** MACROS *******/
/* 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))
/* 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 LHS(p) (((byte *)(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)))
/* Macro to convert a segment, offset definition into a 20 bit address */
#define opAdr(seg,off) ((seg << 4) + off)
/* duVal FLAGS */
struct eDuVal
{
enum flgs
{
DEF=1,
USE=2,
VAL=4
};
int def :1; /* Variable was first defined than used */
int use :1; /* Variable was first used than defined */
int val :1; /* Variable has an initial value. 2 cases:
* 1. When variable is used first (ie. global)
* 2. When a value is moved into the variable
* for the first time. */
void setFlags(uint16_t x)
{
def = x&DEF;
use = x&USE;
val = x&VAL;
}
bool isUSE_VAL() {return use&&val;} /* Use and Val */
};