From 9cd3226536b0976e6e02237d8893e382b717581c Mon Sep 17 00:00:00 2001 From: nemerle Date: Mon, 25 Apr 2016 11:39:07 +0200 Subject: [PATCH] Normalize logic operation keywords and add use msvc fix Logical or should be only 'or','and','not', and not error prone '||','&&','!' --- common/perfhlib.cpp | 12 +- include/ast.h | 10 +- include/disassem.h | 1 + include/icode.h | 50 +- include/locident.h | 27 +- include/symtab.h | 8 +- include/types.h | 26 +- src/BasicBlock.cpp | 18 +- src/CallConvention.cpp | 6 +- src/DccFrontend.cpp | 827 +++---- src/Procedure.cpp | 7 +- src/RegisterNode.cpp | 23 +- src/ast.cpp | 52 +- src/backend.cpp | 20 +- src/chklib.cpp | 8 +- src/comwrite.cpp | 4 +- src/control.cpp | 61 +- src/dataflow.cpp | 109 +- src/dcc.cpp | 14 +- src/dcc_interface.cpp | 3 +- src/disassem.cpp | 40 +- src/fixwild.cpp | 9 +- src/graph.cpp | 794 +++---- src/hlicode.cpp | 6 +- src/icode.cpp | 8 +- src/idioms.cpp | 18 +- src/idioms/arith_idioms.cpp | 21 +- src/idioms/call_idioms.cpp | 11 +- src/idioms/epilogue_idioms.cpp | 26 +- src/idioms/idiom1.cpp | 17 +- src/idioms/mov_idioms.cpp | 17 +- src/idioms/neg_idioms.cpp | 17 +- src/idioms/shift_idioms.cpp | 17 +- src/idioms/xor_idioms.cpp | 21 +- src/locident.cpp | 77 +- src/machine_x86.cpp | 18 +- src/parser.cpp | 2688 +++++++++++------------ src/procs.cpp | 14 +- src/proplong.cpp | 50 +- src/reducible.cpp | 14 +- src/scanner.cpp | 49 +- tools/makedsig/LIB_PatternCollector.cpp | 5 +- tools/makedsig/TPL_PatternCollector.cpp | 7 +- tools/makedsig/fixwild.cpp | 5 +- tools/makedsig/makedsig.cpp | 3 +- 45 files changed, 2670 insertions(+), 2568 deletions(-) diff --git a/common/perfhlib.cpp b/common/perfhlib.cpp index af4ad44..332ba1a 100644 --- a/common/perfhlib.cpp +++ b/common/perfhlib.cpp @@ -12,6 +12,7 @@ */ #include "perfhlib.h" #include "PatternCollector.h" +#include "msvc_fixes.h" #include #include @@ -38,9 +39,6 @@ static bool *visited; /* Array of bools: whether visited */ static bool *deleted; /* Array of bools: whether deleted */ /* Private prototypes */ -static void initGraph(void); -static void addToGraph(int e, int v1, int v2); -static bool isCycle(void); static void duplicateKeys(int v1, int v2); void PerfectHash::setHashParams(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin, @@ -157,7 +155,7 @@ void PerfectHash::map(PatternCollector *collector) } addToGraph(numEdges++, f1, f2); } - if (cycle || (cycle = isCycle())) /* OK - is there a cycle? */ + if (cycle or (cycle = isCycle())) /* OK - is there a cycle? */ { printf("Iteration %d\n", ++c); } @@ -314,7 +312,7 @@ bool PerfectHash::isCycle(void) } for (v=1; v <= NumVert; v++) { - if (!visited[v]) + if (not visited[v]) { if (DFS(-32767, v)) { @@ -415,7 +413,7 @@ duplicateKeys(int v1, int v2) u += T1[keys[j] - SetMin]; } u %= NumVert; - if ((u != v1) && (u != v2)) continue; + if ((u != v1) and (u != v2)) continue; v = 0; for (j=0; j < EntryLen; j++) @@ -425,7 +423,7 @@ duplicateKeys(int v1, int v2) } v %= NumVert; - if ((v == v2) || (v == v1)) + if ((v == v2) or (v == v1)) { printf("Entry #%d key: ", i+1); for (j=0; j < EntryLen; j++) printf("%02X ", keys[j]); diff --git a/include/ast.h b/include/ast.h index 6ba45a2..f97a515 100644 --- a/include/ast.h +++ b/include/ast.h @@ -5,11 +5,15 @@ * (C) Cristina Cifuentes */ #pragma once + +#include "Enums.h" +#include "msvc_fixes.h" + +#include #include #include #include -#include -#include "Enums.h" + static const int operandSize=20; /* The following definitions and types define the Conditional Expression * attributed syntax tree, as defined by the following EBNF: @@ -120,7 +124,7 @@ struct BinaryOperator : public Expr } ~BinaryOperator() { - assert(m_lhs!=m_rhs || m_lhs==nullptr); + assert(m_lhs!=m_rhs or m_lhs==nullptr); delete m_lhs; delete m_rhs; m_lhs=m_rhs=nullptr; diff --git a/include/disassem.h b/include/disassem.h index d0755bf..f1ac699 100644 --- a/include/disassem.h +++ b/include/disassem.h @@ -9,6 +9,7 @@ #include #include "bundle.h" struct LLInst; +struct Function; struct Disassembler { protected: diff --git a/include/icode.h b/include/icode.h index 78e2e70..808d2a4 100644 --- a/include/icode.h +++ b/include/icode.h @@ -3,6 +3,19 @@ * (C) Cristina Cifuentes ****************************************************************************/ #pragma once +#include "msvc_fixes.h" +#include "BinaryImage.h" +#include "libdis.h" +#include "Enums.h" +#include "state.h" // State depends on INDEXBASE, but later need STATE +#include "CallConvention.h" + +#include +#include +#include +#include +#include + #include #include #include @@ -10,15 +23,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include "libdis.h" -#include "Enums.h" -#include "state.h" // State depends on INDEXBASE, but later need STATE -#include "CallConvention.h" //enum condId; @@ -275,12 +279,12 @@ struct LLOperand } bool operator==(const LLOperand &with) const { - return (seg==with.seg) && - (segOver==with.segOver) && - (segValue==with.segValue) && - (regi == with.regi) && - (off == with.off) && - (opz==with.opz) && + return (seg==with.seg) and + (segOver==with.segOver) and + (segValue==with.segValue) and + (regi == with.regi) and + (off == with.off) and + (opz==with.opz) and (proc.proc==with.proc.proc); } int64_t getImm2() const {return opz;} @@ -330,7 +334,7 @@ public: int hllLabNum; /* label # for hll codegen */ bool conditionalJump() { - return (getOpcode() >= iJB) && (getOpcode() < iJCXZ); + return (getOpcode() >= iJB) and (getOpcode() < iJCXZ); } bool testFlags(uint32_t x) const { return (flg & x)!=0;} void setFlags(uint32_t flag) {flg |= flag;} @@ -366,11 +370,11 @@ public: } bool match(llIcode op,eReg dest,eReg src_reg) { - return (getOpcode()==op)&&(m_dst.regi==dest)&&(m_src.regi==src_reg); + return (getOpcode()==op) and (m_dst.regi==dest) and (m_src.regi==src_reg); } bool match(eReg dest,eReg src_reg) { - return (m_dst.regi==dest)&&(m_src.regi==src_reg); + return (m_dst.regi==dest) and (m_src.regi==src_reg); } bool match(eReg dest) { @@ -460,14 +464,14 @@ public: template struct TypeFilter { - bool operator()(ICODE *ic) {return ic->type==HIGH_LEVEL;} - bool operator()(ICODE &ic) {return ic.type==HIGH_LEVEL;} + bool operator()(ICODE *ic) {return ic->type==TYPE;} + bool operator()(ICODE &ic) {return ic.type==TYPE;} }; template struct TypeAndValidFilter { - bool operator()(ICODE *ic) {return (ic->type==HIGH_LEVEL)&&(ic->valid());} - bool operator()(ICODE &ic) {return (ic.type==HIGH_LEVEL)&&ic.valid();} + bool operator()(ICODE *ic) {return (ic->type==TYPE) and (ic->valid());} + bool operator()(ICODE &ic) {return (ic.type==TYPE) and ic.valid();} }; static TypeFilter select_high_level; static TypeAndValidFilter select_valid_high_level; @@ -506,7 +510,7 @@ public: if(iter==uses.end()) return; uses.erase(iter); - assert("Same user more then once!" && uses.end()==std::find(uses.begin(),uses.end(),us)); + assert("Same user more then once!" and uses.end()==std::find(uses.begin(),uses.end(),us)); } }; diff --git a/include/locident.h b/include/locident.h index d1a1533..f7bfd43 100644 --- a/include/locident.h +++ b/include/locident.h @@ -6,14 +6,16 @@ */ #pragma once +#include "msvc_fixes.h" +#include "types.h" +#include "Enums.h" +#include "machine_x86.h" + #include #include #include #include #include -#include "types.h" -#include "Enums.h" -#include "machine_x86.h" /* Type definition */ // this array has to stay in-order of addition i.e. not std::set > @@ -105,11 +107,11 @@ public: protected: LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */ public: - eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */ - struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */ + eReg regi; /* For TYPE_BYTE(WORD)_(UN)SIGN registers */ + struct { /* For TYPE_BYTE(WORD)_(UN)SIGN on the stack */ uint8_t regOff; /* register offset (if any) */ int off; /* offset from BP */ - } bwId; + } bwId; BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */ LONGGLB_TYPE longGlb; struct { /* For TYPE_LONG_(UN)SIGN constants */ @@ -118,21 +120,22 @@ 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;} + + LONGID_TYPE & longId() {assert(isLong() and loc==REG_FRAME); return m_longId;} + const LONGID_TYPE & longId() const {assert(isLong() and loc==REG_FRAME); return m_longId;} + LONG_STKID_TYPE & longStkId() {assert(isLong() and loc==STK_FRAME); return id.longStkId;} + const LONG_STKID_TYPE & longStkId() const {assert(isLong() and 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);} + bool isSigned() const { return (type==TYPE_BYTE_SIGN) or (type==TYPE_WORD_SIGN) or (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); } + bool isLong() const { return (type==TYPE_LONG_UNSIGN) or (type==TYPE_LONG_SIGN); } void setLocalName(int i) { char buf[32]; diff --git a/include/symtab.h b/include/symtab.h index f2410cd..b38582d 100644 --- a/include/symtab.h +++ b/include/symtab.h @@ -3,10 +3,12 @@ * (C) Mike van Emmerik */ #pragma once -#include -#include #include "Enums.h" #include "types.h" +#include "msvc_fixes.h" + +#include +#include struct Expr; struct AstIdent; struct TypeContainer; @@ -91,7 +93,7 @@ struct SYMTABLE { // does not yse pSymName, to ease finding by symOff/symProc combo // in map - return (symOff==other.symOff) && symProc==(other.symProc); + return (symOff==other.symOff) and symProc==(other.symProc); } }; diff --git a/include/types.h b/include/types.h index 71c0c36..a9a7724 100644 --- a/include/types.h +++ b/include/types.h @@ -5,9 +5,13 @@ *************************************************************************** */ #pragma once +#include "Enums.h" +#include "msvc_fixes.h" + #include #include -#include "Enums.h" +#include + /**** Common definitions and macros ****/ #define MAX 0x7FFFFFFF @@ -25,7 +29,7 @@ // 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) ((uint16_t)((uint8_t *)(p))[0] + ((uint16_t)((uint8_t *)(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 */ @@ -64,12 +68,22 @@ struct eDuVal use = x&USE; val = x&VAL; } - bool isUSE_VAL() {return use&&val;} //Use and Val + bool isUSE_VAL() {return use and val;} //Use and Val }; static constexpr const char * hlTypes[13] = { - "", "char", "unsigned char", "int", "unsigned int", - "long", "unsigned long", "record", "int *", "char *", - "", "float", "double" + "", + "char", + "unsigned char", + "int", + "unsigned int", + "long", + "unsigned long", + "record", + "int *", + "char *", + "", + "float", + "double" }; struct TypeContainer diff --git a/src/BasicBlock.cpp b/src/BasicBlock.cpp index f2f4cea..d0cc769 100644 --- a/src/BasicBlock.cpp +++ b/src/BasicBlock.cpp @@ -1,11 +1,15 @@ +#include "BasicBlock.h" + +#include "msvc_fixes.h" +#include "Procedure.h" +#include "dcc.h" +#include "msvc_fixes.h" + #include #include #include #include #include -#include "BasicBlock.h" -#include "Procedure.h" -#include "dcc.h" using namespace std; using namespace boost; @@ -189,8 +193,8 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat } bool BB::isEndOfPath(int latch_node_idx) const { - return nodeType == RETURN_NODE || nodeType == TERMINATE_NODE || - nodeType == NOWHERE_NODE || (dfsLastNum == latch_node_idx); + return nodeType == RETURN_NODE or nodeType == TERMINATE_NODE or + nodeType == NOWHERE_NODE or dfsLastNum == latch_node_idx; } void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, int _ifFollow) { @@ -202,7 +206,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, repCond; /* Repeat condition for while() */ /* Check if this basic block should be analysed */ - if ((_ifFollow != UN_INIT) && (this == pProc->m_dfsLast[_ifFollow])) + if ((_ifFollow != UN_INIT) and (this == pProc->m_dfsLast[_ifFollow])) return; if (wasTraversedAtLevel(DFS_ALPHA)) @@ -380,7 +384,7 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc) for(ICODE &pHli : instructions) { - if ((pHli.type == HIGH_LEVEL) && ( pHli.valid() )) //TODO: use filtering range here. + if ((pHli.type == HIGH_LEVEL) and ( pHli.valid() )) //TODO: use filtering range here. { std::string line = pHli.hl()->write1HlIcode(pProc, numLoc); if (!line.empty()) diff --git a/src/CallConvention.cpp b/src/CallConvention.cpp index dad4a8c..a4bc01e 100644 --- a/src/CallConvention.cpp +++ b/src/CallConvention.cpp @@ -7,11 +7,11 @@ 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) + if(nullptr==c_call) c_call = new C_CallingConvention; - if(!p_call) + if(nullptr==p_call) p_call = new Pascal_CallingConvention; - if(!u_call) + if(nullptr==u_call) u_call = new Unknown_CallingConvention; switch(v) { case UNKNOWN: return u_call; diff --git a/src/DccFrontend.cpp b/src/DccFrontend.cpp index 9c0149c..19a53e4 100644 --- a/src/DccFrontend.cpp +++ b/src/DccFrontend.cpp @@ -1,413 +1,414 @@ -#include "dcc.h" -#include "DccFrontend.h" -#include "project.h" -#include "disassem.h" -#include "CallGraph.h" - -#include -#include - -#include - - -class Loader -{ - bool loadIntoProject(IProject *); -}; - -struct PSP { /* PSP structure */ - uint16_t int20h; /* interrupt 20h */ - uint16_t eof; /* segment, end of allocation block */ - uint8_t res1; /* reserved */ - uint8_t dosDisp[5]; /* far call to DOS function dispatcher */ - uint8_t int22h[4]; /* vector for terminate routine */ - uint8_t int23h[4]; /* vector for ctrl+break routine */ - uint8_t int24h[4]; /* vector for error routine */ - uint8_t res2[22]; /* reserved */ - uint16_t segEnv; /* segment address of environment block */ - uint8_t res3[34]; /* reserved */ - uint8_t int21h[6]; /* opcode for int21h and far return */ - uint8_t res4[6]; /* reserved */ - uint8_t fcb1[16]; /* default file control block 1 */ - uint8_t fcb2[16]; /* default file control block 2 */ - uint8_t res5[4]; /* reserved */ - uint8_t cmdTail[0x80]; /* command tail and disk transfer area */ -}; - -static struct MZHeader { /* EXE file header */ - uint8_t sigLo; /* .EXE signature: 0x4D 0x5A */ - uint8_t sigHi; - uint16_t lastPageSize; /* Size of the last page */ - uint16_t numPages; /* Number of pages in the file */ - uint16_t numReloc; /* Number of relocation items */ - uint16_t numParaHeader; /* # of paragraphs in the header */ - uint16_t minAlloc; /* Minimum number of paragraphs */ - uint16_t maxAlloc; /* Maximum number of paragraphs */ - uint16_t initSS; /* Segment displacement of stack */ - uint16_t initSP; /* Contents of SP at entry */ - uint16_t checkSum; /* Complemented checksum */ - uint16_t initIP; /* Contents of IP at entry */ - uint16_t initCS; /* Segment displacement of code */ - uint16_t relocTabOffset; /* Relocation table offset */ - uint16_t overlayNum; /* Overlay number */ -} header; - -#define EXE_RELOCATION 0x10 /* EXE images rellocated to above PSP */ - -//static void LoadImage(char *filename); -static void displayMemMap(void); -/**************************************************************************** -* displayLoadInfo - Displays low level loader type info. -***************************************************************************/ -void PROG::displayLoadInfo(void) -{ - int i; - - printf("File type is %s\n", (fCOM)?"COM":"EXE"); - if (! fCOM) { - printf("Signature = %02X%02X\n", header.sigLo, header.sigHi); - printf("File size %% 512 = %04X\n", LH(&header.lastPageSize)); - printf("File size / 512 = %04X pages\n", LH(&header.numPages)); - printf("# relocation items = %04X\n", LH(&header.numReloc)); - printf("Offset to load image = %04X paras\n", LH(&header.numParaHeader)); - printf("Minimum allocation = %04X paras\n", LH(&header.minAlloc)); - printf("Maximum allocation = %04X paras\n", LH(&header.maxAlloc)); - } - printf("Load image size = %04" PRIiPTR "\n", cbImage - sizeof(PSP)); - printf("Initial SS:SP = %04X:%04X\n", initSS, initSP); - printf("Initial CS:IP = %04X:%04X\n", initCS, initIP); - - if (option.VeryVerbose && cReloc) - { - printf("\nRelocation Table\n"); - for (i = 0; i < cReloc; i++) - { - printf("%06X -> [%04X]\n", relocTable[i],LH(image() + relocTable[i])); - } - } - printf("\n"); -} - -/***************************************************************************** -* fill - Fills line for displayMemMap() -****************************************************************************/ -static void fill(int ip, char *bf) -{ - PROG &prog(Project::get()->prog); - static uint8_t type[4] = {'.', 'd', 'c', 'x'}; - uint8_t i; - - for (i = 0; i < 16; i++, ip++) - { - *bf++ = ' '; - *bf++ = (ip < prog.cbImage)? type[(prog.map[ip >> 2] >> ((ip & 3) * 2)) & 3]: ' '; - } - *bf = '\0'; -} - - -/***************************************************************************** -* displayMemMap - Displays the memory bitmap -****************************************************************************/ -static void displayMemMap(void) -{ - PROG &prog(Project::get()->prog); - - char c, b1[33], b2[33], b3[33]; - uint8_t i; - int ip = 0; - - printf("\nMemory Map\n"); - while (ip < prog.cbImage) - { - fill(ip, b1); - printf("%06X %s\n", ip, b1); - ip += 16; - for (i = 3, c = b1[1]; i < 32 && c == b1[i]; i += 2) - ; /* Check if all same */ - if (i > 32) - { - fill(ip, b2); /* Skip until next two are not same */ - fill(ip+16, b3); - if (! (strcmp(b1, b2) || strcmp(b1, b3))) - { - printf(" :\n"); - do - { - ip += 16; - fill(ip+16, b1); - } while (! strcmp(b1, b2)); - } - } - } - printf("\n"); -} -DccFrontend::DccFrontend(QObject *parent) : - QObject(parent) -{ -} - -/***************************************************************************** -* FrontEnd - invokes the loader, parser, disassembler (if asm1), icode -* rewritter, and displays any useful information. -****************************************************************************/ -bool DccFrontend::FrontEnd () -{ - - /* Do depth first flow analysis building call graph and procedure list, - * and attaching the I-code to each procedure */ - parse (*Project::get()); - - if (option.asm1) - { - qWarning() << "dcc: writing assembler file "<pProcList) - { - f.markImpure(); - if (option.asm1) - { - ds.disassem(&f); - } - } - if (option.Interact) - { - interactDis(&Project::get()->pProcList.front(), 0); /* Interactive disassembler */ - } - - /* Converts jump target addresses to icode offsets */ - for(Function &f : Project::get()->pProcList) - { - f.bindIcodeOff(); - } - /* Print memory bitmap */ - if (option.Map) - displayMemMap(); - return(true); // we no longer own proj ! -} -struct DosLoader { -protected: - void prepareImage(PROG &prog,size_t sz,QFile &fp) { - /* Allocate a block of memory for the program. */ - prog.cbImage = sz + sizeof(PSP); - prog.Imagez = new uint8_t [prog.cbImage]; - prog.Imagez[0] = 0xCD; /* Fill in PSP int 20h location */ - prog.Imagez[1] = 0x20; /* for termination checking */ - /* Read in the image past where a PSP would go */ - if (sz != fp.read((char *)prog.Imagez + sizeof(PSP),sz)) - fatalError(CANNOT_READ, fp.fileName().toLocal8Bit().data()); - } -}; -struct ComLoader : public DosLoader { - bool canLoad(QFile &fp) { - fp.seek(0); - char sig[2]; - if(2==fp.read(sig,2)) { - return not (sig[0] == 0x4D && sig[1] == 0x5A); - } - return false; - } - bool load(PROG &prog,QFile &fp) { - fp.seek(0); - /* COM file - * In this case the load module size is just the file length - */ - auto cb = fp.size(); - - /* COM programs start off with an ORG 100H (to leave room for a PSP) - * This is also the implied start address so if we load the image - * at offset 100H addresses should all line up properly again. - */ - prog.initCS = 0; - prog.initIP = 0x100; - prog.initSS = 0; - prog.initSP = 0xFFFE; - prog.cReloc = 0; - - prepareImage(prog,cb,fp); - - - /* Set up memory map */ - cb = (prog.cbImage + 3) / 4; - prog.map = (uint8_t *)malloc(cb); - memset(prog.map, BM_UNKNOWN, (size_t)cb); - return true; - } -}; -struct ExeLoader : public DosLoader { - bool canLoad(QFile &fp) { - if(fp.size()> 8); - } - return true; - } -}; -/***************************************************************************** -* LoadImage -****************************************************************************/ -bool Project::load() -{ - // addTask(loaderSelection,PreCond(BinaryImage)) - // addTask(applyLoader,PreCond(Loader)) - const char *fname = binary_path().toLocal8Bit().data(); - QFile finfo(binary_path()); - /* Open the input file */ - if(!finfo.open(QFile::ReadOnly)) { - fatalError(CANNOT_OPEN, fname); - } - /* Read in first 2 bytes to check EXE signature */ - if (finfo.size()<=2) - { - fatalError(CANNOT_READ, fname); - } - ComLoader com_loader; - ExeLoader exe_loader; - if(exe_loader.canLoad(finfo)) { - prog.fCOM = false; - return exe_loader.load(prog,finfo); - } - if(com_loader.canLoad(finfo)) { - prog.fCOM = true; - return com_loader.load(prog,finfo); - } - return false; -} -uint32_t SynthLab; -/* Parses the program, builds the call graph, and returns the list of - * procedures found */ -void DccFrontend::parse(Project &proj) -{ - PROG &prog(proj.prog); - STATE state; - - /* Set initial state */ - state.setState(rES, 0); /* PSP segment */ - state.setState(rDS, 0); - state.setState(rCS, prog.initCS); - state.setState(rSS, prog.initSS); - state.setState(rSP, prog.initSP); - state.IP = ((uint32_t)prog.initCS << 4) + prog.initIP; - SynthLab = SYNTHESIZED_MIN; - - /* Check for special settings of initial state, based on idioms of the - startup code */ - state.checkStartup(); - ilFunction 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; - /* 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); - state.IP = prog.offMain; - } - else - { - start_proc = proj.createFunction(0,"start"); - /* Create initial procedure at program start address */ - start_proc->procEntry = (uint32_t)state.IP; - } - - /* The state info is for the first procedure */ - start_proc->state = state; - - /* Set up call graph initial node */ - proj.callGraph = new CALL_GRAPH; - 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(); - //BUG: proj and g_proj are 'live' at this point ! - - /* Recursively build entire procedure list */ - start_proc->FollowCtrl(proj.callGraph, &state); - - /* This proc needs to be called to clean things up from SetupLibCheck() */ - CleanupLibCheck(); -} +#include "DccFrontend.h" + +#include "dcc.h" +#include "msvc_fixes.h" +#include "project.h" +#include "disassem.h" +#include "CallGraph.h" + +#include +#include +#include + + +class Loader +{ + bool loadIntoProject(IProject *); +}; + +struct PSP { /* PSP structure */ + uint16_t int20h; /* interrupt 20h */ + uint16_t eof; /* segment, end of allocation block */ + uint8_t res1; /* reserved */ + uint8_t dosDisp[5]; /* far call to DOS function dispatcher */ + uint8_t int22h[4]; /* vector for terminate routine */ + uint8_t int23h[4]; /* vector for ctrl+break routine */ + uint8_t int24h[4]; /* vector for error routine */ + uint8_t res2[22]; /* reserved */ + uint16_t segEnv; /* segment address of environment block */ + uint8_t res3[34]; /* reserved */ + uint8_t int21h[6]; /* opcode for int21h and far return */ + uint8_t res4[6]; /* reserved */ + uint8_t fcb1[16]; /* default file control block 1 */ + uint8_t fcb2[16]; /* default file control block 2 */ + uint8_t res5[4]; /* reserved */ + uint8_t cmdTail[0x80]; /* command tail and disk transfer area */ +}; + +static struct MZHeader { /* EXE file header */ + uint8_t sigLo; /* .EXE signature: 0x4D 0x5A */ + uint8_t sigHi; + uint16_t lastPageSize; /* Size of the last page */ + uint16_t numPages; /* Number of pages in the file */ + uint16_t numReloc; /* Number of relocation items */ + uint16_t numParaHeader; /* # of paragraphs in the header */ + uint16_t minAlloc; /* Minimum number of paragraphs */ + uint16_t maxAlloc; /* Maximum number of paragraphs */ + uint16_t initSS; /* Segment displacement of stack */ + uint16_t initSP; /* Contents of SP at entry */ + uint16_t checkSum; /* Complemented checksum */ + uint16_t initIP; /* Contents of IP at entry */ + uint16_t initCS; /* Segment displacement of code */ + uint16_t relocTabOffset; /* Relocation table offset */ + uint16_t overlayNum; /* Overlay number */ +} header; + +#define EXE_RELOCATION 0x10 /* EXE images rellocated to above PSP */ + +//static void LoadImage(char *filename); +static void displayMemMap(void); +/**************************************************************************** +* displayLoadInfo - Displays low level loader type info. +***************************************************************************/ +void PROG::displayLoadInfo(void) +{ + int i; + + printf("File type is %s\n", (fCOM)?"COM":"EXE"); + if (not fCOM) { + printf("Signature = %02X%02X\n", header.sigLo, header.sigHi); + printf("File size %% 512 = %04X\n", LH(&header.lastPageSize)); + printf("File size / 512 = %04X pages\n", LH(&header.numPages)); + printf("# relocation items = %04X\n", LH(&header.numReloc)); + printf("Offset to load image = %04X paras\n", LH(&header.numParaHeader)); + printf("Minimum allocation = %04X paras\n", LH(&header.minAlloc)); + printf("Maximum allocation = %04X paras\n", LH(&header.maxAlloc)); + } + printf("Load image size = %04" PRIiPTR "\n", cbImage - sizeof(PSP)); + printf("Initial SS:SP = %04X:%04X\n", initSS, initSP); + printf("Initial CS:IP = %04X:%04X\n", initCS, initIP); + + if (option.VeryVerbose and cReloc) + { + printf("\nRelocation Table\n"); + for (i = 0; i < cReloc; i++) + { + printf("%06X -> [%04X]\n", relocTable[i],LH(image() + relocTable[i])); + } + } + printf("\n"); +} + +/***************************************************************************** +* fill - Fills line for displayMemMap() +****************************************************************************/ +static void fill(int ip, char *bf) +{ + PROG &prog(Project::get()->prog); + static uint8_t type[4] = {'.', 'd', 'c', 'x'}; + uint8_t i; + + for (i = 0; i < 16; i++, ip++) + { + *bf++ = ' '; + *bf++ = (ip < prog.cbImage)? type[(prog.map[ip >> 2] >> ((ip & 3) * 2)) & 3]: ' '; + } + *bf = '\0'; +} + + +/***************************************************************************** +* displayMemMap - Displays the memory bitmap +****************************************************************************/ +static void displayMemMap(void) +{ + PROG &prog(Project::get()->prog); + + char c, b1[33], b2[33], b3[33]; + uint8_t i; + int ip = 0; + + printf("\nMemory Map\n"); + while (ip < prog.cbImage) + { + fill(ip, b1); + printf("%06X %s\n", ip, b1); + ip += 16; + for (i = 3, c = b1[1]; i < 32 and c == b1[i]; i += 2) + ; /* Check if all same */ + if (i > 32) + { + fill(ip, b2); /* Skip until next two are not same */ + fill(ip+16, b3); + if (not (strcmp(b1, b2) || strcmp(b1, b3))) + { + printf(" :\n"); + do + { + ip += 16; + fill(ip+16, b1); + } while (0==strcmp(b1, b2)); + } + } + } + printf("\n"); +} +DccFrontend::DccFrontend(QObject *parent) : + QObject(parent) +{ +} + +/***************************************************************************** +* FrontEnd - invokes the loader, parser, disassembler (if asm1), icode +* rewritter, and displays any useful information. +****************************************************************************/ +bool DccFrontend::FrontEnd () +{ + + /* Do depth first flow analysis building call graph and procedure list, + * and attaching the I-code to each procedure */ + parse (*Project::get()); + + if (option.asm1) + { + qWarning() << "dcc: writing assembler file "<pProcList) + { + f.markImpure(); + if (option.asm1) + { + ds.disassem(&f); + } + } + if (option.Interact) + { + interactDis(&Project::get()->pProcList.front(), 0); /* Interactive disassembler */ + } + + /* Converts jump target addresses to icode offsets */ + for(Function &f : Project::get()->pProcList) + { + f.bindIcodeOff(); + } + /* Print memory bitmap */ + if (option.Map) + displayMemMap(); + return(true); // we no longer own proj ! +} +struct DosLoader { +protected: + void prepareImage(PROG &prog,size_t sz,QFile &fp) { + /* Allocate a block of memory for the program. */ + prog.cbImage = sz + sizeof(PSP); + prog.Imagez = new uint8_t [prog.cbImage]; + prog.Imagez[0] = 0xCD; /* Fill in PSP int 20h location */ + prog.Imagez[1] = 0x20; /* for termination checking */ + /* Read in the image past where a PSP would go */ + if (sz != fp.read((char *)prog.Imagez + sizeof(PSP),sz)) + fatalError(CANNOT_READ, fp.fileName().toLocal8Bit().data()); + } +}; +struct ComLoader : public DosLoader { + bool canLoad(QFile &fp) { + fp.seek(0); + char sig[2]; + if(2==fp.read(sig,2)) { + return not (sig[0] == 0x4D and sig[1] == 0x5A); + } + return false; + } + bool load(PROG &prog,QFile &fp) { + fp.seek(0); + /* COM file + * In this case the load module size is just the file length + */ + auto cb = fp.size(); + + /* COM programs start off with an ORG 100H (to leave room for a PSP) + * This is also the implied start address so if we load the image + * at offset 100H addresses should all line up properly again. + */ + prog.initCS = 0; + prog.initIP = 0x100; + prog.initSS = 0; + prog.initSP = 0xFFFE; + prog.cReloc = 0; + + prepareImage(prog,cb,fp); + + + /* Set up memory map */ + cb = (prog.cbImage + 3) / 4; + prog.map = (uint8_t *)malloc(cb); + memset(prog.map, BM_UNKNOWN, (size_t)cb); + return true; + } +}; +struct ExeLoader : public DosLoader { + bool canLoad(QFile &fp) { + if(fp.size()> 8); + } + return true; + } +}; +/***************************************************************************** +* LoadImage +****************************************************************************/ +bool Project::load() +{ + // addTask(loaderSelection,PreCond(BinaryImage)) + // addTask(applyLoader,PreCond(Loader)) + const char *fname = binary_path().toLocal8Bit().data(); + QFile finfo(binary_path()); + /* Open the input file */ + if(!finfo.open(QFile::ReadOnly)) { + fatalError(CANNOT_OPEN, fname); + } + /* Read in first 2 bytes to check EXE signature */ + if (finfo.size()<=2) + { + fatalError(CANNOT_READ, fname); + } + ComLoader com_loader; + ExeLoader exe_loader; + if(exe_loader.canLoad(finfo)) { + prog.fCOM = false; + return exe_loader.load(prog,finfo); + } + if(com_loader.canLoad(finfo)) { + prog.fCOM = true; + return com_loader.load(prog,finfo); + } + return false; +} +uint32_t SynthLab; +/* Parses the program, builds the call graph, and returns the list of + * procedures found */ +void DccFrontend::parse(Project &proj) +{ + PROG &prog(proj.prog); + STATE state; + + /* Set initial state */ + state.setState(rES, 0); /* PSP segment */ + state.setState(rDS, 0); + state.setState(rCS, prog.initCS); + state.setState(rSS, prog.initSS); + state.setState(rSP, prog.initSP); + state.IP = ((uint32_t)prog.initCS << 4) + prog.initIP; + SynthLab = SYNTHESIZED_MIN; + + /* Check for special settings of initial state, based on idioms of the + startup code */ + state.checkStartup(); + ilFunction 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; + /* 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); + state.IP = prog.offMain; + } + else + { + start_proc = proj.createFunction(0,"start"); + /* Create initial procedure at program start address */ + start_proc->procEntry = (uint32_t)state.IP; + } + + /* The state info is for the first procedure */ + start_proc->state = state; + + /* Set up call graph initial node */ + proj.callGraph = new CALL_GRAPH; + 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(); + //BUG: proj and g_proj are 'live' at this point ! + + /* Recursively build entire procedure list */ + start_proc->FollowCtrl(proj.callGraph, &state); + + /* This proc needs to be called to clean things up from SetupLibCheck() */ + CleanupLibCheck(); +} diff --git a/src/Procedure.cpp b/src/Procedure.cpp index 536e353..57a04f7 100644 --- a/src/Procedure.cpp +++ b/src/Procedure.cpp @@ -1,6 +1,9 @@ #include "Procedure.h" + +#include "msvc_fixes.h" #include "project.h" #include "scanner.h" + //FunctionType *Function::getFunctionType() const //{ // return &m_type; @@ -15,7 +18,7 @@ void JumpTable::pruneEntries(uint16_t cs) for (uint32_t i = start; i < finish; i += 2) { uint32_t target = cs + LH(&prg->image()[i]); - if (target < finish && target >= start) + if (target < finish and target >= start) finish = target; else if (target >= (uint32_t)prg->cbImage) finish = i; @@ -25,7 +28,7 @@ void JumpTable::pruneEntries(uint16_t cs) { uint32_t target = cs + LH(&prg->image()[i]); /* Be wary of 00 00 as code - it's probably data */ - if (! (prg->image()[target] || prg->image()[target+1]) || scan(target, _Icode)) + if (! (prg->image()[target] or prg->image()[target+1]) or scan(target, _Icode)) finish = i; } diff --git a/src/RegisterNode.cpp b/src/RegisterNode.cpp index 3041c4d..b27d20c 100644 --- a/src/RegisterNode.cpp +++ b/src/RegisterNode.cpp @@ -1,3 +1,10 @@ +#include "types.h" +#include "msvc_fixes.h" +#include "ast.h" +#include "bundle.h" +#include "machine_x86.h" +#include "project.h" + #include #include #include @@ -8,12 +15,6 @@ //#include //#include -#include "types.h" -#include "ast.h" -#include "bundle.h" - -#include "machine_x86.h" -#include "project.h" using namespace std; using namespace boost::adaptors; RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym) @@ -41,7 +42,7 @@ RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym) // ident.type(REGISTER); // hlType type_sel; // regType reg_type; -// if ((icodeFlg & B) || (icodeFlg & SRC_B)) +// if ((icodeFlg & B) or (icodeFlg & SRC_B)) // { // type_sel = TYPE_BYTE_SIGN; // reg_type = BYTE_REG; @@ -80,17 +81,17 @@ string RegisterNode::walkCondExpr(Function *pProc, int *numLoc) const int RegisterNode::hlTypeSize(Function *) const { if (regiType == BYTE_REG) - return (1); + return 1; else - return (2); + return 2; } hlType RegisterNode::expType(Function *pproc) const { if (regiType == BYTE_REG) - return (TYPE_BYTE_SIGN); + return TYPE_BYTE_SIGN; else - return (TYPE_WORD_SIGN); + return TYPE_WORD_SIGN; } Expr *RegisterNode::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym) diff --git a/src/ast.cpp b/src/ast.cpp index c1dd306..be951b0 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -4,29 +4,31 @@ * Date: September 1993 * (C) Cristina Cifuentes */ +#include "ast.h" + +#include "msvc_fixes.h" +#include "types.h" +#include "bundle.h" +#include "machine_x86.h" +#include "project.h" + +#include +#include +#include +#include #include #include #include #include #include -#include -#include -#include -#include -#include "types.h" -#include "ast.h" -#include "bundle.h" -#include "machine_x86.h" -#include "project.h" using namespace std; using namespace boost; using namespace boost::adaptors; + extern int strSize (const uint8_t *, char); extern char *cChar(uint8_t c); - - // Conditional operator symbols in C. Index by condOp enumeration type static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ", " & ", " | ", " ^ ", " ~ ", @@ -146,7 +148,7 @@ AstIdent *AstIdent::Loc(int off, LOCAL_ID *localId) for (i = 0; i < localId->csym(); i++) { const ID &lID(localId->id_arr[i]); - if ((lID.id.bwId.off == off) && (lID.id.bwId.regOff == 0)) + if ((lID.id.bwId.off == off) and (lID.id.bwId.regOff == 0)) break; } if (i == localId->csym()) @@ -181,7 +183,7 @@ GlobalVariableIdx::GlobalVariableIdx (int16_t segValue, int16_t off, uint8_t reg for (i = 0; i < locSym->csym(); i++) { const BWGLB_TYPE &lID(locSym->id_arr[i].id.bwGlb); - if ((lID.seg == segValue) && (lID.off == off) && (lID.regi == regi)) + if ((lID.seg == segValue) and (lID.off == off) and (lID.regi == regi)) break; } if (i == locSym->csym()) @@ -221,7 +223,7 @@ AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, { AstIdent *newExp; /* Check for long constant and save it as a constant expression */ - if ((sd == SRC) && pIcode->ll()->testFlags(I)) /* constant */ + if ((sd == SRC) and pIcode->ll()->testFlags(I)) /* constant */ { int value; if (f == HIGH_FIRST) @@ -296,8 +298,8 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_ const LLOperand &pm(*ll_insn.get(sd)); - if ( ((sd == DST) && ll_insn.testFlags(IM_DST)) or - ((sd == SRC) && ll_insn.testFlags(IM_SRC)) or + if ( ((sd == DST) and ll_insn.testFlags(IM_DST)) or + ((sd == SRC) and ll_insn.testFlags(IM_SRC)) or (sd == LHS_OP)) /* for MUL lhs */ { /* implicit dx:ax */ idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(rDX, rAX), ix_); @@ -306,13 +308,13 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_ duIcode.setRegDU (rAX, du); } - else if ((sd == DST) && ll_insn.testFlags(IM_TMP_DST)) + else if ((sd == DST) and ll_insn.testFlags(IM_TMP_DST)) { /* implicit tmp */ newExp = new RegisterNode(LLOperand(rTMP,2), &pProc->localId); duIcode.setRegDU(rTMP, (operDu)eUSE); } - else if ((sd == SRC) && ll_insn.testFlags(I)) /* constant */ + else if ((sd == SRC) and ll_insn.testFlags(I)) /* constant */ newExp = new Constant(ll_insn.src().getImm2(), 2); else if (pm.regi == rUNDEF) /* global variable */ newExp = new GlobalVariable(pm.segValue, pm.off); @@ -325,14 +327,14 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_ else if (pm.off) /* offset */ { // TODO: this is ABI specific, should be actually based on Function calling conv - if ((pm.seg == rSS) && (pm.regi == INDEX_BP)) /* idx on bp */ + if ((pm.seg == rSS) and (pm.regi == INDEX_BP)) /* idx on bp */ { if (pm.off >= 0) /* argument */ newExp = AstIdent::Param (pm.off, &pProc->args); else /* local variable */ newExp = AstIdent::Loc (pm.off, &pProc->localId); } - else if ((pm.seg == rDS) && (pm.regi == INDEX_BX)) /* bx */ + else if ((pm.seg == rDS) and (pm.regi == INDEX_BX)) /* bx */ { if (pm.off > 0) /* global variable */ newExp = new GlobalVariableIdx(pm.segValue, pm.off, rBX,&pProc->localId); @@ -345,9 +347,9 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_ /**** check long ops, indexed global var *****/ } - else /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */ + else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */ { - if ((pm.seg == rDS) && (pm.regi > INDEX_BP_DI)) /* dereference */ + if ((pm.seg == rDS) and (pm.regi > INDEX_BP_DI)) /* dereference */ { eReg selected; switch (pm.regi) { @@ -376,13 +378,13 @@ condId LLInst::idType(opLoc sd) const { const LLOperand &pm((sd == SRC) ? src() : m_dst); - if ((sd == SRC) && testFlags(I)) + if ((sd == SRC) and testFlags(I)) return (CONSTANT); else if (pm.regi == 0) return (GLOB_VAR); else if ( pm.isReg() ) return (REGISTER); - else if ((pm.seg == rSS) && (pm.regi == INDEX_BP)) + else if ((pm.seg == rSS) and (pm.regi == INDEX_BP)) { //TODO: which pm.seg/pm.regi pairs should produce PARAM/LOCAL_VAR ? if (pm.off >= 0) @@ -877,7 +879,7 @@ Expr *AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId) eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl) { ID *id = &locTbl->id_arr[idx]; - if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) || + if ((id->loc == REG_FRAME) and ((id->type == TYPE_LONG_SIGN) or (id->type == TYPE_LONG_UNSIGN))) { if (id->longId().h() == regi) diff --git a/src/backend.cpp b/src/backend.cpp index 7f62b94..9e9ca6b 100644 --- a/src/backend.cpp +++ b/src/backend.cpp @@ -4,6 +4,12 @@ * Purpose: Back-end module. Generates C code for each procedure. * (C) Cristina Cifuentes ****************************************************************************/ +#include "dcc.h" +#include "msvc_fixes.h" +#include "disassem.h" +#include "project.h" +#include "CallGraph.h" + #include #include #include @@ -17,15 +23,13 @@ #include #include #include -#include "dcc.h" -#include "disassem.h" -#include "project.h" -#include "CallGraph.h" + using namespace boost; using namespace boost::adaptors; -bundle cCode; /* Procedure declaration and code */ using namespace std; +bundle cCode; /* Procedure declaration and code */ + /* Returns a unique index to the next label */ int getNextLabel() { @@ -252,8 +256,8 @@ void Function::codeGen (std::ostream &fs) if (refId.loc == REG_FRAME) { /* Register variables are assigned to a local variable */ - if (((flg & SI_REGVAR) && (refId.id.regi == rSI)) || - ((flg & DI_REGVAR) && (refId.id.regi == rDI))) + if (((flg & SI_REGVAR) and (refId.id.regi == rSI)) or + ((flg & DI_REGVAR) and (refId.id.regi == rDI))) { refId.setLocalName(++numLoc); ostr << "int "<proc->flg & PROC_OUTPUT) || + if ((pcallGraph->proc->flg & PROC_OUTPUT) or (pcallGraph->proc->flg & PROC_ISLIB)) return; pcallGraph->proc->flg |= PROC_OUTPUT; diff --git a/src/chklib.cpp b/src/chklib.cpp index 5abdc77..4a9f62f 100644 --- a/src/chklib.cpp +++ b/src/chklib.cpp @@ -6,6 +6,7 @@ */ #include "dcc.h" +#include "msvc_fixes.h" #include "project.h" #include "perfhlib.h" #include "dcc_interface.h" @@ -15,6 +16,7 @@ #include #include #include + PerfectHash g_pattern_hasher; #define NIL -1 /* Used like NULL, but 0 is valid */ @@ -322,7 +324,7 @@ void SetupLibCheck(void) numVert = readFileShort(g_file); PatLen = readFileShort(g_file); SymLen = readFileShort(g_file); - if ((PatLen != PATLEN) || (SymLen != SYMLEN)) + if ((PatLen != PATLEN) or (SymLen != SYMLEN)) { printf("Sorry! Compiled for sym and pattern lengths of %d and %d\n", SYMLEN, PATLEN); @@ -473,7 +475,7 @@ bool LibCheck(Function & pProc) } /* But is it a real library function? */ i = NIL; - if ((numFunc == 0) || (i=searchPList(ht[h].htSym)) != NIL) + if ((numFunc == 0) or (i=searchPList(ht[h].htSym)) != NIL) { pProc.flg |= PROC_ISLIB; /* It's a lib function */ pProc.callingConv(CConv::C); @@ -604,7 +606,7 @@ static bool locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pa for (j=0; j < iPatLen; j++) { /* j is the index of the uint8_t being considered in the pattern. */ - if ((*pSrc != pattern[j]) && (pattern[j] != WILD)) + if ((*pSrc != pattern[j]) and (pattern[j] != WILD)) { /* A definite mismatch */ break; /* Break to outer loop */ diff --git a/src/comwrite.cpp b/src/comwrite.cpp index e98b346..f3044f0 100644 --- a/src/comwrite.cpp +++ b/src/comwrite.cpp @@ -7,7 +7,9 @@ ****************************************************************************/ #include "dcc.h" +#include "msvc_fixes.h" #include "machine_x86.h" + #include #include using namespace std; @@ -156,7 +158,7 @@ void LLInst::writeIntComment (std::ostringstream &s) { s < 0x1F && src_immed < 0x2F) + else if (src_immed > 0x1F and src_immed < 0x2F) { s < #include #include @@ -10,15 +14,10 @@ #include #include -#include "dcc.h" -//typedef struct list { -// int nodeIdx; -// struct list *next; -//} nodeList; typedef std::list nodeList; /* dfsLast index to the node */ -#define ancestor(a,b) ((a->dfsLastNum < b->dfsLastNum) && (a->dfsFirstNum < b->dfsFirstNum)) +#define ancestor(a,b) ((a->dfsLastNum < b->dfsLastNum) and (a->dfsFirstNum < b->dfsFirstNum)) /* there is a path on the DFST from a to b if the a was first visited in a * dfs, and a was later visited than b when doing the last visit of each * node. */ @@ -48,7 +47,7 @@ static int commonDom (int currImmDom, int predImmDom, Function * pProc) if (predImmDom == NO_DOM) /* predecessor is the root */ return (currImmDom); - while ((currImmDom != NO_DOM) && (predImmDom != NO_DOM) && + while ((currImmDom != NO_DOM) and (predImmDom != NO_DOM) and (currImmDom != predImmDom)) { if (currImmDom < predImmDom) @@ -121,7 +120,7 @@ static void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head) for (TYPEADR_TYPE &typeaddr: pProc->m_dfsLast[loop_node]->edges) { int succ = typeaddr.BBptr->dfsLastNum; - if ((! inList(loopNodes, succ)) && (succ < head->loopFollow)) + if ((not inList(loopNodes, succ)) and (succ < head->loopFollow)) head->loopFollow = succ; } } @@ -149,7 +148,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int continue; immedDom = pProc->m_dfsLast[i]->immedDom; - if (inList (loopNodes, immedDom) && inInt(pProc->m_dfsLast[i], intNodes)) + if (inList (loopNodes, immedDom) and inInt(pProc->m_dfsLast[i], intNodes)) { insertList (loopNodes, i); if (pProc->m_dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/ @@ -163,9 +162,9 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int /* Determine type of loop and follow node */ intNodeType = head->nodeType; if (latchNode->nodeType == TWO_BRANCH) - if ((intNodeType == TWO_BRANCH) || (latchNode == head)) - if ((latchNode == head) || - (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum) && + if ((intNodeType == TWO_BRANCH) or (latchNode == head)) + if ((latchNode == head) or + (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum) and inList (loopNodes, head->edges[ELSE].BBptr->dfsLastNum))) { head->loopType = eNodeHeaderType::REPEAT_TYPE; @@ -299,9 +298,9 @@ void Function::structLoops(derSeq *derivedG) for (size_t i = 0; i < intHead->inEdges.size(); i++) { pred = intHead->inEdges[i]; - if (inInt(pred, intNodes) && isBackEdge(pred, intHead)) + if (inInt(pred, intNodes) and isBackEdge(pred, intHead)) { - if (! latchNode) + if (nullptr == latchNode) latchNode = pred; else if (pred->dfsLastNum > latchNode->dfsLastNum) latchNode = pred; @@ -314,7 +313,7 @@ void Function::structLoops(derSeq *derivedG) /* Check latching node is at the same nesting level of case * statements (if any) and that the node doesn't belong to * another loop. */ - if ((latchNode->caseHead == intHead->caseHead) && + if ((latchNode->caseHead == intHead->caseHead) and (latchNode->loopHead == NO_NODE)) { intHead->latchNode = latchNode->dfsLastNum; @@ -353,7 +352,7 @@ static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail) pBB->traversed = DFS_CASE; current = pBB->dfsLastNum; - if ((current != tail) && (pBB->nodeType != MULTI_BRANCH) && (inList (l, pBB->immedDom))) + if ((current != tail) and (pBB->nodeType != MULTI_BRANCH) and (inList (l, pBB->immedDom))) { insertList (l, current); pBB->caseHead = head; @@ -385,7 +384,7 @@ void Function::structCases() * the current header node, and is not a successor. */ for (size_t j = i + 2; j < numBBs; j++) { - if ((!successor(j, i, this)) && (m_dfsLast[j]->immedDom == i)) + if ((not successor(j, i, this)) and (m_dfsLast[j]->immedDom == i)) { if (exitNode == NO_NODE) { @@ -446,7 +445,7 @@ void Function::structIfs () if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */ continue; - if ((currNode->nodeType == TWO_BRANCH) && (!currNode->back().ll()->testFlags(JX_LOOP))) + if ((currNode->nodeType == TWO_BRANCH) and (not currNode->back().ll()->testFlags(JX_LOOP))) { followInEdges = 0; follow = 0; @@ -468,7 +467,7 @@ void Function::structIfs () /* Determine follow according to number of descendants * immediately dominated by this node */ - if ((follow != 0) && (followInEdges > 1)) + if ((follow != 0) and (followInEdges > 1)) { currNode->ifFollow = follow; if (!unresolved.empty()) @@ -617,33 +616,33 @@ void Function::compoundCond() change = true; //assume change - /* Check (X || Y) case */ - if ((thenBB->nodeType == TWO_BRANCH) && (thenBB->numHlIcodes == 1) && - (thenBB->inEdges.size() == 1) && (thenBB->edges[ELSE].BBptr == elseBB)) + /* Check (X or Y) case */ + if ((thenBB->nodeType == TWO_BRANCH) and (thenBB->numHlIcodes == 1) and + (thenBB->inEdges.size() == 1) and (thenBB->edges[ELSE].BBptr == elseBB)) { if(Case_X_or_Y(pbb, thenBB, elseBB)) --i; } - /* Check (!X && Y) case */ - else if ((thenBB->nodeType == TWO_BRANCH) && (thenBB->numHlIcodes == 1) && - (thenBB->inEdges.size() == 1) && (thenBB->edges[THEN].BBptr == elseBB)) + /* Check (!X and Y) case */ + else if ((thenBB->nodeType == TWO_BRANCH) and (thenBB->numHlIcodes == 1) and + (thenBB->inEdges.size() == 1) and (thenBB->edges[THEN].BBptr == elseBB)) { if(Case_notX_and_Y(pbb, thenBB, elseBB)) --i; } - /* Check (X && Y) case */ - else if ((elseBB->nodeType == TWO_BRANCH) && (elseBB->numHlIcodes == 1) && - (elseBB->inEdges.size()==1) && (elseBB->edges[THEN].BBptr == thenBB)) + /* Check (X and Y) case */ + else if ((elseBB->nodeType == TWO_BRANCH) and (elseBB->numHlIcodes == 1) and + (elseBB->inEdges.size()==1) and (elseBB->edges[THEN].BBptr == thenBB)) { if(Case_X_and_Y(pbb, thenBB, elseBB )) --i; } - /* Check (!X || Y) case */ - else if ((elseBB->nodeType == TWO_BRANCH) && (elseBB->numHlIcodes == 1) && - (elseBB->inEdges.size() == 1) && (elseBB->edges[ELSE].BBptr == thenBB)) + /* Check (!X or Y) case */ + else if ((elseBB->nodeType == TWO_BRANCH) and (elseBB->numHlIcodes == 1) and + (elseBB->inEdges.size() == 1) and (elseBB->edges[ELSE].BBptr == thenBB)) { if(Case_notX_or_Y(pbb, thenBB, elseBB )) --i; diff --git a/src/dataflow.cpp b/src/dataflow.cpp index 3c6a420..72a7fec 100644 --- a/src/dataflow.cpp +++ b/src/dataflow.cpp @@ -4,18 +4,21 @@ * Purpose: Data flow analysis module. * (C) Cristina Cifuentes ****************************************************************************/ + +#include "dcc.h" +#include "project.h" +#include "msvc_fixes.h" + +#include +#include +#include +#include #include #include #include #include #include -#include -#include -#include -#include -#include "dcc.h" -#include "project.h" using namespace boost; using namespace boost::adaptors; struct ExpStack @@ -28,7 +31,7 @@ struct ExpStack void push(Expr *); Expr * pop(); Expr * top() const { - if(!expStk.empty()) + if(not expStk.empty()) return expStk.back(); return nullptr; } @@ -145,7 +148,7 @@ void Function::elimCondCodes () { llIcode useAtOp = llIcode(useAt->ll()->getOpcode()); use = useAt->ll()->flagDU.u; - if ((useAt->type != LOW_LEVEL) || ( ! useAt->valid() ) || ( 0 == use )) + if ((useAt->type != LOW_LEVEL) or ( not useAt->valid() ) or ( 0 == use )) continue; /* Find definition within the same basic block */ defAt=useAt; @@ -158,7 +161,7 @@ void Function::elimCondCodes () continue; notSup = false; LLOperand *dest_ll = defIcode.ll()->get(DST); - if ((useAtOp >= iJB) && (useAtOp <= iJNS)) + if ((useAtOp >= iJB) and (useAtOp <= iJNS)) { iICODE befDefAt = (++riICODE(defAt)).base(); switch (defIcode.ll()->getOpcode()) @@ -194,7 +197,7 @@ void Function::elimCondCodes () reportError (JX_NOT_DEF, defIcode.ll()->getOpcode()); flg |= PROC_ASM; /* generate asm */ } - if (! notSup) + if (not notSup) { assert(lhs); assert(rhs); @@ -226,7 +229,7 @@ void Function::elimCondCodes () } /* Check for extended basic block */ - if ((pBB->size() == 1) &&(useAtOp >= iJB) && (useAtOp <= iJNS)) + if ((pBB->size() == 1) and(useAtOp >= iJB) and (useAtOp <= iJNS)) { ICODE & _prev(pBB->back()); /* For extended basic blocks - previous icode inst */ if (_prev.hl()->opcode == HLI_JCOND) @@ -268,7 +271,7 @@ void Function::genLiveKtes () continue; // skip invalid BBs for(ICODE &insn : *pbb) { - if ((insn.type == HIGH_LEVEL) && ( insn.valid() )) + if ((insn.type == HIGH_LEVEL) and ( insn.valid() )) { liveUse |= (insn.du.use - def); def |= insn.du.def; @@ -342,7 +345,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut) pcallee = ticode.hl()->call.proc; /* user/runtime routine */ - if (! (pcallee->flg & PROC_ISLIB)) + if (not (pcallee->flg & PROC_ISLIB)) { if (pcallee->liveAnal == false) /* hasn't been processed */ pcallee->dataFlow (pbb->liveOut); @@ -350,7 +353,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut) } else /* library routine */ { - if ( (pcallee->flg & PROC_IS_FUNC) && /* returns a value */ + if ( (pcallee->flg & PROC_IS_FUNC) and /* returns a value */ (pcallee->liveOut & pbb->edges[0].BBptr->liveIn).any() ) pbb->liveOut = pcallee->liveOut; @@ -358,7 +361,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut) pbb->liveOut.reset(); } - if ((! (pcallee->flg & PROC_ISLIB)) || ( pbb->liveOut.any() )) + if ((not (pcallee->flg & PROC_ISLIB)) or ( pbb->liveOut.any() )) { switch (pcallee->retVal.type) { case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: @@ -385,7 +388,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut) pbb->liveIn = LivenessSet(pbb->liveUse + (pbb->liveOut - pbb->def)); /* Check if live sets have been modified */ - if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut)) + if ((prevLiveIn != pbb->liveIn) or (prevLiveOut != pbb->liveOut)) change = true; } } @@ -412,9 +415,9 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut) * register */ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at) { - if ((regi == rDI) && (flg & DI_REGVAR)) + if ((regi == rDI) and (flg & DI_REGVAR)) return true; - if ((regi == rSI) && (flg & SI_REGVAR)) + if ((regi == rSI) and (flg & SI_REGVAR)) return true; if (distance(start_at,end())>1) /* several instructions */ { @@ -457,7 +460,7 @@ 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))) + if (not ((picode.hl()->opcode == HLI_CALL) and (picode.hl()->call.proc->flg & PROC_IS_FUNC))) return; BB *tbb = this->edges[0].BBptr; @@ -475,7 +478,7 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode) /* 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)) + if ( picode.du1.used(defRegIdx) and tbb->liveOut.testRegAndSubregs(regi)) picode.du.lastDefRegi.addReg(regi); } @@ -488,11 +491,11 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode) void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode) { if (picode->valid() and not picode->du1.used(defRegIdx) and - (not picode->du.lastDefRegi.testRegAndSubregs(regi)) && - (not ((picode->hl()->opcode == HLI_CALL) && + (not picode->du.lastDefRegi.testRegAndSubregs(regi)) and + (not ((picode->hl()->opcode == HLI_CALL) and (picode->hl()->call.proc->flg & PROC_ISLIB)))) { - if (! (this->liveOut.testRegAndSubregs(regi))) /* not liveOut */ + if (not (this->liveOut.testRegAndSubregs(regi))) /* not liveOut */ { bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId); if (res == true) @@ -540,7 +543,7 @@ void BB::genDU1() defRegIdx++; /* Check if all defined registers have been processed */ - if ((defRegIdx >= picode->du1.getNumRegsDef()) || (defRegIdx == MAX_REGS_DEF)) + if ((defRegIdx >= picode->du1.getNumRegsDef()) or (defRegIdx == MAX_REGS_DEF)) break; } } @@ -588,7 +591,7 @@ void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, { eReg inserted = id_arr[lhs_reg->regiIdx].id.regi; eReg lhsReg = id_arr[op->regiIdx].id.regi; - if((lhsReg==inserted)||Machine_X86::isSubRegisterOf(lhsReg,inserted)) + if((lhsReg==inserted) or Machine_X86::isSubRegisterOf(lhsReg,inserted)) { // Do not replace ax = XYZ; given ax = H << P; with H << P = return; @@ -644,7 +647,7 @@ bool BinaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCA { if(nullptr==m_rhs) return false; - if ( ! m_rhs->xClear (range_to_check, lastBBinst, locs) ) + if ( not m_rhs->xClear (range_to_check, lastBBinst, locs) ) return false; if(nullptr==m_lhs) return false; @@ -690,7 +693,7 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE else { if(numArgsargs.size()) { if(prog.addressingMode=='l') { - if((callee->args[numArgs].type==TYPE_STR)||(callee->args[numArgs].type==TYPE_PTR)) { + if((callee->args[numArgs].type==TYPE_STR) or (callee->args[numArgs].type==TYPE_PTR)) { RegisterNode *rn = dynamic_cast(g_exp_stk.top()); AstIdent *idn = dynamic_cast(g_exp_stk.top()); if(rn) { @@ -815,9 +818,9 @@ void C_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE picode) { numArgs++; } } - else if ((cb == 0) && picode->ll()->testFlags(REST_STK)) + else if ((cb == 0) and picode->ll()->testFlags(REST_STK)) { - while (! g_exp_stk.empty()) + while (not g_exp_stk.empty()) { k+=processCArg (pp, func, &(*picode), numArgs); numArgs++; @@ -907,8 +910,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) * icode expression */ ticode = picode->du1.idx[0].uses.front(); - if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) && - ((ticode->hl()->opcode != HLI_CALL) && + if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and + ((ticode->hl()->opcode != HLI_CALL) and (ticode->hl()->opcode != HLI_RET))) continue; @@ -926,8 +929,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) // 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) && + if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and + ((ti_hl->opcode != HLI_CALL) and (ti_hl->opcode != HLI_RET))) continue; @@ -1026,8 +1029,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) 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) && + if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and + ((ticode->hl()->opcode != HLI_CALL) and (ticode->hl()->opcode != HLI_RET))) continue; locals.processTargetIcode(picode.base(), numHlIcodes, ticode,true); @@ -1038,8 +1041,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) 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) && + if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and + ((ticode->hl()->opcode != HLI_CALL) and (ticode->hl()->opcode != HLI_RET))) continue; @@ -1187,36 +1190,36 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut) isBx = _liveOut.testReg(rBX); isCx = _liveOut.testReg(rCX); isDx = _liveOut.testReg(rDX); - bool isAL = !isAx && _liveOut.testReg(rAL); - bool isAH = !isAx && _liveOut.testReg(rAH); - bool isBL = !isBx && _liveOut.testReg(rBL); - bool isBH = !isBx && _liveOut.testReg(rBH); - bool isCL = !isCx && _liveOut.testReg(rCL); - bool isCH = !isCx && _liveOut.testReg(rCH); - bool isDL = !isDx && _liveOut.testReg(rDL); - bool isDH = !isDx && _liveOut.testReg(rDH); - if(isAL && isAH) + bool isAL = not isAx and _liveOut.testReg(rAL); + bool isAH = not isAx and _liveOut.testReg(rAH); + bool isBL = not isBx and _liveOut.testReg(rBL); + bool isBH = not isBx and _liveOut.testReg(rBH); + bool isCL = not isCx and _liveOut.testReg(rCL); + bool isCH = not isCx and _liveOut.testReg(rCH); + bool isDL = not isDx and _liveOut.testReg(rDL); + bool isDH = not isDx and _liveOut.testReg(rDH); + if(isAL and isAH) { isAx = true; isAH=isAL=false; } - if(isDL && isDH) + if(isDL and isDH) { isDx = true; isDH=isDL=false; } - if(isBL && isBH) + if(isBL and isBH) { isBx = true; isBH=isBL=false; } - if(isCL && isCH) + if(isCL and isCH) { isCx = true; isCH=isCL=false; } - if (isAx && isDx) /* long or pointer */ + if (isAx and isDx) /* long or pointer */ { retVal.type = TYPE_LONG_SIGN; retVal.loc = REG_FRAME; @@ -1224,7 +1227,7 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut) /*idx = */localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), Icode.begin()); localId.propLongId (rAX, rDX, "\0"); } - else if (isAx || isBx || isCx || isDx) /* uint16_t */ + else if (isAx or isBx or isCx or isDx) /* uint16_t */ { retVal.type = TYPE_WORD_SIGN; retVal.loc = REG_FRAME; @@ -1238,7 +1241,7 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut) retVal.id.regi = rDX; /*idx = */localId.newByteWordReg(TYPE_WORD_SIGN,retVal.id.regi); } - else if(isAL||isBL||isCL||isDL) + else if(isAL or isBL or isCL or isDL) { retVal.type = TYPE_BYTE_SIGN; retVal.loc = REG_FRAME; @@ -1252,7 +1255,7 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut) retVal.id.regi = rDL; /*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi); } - else if(isAH||isBH||isCH||isDH) + else if(isAH or isBH or isCH or isDH) { retVal.type = TYPE_BYTE_SIGN; retVal.loc = REG_FRAME; diff --git a/src/dcc.cpp b/src/dcc.cpp index 50b8240..4c0f899 100644 --- a/src/dcc.cpp +++ b/src/dcc.cpp @@ -4,10 +4,18 @@ * (C) Cristina Cifuentes ****************************************************************************/ +#include "dcc.h" + +#include "msvc_fixes.h" +#include "project.h" +#include "CallGraph.h" +#include "DccFrontend.h" + #include #include #include #include + #ifdef LLVM_EXPERIMENTAL #include #include @@ -26,10 +34,6 @@ #endif #include -#include "dcc.h" -#include "project.h" -#include "CallGraph.h" -#include "DccFrontend.h" /* Global variables - extern to other modules */ extern QString asm1_name, asm2_name; /* Assembler output filenames */ @@ -164,7 +168,7 @@ void setupOptions(QCoreApplication &app) { option.filename = args.first(); if(parser.isSet(targetFileOption)) asm1_name = asm2_name = parser.value(targetFileOption); - else if(option.asm1 || option.asm2) { + else if(option.asm1 or option.asm2) { asm1_name = option.filename+".a1"; asm2_name = option.filename+".a2"; } diff --git a/src/dcc_interface.cpp b/src/dcc_interface.cpp index 7a050a2..a3cdc41 100644 --- a/src/dcc_interface.cpp +++ b/src/dcc_interface.cpp @@ -54,8 +54,7 @@ public: IDcc* IDcc::get() { static IDcc *v=0; - if(!v) + if(nullptr == v) v = new DccImpl; - return v; } diff --git a/src/disassem.cpp b/src/disassem.cpp index 90527ff..b5a12ad 100644 --- a/src/disassem.cpp +++ b/src/disassem.cpp @@ -2,6 +2,13 @@ * dcc project disassembler * (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann ****************************************************************************/ +#include "disassem.h" + +#include "dcc.h" +#include "msvc_fixes.h" +#include "symtab.h" +#include "project.h" + #include #include #include @@ -9,11 +16,6 @@ #include #include #include - -#include "dcc.h" -#include "symtab.h" -#include "disassem.h" -#include "project.h" // Note: for the time being, there is no interactive disassembler // for unix @@ -107,7 +109,7 @@ static vector posStack; /* position stack */ void LLInst::findJumpTargets(CIcodeRec &_pc) { - if (testFlags(I) && ! testFlags(JMP_ICODE) && isJmpInst()) + if (testFlags(I) and not testFlags(JMP_ICODE) and isJmpInst()) { /* Replace the immediate operand with an icode index */ iICODE labTgt=_pc.labelSrch(src().getImm2()); @@ -216,9 +218,9 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) /* Disassembly stage 1 -- * Do not try to display NO_CODE entries or synthetic instructions, * other than JMPs, that have been introduced for def/use analysis. */ - if ((option.asm1) && - ( inst.testFlags(NO_CODE) || - (inst.testFlags(SYNTHETIC) && (inst.getOpcode() != iJMP)))) + if ((option.asm1) and + ( inst.testFlags(NO_CODE) or + (inst.testFlags(SYNTHETIC) and (inst.getOpcode() != iJMP)))) { return; } @@ -273,7 +275,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) } oper_stream<< lab_contents.str(); } - if ((inst.getOpcode()==iSIGNEX )&& inst.testFlags(B)) + if ((inst.getOpcode()==iSIGNEX )and inst.testFlags(B)) { inst.setOpcode(iCBW); } @@ -342,7 +344,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) { ICODE *lab=pc.GetIcode(inst.src().getImm2()); selectTable(Label); - if ((inst.src().getImm2() < (uint32_t)numIcode) && /* Ensure in range */ + if ((inst.src().getImm2() < (uint32_t)numIcode) and /* Ensure in range */ readVal(operands_s, lab->ll()->label, nullptr)) { break; /* Symbolic label. Done */ @@ -416,14 +418,14 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) case iOUTS: case iREP_OUTS: if (inst.src().segOver) { - bool is_dx_src=(inst.getOpcode() == iOUTS || inst.getOpcode() == iREP_OUTS); + bool is_dx_src=(inst.getOpcode() == iOUTS or inst.getOpcode() == iREP_OUTS); if(is_dx_src) operands_s<<"dx, "< 0 && j < (int)nextInst; j++) + for (j = inst.label, fImpure = 0; j > 0 and j < (int)nextInst; j++) { fImpure |= BITMAP(j, BM_DATA); } @@ -487,7 +489,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) { result_stream <<"; "<= 0x20) && (op <= 0x27)) + if ((op >= 0x20) and (op <= 0x27)) { /* This is the ST(i), ST form. */ out << "ST("< +#include #ifndef PATLEN #define PATLEN 23 #define WILD 0xF4 #endif -#ifndef bool -#define bool unsigned char -#define uint8_t unsigned char -#endif - static int pc; /* Indexes into pat[] */ /* prototypes */ @@ -410,7 +407,7 @@ void fixWildCards(uint8_t pat[]) case 0xCD: /* int nn */ intArg = pat[pc++]; - if ((intArg >= 0x34) && (intArg <= 0x3B)) + if ((intArg >= 0x34) and (intArg <= 0x3B)) { /* Borland/Microsoft FP emulations */ if (ModRM(pat)) return; diff --git a/src/graph.cpp b/src/graph.cpp index 8f0a3a9..813db8e 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -1,396 +1,398 @@ -/***************************************************************************** - * dcc project CFG related functions - * (C) Cristina Cifuentes - ****************************************************************************/ - -#include -#include -#include -#include - -#include "dcc.h" -#include "graph.h" -#include "project.h" - -using namespace std; -using namespace boost; -extern Project g_proj; -//static BB * rmJMP(Function * pProc, int marker, BB * pBB); -//static void mergeFallThrough(Function * pProc, BB * pBB); -//static void dfsNumbering(BB * pBB, std::vector &dfsLast, int *first, int *last); - -void Function::addOutEdgesForConditionalJump(BB * pBB,int next_ip, LLInst *ll) -{ - pBB->addOutEdge(next_ip); - /* This is checking for jumps off into nowhere */ - if ( not ll->testFlags(NO_LABEL) ) - pBB->addOutEdge(ll->src().getImm2()); -} - -/***************************************************************************** - * createCFG - Create the basic control flow graph - ****************************************************************************/ -void Function::createCFG() -{ - /* Splits Icode associated with the procedure into Basic Blocks. - * The links between BBs represent the control flow graph of the - * procedure. - * A Basic Block is defined to end on one of the following instructions: - * 1) Conditional and unconditional jumps - * 2) CALL(F) - * 3) RET(F) - * 4) On the instruction before a join (a flagged TARGET) - * 5) Repeated string instructions - * 6) End of procedure - */ - - BB * psBB; - BB * pBB; - iICODE pIcode = Icode.begin(); - - stats.numBBbef = stats.numBBaft = 0; - rICODE current_range=make_iterator_range(pIcode,++iICODE(pIcode)); - for (; pIcode!=Icode.end(); ++pIcode,current_range.advance_end(1)) - { - iICODE nextIcode = ++iICODE(pIcode); - pBB = nullptr; - - LLInst *ll = pIcode->ll(); - /* Only process icodes that have valid instructions */ - if(ll->testFlags(NO_CODE)) - continue; - /* Stick a NOWHERE_NODE on the end if we terminate - * with anything other than a ret, jump or terminate */ - if (nextIcode == Icode.end() and - (not ll->testFlags(TERMINATES)) and - (not ll->match(iJMP)) and (not ll->match(iJMPF)) and - (not ll->match(iRET)) and (not ll->match(iRETF))) - { - pBB=BB::Create(current_range, NOWHERE_NODE, this); - } - 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); - addOutEdgesForConditionalJump(pBB,nextIcode->loc_ip, ll); - break; - - case iLOOP: case iLOOPE: case iLOOPNE: - pBB = BB::Create(current_range, LOOP_NODE, this); - addOutEdgesForConditionalJump(pBB,nextIcode->loc_ip, ll); - break; - - 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: - { - 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; - } - - 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, FALL_NODE, this); - pBB->addOutEdge(nextIcode->loc_ip); - } - } - break; - } - if(pBB!=nullptr) // created a new Basic block - { - // restart the range - // end iterator will be updated by expression in for statement - current_range=make_iterator_range(nextIcode,nextIcode); - } - if (nextIcode == Icode.end()) - break; - } - for (auto pr : m_ip_to_bb) - { - BB* pBB=pr.second; - for (auto & elem : pBB->edges) - { - int32_t ip = elem.ip; - if (ip >= SYNTHESIZED_MIN) - { - fatalError (INVALID_SYNTHETIC_BB); - return; - } - 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() -{ - PROG &prog(Project::get()->prog); - for(ICODE &icod : Icode) - { - if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF)) - continue; - //assert that case tbl has less entries then symbol table ???? - //WARNING: Case entries are held in symbol table ! - assert(Project::get()->validSymIdx(icod.ll()->caseEntry)); - const SYM &psym(Project::get()->getSymByIdx(icod.ll()->caseEntry)); - for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++) - { - if (BITMAP(c, BM_CODE)) - { - icod.ll()->setFlags(IMPURE); - flg |= IMPURE; - break; - } - } - } - -} - -/***************************************************************************** - * freeCFG - Deallocates a cfg - ****************************************************************************/ -void Function::freeCFG() -{ - for(auto p : m_ip_to_bb) - { - delete p.second; - } - m_ip_to_bb.clear(); -} - - -/***************************************************************************** - * compressCFG - Remove redundancies and add in-edge information - ****************************************************************************/ -void Function::compressCFG() -{ - BB *pNxt; - int ip, first=0, last; - - /* First pass over BB list removes redundant jumps of the form - * (Un)Conditional -> Unconditional jump */ - for (BB *pBB : m_actual_cfg) //m_cfg - { - if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH)) - continue; - for (TYPEADR_TYPE &edgeRef : pBB->edges) - { - ip = pBB->rbegin()->loc_ip; - pNxt = edgeRef.BBptr->rmJMP(ip, edgeRef.BBptr); - - if (not pBB->edges.empty()) /* Might have been clobbered */ - { - edgeRef.BBptr = pNxt; - assert(pBB->back().loc_ip==ip); - pBB->back().ll()->SetImmediateOp((uint32_t)pNxt->begin()->loc_ip); - //Icode[ip].SetImmediateOp((uint32_t)pNxt->begin()); - } - } - } - - /* Next is a depth-first traversal merging any FALL_NODE or - * ONE_BRANCH that fall through to a node with that as their only - * in-edge. */ - m_actual_cfg.front()->mergeFallThrough(Icode); - - /* Remove redundant BBs created by the above compressions - * and allocate in-edge arrays as required. */ - stats.numBBaft = stats.numBBbef; - bool entry_node=true; - for(BB *pBB : m_actual_cfg) - { - if (pBB->inEdges.empty()) - { - if (entry_node) /* Init it misses out on */ - pBB->index = UN_INIT; - else - { - delete pBB; - stats.numBBaft--; - } - } - else - { - pBB->inEdgeCount = pBB->inEdges.size(); - } - entry_node=false; - } - - /* Allocate storage for dfsLast[] array */ - numBBs = stats.numBBaft; - m_dfsLast.resize(numBBs,nullptr); // = (BB **)allocMem(numBBs * sizeof(BB *)) - - /* Now do a dfs numbering traversal and fill in the inEdges[] array */ - last = numBBs - 1; - m_actual_cfg.front()->dfsNumbering(m_dfsLast, &first, &last); -} - - -/**************************************************************************** - * rmJMP - If BB addressed is just a JMP it is replaced with its target - ***************************************************************************/ -BB *BB::rmJMP(int marker, BB * pBB) -{ - marker += (int)DFS_JMP; - - while (pBB->nodeType == ONE_BRANCH && pBB->size() == 1) - { - if (pBB->traversed != marker) - { - pBB->traversed = (eDFS)marker; - pBB->inEdges.pop_back(); - if (not pBB->inEdges.empty()) - { - pBB->edges[0].BBptr->inEdges.push_back((BB *)nullptr); - } - else - { - pBB->front().ll()->setFlags(NO_CODE); - pBB->front().invalidate(); //pProc->Icode.SetLlInvalid(pBB->begin(), true); - } - - pBB = pBB->edges[0].BBptr; - } - else - { - /* We are going around in circles */ - pBB->nodeType = NOWHERE_NODE; - pBB->front().ll()->replaceSrc(LLOperand::CreateImm2(pBB->front().loc_ip)); - //pBB->front().ll()->src.immed.op = pBB->front().loc_ip; - do { - pBB = pBB->edges[0].BBptr; - pBB->inEdges.pop_back(); // was --numInedges - if (! pBB->inEdges.empty()) - { - pBB->front().ll()->setFlags(NO_CODE); - pBB->front().invalidate(); - // pProc->Icode.setFlags(pBB->start, NO_CODE); - // pProc->Icode.SetLlInvalid(pBB->start, true); - } - } while (pBB->nodeType != NOWHERE_NODE); - - pBB->edges.clear(); - } - } - return pBB; -} - - -/***************************************************************************** - * mergeFallThrough - ****************************************************************************/ -void BB::mergeFallThrough( CIcodeRec &Icode) -{ - BB * pChild; - if (!this) - { - printf("mergeFallThrough on empty BB!\n"); - } - while (nodeType == FALL_NODE || nodeType == ONE_BRANCH) - { - pChild = edges[0].BBptr; - /* Jump to next instruction can always be removed */ - if (nodeType == ONE_BRANCH) - { - assert(Parent==pChild->Parent); - if(back().loc_ip>pChild->front().loc_ip) // back edege - break; - auto iter=std::find_if(this->end(),pChild->begin(),[](ICODE &c) - {return not c.ll()->testFlags(NO_CODE);}); - - 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; - - 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); - } -} - - -/***************************************************************************** - * dfsNumbering - Numbers nodes during first and last visits and determine - * in-edges - ****************************************************************************/ -void BB::dfsNumbering(std::vector &dfsLast, int *first, int *last) -{ - BB * pChild; - traversed = DFS_NUM; - dfsFirstNum = (*first)++; - - /* index is being used as an index to inEdges[]. */ - // for (i = 0; i < edges.size(); i++) - for(auto edge : edges) - { - pChild = edge.BBptr; - pChild->inEdges[pChild->index++] = this; - - /* Is this the last visit? */ - if (pChild->index == int(pChild->inEdges.size())) - pChild->index = UN_INIT; - - if (pChild->traversed != DFS_NUM) - pChild->dfsNumbering(dfsLast, first, last); - } - dfsLastNum = *last; - dfsLast[(*last)--] = this; -} +/***************************************************************************** + * dcc project CFG related functions + * (C) Cristina Cifuentes + ****************************************************************************/ + +#include "graph.h" + +#include "msvc_fixes.h" +#include "dcc.h" +#include "project.h" + +#include +#include +#include +#include + +using namespace std; +using namespace boost; +extern Project g_proj; +//static BB * rmJMP(Function * pProc, int marker, BB * pBB); +//static void mergeFallThrough(Function * pProc, BB * pBB); +//static void dfsNumbering(BB * pBB, std::vector &dfsLast, int *first, int *last); + +void Function::addOutEdgesForConditionalJump(BB * pBB,int next_ip, LLInst *ll) +{ + pBB->addOutEdge(next_ip); + /* This is checking for jumps off into nowhere */ + if ( not ll->testFlags(NO_LABEL) ) + pBB->addOutEdge(ll->src().getImm2()); +} + +/***************************************************************************** + * createCFG - Create the basic control flow graph + ****************************************************************************/ +void Function::createCFG() +{ + /* Splits Icode associated with the procedure into Basic Blocks. + * The links between BBs represent the control flow graph of the + * procedure. + * A Basic Block is defined to end on one of the following instructions: + * 1) Conditional and unconditional jumps + * 2) CALL(F) + * 3) RET(F) + * 4) On the instruction before a join (a flagged TARGET) + * 5) Repeated string instructions + * 6) End of procedure + */ + + BB * psBB; + BB * pBB; + iICODE pIcode = Icode.begin(); + + stats.numBBbef = stats.numBBaft = 0; + rICODE current_range=make_iterator_range(pIcode,++iICODE(pIcode)); + for (; pIcode!=Icode.end(); ++pIcode,current_range.advance_end(1)) + { + iICODE nextIcode = ++iICODE(pIcode); + pBB = nullptr; + + LLInst *ll = pIcode->ll(); + /* Only process icodes that have valid instructions */ + if(ll->testFlags(NO_CODE)) + continue; + /* Stick a NOWHERE_NODE on the end if we terminate + * with anything other than a ret, jump or terminate */ + if (nextIcode == Icode.end() and + (not ll->testFlags(TERMINATES)) and + (not ll->match(iJMP)) and (not ll->match(iJMPF)) and + (not ll->match(iRET)) and (not ll->match(iRETF))) + { + pBB=BB::Create(current_range, NOWHERE_NODE, this); + } + 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); + addOutEdgesForConditionalJump(pBB,nextIcode->loc_ip, ll); + break; + + case iLOOP: case iLOOPE: case iLOOPNE: + pBB = BB::Create(current_range, LOOP_NODE, this); + addOutEdgesForConditionalJump(pBB,nextIcode->loc_ip, ll); + break; + + 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: + { + Function * p = ll->src().proc.proc; + pBB = BB::Create(current_range, CALL_NODE, this); + if (p and not ((p->flg) & TERMINATES) ) + pBB->addOutEdge(nextIcode->loc_ip); + break; + } + + 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, FALL_NODE, this); + pBB->addOutEdge(nextIcode->loc_ip); + } + } + break; + } + if(pBB!=nullptr) // created a new Basic block + { + // restart the range + // end iterator will be updated by expression in for statement + current_range=make_iterator_range(nextIcode,nextIcode); + } + if (nextIcode == Icode.end()) + break; + } + for (auto pr : m_ip_to_bb) + { + BB* pBB=pr.second; + for (auto & elem : pBB->edges) + { + int32_t ip = elem.ip; + if (ip >= SYNTHESIZED_MIN) + { + fatalError (INVALID_SYNTHETIC_BB); + return; + } + 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() +{ + PROG &prog(Project::get()->prog); + for(ICODE &icod : Icode) + { + if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF)) + continue; + //assert that case tbl has less entries then symbol table ???? + //WARNING: Case entries are held in symbol table ! + assert(Project::get()->validSymIdx(icod.ll()->caseEntry)); + const SYM &psym(Project::get()->getSymByIdx(icod.ll()->caseEntry)); + for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++) + { + if (BITMAP(c, BM_CODE)) + { + icod.ll()->setFlags(IMPURE); + flg |= IMPURE; + break; + } + } + } + +} + +/***************************************************************************** + * freeCFG - Deallocates a cfg + ****************************************************************************/ +void Function::freeCFG() +{ + for(auto p : m_ip_to_bb) + { + delete p.second; + } + m_ip_to_bb.clear(); +} + + +/***************************************************************************** + * compressCFG - Remove redundancies and add in-edge information + ****************************************************************************/ +void Function::compressCFG() +{ + BB *pNxt; + int ip, first=0, last; + + /* First pass over BB list removes redundant jumps of the form + * (Un)Conditional -> Unconditional jump */ + for (BB *pBB : m_actual_cfg) //m_cfg + { + if(pBB->inEdges.empty() or (pBB->nodeType != ONE_BRANCH and pBB->nodeType != TWO_BRANCH)) + continue; + for (TYPEADR_TYPE &edgeRef : pBB->edges) + { + ip = pBB->rbegin()->loc_ip; + pNxt = edgeRef.BBptr->rmJMP(ip, edgeRef.BBptr); + + if (not pBB->edges.empty()) /* Might have been clobbered */ + { + edgeRef.BBptr = pNxt; + assert(pBB->back().loc_ip==ip); + pBB->back().ll()->SetImmediateOp((uint32_t)pNxt->begin()->loc_ip); + //Icode[ip].SetImmediateOp((uint32_t)pNxt->begin()); + } + } + } + + /* Next is a depth-first traversal merging any FALL_NODE or + * ONE_BRANCH that fall through to a node with that as their only + * in-edge. */ + m_actual_cfg.front()->mergeFallThrough(Icode); + + /* Remove redundant BBs created by the above compressions + * and allocate in-edge arrays as required. */ + stats.numBBaft = stats.numBBbef; + bool entry_node=true; + for(BB *pBB : m_actual_cfg) + { + if (pBB->inEdges.empty()) + { + if (entry_node) /* Init it misses out on */ + pBB->index = UN_INIT; + else + { + delete pBB; + stats.numBBaft--; + } + } + else + { + pBB->inEdgeCount = pBB->inEdges.size(); + } + entry_node=false; + } + + /* Allocate storage for dfsLast[] array */ + numBBs = stats.numBBaft; + m_dfsLast.resize(numBBs,nullptr); // = (BB **)allocMem(numBBs * sizeof(BB *)) + + /* Now do a dfs numbering traversal and fill in the inEdges[] array */ + last = numBBs - 1; + m_actual_cfg.front()->dfsNumbering(m_dfsLast, &first, &last); +} + + +/**************************************************************************** + * rmJMP - If BB addressed is just a JMP it is replaced with its target + ***************************************************************************/ +BB *BB::rmJMP(int marker, BB * pBB) +{ + marker += (int)DFS_JMP; + + while (pBB->nodeType == ONE_BRANCH and pBB->size() == 1) + { + if (pBB->traversed != marker) + { + pBB->traversed = (eDFS)marker; + pBB->inEdges.pop_back(); + if (not pBB->inEdges.empty()) + { + pBB->edges[0].BBptr->inEdges.push_back((BB *)nullptr); + } + else + { + pBB->front().ll()->setFlags(NO_CODE); + pBB->front().invalidate(); //pProc->Icode.SetLlInvalid(pBB->begin(), true); + } + + pBB = pBB->edges[0].BBptr; + } + else + { + /* We are going around in circles */ + pBB->nodeType = NOWHERE_NODE; + pBB->front().ll()->replaceSrc(LLOperand::CreateImm2(pBB->front().loc_ip)); + //pBB->front().ll()->src.immed.op = pBB->front().loc_ip; + do { + pBB = pBB->edges[0].BBptr; + pBB->inEdges.pop_back(); // was --numInedges + if (not pBB->inEdges.empty()) + { + pBB->front().ll()->setFlags(NO_CODE); + pBB->front().invalidate(); + // pProc->Icode.setFlags(pBB->start, NO_CODE); + // pProc->Icode.SetLlInvalid(pBB->start, true); + } + } while (pBB->nodeType != NOWHERE_NODE); + + pBB->edges.clear(); + } + } + return pBB; +} + + +/***************************************************************************** + * mergeFallThrough + ****************************************************************************/ +void BB::mergeFallThrough( CIcodeRec &Icode) +{ + BB * pChild; + if (nullptr==this) + { + printf("mergeFallThrough on empty BB!\n"); + } + while (nodeType == FALL_NODE or nodeType == ONE_BRANCH) + { + pChild = edges[0].BBptr; + /* Jump to next instruction can always be removed */ + if (nodeType == ONE_BRANCH) + { + assert(Parent==pChild->Parent); + if(back().loc_ip>pChild->front().loc_ip) // back edege + break; + auto iter=std::find_if(this->end(),pChild->begin(),[](ICODE &c) + {return not c.ll()->testFlags(NO_CODE);}); + + 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; + + 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); + } +} + + +/***************************************************************************** + * dfsNumbering - Numbers nodes during first and last visits and determine + * in-edges + ****************************************************************************/ +void BB::dfsNumbering(std::vector &dfsLast, int *first, int *last) +{ + BB * pChild; + traversed = DFS_NUM; + dfsFirstNum = (*first)++; + + /* index is being used as an index to inEdges[]. */ + // for (i = 0; i < edges.size(); i++) + for(auto edge : edges) + { + pChild = edge.BBptr; + pChild->inEdges[pChild->index++] = this; + + /* Is this the last visit? */ + if (pChild->index == int(pChild->inEdges.size())) + pChild->index = UN_INIT; + + if (pChild->traversed != DFS_NUM) + pChild->dfsNumbering(dfsLast, first, last); + } + dfsLastNum = *last; + dfsLast[(*last)--] = this; +} diff --git a/src/hlicode.cpp b/src/hlicode.cpp index 4f85b9d..4ff5c68 100644 --- a/src/hlicode.cpp +++ b/src/hlicode.cpp @@ -24,7 +24,7 @@ void HLTYPE::setAsgn(Expr *lhs, Expr *rhs) } void ICODE::checkHlCall() { - //assert((ll()->immed.proc.cb != 0)||ll()->immed.proc.proc!=0); + //assert((ll()->immed.proc.cb != 0) or ll()->immed.proc.proc!=0); } /* Places the new HLI_CALL high-level operand in the high-level icode array */ void ICODE::newCallHl() @@ -83,7 +83,7 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId) for ( ; numDefs > 0; numDefs--) { - if (du1.used(numDefs-1)||(du.lastDefRegi.testReg(regi))) + if (du1.used(numDefs-1) or (du.lastDefRegi.testReg(regi))) break; } } @@ -328,7 +328,7 @@ void Function::highLevelGen() { if ( not ll->testFlags(NO_SRC) ) /* if there is src op */ rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE); - if(ll->m_dst.isSet() || (ll->getOpcode()==iMOD)) + if(ll->m_dst.isSet() or (ll->getOpcode()==iMOD)) lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE); } if(ll->getOpcode()==iPUSH) { diff --git a/src/icode.cpp b/src/icode.cpp index 8134054..c62d8f1 100644 --- a/src/icode.cpp +++ b/src/icode.cpp @@ -1,13 +1,13 @@ // Object oriented icode code for dcc // (C) 1997 Mike Van Emmerik +#include "icode.h" -#include - +#include "msvc_fixes.h" #include "dcc.h" #include "types.h" // Common types like uint8_t, etc #include "ast.h" // Some icode types depend on these -#include "icode.h" +#include ICODE::TypeFilter ICODE::select_high_level; ICODE::TypeAndValidFilter ICODE::select_valid_high_level; @@ -87,7 +87,7 @@ void LLInst::emitGotoLabel (int indLevel) bool LLOperand::isReg() const { - return (regi>=rAX) && (regi<=rTMP); + return (regi>=rAX) and (regi<=rTMP); } void LLOperand::addProcInformation(int param_count, CConv::Type call_conv) { diff --git a/src/idioms.cpp b/src/idioms.cpp index b796539..44fe2ee 100644 --- a/src/idioms.cpp +++ b/src/idioms.cpp @@ -4,14 +4,11 @@ ****************************************************************************/ //#include -//#if( (LLVM_VERSION_MAJOR==3 ) && (LLVM_VERSION_MINOR>3) ) +//#if( (LLVM_VERSION_MAJOR==3 ) and (LLVM_VERSION_MINOR>3) ) //#include //#else //#include //#endif -#include -#include -#include #include "idiom.h" #include "idiom1.h" #include "epilogue_idioms.h" @@ -22,6 +19,11 @@ #include "shift_idioms.h" #include "arith_idioms.h" #include "dcc.h" +#include "msvc_fixes.h" + +#include +#include +#include /***************************************************************************** * JmpInst - Returns true if opcode is a conditional or unconditional jump ****************************************************************************/ @@ -122,11 +124,11 @@ void Function::findIdioms() /* Check for library functions that return a long register. * Propagate this result */ if (pIcode->ll()->src().proc.proc != nullptr) - if ((pIcode->ll()->src().proc.proc->flg & PROC_ISLIB) && + if ((pIcode->ll()->src().proc.proc->flg & PROC_ISLIB) and (pIcode->ll()->src().proc.proc->flg & PROC_IS_FUNC)) { if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN) - || (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN)) + or (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN)) localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), pIcode/*ip*/); } @@ -209,7 +211,7 @@ void Function::findIdioms() } /* Check if number of parameter bytes match their calling convention */ - if ((flg & PROC_HLL) && (!args.empty())) + if ((flg & PROC_HLL) and (!args.empty())) { args.m_minOff += (flg & PROC_FAR ? 4 : 2); delta = args.maxOff - args.m_minOff; @@ -236,7 +238,7 @@ void Function::bindIcodeOff() for(ICODE &c : Icode) // TODO: use filtered here { LLInst *ll=c.ll(); - if (ll->testFlags(I) && ll->isJmpInst()) + if (ll->testFlags(I) and ll->isJmpInst()) { iICODE loc=Icode.labelSrch(ll->src().getImm2()); if (loc!=Icode.end()) diff --git a/src/idioms/arith_idioms.cpp b/src/idioms/arith_idioms.cpp index 99e4446..9204e7e 100644 --- a/src/idioms/arith_idioms.cpp +++ b/src/idioms/arith_idioms.cpp @@ -1,5 +1,8 @@ -#include "dcc.h" #include "arith_idioms.h" + +#include "dcc.h" +#include "msvc_fixes.h" + using namespace std; /***************************************************************************** @@ -105,7 +108,7 @@ bool Idiom18::match(iICODE picode) if(not m_icodes[0]->ll()->matchWithRegDst(iMOV) ) return false; regi = m_icodes[0]->ll()->m_dst.regi; - if( not ( m_icodes[2]->ll()->match(iCMP,regi) && + if( not ( m_icodes[2]->ll()->match(iCMP,regi) and m_icodes[3]->ll()->conditionalJump() ) ) return false; // Simple matching finished, select apropriate matcher based on dst type @@ -118,9 +121,9 @@ bool Idiom18::match(iICODE picode) else if ( m_icodes[1]->ll()->m_dst.isReg() ) /* register */ { m_idiom_type = 1; -// if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR)) +// if ((m_icodes[1]->ll()->dst.regi == rSI) and (m_func->flg & SI_REGVAR)) // m_idiom_type = 1; -// else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR)) +// else if ((m_icodes[1]->ll()->dst.regi == rDI) and (m_func->flg & DI_REGVAR)) // m_idiom_type = 1; } else if (m_icodes[1]->ll()->m_dst.off) /* local variable */ @@ -204,8 +207,8 @@ bool Idiom19::match(iICODE picode) /* not supported yet */ ; else if ( m_icodes[0]->ll()->m_dst.isReg() ) /* register */ { - // if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) || - // ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR))) + // if (((picode->ll()->dst.regi == rSI) and (pproc->flg & SI_REGVAR)) or + // ((picode->ll()->dst.regi == rDI) and (pproc->flg & DI_REGVAR))) return true; } else if (m_icodes[0]->ll()->m_dst.off) /* stack variable */ @@ -271,9 +274,9 @@ bool Idiom20::match(iICODE picode) else if ( ll_dest.isReg() ) /* register */ { type = 1; -// if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR)) +// if ((ll_dest.regi == rSI) and (m_func->flg & SI_REGVAR)) // type = 1; -// else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR)) +// else if ((ll_dest.regi == rDI) and (m_func->flg & DI_REGVAR)) // type = 1; } else if (ll_dest.off) /* local variable */ @@ -286,7 +289,7 @@ bool Idiom20::match(iICODE picode) } regi = m_icodes[1]->ll()->m_dst.regi; const LLOperand &mov_src(m_icodes[1]->ll()->src()); - if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump()) + if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) and m_icodes[3]->ll()->conditionalJump()) { switch(type) { diff --git a/src/idioms/call_idioms.cpp b/src/idioms/call_idioms.cpp index 9267a85..d5099b9 100644 --- a/src/idioms/call_idioms.cpp +++ b/src/idioms/call_idioms.cpp @@ -1,5 +1,8 @@ -#include "dcc.h" #include "call_idioms.h" + +#include "dcc.h" +#include "msvc_fixes.h" + using namespace std; /***************************************************************************** * idiom3 - C calling convention. @@ -22,7 +25,7 @@ bool Idiom3::match(iICODE picode) /* Match ADD SP, immed */ for(int i=0; i<2; ++i) m_icodes[i] = picode++; - if ( m_icodes[1]->ll()->testFlags(I) && m_icodes[1]->ll()->match(iADD,rSP)) + if ( m_icodes[1]->ll()->testFlags(I) and m_icodes[1]->ll()->match(iADD,rSP)) { m_param_count = m_icodes[1]->ll()->src().getImm2(); return true; @@ -78,10 +81,10 @@ bool Idiom17::match(iICODE picode) { int i=0; regi = m_icodes[1]->ll()->m_dst.regi; - if ((regi >= rAX) && (regi <= rBX)) + if ((regi >= rAX) and (regi <= rBX)) i++; - while (picode != m_end && picode->ll()->match(iPOP)) + while (picode != m_end and picode->ll()->match(iPOP)) { if (picode->ll()->m_dst.regi != regi) break; diff --git a/src/idioms/epilogue_idioms.cpp b/src/idioms/epilogue_idioms.cpp index eb00390..5b9f0da 100644 --- a/src/idioms/epilogue_idioms.cpp +++ b/src/idioms/epilogue_idioms.cpp @@ -1,6 +1,8 @@ -#include "dcc.h" #include "epilogue_idioms.h" +#include "dcc.h" +#include "msvc_fixes.h" + /***************************************************************************** * popStkVars - checks for * [POP DI] @@ -14,9 +16,9 @@ void EpilogIdiom::popStkVars(iICODE pIcode) /* Match [POP DI] */ if (pIcode->ll()->match(iPOP)) { - if ((m_func->flg & DI_REGVAR) && pIcode->ll()->match(rDI)) + if ((m_func->flg & DI_REGVAR) and pIcode->ll()->match(rDI)) m_icodes.push_front(pIcode); - else if ((m_func->flg & SI_REGVAR) && pIcode->ll()->match(rSI)) + else if ((m_func->flg & SI_REGVAR) and pIcode->ll()->match(rSI)) m_icodes.push_front(pIcode); } ++pIcode; @@ -25,9 +27,9 @@ void EpilogIdiom::popStkVars(iICODE pIcode) /* Match [POP SI] */ if (pIcode->ll()->match(iPOP)) { - if ((m_func->flg & SI_REGVAR) && pIcode->ll()->match(rSI)) + if ((m_func->flg & SI_REGVAR) and pIcode->ll()->match(rSI)) m_icodes.push_front(pIcode); - else if ((m_func->flg & DI_REGVAR) && pIcode->ll()->match(rDI)) + else if ((m_func->flg & DI_REGVAR) and pIcode->ll()->match(rDI)) m_icodes.push_front(pIcode); } } @@ -46,7 +48,7 @@ bool Idiom2::match(iICODE pIcode) iICODE nicode; if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0 return false; - if ( pIcode->ll()->testFlags(I) || (not pIcode->ll()->match(rSP,rBP)) ) + if ( pIcode->ll()->testFlags(I) or (not pIcode->ll()->match(rSP,rBP)) ) return false; if(distance(pIcode,m_end)<3) return false; @@ -55,21 +57,21 @@ bool Idiom2::match(iICODE pIcode) m_icodes.push_back(pIcode); /* Get next icode, skip over holes in the icode array */ nicode = ++iICODE(pIcode); - while (nicode->ll()->testFlags(NO_CODE) && (nicode != m_end)) + while (nicode->ll()->testFlags(NO_CODE) and (nicode != m_end)) { nicode++; } if(nicode == m_end) return false; - if (nicode->ll()->match(iPOP,rBP) && ! (nicode->ll()->testFlags(I | TARGET | CASE)) ) + if (nicode->ll()->match(iPOP,rBP) and ! (nicode->ll()->testFlags(I | TARGET | CASE)) ) { m_icodes.push_back(nicode++); // Matched POP BP /* Match RET(F) */ - if ( nicode != m_end && - !(nicode->ll()->testFlags(I | TARGET | CASE)) && - (nicode->ll()->match(iRET) || nicode->ll()->match(iRETF)) + if ( nicode != m_end and + !(nicode->ll()->testFlags(I | TARGET | CASE)) and + (nicode->ll()->match(iRET) or nicode->ll()->match(iRETF)) ) { m_icodes.push_back(nicode); // Matched RET @@ -118,7 +120,7 @@ bool Idiom4::match(iICODE pIcode) { iICODE prev1 = --iICODE(pIcode); /* Check for POP BP */ - if (prev1->ll()->match(iPOP,rBP) && not prev1->ll()->testFlags(I) ) + if (prev1->ll()->match(iPOP,rBP) and not prev1->ll()->testFlags(I) ) m_icodes.push_back(prev1); else if(prev1!=m_func->Icode.begin()) { diff --git a/src/idioms/idiom1.cpp b/src/idioms/idiom1.cpp index a19bd53..db8a2a1 100644 --- a/src/idioms/idiom1.cpp +++ b/src/idioms/idiom1.cpp @@ -1,5 +1,8 @@ #include "idiom1.h" + #include "dcc.h" +#include "msvc_fixes.h" + /***************************************************************************** * checkStkVars - Checks for PUSH SI @@ -19,14 +22,14 @@ int Idiom1::checkStkVars (iICODE pIcode) { si_matched = 1; ++pIcode; - if ((pIcode != m_end) && pIcode->ll()->match(iPUSH,rDI)) // Look for PUSH DI + if ((pIcode != m_end) and pIcode->ll()->match(iPUSH,rDI)) // Look for PUSH DI di_matched = 1; } else if (pIcode->ll()->match(iPUSH,rDI)) { di_matched = 1; ++pIcode; - if ((pIcode != m_end) && pIcode->ll()->match(iPUSH,rSI)) // Look for PUSH SI + if ((pIcode != m_end) and pIcode->ll()->match(iPUSH,rSI)) // Look for PUSH SI si_matched = 1; } m_func->flg |= (si_matched ? SI_REGVAR : 0) | (di_matched ? DI_REGVAR : 0); @@ -60,13 +63,13 @@ bool Idiom1::match(iICODE picode) m_icodes.clear(); m_min_off = 0; /* PUSH BP as first instruction of procedure */ - if ( (not picode->ll()->testFlags(I)) && picode->ll()->src().regi == rBP) + if ( (not picode->ll()->testFlags(I)) and picode->ll()->src().regi == rBP) { m_icodes.push_back( picode++ ); // insert iPUSH if(picode==m_end) return false; /* MOV BP, SP as next instruction */ - if ( !picode->ll()->testFlags(I | TARGET | CASE) && picode->ll()->match(iMOV ,rBP,rSP) ) + if ( not picode->ll()->testFlags(I | TARGET | CASE) and picode->ll()->match(iMOV ,rBP,rSP) ) { m_icodes.push_back( picode++ ); // insert iMOV if(picode==m_end) @@ -75,7 +78,7 @@ bool Idiom1::match(iICODE picode) /* Look for SUB SP, immed */ if ( - picode->ll()->testFlags(I | TARGET | CASE) && picode->ll()->match(iSUB,rSP) + picode->ll()->testFlags(I | TARGET | CASE) and picode->ll()->match(iSUB,rSP) ) { m_icodes.push_back( picode++ ); // insert iSUB @@ -98,8 +101,8 @@ bool Idiom1::match(iICODE picode) if(picode == m_end) return false; /* Look for MOV BP, SP */ - if ( picode != m_end && - !picode->ll()->testFlags(I | TARGET | CASE) && + if ( picode != m_end and + not picode->ll()->testFlags(I | TARGET | CASE) and picode->ll()->match(iMOV,rBP,rSP)) { m_icodes.push_back(picode); diff --git a/src/idioms/mov_idioms.cpp b/src/idioms/mov_idioms.cpp index bda01b6..660c3e4 100644 --- a/src/idioms/mov_idioms.cpp +++ b/src/idioms/mov_idioms.cpp @@ -1,5 +1,8 @@ -#include "dcc.h" #include "mov_idioms.h" + +#include "dcc.h" +#include "msvc_fixes.h" + using namespace std; /***************************************************************************** @@ -30,17 +33,17 @@ bool Idiom14::match(iICODE pIcode) LLInst * matched [] {m_icodes[0]->ll(),m_icodes[1]->ll()}; /* Check for regL */ m_regL = matched[0]->m_dst.regi; - if (not matched[0]->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX))) + if (not matched[0]->testFlags(I) and ((m_regL == rAX) or (m_regL ==rBX))) { /* Check for XOR regH, regH */ - if (matched[1]->match(iXOR) && not matched[1]->testFlags(I)) + if (matched[1]->match(iXOR) and not matched[1]->testFlags(I)) { m_regH = matched[1]->m_dst.regi; if (m_regH == matched[1]->src().getReg2()) { - if ((m_regL == rAX) && (m_regH == rDX)) + if ((m_regL == rAX) and (m_regH == rDX)) return true; - if ((m_regL == rBX) && (m_regH == rCX)) + if ((m_regL == rBX) and (m_regH == rCX)) return true; } } @@ -81,10 +84,10 @@ bool Idiom13::match(iICODE pIcode) /* Check for regL */ regi = m_icodes[0]->ll()->m_dst.regi; - if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH)) + if (not m_icodes[0]->ll()->testFlags(I) and (regi >= rAL) and (regi <= rBH)) { /* Check for MOV regH, 0 */ - if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0)) + if (m_icodes[1]->ll()->match(iMOV,I) and (m_icodes[1]->ll()->src().getImm2() == 0)) { if (m_icodes[1]->ll()->m_dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc. { diff --git a/src/idioms/neg_idioms.cpp b/src/idioms/neg_idioms.cpp index b10db1b..fd833d9 100644 --- a/src/idioms/neg_idioms.cpp +++ b/src/idioms/neg_idioms.cpp @@ -1,5 +1,8 @@ -#include "dcc.h" #include "neg_idioms.h" + +#include "dcc.h" +#include "msvc_fixes.h" + using namespace std; @@ -23,7 +26,7 @@ bool Idiom11::match (iICODE picode) for(int i=0; i<3; ++i) m_icodes[i]=picode++; type = m_icodes[0]->ll()->idType(DST); - if(type==CONSTANT || type == OTHER) + if(type==CONSTANT or type == OTHER) return false; /* Check NEG reg/mem * SBB reg/mem, 0*/ @@ -32,7 +35,7 @@ bool Idiom11::match (iICODE picode) switch (type) { case GLOB_VAR: - if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) && + if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) and (m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off)) return true; break; @@ -83,11 +86,11 @@ bool Idiom16::match (iICODE picode) m_icodes[i]=picode++; uint8_t regi = m_icodes[0]->ll()->m_dst.regi; - if ((regi >= rAX) && (regi < INDEX_BX_SI)) + if ((regi >= rAX) and (regi < INDEX_BX_SI)) { - if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC)) - if ((m_icodes[1]->ll()->m_dst.regi == (m_icodes[1]->ll()->src().getReg2())) && - m_icodes[1]->ll()->match((eReg)regi) && + if (m_icodes[1]->ll()->match(iSBB) and m_icodes[2]->ll()->match(iINC)) + if ((m_icodes[1]->ll()->m_dst.regi == (m_icodes[1]->ll()->src().getReg2())) and + m_icodes[1]->ll()->match((eReg)regi) and m_icodes[2]->ll()->match((eReg)regi)) return true; } diff --git a/src/idioms/shift_idioms.cpp b/src/idioms/shift_idioms.cpp index 161a240..82ea32b 100644 --- a/src/idioms/shift_idioms.cpp +++ b/src/idioms/shift_idioms.cpp @@ -1,5 +1,8 @@ -#include "dcc.h" #include "shift_idioms.h" + +#include "dcc.h" +#include "msvc_fixes.h" + using namespace std; @@ -18,8 +21,8 @@ bool Idiom8::match(iICODE pIcode) return false; m_icodes[0]=pIcode++; m_icodes[1]=pIcode++; - if (m_icodes[0]->ll()->testFlags(I) && (m_icodes[0]->ll()->src().getImm2() == 1)) - if ( m_icodes[1]->ll()->match(iRCR,I) && + if (m_icodes[0]->ll()->testFlags(I) and (m_icodes[0]->ll()->src().getImm2() == 1)) + if ( m_icodes[1]->ll()->match(iRCR,I) and (m_icodes[1]->ll()->src().getImm2() == 1)) return true; return false; @@ -107,8 +110,8 @@ bool Idiom12::match(iICODE pIcode) return false; m_icodes[0]=pIcode++; m_icodes[1]=pIcode++; - if (m_icodes[0]->ll()->testFlags(I) && (m_icodes[0]->ll()->src().getImm2() == 1)) - if (m_icodes[1]->ll()->match(iRCL,I) && (m_icodes[1]->ll()->src().getImm2() == 1)) + if (m_icodes[0]->ll()->testFlags(I) and (m_icodes[0]->ll()->src().getImm2() == 1)) + if (m_icodes[1]->ll()->match(iRCL,I) and (m_icodes[1]->ll()->src().getImm2() == 1)) return true; return false; } @@ -147,8 +150,8 @@ bool Idiom9::match(iICODE pIcode) return false; m_icodes[0]=pIcode++; m_icodes[1]=pIcode++; - if (m_icodes[0]->ll()->testFlags(I) && (m_icodes[0]->ll()->src().getImm2() == 1)) - if (m_icodes[1]->ll()->match(iRCR,I) && (m_icodes[1]->ll()->src().getImm2() == 1)) + if (m_icodes[0]->ll()->testFlags(I) and (m_icodes[0]->ll()->src().getImm2() == 1)) + if (m_icodes[1]->ll()->match(iRCR,I) and (m_icodes[1]->ll()->src().getImm2() == 1)) return true; return false; } diff --git a/src/idioms/xor_idioms.cpp b/src/idioms/xor_idioms.cpp index a7aefcb..b425b36 100644 --- a/src/idioms/xor_idioms.cpp +++ b/src/idioms/xor_idioms.cpp @@ -1,5 +1,8 @@ -#include "dcc.h" #include "xor_idioms.h" + +#include "dcc.h" +#include "msvc_fixes.h" + using namespace std; /***************************************************************************** @@ -28,11 +31,11 @@ bool Idiom21::match (iICODE picode) dst = &m_icodes[0]->ll()->m_dst; src = &m_icodes[0]->ll()->src(); - if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI)) + if ((dst->regi == src->getReg2()) and (dst->getReg2() > 0) and (dst->getReg2() < INDEX_BX_SI)) { - if ((dst->getReg2() == rDX) && m_icodes[1]->ll()->match(rAX)) + if ((dst->getReg2() == rDX) and m_icodes[1]->ll()->match(rAX)) return true; - if ((dst->getReg2() == rCX) && m_icodes[1]->ll()->match(rBX)) + if ((dst->getReg2() == rCX) and m_icodes[1]->ll()->match(rBX)) return true; } return false; @@ -67,7 +70,7 @@ bool Idiom7::match(iICODE picode) src = &picode->ll()->src(); if (dst->regi == 0) /* global variable */ { - if ((dst->segValue == src->segValue) && (dst->off == src->off)) + if ((dst->segValue == src->segValue) and (dst->off == src->off)) return true; } else if (dst->regi < INDEX_BX_SI) /* register */ @@ -75,9 +78,9 @@ bool Idiom7::match(iICODE picode) if (dst->regi == src->regi) return true; } - else if ((dst->off) && (dst->seg == rSS) && (dst->regi == INDEX_BP)) /* offset from BP */ + else if ((dst->off) and (dst->seg == rSS) and (dst->regi == INDEX_BP)) /* offset from BP */ { - if ((dst->off == src->off) && (dst->seg == src->seg) && (dst->regi == src->regi)) + if ((dst->off == src->off) and (dst->seg == src->seg) and (dst->regi == src->regi)) return true; } return false; @@ -114,8 +117,8 @@ bool Idiom10::match(iICODE pIcode) m_icodes[0]=pIcode++; m_icodes[1]=pIcode++; /* Check OR reg, reg */ - if (not m_icodes[0]->ll()->testFlags(I) && - m_icodes[0]->ll()->src().isReg() && + if (not m_icodes[0]->ll()->testFlags(I) and + m_icodes[0]->ll()->src().isReg() and (m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2())) if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump() { diff --git a/src/locident.cpp b/src/locident.cpp index 6207d66..4597397 100644 --- a/src/locident.cpp +++ b/src/locident.cpp @@ -4,10 +4,13 @@ * Date: October 1993 * (C) Cristina Cifuentes */ +#include "locident.h" + +#include "dcc.h" +#include "msvc_fixes.h" #include -#include "locident.h" -#include "dcc.h" + bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const { return (a->ll()->src().getReg2()==m_l) and (b->ll()->m_dst.getReg2()==m_h); @@ -23,7 +26,7 @@ ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false) macro[0]=0; memset(&id,0,sizeof(id)); loc=f; - assert(not ((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN))); + assert(not ((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN))); } ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false) { @@ -31,7 +34,7 @@ ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false) memset(&id,0,sizeof(id)); loc=REG_FRAME; m_longId = s; - assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN)); + assert((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN)); } ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(false) { @@ -39,7 +42,7 @@ ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(fals memset(&id,0,sizeof(id)); loc=STK_FRAME; id.longStkId = s; - assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN)); + assert((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN)); } ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false) @@ -48,7 +51,7 @@ ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false) memset(&id,0,sizeof(id)); loc=GLB_FRAME; id.longGlb = s; - assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN)); + assert((t==TYPE_LONG_SIGN) or (t==TYPE_LONG_UNSIGN)); } @@ -75,7 +78,7 @@ int LOCAL_ID::newByteWordReg(hlType t, eReg regi) /* Check for entry in the table */ auto found=std::find_if(id_arr.begin(),id_arr.end(),[t,regi](ID &el)->bool { - return ((el.type == t) && (el.id.regi == regi)); + return ((el.type == t) and (el.id.regi == regi)); }); if(found!=id_arr.end()) return found-id_arr.begin(); @@ -96,9 +99,9 @@ int LOCAL_ID::newByteWordReg(hlType t, eReg regi) void LOCAL_ID::flagByteWordId (int off) { auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool { - //if (((en.type == TYPE_WORD_SIGN) || (en.type == TYPE_BYTE_SIGN)) && - if ((en.typeBitsize()<=16) && - (en.id.bwId.off == off) && (en.id.bwId.regOff == 0)) + //if (((en.type == TYPE_WORD_SIGN) or (en.type == TYPE_BYTE_SIGN)) and + if ((en.typeBitsize()<=16) and + (en.id.bwId.off == off) and (en.id.bwId.regOff == 0)) return true; return false; }); @@ -118,7 +121,7 @@ int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff) /* Check for entry in the table */ auto found=std::find_if(id_arr.begin(),id_arr.end(),[off,regOff](ID &el)->bool { - if ((el.id.bwId.off == off) && (el.id.bwId.regOff == regOff)) + if ((el.id.bwId.off == off) and (el.id.bwId.regOff == regOff)) return true; return false; }); @@ -148,9 +151,9 @@ int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t) /* Check for entry in the table */ for (size_t idx = 0; idx < id_arr.size(); idx++) { - if (/*(locSym->id[idx].type == t) && Not checking type */ - (id_arr[idx].id.bwGlb.seg == seg) && - (id_arr[idx].id.bwGlb.off == off) && + if (/*(locSym->id[idx].type == t) and Not checking type */ + (id_arr[idx].id.bwGlb.seg == seg) and + (id_arr[idx].id.bwGlb.off == off) and (id_arr[idx].id.bwGlb.regi == regi)) return (idx); } @@ -178,10 +181,10 @@ int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_) for (idx = 0; idx < id_arr.size(); idx++) { ID &entry(id_arr[idx]); - if(!entry.isLong() || (entry.loc != REG_FRAME)) + if(!entry.isLong() or (entry.loc != REG_FRAME)) continue; - if (/*(locSym->id[idx].type == t) && Not checking type */ - (entry.longId().h() == regH) && + if (/*(locSym->id[idx].type == t) and Not checking type */ + (entry.longId().h() == regH) and (entry.longId().l() == regL)) { /* Check for occurrence in the list */ @@ -218,9 +221,9 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t) /* Check for entry in the table */ for (idx = 0; idx < id_arr.size(); idx++) { - if (/*(locSym->id[idx].type == t) && Not checking type */ - (id_arr[idx].id.longGlb.seg == seg) && - (id_arr[idx].id.longGlb.offH == offH) && + if (/*(locSym->id[idx].type == t) and Not checking type */ + (id_arr[idx].id.longGlb.seg == seg) and + (id_arr[idx].id.longGlb.offH == offH) and (id_arr[idx].id.longGlb.offL == offL)) return (idx); } @@ -242,10 +245,10 @@ int LOCAL_ID::newLongIdx( int16_t seg, int16_t offH, int16_t offL,uint8_t regi, /* Check for entry in the table */ for (idx = 0; idx < id_arr.size(); idx++) { - if (/*(locSym->id[idx].type == t) && Not checking type */ - (id_arr[idx].id.longGlb.seg == seg) && - (id_arr[idx].id.longGlb.offH == offH) && - (id_arr[idx].id.longGlb.offL == offL) && + if (/*(locSym->id[idx].type == t) and Not checking type */ + (id_arr[idx].id.longGlb.seg == seg) and + (id_arr[idx].id.longGlb.offH == offH) and + (id_arr[idx].id.longGlb.offL == offL) and (id_arr[idx].id.longGlb.regi == regi)) return (idx); } @@ -272,8 +275,8 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL) { if(id_arr[idx].loc!=STK_FRAME) continue; - if ((id_arr[idx].type == t) && - (id_arr[idx].longStkId().offH == offH) && + if ((id_arr[idx].type == t) and + (id_arr[idx].longStkId().offH == offH) and (id_arr[idx].longStkId().offL == offL)) return (idx); } @@ -320,9 +323,9 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L } else if (pmL->off) { /* offset */ - if ((pmL->seg == rSS) && (pmL->regi == INDEX_BP)) /* idx on bp */ + if ((pmL->seg == rSS) and (pmL->regi == INDEX_BP)) /* idx on bp */ idx = newLongStk(TYPE_LONG_SIGN, pmH->off, pmL->off); - else if ((pmL->seg == rDS) && (pmL->regi == INDEX_BX)) /* bx */ + else if ((pmL->seg == rDS) and (pmL->regi == INDEX_BX)) /* bx */ { /* glb var indexed on bx */ printf("Bx indexed global, BX is an unused parameter to newLongIdx\n"); idx = newLongIdx(pmH->segValue, pmH->off, pmL->off,rBX,TYPE_LONG_SIGN); @@ -332,8 +335,8 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L printf ("long not supported, idx <> bp\n"); } - else /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */ - printf ("long not supported, idx && no off\n"); + else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */ + printf ("long not supported, idx and no off\n"); return (idx); } @@ -357,7 +360,7 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc pmLdst = &atOffset.m_dst; pmHsrc = &pIcode->ll()->src(); pmLsrc = &atOffset.src(); -// if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off)) +// if ((longId.offH == pmHsrc->off) and (longId.offL == pmLsrc->off)) // { // asgn.lhs = AstIdent::LongIdx (i); @@ -367,14 +370,14 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc // } // return true; // } -// else if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off)) +// else if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off)) // { // asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset); // asgn.rhs = AstIdent::LongIdx (i); // return true; // } - if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off)) + if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off)) { asgn.lhs = AstIdent::LongIdx (i); @@ -384,7 +387,7 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc } return true; } - else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off)) + else if ((longId.offH == pmHsrc->off) and (longId.offL == pmLsrc->off)) { asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset); asgn.rhs = AstIdent::LongIdx (i); @@ -414,7 +417,7 @@ bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i, pmHsrc = &pIcode->ll()->src(); pmLsrc = &atOffset.src(); - if ((longId.h() == pmHdst->regi) && (longId.l() == pmLdst->regi)) + if ((longId.h() == pmHdst->regi) and (longId.l() == pmLdst->regi)) { asgn.lhs = AstIdent::LongIdx (i); if ( not pIcode->ll()->testFlags(NO_SRC) ) @@ -423,7 +426,7 @@ bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i, } return true; } - else if ((longId.h() == pmHsrc->regi) && (longId.l() == pmLsrc->regi)) + else if ((longId.h() == pmHsrc->regi) and (longId.l() == pmLsrc->regi)) { asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset); asgn.rhs = AstIdent::LongIdx (i); @@ -442,7 +445,7 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl) ID *id; id = &locTbl->id_arr[idx]; - if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) || + if ((id->loc == REG_FRAME) and ((id->type == TYPE_LONG_SIGN) or (id->type == TYPE_LONG_UNSIGN))) { if (id->longId().h() == regi) diff --git a/src/machine_x86.cpp b/src/machine_x86.cpp index 46e6afe..16eb0e7 100644 --- a/src/machine_x86.cpp +++ b/src/machine_x86.cpp @@ -1,6 +1,10 @@ -#include #include "machine_x86.h" + +#include "msvc_fixes.h" #include "icode.h" + +#include + // Index registers **** temp solution static const std::string regNames[] = { "undef", @@ -89,11 +93,11 @@ const std::string &Machine_X86::floatOpName(unsigned r) bool Machine_X86::physicalReg(eReg r) { - return (r>=rAX) && (r=rAX) and (r= INDEX_BX_SI; + return r == 0 or r >= INDEX_BX_SI; } //TODO: Move these to Machine_X86 eReg Machine_X86::subRegH(eReg reg) @@ -106,18 +110,18 @@ eReg Machine_X86::subRegL(eReg reg) } bool Machine_X86::isSubRegisterOf(eReg reg,eReg parent) { - if ((parent < rAX) || (parent > rBX)) + if ((parent < rAX) or (parent > rBX)) return false; // only AX -> BX are coverede by subregisters - return ((reg==subRegH(parent)) || (reg == subRegL(parent))); + return ((reg==subRegH(parent)) or (reg == subRegL(parent))); } bool Machine_X86::hasSubregisters(eReg reg) { - return ((reg >= rAX) && (reg <= rBX)); + return ((reg >= rAX) and (reg <= rBX)); } bool Machine_X86::isPartOfComposite(eReg reg) { - return ((reg >= rAL) && (reg <= rBH)); + return ((reg >= rAL) and (reg <= rBH)); } eReg Machine_X86::compositeParent(eReg reg) diff --git a/src/parser.cpp b/src/parser.cpp index 01aa2ce..a6a5766 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,1344 +1,1344 @@ -/**************************************************************************** - * dcc project procedure list builder - * (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann - ****************************************************************************/ - -#include -#include -#include /* For exit() */ -#include -#include -#include -#include -#include -#include - -#include "dcc.h" -#include "project.h" -#include "CallGraph.h" -using namespace std; - -//static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate); -static void setBits(int16_t type, uint32_t start, uint32_t len); -static void process_MOV(LLInst &ll, STATE * pstate); -static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag); -void interactDis(Function * initProc, int ic); -extern uint32_t SynthLab; - - -/* Returns the size of the string pointed by sym and delimited by delim. - * Size includes delimiter. */ -int strSize (const uint8_t *sym, char delim) -{ - PROG &prog(Project::get()->prog); - int till_end = sym-prog.image(); - const uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim); - return end_ptr-sym+1; -} -ICODE * Function::translate_DIV(LLInst *ll, ICODE &_Icode) -{ - /* MOV rTMP, reg */ - - 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 */ - SYM * psym; - uint32_t offset; - eErrorId err; - bool done = false; - SYMTAB &global_symbol_table(Project::get()->symtab); - if (name.find("chkstk") != string::npos) - { - // Danger! Dcc will likely fall over in this code. - // So we act as though we have done with this proc - // pProc->flg &= ~TERMINATES; // Not sure about this - done = true; - // And mark it as a library function, so structure() won't choke on it - flg |= PROC_ISLIB; - return; - } - if (option.VeryVerbose) - { - printf("Parsing proc %s at %X\n", name.c_str(), pstate->IP); - } - - while (! done ) - { - err = scan(pstate->IP, _Icode); - if(err) - break; - LLInst *ll = _Icode.ll(); - pstate->IP += (uint32_t)ll->numBytes; - setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes); - - process_operands(_Icode,pstate); - - /* Keep track of interesting instruction flags in procedure */ - flg |= (ll->getFlag() & (NOT_HLL | FLOAT_OP)); - - /* Check if this instruction has already been parsed */ - iICODE labLoc = Icode.labelSrch(ll->label); - if (Icode.end()!=labLoc) - { /* Synthetic jump */ - _Icode.type = LOW_LEVEL; - ll->set(iJMP,I | SYNTHETIC | NO_OPS); - ll->replaceSrc(LLOperand::CreateImm2(labLoc->ll()->GetLlLabel())); - ll->label = SynthLab++; - } - - /* Copy Icode to Proc */ - if ((ll->getOpcode() == iDIV) || (ll->getOpcode() == iIDIV)) - pIcode = translate_DIV(ll, _Icode); - else if (_Icode.ll()->getOpcode() == iXCHG) - pIcode = translate_XCHG(ll, _Icode); - else - pIcode = Icode.addIcode(&_Icode); - - switch (ll->getOpcode()) { - /*** Conditional jumps ***/ - case iLOOP: case iLOOPE: case iLOOPNE: - 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: - { - STATE StCopy; - int ip = Icode.size()-1; /* Index of this jump */ - ICODE &prev(*(++Icode.rbegin())); /* Previous icode */ - bool fBranch = false; - - pstate->JCond.regi = 0; - - /* This sets up range check for indexed JMPs hopefully - * Handles JA/JAE for fall through and JB/JBE on branch - */ - if (ip > 0 && prev.ll()->getOpcode() == iCMP && (prev.ll()->testFlags(I))) - { - pstate->JCond.immed = (int16_t)prev.ll()->src().getImm2(); - if (ll->match(iJA) || ll->match(iJBE) ) - pstate->JCond.immed++; - if (ll->getOpcode() == iJAE || ll->getOpcode() == iJA) - pstate->JCond.regi = prev.ll()->m_dst.regi; - fBranch = (bool) (ll->getOpcode() == iJB || ll->getOpcode() == iJBE); - } - StCopy = *pstate; - - /* Straight line code */ - this->FollowCtrl (pcallGraph, &StCopy); // recurrent ? - - if (fBranch) /* Do branching code */ - { - pstate->JCond.regi = prev.ll()->m_dst.regi; - } - /* Next icode. Note: not the same as GetLastIcode() because of the call - to FollowCtrl() */ - pIcode = Icode.GetIcode(ip); - } /* Fall through to do the jump path */ - - /*** Jumps ***/ - case iJMP: - case iJMPF: /* Returns true if we've run into a loop */ - done = process_JMP (*pIcode, pstate, pcallGraph); - break; - - /*** Calls ***/ - case iCALL: - case iCALLF: - done = process_CALL (*pIcode, pcallGraph, pstate); - pstate->kill(rBX); - pstate->kill(rCX); - break; - - /*** Returns ***/ - case iRET: - case iRETF: - this->flg |= (ll->getOpcode() == iRET)? PROC_NEAR:PROC_FAR; - /* Fall through */ - case iIRET: - this->flg &= ~TERMINATES; - done = true; - break; - - case iINT: - if (ll->src().getImm2() == 0x21 && pstate->f[rAH]) - { - int funcNum = pstate->r[rAH]; - int operand; - int size; - - /* Save function number */ - Icode.back().ll()->m_dst.off = (int16_t)funcNum; - //Icode.GetIcode(Icode.GetNumIcodes() - 1)-> - - /* Program termination: int21h, fn 00h, 31h, 4Ch */ - done = (bool)(funcNum == 0x00 || funcNum == 0x31 || - funcNum == 0x4C); - - /* String functions: int21h, fn 09h */ - if (pstate->f[rDX]) /* offset goes into DX */ - if (funcNum == 0x09) - { - operand = ((uint32_t)(uint16_t)pstate->r[rDS]<<4) + - (uint32_t)(uint16_t)pstate->r[rDX]; - size = prog.fCOM ? - strSize (&prog.image()[operand], '$') : - strSize (&prog.image()[operand], '$'); // + 0x100 - global_symbol_table.updateSymType (operand, TypeContainer(TYPE_STR, size)); - } - } - else if ((ll->src().getImm2() == 0x2F) && (pstate->f[rAH])) - { - Icode.back().ll()->m_dst.off = pstate->r[rAH]; - } - else /* Program termination: int20h, int27h */ - done = (ll->src().getImm2() == 0x20 || ll->src().getImm2() == 0x27); - if (done) - pIcode->ll()->setFlags(TERMINATES); - break; - - case iMOV: - process_MOV(*pIcode->ll(), pstate); - break; - - /* case iXCHG: - process_MOV (pIcode, pstate); - - break; **** HERE ***/ - - case iSHL: - if (pstate->JCond.regi == ll->m_dst.regi) - { - if ((ll->testFlags(I)) && ll->src().getImm2() == 1) - pstate->JCond.immed *= 2; - else - pstate->JCond.regi = 0; - } - break; - - case iLEA: - if (ll->src().getReg2()== rUNDEF) /* direct mem offset */ - pstate->setState( ll->m_dst.getReg2(), ll->src().off); - break; - - case iLDS: case iLES: - if ((psym = lookupAddr(&ll->src(), pstate, 4, eDuVal::USE)) - /* && (Icode.ll()->flg & SEG_IMMED) */ ) - { - offset = LH(&prog.image()[psym->label]); - pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES, - LH(&prog.image()[psym->label + 2])); - pstate->setState( ll->m_dst.regi, (int16_t)offset); - psym->type = TYPE_PTR; - } - break; - } - } - - if (err) { - this->flg &= ~TERMINATES; - - if (err == INVALID_386OP || err == INVALID_OPCODE) - { - fatalError(err, prog.image()[_Icode.ll()->label], _Icode.ll()->label); - this->flg |= PROC_BADINST; - } - else if (err == IP_OUT_OF_RANGE) - fatalError (err, _Icode.ll()->label); - else - reportError(err, _Icode.ll()->label); - } -} - -/* Firstly look for a leading range check of the form:- - * CMP {BX | SI | DI}, immed - * JA | JAE | JB | JBE - * This is stored in the current state as if we had just - * followed a JBE branch (i.e. [reg] lies between 0 - immed). -*/ -void Function::extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table) -{ - static uint8_t i2r[4] = {rSI, rDI, rBP, rBX}; - if (pstate->JCond.regi == i2r[pIcode.ll()->src().getReg2()-INDEX_SI]) - table.finish = table.start + pstate->JCond.immed; - else - table.finish = table.start + 2; -} - -/* process_JMP - Handles JMPs, returns true if we should end recursion */ -bool Function::followAllTableEntries(JumpTable &table, uint32_t cs, ICODE& pIcode, CALL_GRAPH* pcallGraph, STATE *pstate) -{ - PROG &prog(Project::get()->prog); - STATE StCopy; - - setBits(BM_DATA, table.start, table.size()*table.entrySize()); - - pIcode.ll()->setFlags(SWITCH); - pIcode.ll()->caseTbl2.resize( table.size() ); - assert(pIcode.ll()->caseTbl2.size()<512); - uint32_t k=0; - for (size_t i = table.start; i < table.finish; i += 2) - { - StCopy = *pstate; - StCopy.IP = cs + LH(&prog.image()[i]); - iICODE last_current_insn = (++Icode.rbegin()).base(); - - FollowCtrl (pcallGraph, &StCopy); - - ++last_current_insn; // incremented here because FollowCtrl might have adde more instructions after the Jmp - last_current_insn->ll()->caseEntry = k++; - last_current_insn->ll()->setFlags(CASE); - pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() ); - } - return true; -} -bool Function::decodeIndirectJMP(ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) -{ - PROG &prog(Project::get()->prog); -// mov cx,NUM_CASES -// mov bx,JUMP_TABLE - -// LAB1: -// mov ax, [bx] -// cmp ax,VAL -// jz LAB2 -// add bx,2 -// loop LAB1 -// jmp DEFAULT_CASE -// LAB2 -// jmp word ptr [bx+2*NUM_CASES] - static const llIcode match_seq[] = {iMOV,iMOV,iMOV,iCMP,iJE,iADD,iLOOP,iJMP,iJMP}; - - if(Icode.size()<8) - return false; - if(&Icode.back()!=&pIcode) // not the last insn in the list skip it - return false; - if(pIcode.ll()->src().regi != INDEX_BX) { - return false; - } - // find address-wise predecessors of the icode - std::deque matched; - QMap addrmap; - for(ICODE & ic : Icode) { - addrmap[ic.ll()->GetLlLabel()] = ⁣ - } - auto iter = addrmap.find(pIcode.ll()->GetLlLabel()); - while(matched.size()<9) { - matched.push_front(*iter); - --iter; - if(iter==addrmap.end()) - return false; - } - // pattern starts at the last jmp - ICODE *load_num_cases = matched[0]; - ICODE *load_jump_table_addr = matched[1]; - ICODE *read_case_entry_insn = matched[2]; - ICODE *cmp_case_val_insn = matched[3]; - ICODE *exit_loop_insn = matched[4]; - ICODE *add_bx_insn = matched[5]; - ICODE *loop_insn = matched[6]; - ICODE *default_jmp = matched[7]; - ICODE *last_jmp = matched[8]; - for(int i=0; i<8; ++i) { - if(matched[i+1]->ll()->GetLlLabel()!=matched[i]->ll()->GetLlLabel()+matched[i]->ll()->numBytes) { - qDebug() << "Matching jump pattern impossible - undecoded instructions in pattern area "; - return false; - } - } - for(int i=0; i<9; ++i) { - if(matched[i]->ll()->getOpcode()!=match_seq[i]) { - return false; - } - } - // verify that bx+offset == 2* case count - uint32_t num_cases = load_num_cases->ll()->src().getImm2(); - if(last_jmp->ll()->src().off != 2*num_cases) - return false; - const LLOperand &op = last_jmp->ll()->src(); - if(op.regi != INDEX_BX) - return false; - if(!load_jump_table_addr->ll()->src().isImmediate()) - return false; - uint32_t cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4; - uint32_t table_addr = cs + load_jump_table_addr->ll()->src().getImm2(); - uint32_t default_label = cs + default_jmp->ll()->src().getImm2(); - setBits(BM_DATA, table_addr, num_cases*2 + num_cases*2); // num_cases of short values + num cases short ptrs - pIcode.ll()->setFlags(SWITCH); - - for(int i=0; ill()->caseEntry = i; - last_current_insn->ll()->setFlags(CASE); - pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() ); - } - return true; -} -bool Function::decodeIndirectJMP2(ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) -{ - PROG &prog(Project::get()->prog); -// mov cx,NUM_CASES -// mov bx,JUMP_TABLE - -// LAB1: -// mov ax, [bx] -// cmp ax, LOW_WORD_OF_VAL -// jnz LAB2 -// mov ax, [bx + 2 * NUM_CASES] -// cmp ax, HIGH_WORD_OF_VAL -// jz LAB3 -// LAB2 -// add bx,2 -// loop LAB1 -// jmp DEFAULT_CASE -// LAB3 -// jmp word ptr [bx+2*NUM_CASES] - static const llIcode match_seq[] = {iMOV,iMOV,iMOV,iCMP,iJNE,iMOV,iCMP,iJE,iADD,iLOOP,iJMP,iJMP}; - - if(Icode.size()<12) - return false; - if(&Icode.back()!=&pIcode) // not the last insn in the list skip it - return false; - if(pIcode.ll()->src().regi != INDEX_BX) { - return false; - } - // find address-wise predecessors of the icode - std::deque matched; - QMap addrmap; - for(ICODE & ic : Icode) { - addrmap[ic.ll()->GetLlLabel()] = ⁣ - } - auto iter = addrmap.find(pIcode.ll()->GetLlLabel()); - while(matched.size()<12) { - matched.push_front(*iter); - --iter; - if(iter==addrmap.end()) - return false; - } - // pattern starts at the last jmp - ICODE *load_num_cases = matched[0]; - ICODE *load_jump_table_addr = matched[1]; - ICODE *default_jmp = matched[10]; - ICODE *last_jmp = matched[11]; - - for(int i=0; i<11; ++i) { - if(matched[i+1]->ll()->GetLlLabel()!=matched[i]->ll()->GetLlLabel()+matched[i]->ll()->numBytes) { - qDebug() << "Matching jump pattern impossible - undecoded instructions in pattern area "; - return false; - } - } - for(int i=0; i<12; ++i) { - if(matched[i]->ll()->getOpcode()!=match_seq[i]) { - return false; - } - } - // verify that bx+offset == 2* case count - uint32_t num_cases = load_num_cases->ll()->src().getImm2(); - if(last_jmp->ll()->src().off != 4*num_cases) - return false; - const LLOperand &op = last_jmp->ll()->src(); - if(op.regi != INDEX_BX) - return false; - if(!load_jump_table_addr->ll()->src().isImmediate()) - return false; - uint32_t cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4; - uint32_t table_addr = cs + load_jump_table_addr->ll()->src().getImm2(); - int default_label = cs + default_jmp->ll()->src().getImm2(); - setBits(BM_DATA, table_addr, num_cases*4 + num_cases*2); // num_cases of long values + num cases short ptrs - pIcode.ll()->setFlags(SWITCH); - - for(int i=0; ill()->caseEntry = i; - last_current_insn->ll()->setFlags(CASE); - pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() ); - } - return true; -} - -bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) -{ - PROG &prog(Project::get()->prog); - static uint8_t i2r[4] = {rSI, rDI, rBP, rBX}; - ICODE _Icode; - uint32_t cs, offTable, endTable; - uint32_t i, k, seg, target; - - if (pIcode.ll()->testFlags(I)) - { - if (pIcode.ll()->getOpcode() == iJMPF) - pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); - pstate->IP = pIcode.ll()->src().getImm2(); - int64_t i = pIcode.ll()->src().getImm2(); - if (i < 0) - { - exit(1); - } - - /* Return true if jump target is already parsed */ - return Icode.alreadyDecoded(i); - } - /* We've got an indirect JMP - look for switch() stmt. idiom of the form - * JMP uint16_t ptr word_offset[rBX | rSI | rDI] */ - seg = (pIcode.ll()->src().seg)? pIcode.ll()->src().seg: rDS; - - /* Ensure we have a uint16_t offset & valid seg */ - if (pIcode.ll()->match(iJMP) and (pIcode.ll()->testFlags(WORD_OFF)) and - pstate->f[seg] and - (pIcode.ll()->src().regi == INDEX_SI || - pIcode.ll()->src().regi == INDEX_DI || /* Idx reg. BX, SI, DI */ - pIcode.ll()->src().regi == INDEX_BX)) - { - - offTable = ((uint32_t)(uint16_t)pstate->r[seg] << 4) + pIcode.ll()->src().off; - - /* Firstly look for a leading range check of the form:- - * CMP {BX | SI | DI}, immed - * JA | JAE | JB | JBE - * This is stored in the current state as if we had just - * followed a JBE branch (i.e. [reg] lies between 0 - immed). - */ - if (pstate->JCond.regi == i2r[pIcode.ll()->src().regi-(INDEX_BX_SI+4)]) - endTable = offTable + pstate->JCond.immed; - else - endTable = (uint32_t)prog.cbImage; - - /* Search for first uint8_t flagged after start of table */ - for (i = offTable; i <= endTable; i++) - if (BITMAP(i, BM_CODE | BM_DATA)) - break; - endTable = i & ~1; /* Max. possible table size */ - - /* Now do some heuristic pruning. Look for ptrs. into the table - * and for addresses that don't appear to point to valid code. - */ - cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4; - for (i = offTable; i < endTable; i += 2) - { - target = cs + LH(&prog.image()[i]); - if (target < endTable && target >= offTable) - endTable = target; - else if (target >= (uint32_t)prog.cbImage) - endTable = i; - } - - for (i = offTable; i < endTable; i += 2) - { - target = cs + LH(&prog.image()[i]); - /* Be wary of 00 00 as code - it's probably data */ - if (! (prog.image()[target] || prog.image()[target+1]) || - scan(target, _Icode)) - endTable = i; - } - - /* Now for each entry in the table take a copy of the current - * state and recursively call FollowCtrl(). */ - if (offTable < endTable) - { - assert(((endTable - offTable) / 2)<512); - STATE StCopy; - //int ip; - //uint32_t *psw; - - setBits(BM_DATA, offTable, endTable - offTable); - - pIcode.ll()->setFlags(SWITCH); - //pIcode.ll()->caseTbl2.numEntries = (endTable - offTable) / 2; - - for (i = offTable, k = 0; i < endTable; i += 2) - { - StCopy = *pstate; - StCopy.IP = cs + LH(&prog.image()[i]); - iICODE last_current_insn = (++Icode.rbegin()).base(); - //ip = Icode.size(); - - FollowCtrl (pcallGraph, &StCopy); - ++last_current_insn; - last_current_insn->ll()->caseEntry = k++; - last_current_insn->ll()->setFlags(CASE); - pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() ); - - } - return true; - } - } - if(decodeIndirectJMP(pIcode,pstate,pcallGraph)) { - return true; - } - if(decodeIndirectJMP2(pIcode,pstate,pcallGraph)) { - return true; - } - - /* Can't do anything with this jump */ - - flg |= PROC_IJMP; - flg &= ~TERMINATES; - interactDis(this, this->Icode.size()-1); - return true; -} - - -/* Process procedure call. - * Note: We assume that CALL's will return unless there is good evidence to - * the contrary - thus we return false unless all paths in the called - * procedure end in DOS exits. This is reasonable since C procedures - * will always include the epilogue after the call anyway and it's to - * be assumed that if an assembler program contains a CALL that the - * programmer expected it to come back - otherwise surely a JMP would - * have been used. */ - -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; - /* For Indirect Calls, find the function address */ - bool indirect = false; - //pIcode.ll()->immed.proc.proc=fakeproc; - if ( not pIcode.ll()->testFlags(I) ) - { - /* Not immediate, i.e. indirect call */ - - if (pIcode.ll()->m_dst.regi && (!option.Calls)) - { - /* We have not set the brave option to attempt to follow - the execution path through register indirect calls. - So we just exit this function, and ignore the call. - We probably should not have parsed this deep, anyway. - */ - return false; - } - - /* Offset into program image is seg:off of read input */ - /* Note: this assumes that the pointer itself is at - es:0 where es:0 is the start of the image. This is - usually wrong! Consider also CALL [BP+0E] in which the - segment for the pointer is in SS! - Mike */ - if(pIcode.ll()->m_dst.isReg()) - { - if( not pstate->isKnown(pIcode.ll()->m_dst.regi) - or - not pstate->isKnown(pIcode.ll()->m_dst.seg) - ) - { - fprintf(stderr,"Indirect call with unknown register values\n"); - return false; - } - off = pstate->r[pIcode.ll()->m_dst.seg]; - off <<=4; - off += pstate->r[pIcode.ll()->m_dst.regi]; - - } - else - { - off = (uint32_t)(uint16_t)pIcode.ll()->m_dst.off + - ((uint32_t)(uint16_t)pIcode.ll()->m_dst.segValue << 4); - } - - /* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at - * previous offset into the program image */ - uint32_t tgtAddr=0; - if (pIcode.ll()->getOpcode() == iCALLF) - tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(LH(&prog.image()[off+2])) << 4); - else - tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(uint16_t)state.r[rCS] << 4); - pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) ); - pIcode.ll()->setFlags(I); - indirect = true; - } - - /* Process CALL. Function address is located in pIcode.ll()->immed.op */ - if (pIcode.ll()->testFlags(I)) - { - /* Search procedure list for one with appropriate entry point */ - ilFunction iter = Project::get()->findByEntry(pIcode.ll()->src().getImm2()); - - /* Create a new procedure node and save copy of the state */ - if ( not Project::get()->valid(iter) ) - { - iter = Project::get()->createFunction(0,""); - Function &x(*iter); - x.procEntry = pIcode.ll()->src().getImm2(); - LibCheck(x); - - if (x.flg & PROC_ISLIB) - { - /* A library function. No need to do any more to it */ - pcallGraph->insertCallGraph (this, iter); - //iter = (++pProcList.rbegin()).base(); - last_insn.ll()->src().proc.proc = &x; - return false; - } - - if (indirect) - x.flg |= PROC_ICALL; - - if (x.name.empty()) /* Don't overwrite existing name */ - { - ostringstream os; - os<<"proc_"<< ++prog.cProcs; - x.name = os.str(); - } - x.depth = x.depth + 1; - x.flg |= TERMINATES; - - /* Save machine state in localState, load up IP and CS.*/ - localState = *pstate; - pstate->IP = pIcode.ll()->src().getImm2(); - if (pIcode.ll()->getOpcode() == iCALLF) - pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); - x.state = *pstate; - - /* Insert new procedure in call graph */ - pcallGraph->insertCallGraph (this, iter); - - /* Process new procedure */ - x.FollowCtrl (pcallGraph, pstate); - - /* Restore segment registers & IP from localState */ - pstate->IP = localState.IP; - pstate->setState( rCS, localState.r[rCS]); - pstate->setState( rDS, localState.r[rDS]); - pstate->setState( rES, localState.r[rES]); - pstate->setState( rSS, localState.r[rSS]); - - } - else - Project::get()->callGraph->insertCallGraph (this, iter); - - last_insn.ll()->src().proc.proc = &(*iter); // ^ target proc - - /* return ((p->flg & TERMINATES) != 0); */ - } - return false; // Cristina, please check!! -} - - -/* process_MOV - Handles state changes due to simple assignments */ -static void process_MOV(LLInst & ll, STATE * pstate) -{ - PROG &prog(Project::get()->prog); - SYM * psym, *psym2; /* Pointer to symbol in global symbol table */ - uint8_t dstReg = ll.m_dst.regi; - uint8_t srcReg = ll.src().regi; - if (dstReg > 0 && dstReg < INDEX_BX_SI) - { - if (ll.testFlags(I)) - pstate->setState( dstReg, (int16_t)ll.src().getImm2()); - else if (srcReg == 0) /* direct memory offset */ - { - psym = lookupAddr(&ll.src(), pstate, 2, eDuVal::USE); - if (psym && ((psym->flg & SEG_IMMED) || psym->duVal.val)) - pstate->setState( dstReg, LH(&prog.image()[psym->label])); - } - else if (srcReg < INDEX_BX_SI && pstate->f[srcReg]) /* reg */ - { - pstate->setState( dstReg, pstate->r[srcReg]); - - /* Follow moves of the possible index register */ - if (pstate->JCond.regi == srcReg) - pstate->JCond.regi = dstReg; - } - } - else if (dstReg == 0) { /* direct memory offset */ - int size=2; - if((ll.src().regi>=rAL)&&(ll.src().regi<=rBH)) - size=1; - psym = lookupAddr (&ll.m_dst, pstate, size, eDEF); - if (psym && ! (psym->duVal.val)) /* no initial value yet */ - { - if (ll.testFlags(I)) /* immediate */ - { - //prog.image()[psym->label] = (uint8_t)ll.src().getImm2(); - pstate->setMemoryByte(psym->label,(uint8_t)ll.src().getImm2()); - if(psym->size>1) - { - pstate->setMemoryByte(psym->label+1,uint8_t(ll.src().getImm2()>>8)); - //prog.image()[psym->label+1] = (uint8_t)(ll.src().getImm2()>>8); - } - psym->duVal.val = 1; - } - else if (srcReg == 0) /* direct mem offset */ - { - psym2 = lookupAddr (&ll.src(), pstate, 2, eDuVal::USE); - if (psym2 && ((psym->flg & SEG_IMMED) || (psym->duVal.val))) - { - //prog.image()[psym->label] = (uint8_t)prog.image()[psym2->label]; - pstate->setMemoryByte(psym->label,(uint8_t)prog.image()[psym2->label]); - if(psym->size>1) - { - pstate->setMemoryByte(psym->label+1,(uint8_t)prog.image()[psym2->label+1]); - //prog.image()[psym->label+1] = prog.image()[psym2->label+1];//(uint8_t)(prog.image()[psym2->label+1] >> 8); - } - psym->duVal.setFlags(eDuVal::DEF); - psym2->duVal.setFlags(eDuVal::USE); - } - } - else if (srcReg < INDEX_BX_SI && pstate->f[srcReg]) /* reg */ - { - //prog.image()[psym->label] = (uint8_t)pstate->r[srcReg]; - pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]); - if(psym->size>1) - { - pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]>>8); - //prog.image()[psym->label+1] = (uint8_t)(pstate->r[srcReg] >> 8); - } - psym->duVal.setFlags(eDuVal::DEF); - } - } - } -} - - - -/* Updates the offset entry to the stack frame table (arguments), - * and returns a pointer to such entry. */ -void STKFRAME::updateFrameOff ( int16_t off, int _size, uint16_t duFlag) -{ - /* Check for symbol in stack frame table */ - auto iter=findByLabel(off); - if(iter!=end()) - { - if (iter->size < _size) - { - iter->size = _size; - } - } - else - { - char nm[16]; - STKSYM new_sym; - - sprintf (nm, "arg%" PRIu64, uint64_t(size())); - new_sym.name = nm; - new_sym.label= off; - new_sym.size = _size; - new_sym.type = TypeContainer::defaultTypeForSize(_size); - if (duFlag == eDuVal::USE) /* must already have init value */ - { - new_sym.duVal.use=1; - //new_sym.duVal.val=1; - } - else - { - new_sym.duVal.setFlags(duFlag); - } - push_back(new_sym); - this->numArgs++; - } - - /* Save maximum argument offset */ - if ((uint32_t)this->maxOff < (off + (uint32_t)_size)) - this->maxOff = off + (int16_t)_size; -} - - -/* lookupAddr - Looks up a data reference in the symbol table and stores it - * if necessary. - * Returns a pointer to the symbol in the - * symbol table, or Null if it's not a direct memory offset. */ -static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag) -{ - PROG &prog(Project::get()->prog); - int i; - SYM * psym=nullptr; - uint32_t operand; - bool created_new=false; - if (pm->regi != rUNDEF) - return nullptr; // register or indexed - - /* Global var */ - if (pm->segValue) /* there is a value in the seg field */ - { - operand = opAdr (pm->segValue, pm->off); - psym = Project::get()->symtab.updateGlobSym (operand, size, duFlag,created_new); - } - else if (pstate->f[pm->seg]) /* new value */ - { - pm->segValue = pstate->r[pm->seg]; - operand = opAdr(pm->segValue, pm->off); - psym = Project::get()->symtab.updateGlobSym (operand, size, duFlag,created_new); - - /* Flag new memory locations that are segment values */ - if (created_new) - { - if (size == 4) - operand += 2; /* High uint16_t */ - for (i = 0; i < prog.cReloc; i++) - if (prog.relocTable[i] == operand) { - psym->flg = SEG_IMMED; - break; - } - } - } - /* Check for out of bounds */ - if (psym and (psym->label < (uint32_t)prog.cbImage)) - return psym; - return nullptr; -} - - -/* setState - Assigns a value to a reg. */ -void STATE::setState(uint16_t reg, int16_t value) -{ - value &= 0xFFFF; - r[reg] = value; - f[reg] = true; - switch (reg) { - case rAX: case rCX: case rDX: case rBX: - r[reg + rAL - rAX] = value & 0xFF; - f[reg + rAL - rAX] = true; - r[reg + rAH - rAX] = (value >> 8) & 0xFF; - f[reg + rAH - rAX] = true; - break; - - case rAL: case rCL: case rDL: case rBL: - if (f[reg - rAL + rAH]) { - r[reg - rAL + rAX] =(r[reg - rAL + rAH] << 8) + (value & 0xFF); - f[reg - rAL + rAX] = true; - } - break; - - case rAH: case rCH: case rDH: case rBH: - if (f[reg - rAH + rAL]) - { - r[reg - rAH + rAX] = r[reg - rAH + rAL] + ((value & 0xFF) << 8); - f[reg - rAH + rAX] = true; - } - break; - } -} - - -/* labelSrchRepl - Searches Icode for instruction with label = target, and - replaces *pIndex with an icode index */ - - -/* setBits - Sets memory bitmap bits for BM_CODE or BM_DATA (additively) */ -static void setBits(int16_t type, uint32_t start, uint32_t len) -{ - PROG &prog(Project::get()->prog); - uint32_t i; - - if (start < (uint32_t)prog.cbImage) - { - if (start + len > (uint32_t)prog.cbImage) - len = (uint32_t)(prog.cbImage - start); - - for (i = start + len - 1; i >= start; i--) - { - prog.map[i >> 2] |= type << ((i & 3) << 1); - if (i == 0) break; // Fixes inf loop! - } - } -} - -/* Checks which registers were used and updates the du.u flag. - * Places local variables on the local symbol table. - * Arguments: d : SRC or DST icode operand - * pIcode: ptr to icode instruction - * pProc : ptr to current procedure structure - * pstate: ptr to current procedure state - * size : size of the operand - * ix : current index into icode array */ -static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int size) -{ - const LLOperand * pm = pIcode.ll()->get(d) ; - SYM * psym; - - if ( Machine_X86::isMemOff(pm->regi) ) - { - if (pm->regi == INDEX_BP) /* indexed on bp */ - { - if (pm->off >= 2) - pProc->args.updateFrameOff ( pm->off, size, eDuVal::USE); - else if (pm->off < 0) - pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0); - } - - else if (pm->regi == INDEX_BP_SI || pm->regi == INDEX_BP_DI) - pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, - (uint8_t)((pm->regi == INDEX_BP_SI) ? rSI : rDI)); - - else if ((pm->regi >= INDEX_SI) && (pm->regi <= INDEX_BX)) - { - if ((pm->seg == rDS) && (pm->regi == INDEX_BX)) /* bx */ - { - if (pm->off > 0) /* global indexed variable */ - pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN); - } - pIcode.du.use.addReg(pm->regi); - } - - else - { - psym = lookupAddr(const_cast(pm), pstate, size, eDuVal::USE); - if( nullptr != psym ) - { - setBits (BM_DATA, psym->label, (uint32_t)size); - pIcode.ll()->setFlags(SYM_USE); - pIcode.ll()->caseEntry = distance(&Project::get()->symtab[0],psym); //WARNING: was setting case count - - } - } - } - - /* Use of register */ - else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I)))) - pIcode.du.use.addReg(pm->regi); -} - - -/* Checks which registers were defined (ie. got a new value) and updates the - * du.d flag. - * Places local variables in the local symbol table. */ -static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int size) -{ - LLOperand *pm = pIcode.ll()->get(d); - if (pm->regi==0) - { - SYM * psym; - psym = lookupAddr(pm, pstate, size, eDEF); - if (nullptr!=psym) - { - setBits(BM_DATA, psym->label, (uint32_t)size); - pIcode.ll()->setFlags(SYM_DEF); - pIcode.ll()->caseEntry = distance(&Project::get()->symtab[0],psym); // WARNING: was setting Case count - } - } - else if (pm->regi >= INDEX_BX_SI) - { - if (pm->regi == INDEX_BP) /* indexed on bp */ - { - if (pm->off >= 2) - pProc->args.updateFrameOff ( pm->off, size, eDEF); - else if (pm->off < 0) - pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0); - } - - else if (pm->regi == INDEX_BP_SI || pm->regi == INDEX_BP_DI) - { - pProc->localId.newByteWordStk(TYPE_WORD_SIGN, pm->off, - (uint8_t)((pm->regi == INDEX_BP_SI) ? rSI : rDI)); - } - - else if ((pm->regi >= INDEX_SI) && (pm->regi <= INDEX_BX)) - { - if ((pm->seg == rDS) && (pm->regi == INDEX_BX)) /* bx */ - { - if (pm->off > 0) /* global var */ - pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN); - } - pIcode.du.use.addReg(pm->regi); - } - } - /* Definition of register */ - else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I)))) - { - assert(not pIcode.ll()->match(iPUSH)); - pIcode.du1.addDef(pm->regi); - pIcode.du.def.addReg(pm->regi); - } -} - - -/* use_def - operand is both use and def'd. - * Note: the destination will always be a register, stack variable, or global - * variable. */ -static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int cb) -{ - const LLOperand * pm = pIcode.ll()->get(d); - - use (d, pIcode, pProc, pstate, cb); - - if (pm->regi < INDEX_BX_SI) /* register */ - { - assert(not pIcode.ll()->match(iPUSH)); - pIcode.du1.addDef(pm->regi); - pIcode.du.def.addReg(pm->regi); - } -} - - -/* Set DU vector, local variables and arguments, and DATA bits in the - * bitmap */ -extern LLOperand convertOperand(const x86_op_t &from); -void Function::process_operands(ICODE & pIcode, STATE * pstate) -{ - LLInst &ll_ins(*pIcode.ll()); - - int sseg = (ll_ins.src().seg)? ll_ins.src().seg: rDS; - int cb = pIcode.ll()->testFlags(B) ? 1: 2; - //x86_op_t *im= pIcode.insn.x86_get_imm(); - bool Imm = (pIcode.ll()->testFlags(I)); - - switch (pIcode.ll()->getOpcode()) { - case iAND: case iOR: case iXOR: - case iSAR: case iSHL: case iSHR: - case iRCL: case iRCR: case iROL: case iROR: - case iADD: case iADC: case iSUB: case iSBB: - if (! Imm) { - use(SRC, pIcode, this, pstate, cb); - } - case iINC: case iDEC: case iNEG: case iNOT: - case iAAA: case iAAD: case iAAM: case iAAS: - case iDAA: case iDAS: - use_def(DST, pIcode, this, pstate, cb); - break; - - case iXCHG: - /* This instruction is replaced by 3 instructions, only need - * to define the src operand and use the destination operand - * in the mean time. */ - use(SRC, pIcode, this, pstate, cb); - def(DST, pIcode, this, pstate, cb); - break; - - case iTEST: case iCMP: - if (! Imm) - use(SRC, pIcode, this, pstate, cb); - use(DST, pIcode, this, pstate, cb); - break; - - case iDIV: case iIDIV: - use(SRC, pIcode, this, pstate, cb); - if (cb == 1) - pIcode.du.use.addReg(rTMP); - break; - - case iMUL: case iIMUL: - use(SRC, pIcode, this, pstate, cb); - if (! Imm) - { - use (DST, pIcode, this, pstate, cb); - if (cb == 1) - { - pIcode.du.def.addReg(rAX); - pIcode.du1.addDef(rAX); - } - else - { - pIcode.du.def.addReg(rAX).addReg(rDX); - pIcode.du1.addDef(rAX).addDef(rDX); - } - } - else - def (DST, pIcode, this, pstate, cb); - break; - - case iSIGNEX: - cb = pIcode.ll()->testFlags(SRC_B) ? 1 : 2; - if (cb == 1) /* uint8_t */ - { - pIcode.du.def.addReg(rAX); - pIcode.du1.addDef(rAX); - pIcode.du.use.addReg(rAL); - } - else /* uint16_t */ - { - pIcode.du.def.addReg(rDX).addReg(rAX); - pIcode.du1.addDef(rAX).addDef(rDX); - pIcode.du.use.addReg(rAX); - } - break; - - case iCALLF: /* Ignore def's on CS for now */ - cb = 4; - case iCALL: case iPUSH: case iPOP: - if (! Imm) { - if (pIcode.ll()->getOpcode() == iPOP) - def(DST, pIcode, this, pstate, cb); - else - use(DST, pIcode, this, pstate, cb); - } - break; - - case iESC: /* operands may be larger */ - use(DST, pIcode, this, pstate, cb); - break; - - case iLDS: case iLES: - { - 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); - break; - - case iLEA: - use(SRC, pIcode, this, pstate, 2); - def(DST, pIcode, this, pstate, 2); - break; - - case iBOUND: - use(SRC, pIcode, this, pstate, 4); - use(DST, pIcode, this, pstate, cb); - break; - - case iJMPF: - cb = 4; - case iJMP: - if (! Imm) - use(SRC, pIcode, this, pstate, cb); - break; - - case iLOOP: case iLOOPE: case iLOOPNE: - pIcode.du.def.addReg(rCX); - pIcode.du1.addDef(rCX); - case iJCXZ: - pIcode.du.use.addReg(rCX); - break; - - case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS: - pIcode.du.addDefinedAndUsed(rCX); - pIcode.du1.addDef(rCX); - case iCMPS: case iMOVS: - pIcode.du.addDefinedAndUsed(rSI); - pIcode.du.addDefinedAndUsed(rDI); - pIcode.du1.addDef(rSI).addDef(rDI); - pIcode.du.use.addReg(rES).addReg(sseg); - break; - - case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS: - pIcode.du.addDefinedAndUsed(rCX); - pIcode.du1.addDef(rCX); - case iSCAS: case iSTOS: case iINS: - pIcode.du.def.addReg(rDI); - pIcode.du1.addDef(rDI); - if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS) - { - pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX); - } - else - { - pIcode.du.use.addReg(rDI).addReg(rES).addReg((cb == 2)? rAX: rAL); - } - break; - - case iREP_LODS: - 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); - pIcode.du1.addDef(rCX); - case iOUTS: - pIcode.du.addDefinedAndUsed(rSI); - pIcode.du1.addDef(rSI); - pIcode.du.use.addReg(rDX).addReg(sseg); - break; - - case iIN: case iOUT: - def(DST, pIcode, this, pstate, cb); - if (! Imm) - { - pIcode.du.use.addReg(rDX); - } - break; - } - - for (int i = rSP; i <= rBH; i++) /* Kill all defined registers */ - if (pIcode.ll()->flagDU.d & (1 << i)) - pstate->f[i] = false; -} - +/**************************************************************************** + * dcc project procedure list builder + * (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann + ****************************************************************************/ +#include "dcc.h" +#include "project.h" +#include "CallGraph.h" +#include "msvc_fixes.h" + +#include +#include +#include /* For exit() */ +#include +#include +#include +#include +#include +#include + +using namespace std; + +//static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate); +static void setBits(int16_t type, uint32_t start, uint32_t len); +static void process_MOV(LLInst &ll, STATE * pstate); +static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag); +void interactDis(Function * initProc, int ic); +extern uint32_t SynthLab; + + +/* Returns the size of the string pointed by sym and delimited by delim. + * Size includes delimiter. */ +int strSize (const uint8_t *sym, char delim) +{ + PROG &prog(Project::get()->prog); + int till_end = sym-prog.image(); + const uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim); + return end_ptr-sym+1; +} +ICODE * Function::translate_DIV(LLInst *ll, ICODE &_Icode) +{ + /* MOV rTMP, reg */ + + 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) and (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) and (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 */ + SYM * psym; + uint32_t offset; + eErrorId err; + bool done = false; + SYMTAB &global_symbol_table(Project::get()->symtab); + if (name.find("chkstk") != string::npos) + { + // Danger! Dcc will likely fall over in this code. + // So we act as though we have done with this proc + // pProc->flg &= ~TERMINATES; // Not sure about this + done = true; + // And mark it as a library function, so structure() won't choke on it + flg |= PROC_ISLIB; + return; + } + if (option.VeryVerbose) + { + printf("Parsing proc %s at %X\n", name.c_str(), pstate->IP); + } + + while (not done ) + { + err = scan(pstate->IP, _Icode); + if(err) + break; + LLInst *ll = _Icode.ll(); + pstate->IP += (uint32_t)ll->numBytes; + setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes); + + process_operands(_Icode,pstate); + + /* Keep track of interesting instruction flags in procedure */ + flg |= (ll->getFlag() & (NOT_HLL | FLOAT_OP)); + + /* Check if this instruction has already been parsed */ + iICODE labLoc = Icode.labelSrch(ll->label); + if (Icode.end()!=labLoc) + { /* Synthetic jump */ + _Icode.type = LOW_LEVEL; + ll->set(iJMP,I | SYNTHETIC | NO_OPS); + ll->replaceSrc(LLOperand::CreateImm2(labLoc->ll()->GetLlLabel())); + ll->label = SynthLab++; + } + + /* Copy Icode to Proc */ + if ((ll->getOpcode() == iDIV) or (ll->getOpcode() == iIDIV)) + pIcode = translate_DIV(ll, _Icode); + else if (_Icode.ll()->getOpcode() == iXCHG) + pIcode = translate_XCHG(ll, _Icode); + else + pIcode = Icode.addIcode(&_Icode); + + switch (ll->getOpcode()) { + /*** Conditional jumps ***/ + case iLOOP: case iLOOPE: case iLOOPNE: + 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: + { + STATE StCopy; + int ip = Icode.size()-1; /* Index of this jump */ + ICODE &prev(*(++Icode.rbegin())); /* Previous icode */ + bool fBranch = false; + + pstate->JCond.regi = 0; + + /* This sets up range check for indexed JMPs hopefully + * Handles JA/JAE for fall through and JB/JBE on branch + */ + if (ip > 0 and prev.ll()->getOpcode() == iCMP and (prev.ll()->testFlags(I))) + { + pstate->JCond.immed = (int16_t)prev.ll()->src().getImm2(); + if (ll->match(iJA) or ll->match(iJBE) ) + pstate->JCond.immed++; + if (ll->getOpcode() == iJAE or ll->getOpcode() == iJA) + pstate->JCond.regi = prev.ll()->m_dst.regi; + fBranch = (bool) (ll->getOpcode() == iJB or ll->getOpcode() == iJBE); + } + StCopy = *pstate; + + /* Straight line code */ + this->FollowCtrl (pcallGraph, &StCopy); // recurrent ? + + if (fBranch) /* Do branching code */ + { + pstate->JCond.regi = prev.ll()->m_dst.regi; + } + /* Next icode. Note: not the same as GetLastIcode() because of the call + to FollowCtrl() */ + pIcode = Icode.GetIcode(ip); + } /* Fall through to do the jump path */ + + /*** Jumps ***/ + case iJMP: + case iJMPF: /* Returns true if we've run into a loop */ + done = process_JMP (*pIcode, pstate, pcallGraph); + break; + + /*** Calls ***/ + case iCALL: + case iCALLF: + done = process_CALL (*pIcode, pcallGraph, pstate); + pstate->kill(rBX); + pstate->kill(rCX); + break; + + /*** Returns ***/ + case iRET: + case iRETF: + this->flg |= (ll->getOpcode() == iRET)? PROC_NEAR:PROC_FAR; + /* Fall through */ + case iIRET: + this->flg &= ~TERMINATES; + done = true; + break; + + case iINT: + if (ll->src().getImm2() == 0x21 and pstate->f[rAH]) + { + int funcNum = pstate->r[rAH]; + int operand; + int size; + + /* Save function number */ + Icode.back().ll()->m_dst.off = (int16_t)funcNum; + //Icode.GetIcode(Icode.GetNumIcodes() - 1)-> + + /* Program termination: int21h, fn 00h, 31h, 4Ch */ + done = (bool)(funcNum == 0x00 or funcNum == 0x31 or + funcNum == 0x4C); + + /* String functions: int21h, fn 09h */ + if (pstate->f[rDX]) /* offset goes into DX */ + if (funcNum == 0x09) + { + operand = ((uint32_t)(uint16_t)pstate->r[rDS]<<4) + + (uint32_t)(uint16_t)pstate->r[rDX]; + size = prog.fCOM ? + strSize (&prog.image()[operand], '$') : + strSize (&prog.image()[operand], '$'); // + 0x100 + global_symbol_table.updateSymType (operand, TypeContainer(TYPE_STR, size)); + } + } + else if ((ll->src().getImm2() == 0x2F) and (pstate->f[rAH])) + { + Icode.back().ll()->m_dst.off = pstate->r[rAH]; + } + else /* Program termination: int20h, int27h */ + done = (ll->src().getImm2() == 0x20 or ll->src().getImm2() == 0x27); + if (done) + pIcode->ll()->setFlags(TERMINATES); + break; + + case iMOV: + process_MOV(*pIcode->ll(), pstate); + break; + + /* case iXCHG: + process_MOV (pIcode, pstate); + + break; **** HERE ***/ + + case iSHL: + if (pstate->JCond.regi == ll->m_dst.regi) + { + if ((ll->testFlags(I)) and ll->src().getImm2() == 1) + pstate->JCond.immed *= 2; + else + pstate->JCond.regi = 0; + } + break; + + case iLEA: + if (ll->src().getReg2()== rUNDEF) /* direct mem offset */ + pstate->setState( ll->m_dst.getReg2(), ll->src().off); + break; + + case iLDS: case iLES: + if ((psym = lookupAddr(&ll->src(), pstate, 4, eDuVal::USE)) + /* and (Icode.ll()->flg & SEG_IMMED) */ ) + { + offset = LH(&prog.image()[psym->label]); + pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES, + LH(&prog.image()[psym->label + 2])); + pstate->setState( ll->m_dst.regi, (int16_t)offset); + psym->type = TYPE_PTR; + } + break; + } + } + + if (err) { + this->flg &= ~TERMINATES; + + if (err == INVALID_386OP or err == INVALID_OPCODE) + { + fatalError(err, prog.image()[_Icode.ll()->label], _Icode.ll()->label); + this->flg |= PROC_BADINST; + } + else if (err == IP_OUT_OF_RANGE) + fatalError (err, _Icode.ll()->label); + else + reportError(err, _Icode.ll()->label); + } +} + +/* Firstly look for a leading range check of the form:- + * CMP {BX | SI | DI}, immed + * JA | JAE | JB | JBE + * This is stored in the current state as if we had just + * followed a JBE branch (i.e. [reg] lies between 0 - immed). +*/ +void Function::extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table) +{ + static uint8_t i2r[4] = {rSI, rDI, rBP, rBX}; + if (pstate->JCond.regi == i2r[pIcode.ll()->src().getReg2()-INDEX_SI]) + table.finish = table.start + pstate->JCond.immed; + else + table.finish = table.start + 2; +} + +/* process_JMP - Handles JMPs, returns true if we should end recursion */ +bool Function::followAllTableEntries(JumpTable &table, uint32_t cs, ICODE& pIcode, CALL_GRAPH* pcallGraph, STATE *pstate) +{ + PROG &prog(Project::get()->prog); + STATE StCopy; + + setBits(BM_DATA, table.start, table.size()*table.entrySize()); + + pIcode.ll()->setFlags(SWITCH); + pIcode.ll()->caseTbl2.resize( table.size() ); + assert(pIcode.ll()->caseTbl2.size()<512); + uint32_t k=0; + for (size_t i = table.start; i < table.finish; i += 2) + { + StCopy = *pstate; + StCopy.IP = cs + LH(&prog.image()[i]); + iICODE last_current_insn = (++Icode.rbegin()).base(); + + FollowCtrl (pcallGraph, &StCopy); + + ++last_current_insn; // incremented here because FollowCtrl might have adde more instructions after the Jmp + last_current_insn->ll()->caseEntry = k++; + last_current_insn->ll()->setFlags(CASE); + pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() ); + } + return true; +} +bool Function::decodeIndirectJMP(ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) +{ + PROG &prog(Project::get()->prog); +// mov cx,NUM_CASES +// mov bx,JUMP_TABLE + +// LAB1: +// mov ax, [bx] +// cmp ax,VAL +// jz LAB2 +// add bx,2 +// loop LAB1 +// jmp DEFAULT_CASE +// LAB2 +// jmp word ptr [bx+2*NUM_CASES] + static const llIcode match_seq[] = {iMOV,iMOV,iMOV,iCMP,iJE,iADD,iLOOP,iJMP,iJMP}; + + if(Icode.size()<8) + return false; + if(&Icode.back()!=&pIcode) // not the last insn in the list skip it + return false; + if(pIcode.ll()->src().regi != INDEX_BX) { + return false; + } + // find address-wise predecessors of the icode + std::deque matched; + QMap addrmap; + for(ICODE & ic : Icode) { + addrmap[ic.ll()->GetLlLabel()] = ⁣ + } + auto iter = addrmap.find(pIcode.ll()->GetLlLabel()); + while(matched.size()<9) { + matched.push_front(*iter); + --iter; + if(iter==addrmap.end()) + return false; + } + // pattern starts at the last jmp + ICODE *load_num_cases = matched[0]; + ICODE *load_jump_table_addr = matched[1]; + ICODE *read_case_entry_insn = matched[2]; + ICODE *cmp_case_val_insn = matched[3]; + ICODE *exit_loop_insn = matched[4]; + ICODE *add_bx_insn = matched[5]; + ICODE *loop_insn = matched[6]; + ICODE *default_jmp = matched[7]; + ICODE *last_jmp = matched[8]; + for(int i=0; i<8; ++i) { + if(matched[i+1]->ll()->GetLlLabel()!=matched[i]->ll()->GetLlLabel()+matched[i]->ll()->numBytes) { + qDebug() << "Matching jump pattern impossible - undecoded instructions in pattern area "; + return false; + } + } + for(int i=0; i<9; ++i) { + if(matched[i]->ll()->getOpcode()!=match_seq[i]) { + return false; + } + } + // verify that bx+offset == 2* case count + uint32_t num_cases = load_num_cases->ll()->src().getImm2(); + if(last_jmp->ll()->src().off != 2*num_cases) + return false; + const LLOperand &op = last_jmp->ll()->src(); + if(op.regi != INDEX_BX) + return false; + if(not load_jump_table_addr->ll()->src().isImmediate()) + return false; + uint32_t cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4; + uint32_t table_addr = cs + load_jump_table_addr->ll()->src().getImm2(); + uint32_t default_label = cs + default_jmp->ll()->src().getImm2(); + setBits(BM_DATA, table_addr, num_cases*2 + num_cases*2); // num_cases of short values + num cases short ptrs + pIcode.ll()->setFlags(SWITCH); + + for(int i=0; ill()->caseEntry = i; + last_current_insn->ll()->setFlags(CASE); + pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() ); + } + return true; +} +bool Function::decodeIndirectJMP2(ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) +{ + PROG &prog(Project::get()->prog); +// mov cx,NUM_CASES +// mov bx,JUMP_TABLE + +// LAB1: +// mov ax, [bx] +// cmp ax, LOW_WORD_OF_VAL +// jnz LAB2 +// mov ax, [bx + 2 * NUM_CASES] +// cmp ax, HIGH_WORD_OF_VAL +// jz LAB3 +// LAB2 +// add bx,2 +// loop LAB1 +// jmp DEFAULT_CASE +// LAB3 +// jmp word ptr [bx+2*NUM_CASES] + static const llIcode match_seq[] = {iMOV,iMOV,iMOV,iCMP,iJNE,iMOV,iCMP,iJE,iADD,iLOOP,iJMP,iJMP}; + + if(Icode.size()<12) + return false; + if(&Icode.back() != &pIcode) // not the last insn in the list skip it + return false; + if(pIcode.ll()->src().regi != INDEX_BX) { + return false; + } + // find address-wise predecessors of the icode + std::deque matched; + QMap addrmap; + for(ICODE & ic : Icode) { + addrmap[ic.ll()->GetLlLabel()] = ⁣ + } + auto iter = addrmap.find(pIcode.ll()->GetLlLabel()); + while(matched.size()<12) { + matched.push_front(*iter); + --iter; + if(iter==addrmap.end()) + return false; + } + // pattern starts at the last jmp + ICODE *load_num_cases = matched[0]; + ICODE *load_jump_table_addr = matched[1]; + ICODE *default_jmp = matched[10]; + ICODE *last_jmp = matched[11]; + + for(int i=0; i<11; ++i) { + if(matched[i+1]->ll()->GetLlLabel()!=matched[i]->ll()->GetLlLabel()+matched[i]->ll()->numBytes) { + qDebug() << "Matching jump pattern impossible - undecoded instructions in pattern area "; + return false; + } + } + for(int i=0; i<12; ++i) { + if(matched[i]->ll()->getOpcode()!=match_seq[i]) { + return false; + } + } + // verify that bx+offset == 2* case count + uint32_t num_cases = load_num_cases->ll()->src().getImm2(); + if(last_jmp->ll()->src().off != 4*num_cases) + return false; + const LLOperand &op = last_jmp->ll()->src(); + if(op.regi != INDEX_BX) + return false; + if(not load_jump_table_addr->ll()->src().isImmediate()) + return false; + uint32_t cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4; + uint32_t table_addr = cs + load_jump_table_addr->ll()->src().getImm2(); + int default_label = cs + default_jmp->ll()->src().getImm2(); + setBits(BM_DATA, table_addr, num_cases*4 + num_cases*2); // num_cases of long values + num cases short ptrs + pIcode.ll()->setFlags(SWITCH); + + for(int i=0; ill()->caseEntry = i; + last_current_insn->ll()->setFlags(CASE); + pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() ); + } + return true; +} + +bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) +{ + PROG &prog(Project::get()->prog); + static uint8_t i2r[4] = {rSI, rDI, rBP, rBX}; + ICODE _Icode; + uint32_t cs, offTable, endTable; + uint32_t i, k, seg, target; + + if (pIcode.ll()->testFlags(I)) + { + if (pIcode.ll()->getOpcode() == iJMPF) + pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); + pstate->IP = pIcode.ll()->src().getImm2(); + int64_t i = pIcode.ll()->src().getImm2(); + if (i < 0) + { + exit(1); + } + + /* Return true if jump target is already parsed */ + return Icode.alreadyDecoded(i); + } + /* We've got an indirect JMP - look for switch() stmt. idiom of the form + * JMP uint16_t ptr word_offset[rBX | rSI | rDI] */ + seg = (pIcode.ll()->src().seg)? pIcode.ll()->src().seg: rDS; + + /* Ensure we have a uint16_t offset & valid seg */ + if (pIcode.ll()->match(iJMP) and (pIcode.ll()->testFlags(WORD_OFF)) and + pstate->f[seg] and + (pIcode.ll()->src().regi == INDEX_SI or + pIcode.ll()->src().regi == INDEX_DI or /* Idx reg. BX, SI, DI */ + pIcode.ll()->src().regi == INDEX_BX)) + { + + offTable = ((uint32_t)(uint16_t)pstate->r[seg] << 4) + pIcode.ll()->src().off; + + /* Firstly look for a leading range check of the form:- + * CMP {BX | SI | DI}, immed + * JA | JAE | JB | JBE + * This is stored in the current state as if we had just + * followed a JBE branch (i.e. [reg] lies between 0 - immed). + */ + if (pstate->JCond.regi == i2r[pIcode.ll()->src().regi-(INDEX_BX_SI+4)]) + endTable = offTable + pstate->JCond.immed; + else + endTable = (uint32_t)prog.cbImage; + + /* Search for first uint8_t flagged after start of table */ + for (i = offTable; i <= endTable; i++) + if (BITMAP(i, BM_CODE | BM_DATA)) + break; + endTable = i & ~1; /* Max. possible table size */ + + /* Now do some heuristic pruning. Look for ptrs. into the table + * and for addresses that don't appear to point to valid code. + */ + cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4; + for (i = offTable; i < endTable; i += 2) + { + target = cs + LH(&prog.image()[i]); + if (target < endTable and target >= offTable) + endTable = target; + else if (target >= (uint32_t)prog.cbImage) + endTable = i; + } + + for (i = offTable; i < endTable; i += 2) + { + target = cs + LH(&prog.image()[i]); + /* Be wary of 00 00 as code - it's probably data */ + if (not (prog.image()[target] or prog.image()[target+1]) or + scan(target, _Icode)) + endTable = i; + } + + /* Now for each entry in the table take a copy of the current + * state and recursively call FollowCtrl(). */ + if (offTable < endTable) + { + assert(((endTable - offTable) / 2)<512); + STATE StCopy; + //int ip; + //uint32_t *psw; + + setBits(BM_DATA, offTable, endTable - offTable); + + pIcode.ll()->setFlags(SWITCH); + //pIcode.ll()->caseTbl2.numEntries = (endTable - offTable) / 2; + + for (i = offTable, k = 0; i < endTable; i += 2) + { + StCopy = *pstate; + StCopy.IP = cs + LH(&prog.image()[i]); + iICODE last_current_insn = (++Icode.rbegin()).base(); + //ip = Icode.size(); + + FollowCtrl (pcallGraph, &StCopy); + ++last_current_insn; + last_current_insn->ll()->caseEntry = k++; + last_current_insn->ll()->setFlags(CASE); + pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() ); + + } + return true; + } + } + if(decodeIndirectJMP(pIcode,pstate,pcallGraph)) { + return true; + } + if(decodeIndirectJMP2(pIcode,pstate,pcallGraph)) { + return true; + } + + /* Can't do anything with this jump */ + + flg |= PROC_IJMP; + flg &= ~TERMINATES; + interactDis(this, this->Icode.size()-1); + return true; +} + + +/* Process procedure call. + * Note: We assume that CALL's will return unless there is good evidence to + * the contrary - thus we return false unless all paths in the called + * procedure end in DOS exits. This is reasonable since C procedures + * will always include the epilogue after the call anyway and it's to + * be assumed that if an assembler program contains a CALL that the + * programmer expected it to come back - otherwise surely a JMP would + * have been used. */ + +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; + /* For Indirect Calls, find the function address */ + bool indirect = false; + //pIcode.ll()->immed.proc.proc=fakeproc; + if ( not pIcode.ll()->testFlags(I) ) + { + /* Not immediate, i.e. indirect call */ + + if (pIcode.ll()->m_dst.regi and (not option.Calls)) + { + /* We have not set the brave option to attempt to follow + the execution path through register indirect calls. + So we just exit this function, and ignore the call. + We probably should not have parsed this deep, anyway. */ + return false; + } + + /* Offset into program image is seg:off of read input */ + /* Note: this assumes that the pointer itself is at + es:0 where es:0 is the start of the image. This is + usually wrong! Consider also CALL [BP+0E] in which the + segment for the pointer is in SS! - Mike */ + if(pIcode.ll()->m_dst.isReg()) + { + if( not pstate->isKnown(pIcode.ll()->m_dst.regi) + or + not pstate->isKnown(pIcode.ll()->m_dst.seg) + ) + { + fprintf(stderr,"Indirect call with unknown register values\n"); + return false; + } + off = pstate->r[pIcode.ll()->m_dst.seg]; + off <<=4; + off += pstate->r[pIcode.ll()->m_dst.regi]; + + } + else + { + off = (uint32_t)(uint16_t)pIcode.ll()->m_dst.off + + ((uint32_t)(uint16_t)pIcode.ll()->m_dst.segValue << 4); + } + + /* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at + * previous offset into the program image */ + uint32_t tgtAddr=0; + if (pIcode.ll()->getOpcode() == iCALLF) + tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(LH(&prog.image()[off+2])) << 4); + else + tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(uint16_t)state.r[rCS] << 4); + pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) ); + pIcode.ll()->setFlags(I); + indirect = true; + } + + /* Process CALL. Function address is located in pIcode.ll()->immed.op */ + if (pIcode.ll()->testFlags(I)) + { + /* Search procedure list for one with appropriate entry point */ + ilFunction iter = Project::get()->findByEntry(pIcode.ll()->src().getImm2()); + + /* Create a new procedure node and save copy of the state */ + if ( not Project::get()->valid(iter) ) + { + iter = Project::get()->createFunction(0,""); + Function &x(*iter); + x.procEntry = pIcode.ll()->src().getImm2(); + LibCheck(x); + + if (x.flg & PROC_ISLIB) + { + /* A library function. No need to do any more to it */ + pcallGraph->insertCallGraph (this, iter); + //iter = (++pProcList.rbegin()).base(); + last_insn.ll()->src().proc.proc = &x; + return false; + } + + if (indirect) + x.flg |= PROC_ICALL; + + if (x.name.empty()) /* Don't overwrite existing name */ + { + ostringstream os; + os<<"proc_"<< ++prog.cProcs; + x.name = os.str(); + } + x.depth = x.depth + 1; + x.flg |= TERMINATES; + + /* Save machine state in localState, load up IP and CS.*/ + localState = *pstate; + pstate->IP = pIcode.ll()->src().getImm2(); + if (pIcode.ll()->getOpcode() == iCALLF) + pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); + x.state = *pstate; + + /* Insert new procedure in call graph */ + pcallGraph->insertCallGraph (this, iter); + + /* Process new procedure */ + x.FollowCtrl (pcallGraph, pstate); + + /* Restore segment registers & IP from localState */ + pstate->IP = localState.IP; + pstate->setState( rCS, localState.r[rCS]); + pstate->setState( rDS, localState.r[rDS]); + pstate->setState( rES, localState.r[rES]); + pstate->setState( rSS, localState.r[rSS]); + + } + else + Project::get()->callGraph->insertCallGraph (this, iter); + + last_insn.ll()->src().proc.proc = &(*iter); // ^ target proc + + /* return ((p->flg & TERMINATES) != 0); */ + } + return false; // Cristina, please check!! +} + + +/* process_MOV - Handles state changes due to simple assignments */ +static void process_MOV(LLInst & ll, STATE * pstate) +{ + PROG &prog(Project::get()->prog); + SYM * psym, *psym2; /* Pointer to symbol in global symbol table */ + uint8_t dstReg = ll.m_dst.regi; + uint8_t srcReg = ll.src().regi; + if (dstReg > 0 and dstReg < INDEX_BX_SI) + { + if (ll.testFlags(I)) + pstate->setState( dstReg, (int16_t)ll.src().getImm2()); + else if (srcReg == 0) /* direct memory offset */ + { + psym = lookupAddr(&ll.src(), pstate, 2, eDuVal::USE); + if (psym and ((psym->flg & SEG_IMMED) or psym->duVal.val)) + pstate->setState( dstReg, LH(&prog.image()[psym->label])); + } + else if (srcReg < INDEX_BX_SI and pstate->f[srcReg]) /* reg */ + { + pstate->setState( dstReg, pstate->r[srcReg]); + + /* Follow moves of the possible index register */ + if (pstate->JCond.regi == srcReg) + pstate->JCond.regi = dstReg; + } + } + else if (dstReg == 0) { /* direct memory offset */ + int size=2; + if((ll.src().regi>=rAL)and(ll.src().regi<=rBH)) + size=1; + psym = lookupAddr (&ll.m_dst, pstate, size, eDEF); + if (psym and not (psym->duVal.val)) /* no initial value yet */ + { + if (ll.testFlags(I)) /* immediate */ + { + //prog.image()[psym->label] = (uint8_t)ll.src().getImm2(); + pstate->setMemoryByte(psym->label,(uint8_t)ll.src().getImm2()); + if(psym->size>1) + { + pstate->setMemoryByte(psym->label+1,uint8_t(ll.src().getImm2()>>8)); + //prog.image()[psym->label+1] = (uint8_t)(ll.src().getImm2()>>8); + } + psym->duVal.val = 1; + } + else if (srcReg == 0) /* direct mem offset */ + { + psym2 = lookupAddr (&ll.src(), pstate, 2, eDuVal::USE); + if (psym2 and ((psym->flg & SEG_IMMED) or (psym->duVal.val))) + { + //prog.image()[psym->label] = (uint8_t)prog.image()[psym2->label]; + pstate->setMemoryByte(psym->label,(uint8_t)prog.image()[psym2->label]); + if(psym->size>1) + { + pstate->setMemoryByte(psym->label+1,(uint8_t)prog.image()[psym2->label+1]); + //prog.image()[psym->label+1] = prog.image()[psym2->label+1];//(uint8_t)(prog.image()[psym2->label+1] >> 8); + } + psym->duVal.setFlags(eDuVal::DEF); + psym2->duVal.setFlags(eDuVal::USE); + } + } + else if (srcReg < INDEX_BX_SI and pstate->f[srcReg]) /* reg */ + { + //prog.image()[psym->label] = (uint8_t)pstate->r[srcReg]; + pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]); + if(psym->size>1) + { + pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]>>8); + //prog.image()[psym->label+1] = (uint8_t)(pstate->r[srcReg] >> 8); + } + psym->duVal.setFlags(eDuVal::DEF); + } + } + } +} + + + +/* Updates the offset entry to the stack frame table (arguments), + * and returns a pointer to such entry. */ +void STKFRAME::updateFrameOff ( int16_t off, int _size, uint16_t duFlag) +{ + /* Check for symbol in stack frame table */ + auto iter=findByLabel(off); + if(iter!=end()) + { + if (iter->size < _size) + { + iter->size = _size; + } + } + else + { + char nm[16]; + STKSYM new_sym; + + sprintf (nm, "arg%" PRIu64, uint64_t(size())); + new_sym.name = nm; + new_sym.label= off; + new_sym.size = _size; + new_sym.type = TypeContainer::defaultTypeForSize(_size); + if (duFlag == eDuVal::USE) /* must already have init value */ + { + new_sym.duVal.use=1; + //new_sym.duVal.val=1; + } + else + { + new_sym.duVal.setFlags(duFlag); + } + push_back(new_sym); + this->numArgs++; + } + + /* Save maximum argument offset */ + if ((uint32_t)this->maxOff < (off + (uint32_t)_size)) + this->maxOff = off + (int16_t)_size; +} + + +/* lookupAddr - Looks up a data reference in the symbol table and stores it + * if necessary. + * Returns a pointer to the symbol in the + * symbol table, or Null if it's not a direct memory offset. */ +static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag) +{ + PROG &prog(Project::get()->prog); + int i; + SYM * psym=nullptr; + uint32_t operand; + bool created_new=false; + if (pm->regi != rUNDEF) + return nullptr; // register or indexed + + /* Global var */ + if (pm->segValue) /* there is a value in the seg field */ + { + operand = opAdr (pm->segValue, pm->off); + psym = Project::get()->symtab.updateGlobSym (operand, size, duFlag,created_new); + } + else if (pstate->f[pm->seg]) /* new value */ + { + pm->segValue = pstate->r[pm->seg]; + operand = opAdr(pm->segValue, pm->off); + psym = Project::get()->symtab.updateGlobSym (operand, size, duFlag,created_new); + + /* Flag new memory locations that are segment values */ + if (created_new) + { + if (size == 4) + operand += 2; /* High uint16_t */ + for (i = 0; i < prog.cReloc; i++) + if (prog.relocTable[i] == operand) { + psym->flg = SEG_IMMED; + break; + } + } + } + /* Check for out of bounds */ + if (psym and (psym->label < (uint32_t)prog.cbImage)) + return psym; + return nullptr; +} + + +/* setState - Assigns a value to a reg. */ +void STATE::setState(uint16_t reg, int16_t value) +{ + value &= 0xFFFF; + r[reg] = value; + f[reg] = true; + switch (reg) { + case rAX: case rCX: case rDX: case rBX: + r[reg + rAL - rAX] = value & 0xFF; + f[reg + rAL - rAX] = true; + r[reg + rAH - rAX] = (value >> 8) & 0xFF; + f[reg + rAH - rAX] = true; + break; + + case rAL: case rCL: case rDL: case rBL: + if (f[reg - rAL + rAH]) { + r[reg - rAL + rAX] =(r[reg - rAL + rAH] << 8) + (value & 0xFF); + f[reg - rAL + rAX] = true; + } + break; + + case rAH: case rCH: case rDH: case rBH: + if (f[reg - rAH + rAL]) + { + r[reg - rAH + rAX] = r[reg - rAH + rAL] + ((value & 0xFF) << 8); + f[reg - rAH + rAX] = true; + } + break; + } +} + + +/* labelSrchRepl - Searches Icode for instruction with label = target, and + replaces *pIndex with an icode index */ + + +/* setBits - Sets memory bitmap bits for BM_CODE or BM_DATA (additively) */ +static void setBits(int16_t type, uint32_t start, uint32_t len) +{ + PROG &prog(Project::get()->prog); + uint32_t i; + + if (start < (uint32_t)prog.cbImage) + { + if (start + len > (uint32_t)prog.cbImage) + len = (uint32_t)(prog.cbImage - start); + + for (i = start + len - 1; i >= start; i--) + { + prog.map[i >> 2] |= type << ((i & 3) << 1); + if (i == 0) break; // Fixes inf loop! + } + } +} + +/* Checks which registers were used and updates the du.u flag. + * Places local variables on the local symbol table. + * Arguments: d : SRC or DST icode operand + * pIcode: ptr to icode instruction + * pProc : ptr to current procedure structure + * pstate: ptr to current procedure state + * size : size of the operand + * ix : current index into icode array */ +static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int size) +{ + const LLOperand * pm = pIcode.ll()->get(d) ; + SYM * psym; + + if ( Machine_X86::isMemOff(pm->regi) ) + { + if (pm->regi == INDEX_BP) /* indexed on bp */ + { + if (pm->off >= 2) + pProc->args.updateFrameOff ( pm->off, size, eDuVal::USE); + else if (pm->off < 0) + pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0); + } + + else if (pm->regi == INDEX_BP_SI or pm->regi == INDEX_BP_DI) + pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, + (uint8_t)((pm->regi == INDEX_BP_SI) ? rSI : rDI)); + + else if ((pm->regi >= INDEX_SI) and (pm->regi <= INDEX_BX)) + { + if ((pm->seg == rDS) and (pm->regi == INDEX_BX)) /* bx */ + { + if (pm->off > 0) /* global indexed variable */ + pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN); + } + pIcode.du.use.addReg(pm->regi); + } + + else + { + psym = lookupAddr(const_cast(pm), pstate, size, eDuVal::USE); + if( nullptr != psym ) + { + setBits (BM_DATA, psym->label, (uint32_t)size); + pIcode.ll()->setFlags(SYM_USE); + pIcode.ll()->caseEntry = distance(&Project::get()->symtab[0],psym); //WARNING: was setting case count + + } + } + } + + /* Use of register */ + else if ((d == DST) or ((d == SRC) and (not pIcode.ll()->testFlags(I)))) + pIcode.du.use.addReg(pm->regi); +} + + +/* Checks which registers were defined (ie. got a new value) and updates the + * du.d flag. + * Places local variables in the local symbol table. */ +static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int size) +{ + LLOperand *pm = pIcode.ll()->get(d); + if (pm->regi==0) + { + SYM * psym; + psym = lookupAddr(pm, pstate, size, eDEF); + if (nullptr!=psym) + { + setBits(BM_DATA, psym->label, (uint32_t)size); + pIcode.ll()->setFlags(SYM_DEF); + pIcode.ll()->caseEntry = distance(&Project::get()->symtab[0],psym); // WARNING: was setting Case count + } + } + else if (pm->regi >= INDEX_BX_SI) + { + if (pm->regi == INDEX_BP) /* indexed on bp */ + { + if (pm->off >= 2) + pProc->args.updateFrameOff ( pm->off, size, eDEF); + else if (pm->off < 0) + pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0); + } + + else if (pm->regi == INDEX_BP_SI or pm->regi == INDEX_BP_DI) + { + pProc->localId.newByteWordStk(TYPE_WORD_SIGN, pm->off, + (uint8_t)((pm->regi == INDEX_BP_SI) ? rSI : rDI)); + } + + else if ((pm->regi >= INDEX_SI) and (pm->regi <= INDEX_BX)) + { + if ((pm->seg == rDS) and (pm->regi == INDEX_BX)) /* bx */ + { + if (pm->off > 0) /* global var */ + pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN); + } + pIcode.du.use.addReg(pm->regi); + } + } + /* Definition of register */ + else if ((d == DST) or ((d == SRC) and (not pIcode.ll()->testFlags(I)))) + { + assert(not pIcode.ll()->match(iPUSH)); + pIcode.du1.addDef(pm->regi); + pIcode.du.def.addReg(pm->regi); + } +} + + +/* use_def - operand is both use and def'd. + * Note: the destination will always be a register, stack variable, or global + * variable. */ +static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int cb) +{ + const LLOperand * pm = pIcode.ll()->get(d); + + use (d, pIcode, pProc, pstate, cb); + + if (pm->regi < INDEX_BX_SI) /* register */ + { + assert(not pIcode.ll()->match(iPUSH)); + pIcode.du1.addDef(pm->regi); + pIcode.du.def.addReg(pm->regi); + } +} + + +/* Set DU vector, local variables and arguments, and DATA bits in the + * bitmap */ +extern LLOperand convertOperand(const x86_op_t &from); +void Function::process_operands(ICODE & pIcode, STATE * pstate) +{ + LLInst &ll_ins(*pIcode.ll()); + + int sseg = (ll_ins.src().seg)? ll_ins.src().seg: rDS; + int cb = pIcode.ll()->testFlags(B) ? 1: 2; + //x86_op_t *im= pIcode.insn.x86_get_imm(); + bool Imm = (pIcode.ll()->testFlags(I)); + + switch (pIcode.ll()->getOpcode()) { + case iAND: case iOR: case iXOR: + case iSAR: case iSHL: case iSHR: + case iRCL: case iRCR: case iROL: case iROR: + case iADD: case iADC: case iSUB: case iSBB: + if (not Imm) { + use(SRC, pIcode, this, pstate, cb); + } + case iINC: case iDEC: case iNEG: case iNOT: + case iAAA: case iAAD: case iAAM: case iAAS: + case iDAA: case iDAS: + use_def(DST, pIcode, this, pstate, cb); + break; + + case iXCHG: + /* This instruction is replaced by 3 instructions, only need + * to define the src operand and use the destination operand + * in the mean time. */ + use(SRC, pIcode, this, pstate, cb); + def(DST, pIcode, this, pstate, cb); + break; + + case iTEST: case iCMP: + if (not Imm) + use(SRC, pIcode, this, pstate, cb); + use(DST, pIcode, this, pstate, cb); + break; + + case iDIV: case iIDIV: + use(SRC, pIcode, this, pstate, cb); + if (cb == 1) + pIcode.du.use.addReg(rTMP); + break; + + case iMUL: case iIMUL: + use(SRC, pIcode, this, pstate, cb); + if (! Imm) + { + use (DST, pIcode, this, pstate, cb); + if (cb == 1) + { + pIcode.du.def.addReg(rAX); + pIcode.du1.addDef(rAX); + } + else + { + pIcode.du.def.addReg(rAX).addReg(rDX); + pIcode.du1.addDef(rAX).addDef(rDX); + } + } + else + def (DST, pIcode, this, pstate, cb); + break; + + case iSIGNEX: + cb = pIcode.ll()->testFlags(SRC_B) ? 1 : 2; + if (cb == 1) /* uint8_t */ + { + pIcode.du.def.addReg(rAX); + pIcode.du1.addDef(rAX); + pIcode.du.use.addReg(rAL); + } + else /* uint16_t */ + { + pIcode.du.def.addReg(rDX).addReg(rAX); + pIcode.du1.addDef(rAX).addDef(rDX); + pIcode.du.use.addReg(rAX); + } + break; + + case iCALLF: /* Ignore def's on CS for now */ + cb = 4; + case iCALL: case iPUSH: case iPOP: + if (! Imm) { + if (pIcode.ll()->getOpcode() == iPOP) + def(DST, pIcode, this, pstate, cb); + else + use(DST, pIcode, this, pstate, cb); + } + break; + + case iESC: /* operands may be larger */ + use(DST, pIcode, this, pstate, cb); + break; + + case iLDS: case iLES: + { + 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); + break; + + case iLEA: + use(SRC, pIcode, this, pstate, 2); + def(DST, pIcode, this, pstate, 2); + break; + + case iBOUND: + use(SRC, pIcode, this, pstate, 4); + use(DST, pIcode, this, pstate, cb); + break; + + case iJMPF: + cb = 4; + case iJMP: + if (! Imm) + use(SRC, pIcode, this, pstate, cb); + break; + + case iLOOP: case iLOOPE: case iLOOPNE: + pIcode.du.def.addReg(rCX); + pIcode.du1.addDef(rCX); + case iJCXZ: + pIcode.du.use.addReg(rCX); + break; + + case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS: + pIcode.du.addDefinedAndUsed(rCX); + pIcode.du1.addDef(rCX); + case iCMPS: case iMOVS: + pIcode.du.addDefinedAndUsed(rSI); + pIcode.du.addDefinedAndUsed(rDI); + pIcode.du1.addDef(rSI).addDef(rDI); + pIcode.du.use.addReg(rES).addReg(sseg); + break; + + case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS: + pIcode.du.addDefinedAndUsed(rCX); + pIcode.du1.addDef(rCX); + case iSCAS: case iSTOS: case iINS: + pIcode.du.def.addReg(rDI); + pIcode.du1.addDef(rDI); + if (pIcode.ll()->getOpcode() == iREP_INS or pIcode.ll()->getOpcode()== iINS) + { + pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX); + } + else + { + pIcode.du.use.addReg(rDI).addReg(rES).addReg((cb == 2)? rAX: rAL); + } + break; + + case iREP_LODS: + 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); + pIcode.du1.addDef(rCX); + case iOUTS: + pIcode.du.addDefinedAndUsed(rSI); + pIcode.du1.addDef(rSI); + pIcode.du.use.addReg(rDX).addReg(sseg); + break; + + case iIN: case iOUT: + def(DST, pIcode, this, pstate, cb); + if (! Imm) + { + pIcode.du.use.addReg(rDX); + } + break; + } + + for (int i = rSP; i <= rBH; i++) /* Kill all defined registers */ + if (pIcode.ll()->flagDU.d & (1 << i)) + pstate->f[i] = false; +} + diff --git a/src/procs.cpp b/src/procs.cpp index 0f618bf..ae9b1e8 100644 --- a/src/procs.cpp +++ b/src/procs.cpp @@ -5,12 +5,14 @@ * (C) Cristina Cifuentes */ -#include -#include #include "dcc.h" +#include "msvc_fixes.h" #include "project.h" #include "CallGraph.h" +#include +#include + extern Project g_proj; /* Static indentation buffer */ static constexpr int indSize=81; /* size of indentation buffer; max 20 */ @@ -111,7 +113,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const if(type==REGISTER) assert(lhs_reg); if(type==LONG_VAR) - assert(!lhs_reg); + assert(nullptr==lhs_reg); if (lhs_reg) { regL = id_arr[lhs_reg->regiIdx].id.regi; @@ -227,7 +229,7 @@ bool CallType::newStkArg(Expr *exp, llIcode opcode, Function * pproc) if (expr) { regi = pproc->localId.id_arr[expr->regiIdx].id.regi; - if ((regi >= rES) && (regi <= rDS)) + if ((regi >= rES) and (regi <= rDS)) { return (opcode == iCALLF) ? false : true; } @@ -365,8 +367,8 @@ void STKFRAME::adjustForArgType(size_t numArg_, hlType actType_) case TYPE_LONG_UNSIGN: case TYPE_LONG_SIGN: - if ((forType == TYPE_WORD_UNSIGN) || - (forType == TYPE_WORD_SIGN) || + if ((forType == TYPE_WORD_UNSIGN) or + (forType == TYPE_WORD_SIGN) or (forType == TYPE_UNKNOWN)) { /* Merge low and high */ diff --git a/src/proplong.cpp b/src/proplong.cpp index 67ca34b..026e37b 100644 --- a/src/proplong.cpp +++ b/src/proplong.cpp @@ -4,18 +4,20 @@ * registers) along the graph. Structure the graph in this way. * (C) Cristina Cifuentes **************************************************************************/ +#include "dcc.h" +#include "msvc_fixes.h" + #include #include #include #include -#include "dcc.h" /* Returns whether the given icode opcode is within the range of valid * high-level conditional jump icodes (iJB..iJG) */ static bool isJCond (llIcode opcode) { - if ((opcode >= iJB) && (opcode <= iJG)) + if ((opcode >= iJB) and (opcode <= iJG)) return true; return false; } @@ -32,10 +34,10 @@ static bool isLong23 (BB * pbb, iICODE &off, int *arc) e = pbb->edges[ELSE].BBptr; /* Check along the THEN path */ - if ((t->size() == 1) && (t->nodeType == TWO_BRANCH) && (t->inEdges.size() == 1)) + if ((t->size() == 1) and (t->nodeType == TWO_BRANCH) and (t->inEdges.size() == 1)) { obb2 = t->edges[THEN].BBptr; - if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ll()->getOpcode() == iCMP)) + if ((obb2->size() == 2) and (obb2->nodeType == TWO_BRANCH) and (obb2->front().ll()->getOpcode() == iCMP)) { off = obb2->begin();//std::distance(iter,obb2->begin2()); *arc = THEN; @@ -44,10 +46,10 @@ static bool isLong23 (BB * pbb, iICODE &off, int *arc) } /* Check along the ELSE path */ - else if ((e->size() == 1) && (e->nodeType == TWO_BRANCH) && (e->inEdges.size() == 1)) + else if ((e->size() == 1) and (e->nodeType == TWO_BRANCH) and (e->inEdges.size() == 1)) { obb2 = e->edges[THEN].BBptr; - if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ll()->getOpcode() == iCMP)) + if ((obb2->size() == 2) and (obb2->nodeType == TWO_BRANCH) and (obb2->front().ll()->getOpcode() == iCMP)) { off = obb2->begin();//std::distance(iter,obb2->begin2());//obb2->front().loc_ip - i; *arc = ELSE; @@ -66,8 +68,8 @@ static bool isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off) return false; // preincrement because pIcode is not checked here iICODE icodes[] = { ++pIcode,++pIcode,++pIcode }; - if ( icodes[1]->ll()->match(iCMP) && - (isJCond ((llIcode)icodes[0]->ll()->getOpcode())) && + if ( icodes[1]->ll()->match(iCMP) and + (isJCond ((llIcode)icodes[0]->ll()->getOpcode())) and (isJCond ((llIcode)icodes[2]->ll()->getOpcode()))) { off = initial_icode; @@ -101,7 +103,7 @@ static int longJCond23 (Assignment &asgn, iICODE pIcode, int arc, iICODE atOffse /* Modify in edges of target basic block */ auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(), [obb1,obb2](BB *b) -> bool { - return (b==obb1) || (b==obb2); }); + return (b==obb1) or (b==obb2); }); tbb->inEdges.erase(newlast,tbb->inEdges.end()); tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */ @@ -129,7 +131,7 @@ static int longJCond23 (Assignment &asgn, iICODE pIcode, int arc, iICODE atOffse /* Modify in edges of the ELSE basic block */ tbb = obb2->edges[ELSE].BBptr; auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(), - [obb1,obb2](BB *b) -> bool { return (b==obb1) || (b==obb2); }); + [obb1,obb2](BB *b) -> bool { return (b==obb1) or (b==obb2); }); tbb->inEdges.erase(newlast,tbb->inEdges.end()); tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */ @@ -246,7 +248,7 @@ void Function::propLongStk (int i, const ID &pLocId) next1 = ++iICODE(pIcode); if(next1==pEnd) break; - if ((pIcode->type == HIGH_LEVEL) || ( not pIcode->valid() )) + if ((pIcode->type == HIGH_LEVEL) or ( not pIcode->valid() )) continue; if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode()) { @@ -288,7 +290,7 @@ void Function::propLongStk (int i, const ID &pLocId) } //TODO: Simplify this! /* Check long conditional (i.e. 2 CMPs and 3 branches */ - else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc))) + else if ((pIcode->ll()->getOpcode() == iCMP) and (isLong23 (pIcode->getParent(), l23, &arc))) { if ( checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *l23->ll()) ) { @@ -298,7 +300,7 @@ void Function::propLongStk (int i, const ID &pLocId) /* Check for long conditional equality or inequality. This requires * 2 CMPs and 2 branches */ - else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23)) + else if ((pIcode->ll()->getOpcode() == iCMP) and isLong22 (pIcode, pEnd, l23)) { if ( checkLongEq (pLocId.longStkId(), pIcode, i, this,asgn, *l23->ll()) ) { @@ -321,7 +323,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be ICODE &icode(*pIcode); - if ((icode.type == HIGH_LEVEL) || ( not icode.valid() )) + if ((icode.type == HIGH_LEVEL) or ( not icode.valid() )) continue; if (icode.ll()->getOpcode() != next1->ll()->getOpcode()) continue; @@ -331,7 +333,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be case iMOV: pmH = &icode.ll()->m_dst; pmL = &next1->ll()->m_dst; - if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi)) + if ((pLocId.longId().h() == pmH->regi) and (pLocId.longId().l() == pmL->regi)) { localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert icode.setRegDU( pmL->regi, eDEF); @@ -346,7 +348,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be case iPOP: pmH = &next1->ll()->m_dst; pmL = &icode.ll()->m_dst; - if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi)) + if ((pLocId.longId().h() == pmH->regi) and (pLocId.longId().l() == pmL->regi)) { asgn.lhs = AstIdent::LongIdx (loc_ident_idx); icode.setRegDU( pmH->regi, eDEF); @@ -362,7 +364,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be case iAND: case iOR: case iXOR: pmL = &icode.ll()->m_dst; pmH = &next1->ll()->m_dst; - if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi)) + if ((pLocId.longId().h() == pmH->regi) and (pLocId.longId().l() == pmL->regi)) { asgn.lhs = AstIdent::LongIdx (loc_ident_idx); asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll()); @@ -399,7 +401,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be LLOperand * pmH,* pmL; /* Pointers to dst LOW_LEVEL icodes */ int arc; - if ((pIcode->type == HIGH_LEVEL) || ( not pIcode->valid() )) + if ((pIcode->type == HIGH_LEVEL) or ( not pIcode->valid() )) continue; if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode()) @@ -412,7 +414,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be const LLOperand &src_op2(next1->ll()->src()); eReg srcReg1=src_op1.getReg2(); eReg nextReg2=src_op2.getReg2(); - if ((ref_long.h() == srcReg1) && (ref_long.l() == nextReg2)) + if ((ref_long.h() == srcReg1) and (ref_long.l() == nextReg2)) { pIcode->setRegDU( nextReg2, eUSE); @@ -431,7 +433,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be const LONGID_TYPE &ref_long(pLocId.longId()); const LLOperand &src_op1(pIcode->ll()->src()); const LLOperand &src_op2(next1->ll()->src()); - if ((ref_long.h() == src_op1.getReg2()) && (ref_long.l() == src_op2.getReg2())) + if ((ref_long.h() == src_op1.getReg2()) and (ref_long.l() == src_op2.getReg2())) { asgn.rhs = AstIdent::LongIdx (loc_ident_idx); pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE); @@ -447,7 +449,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be case iAND: case iOR: case iXOR: pmL = &pIcode->ll()->m_dst; pmH = &next1->ll()->m_dst; - if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi)) + if ((pLocId.longId().h() == pmH->regi) and (pLocId.longId().l() == pmL->regi)) { asgn.lhs = AstIdent::LongIdx (loc_ident_idx); pIcode->setRegDU( pmH->regi, USE_DEF); @@ -474,7 +476,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be } /* eos */ /* Check long conditional (i.e. 2 CMPs and 3 branches */ - else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc))) + else if ((pIcode->ll()->getOpcode() == iCMP) and (isLong23 (pIcode->getParent(), long_loc, &arc))) { if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll())) { @@ -485,7 +487,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be /* Check for long conditional equality or inequality. This requires * 2 CMPs and 2 branches */ - else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc))) + else if (pIcode->ll()->match(iCMP) and (isLong22 (pIcode, pEnd, long_loc))) { if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) ) { @@ -498,7 +500,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be * JX lab * => HLI_JCOND (regH:regL X 0) lab * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */ - else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode()))) + else if (pIcode->ll()->match(iOR) and (next1 != pEnd) and (isJCond ((llIcode)next1->ll()->getOpcode()))) { if (pLocId.longId().srcDstRegMatch(pIcode,pIcode)) { diff --git a/src/reducible.cpp b/src/reducible.cpp index 535f720..08a484f 100644 --- a/src/reducible.cpp +++ b/src/reducible.cpp @@ -3,12 +3,14 @@ * constructs an equivalent reducible graph if one is not found. * (C) Cristina Cifuentes ********************************************************************/ +#include "dcc.h" +#include "msvc_fixes.h" + #include #include #include #include #include -#include "dcc.h" static int numInt; /* Number of intervals */ @@ -79,7 +81,7 @@ void interval::appendNodeInt(queue &pqH, BB *node) /* Check header list for occurrence of node, if found, remove it * and decrement number of out-edges from this interval. */ - if (node->beenOnH && !pqH.empty()) + if (node->beenOnH and !pqH.empty()) { auto found_iter=std::find(pqH.begin(),pqH.end(),node); if(found_iter!=pqH.end()) @@ -147,7 +149,7 @@ void derSeq_Entry::findIntervals (Function *c) else /* node has been visited before */ if (succ->inEdgeCount == 0) { - if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */ + if (succ->reachingInt == header or succ->inInterval == pI) /* same interval */ { if (succ != header) pI->appendNodeInt (H, succ); @@ -155,7 +157,7 @@ void derSeq_Entry::findIntervals (Function *c) else /* out edge */ pI->numOutEdges++; } - else if (succ != header && succ->beenOnH) + else if (succ != header and succ->beenOnH) pI->numOutEdges++; } } @@ -230,7 +232,7 @@ void freeDerivedSeq(derSeq &derivedG) derSeq_Entry::~derSeq_Entry() { freeInterval (&Ii); - // if(Gi && Gi->nodeType == INTERVAL_NODE) + // if(Gi and Gi->nodeType == INTERVAL_NODE) // freeCFG (Gi); } @@ -259,7 +261,7 @@ bool Function::nextOrderGraph (derSeq &derivedGi) const queue &listIi(Ii->nodes); /* Check for more than 1 interval */ - if (sameGraph && (listIi.size()>1)) + if (sameGraph and (listIi.size()>1)) sameGraph = false; /* Find out edges */ diff --git a/src/scanner.cpp b/src/scanner.cpp index fb325da..4938ffa 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -4,13 +4,16 @@ * I-code * (C) Cristina Cifuentes, Jeff Ledermann ****************************************************************************/ +#include "scanner.h" + +#include "msvc_fixes.h" +#include "dcc.h" +#include "project.h" #include #include #include -#include "dcc.h" -#include "scanner.h" -#include "project.h" + /* Parser flags */ #define TO_REG 0x000100 /* rm is source */ #define S_EXT 0x000200 /* sign extend */ @@ -380,7 +383,7 @@ static void fixFloatEmulation(x86_insn_t &insn) return; PROG &prog(Project::get()->prog); uint16_t wOp=insn.x86_get_imm()->data.word; - if ((wOp < 0x34) || (wOp > 0x3B)) + if ((wOp < 0x34) or (wOp > 0x3B)) return; uint8_t buf[16]; /* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */ @@ -403,7 +406,7 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l) PROG &prog(Project::get()->prog); X86_Disasm ds(opt_16_bit); int cnt=ds.x86_disasm(prog.image(),prog.cbImage,0,ip,&l); - if(cnt && l.is_valid()) + if(cnt and l.is_valid()) { fixFloatEmulation(l); //can change 'l' } @@ -413,7 +416,7 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l) } eReg convertRegister(const x86_reg_t ®) { - if( (reg_pc==reg.type) || (0==reg.id)) + if( (reg_pc==reg.type) or (0==reg.id)) return rUNDEF; eReg regmap[]={ rUNDEF, @@ -518,7 +521,7 @@ LLOperand convertOperand(const x86_op_t &from) default: fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type); } - if(res.isSet() && (res.seg == rUNDEF)) + if(res.isSet() and (res.seg == rUNDEF)) { res.seg = rDS; } @@ -627,7 +630,7 @@ static int signex(uint8_t b) static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off) { /* If not to register (i.e. to r/m), and talking about r/m, then this is dest */ - LLOperand *pm = (!(stateTable[i].flg & TO_REG) == fdst) ? &pIcode->ll()->m_dst : &pIcode->ll()->src(); + LLOperand *pm = ((stateTable[i].flg & TO_REG) != fdst) ? &pIcode->ll()->m_dst : &pIcode->ll()->src(); /* Set segment. A later procedure (lookupAddr in proclist.c) will * provide the value of this segment in the field segValue. @@ -638,7 +641,7 @@ static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off } else { /* no override, check indexed register */ - if ((reg >= INDEX_BX_SI) && (reg == INDEX_BP_SI || reg == INDEX_BP_DI || reg == INDEX_BP)) + if ((reg >= INDEX_BX_SI) and (reg == INDEX_BP_SI or reg == INDEX_BP_DI or reg == INDEX_BP)) { pm->seg = rSS; /* indexed on bp */ } @@ -650,7 +653,7 @@ static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off pm->regi = (eReg)reg; pm->off = (int16_t)off; - if (reg && reg < INDEX_BX_SI && (stateTable[i].flg & B)) + if (reg and (reg < INDEX_BX_SI) and (stateTable[i].flg & B)) { pm->regi = Machine_X86::subRegL(pm->regi); } @@ -694,7 +697,7 @@ static void rm(int i) break; } //pIcode->insn.get_dest()-> - if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP || + if ((stateTable[i].flg & NSP) and (pIcode->ll()->src().getReg2()==rSP or pIcode->ll()->m_dst.getReg2()==rSP)) pIcode->ll()->setFlags(NOT_HLL); } @@ -717,7 +720,7 @@ static void segrm(int i) { int reg = REG(*pInst) + rES; - if (reg > rDS || (reg == rCS && (stateTable[i].flg & TO_REG))) + if (reg > rDS or (reg == rCS and (stateTable[i].flg & TO_REG))) pIcode->ll()->setOpcode((llIcode)0); // setCBW because it has that index else { setAddress(i, false, 0, (int16_t)reg, 0); @@ -793,7 +796,7 @@ static void memOnly(int ) ****************************************************************************/ static void memReg0(int i) { - if (REG(*pInst) || (*pInst & 0xC0) == 0xC0) + if (REG(*pInst) or (*pInst & 0xC0) == 0xC0) pIcode->ll()->setOpcode((llIcode)0); else rm(i); @@ -810,7 +813,7 @@ static void immed(int i) pIcode->ll()->setOpcode(immedTable[REG(*pInst)]) ; rm(i); - if (pIcode->ll()->getOpcode() == iADD || pIcode->ll()->getOpcode() == iSUB) + if (pIcode->ll()->getOpcode() == iADD or pIcode->ll()->getOpcode() == iSUB) pIcode->ll()->clrFlags(NOT_HLL); /* Allow ADD/SUB SP, immed */ } @@ -845,13 +848,13 @@ static void trans(int i) // if(transTable[REG(*pInst)]==iPUSH) { // printf("es"); // } - if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */ + if ((uint8_t)REG(*pInst) < 2 or not (stateTable[i].flg & B)) { /* INC & DEC */ ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */ rm(i); ll->replaceSrc( pIcode->ll()->m_dst ); - if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF)) + if (ll->match(iJMP) or ll->match(iCALL) or ll->match(iCALLF)) ll->setFlags(NO_OPS); - else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC)) + else if (ll->match(iINC) or ll->match(iPUSH) or ll->match(iDEC)) ll->setFlags(NO_SRC); } } @@ -878,15 +881,15 @@ static void arith(int i) else data2(i); } - else if (!(opcode == iNOT || opcode == iNEG)) + else if (not (opcode == iNOT or opcode == iNEG)) { pIcode->ll()->replaceSrc( pIcode->ll()->m_dst ); setAddress(i, true, 0, rAX, 0); /* dst = AX */ } - else if (opcode == iNEG || opcode == iNOT) + else if (opcode == iNEG or opcode == iNOT) pIcode->ll()->setFlags(NO_SRC); - if ((opcode == iDIV) || (opcode == iIDIV)) + if ((opcode == iDIV) or (opcode == iIDIV)) { if ( not pIcode->ll()->testFlags(B) ) pIcode->ll()->setFlags(IM_TMP_DST); @@ -981,7 +984,7 @@ static void dispF(int i) ****************************************************************************/ static void prefix(int ) { - if (pIcode->ll()->getOpcode() == iREPE || pIcode->ll()->getOpcode() == iREPNE) + if (pIcode->ll()->getOpcode() == iREPE or pIcode->ll()->getOpcode() == iREPNE) RepPrefix = pIcode->ll()->getOpcode(); else SegPrefix = pIcode->ll()->getOpcode(); @@ -1001,7 +1004,7 @@ static void strop(int ) { if (RepPrefix) { - if ( pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) ) + if ( pIcode->ll()->match(iCMPS) or pIcode->ll()->match(iSCAS) ) { if(pIcode->insn.prefix & insn_rep_zero) { @@ -1075,7 +1078,7 @@ static void none2(int ) static void checkInt(int ) { uint16_t wOp = (uint16_t) pIcode->ll()->src().getImm2(); - if ((wOp >= 0x34) && (wOp <= 0x3B)) + if ((wOp >= 0x34) and (wOp <= 0x3B)) { /* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */ diff --git a/tools/makedsig/LIB_PatternCollector.cpp b/tools/makedsig/LIB_PatternCollector.cpp index d2dce5d..b8f93a7 100644 --- a/tools/makedsig/LIB_PatternCollector.cpp +++ b/tools/makedsig/LIB_PatternCollector.cpp @@ -1,4 +1,7 @@ #include "LIB_PatternCollector.h" + +#include "msvc_fixes.h" + #include #include /** \note there is an untested assumption that the *first* segment definition @@ -88,7 +91,7 @@ int LIB_PatternCollector::readSyms(FILE *fl) ++segnum; b = readByte(fl); /* Class name index */ - if ((b == codeLNAMES) && (codeSEGDEF == NONE)) + if ((b == codeLNAMES) and (codeSEGDEF == NONE)) { /* This is the segment defining the code class */ codeSEGDEF = segnum; diff --git a/tools/makedsig/TPL_PatternCollector.cpp b/tools/makedsig/TPL_PatternCollector.cpp index d007a70..5fd7134 100644 --- a/tools/makedsig/TPL_PatternCollector.cpp +++ b/tools/makedsig/TPL_PatternCollector.cpp @@ -1,4 +1,7 @@ #include "TPL_PatternCollector.h" + +#include "msvc_fixes.h" + #include /** \note Fundamental problem: there seems to be no information linking the names @@ -255,7 +258,7 @@ void TPL_PatternCollector::enterUnitProcs(FILE *f) readString(f); strcpy(name, (char *)buf); cat = readByte(f); - if ((cat == charProc) || (cat == charFunc)) + if ((cat == charProc) or (cat == charFunc)) { grab(f,skipPmap); /* Skip to the pmap */ pmapOff = readShort(f); /* pmap offset */ @@ -278,7 +281,7 @@ void TPL_PatternCollector::enterUnitProcs(FILE *f) int TPL_PatternCollector::readSyms(FILE *f) { grab(f,4); - if ((strncmp((char *)buf, "TPU0", 4) != 0) && ((strncmp((char *)buf, "TPU5", 4) != 0))) + if ((strncmp((char *)buf, "TPU0", 4) != 0) and ((strncmp((char *)buf, "TPU5", 4) != 0))) { printf("Not a Turbo Pascal version 4 or 5 library file\n"); fclose(f); diff --git a/tools/makedsig/fixwild.cpp b/tools/makedsig/fixwild.cpp index 12323e6..e2869a6 100644 --- a/tools/makedsig/fixwild.cpp +++ b/tools/makedsig/fixwild.cpp @@ -25,8 +25,11 @@ * * \* * * * * * * * * * * * */ +#include "msvc_fixes.h" + #include #include + #ifndef PATLEN #define PATLEN 23 #define WILD 0xF4 @@ -417,7 +420,7 @@ void fixWildCards(uint8_t pat[]) case 0xCD: /* Int nn */ intArg = pat[pc++]; - if ((intArg >= 0x34) && (intArg <= 0x3B)) + if ((intArg >= 0x34) and (intArg <= 0x3B)) { /* Borland/Microsoft FP emulations */ if (ModRM(pat)) return; diff --git a/tools/makedsig/makedsig.cpp b/tools/makedsig/makedsig.cpp index 0465dee..b7f39c6 100644 --- a/tools/makedsig/makedsig.cpp +++ b/tools/makedsig/makedsig.cpp @@ -3,6 +3,7 @@ #include "LIB_PatternCollector.h" #include "TPL_PatternCollector.h" #include "perfhlib.h" /* Symbol table prototypes */ +#include "msvc_fixes.h" #include #include @@ -48,7 +49,7 @@ int main(int argc, char *argv[]) return 0; } QString arg2 = app.arguments()[1]; - if (arg2.startsWith("-h") || arg2.startsWith("-?")) + if (arg2.startsWith("-h") or arg2.startsWith("-?")) { printUsage(true); return 0;