WIP - do not use.

This commit is contained in:
nemerle 2016-05-19 10:18:17 +02:00
parent bc654cbf76
commit 14ceb301c1
17 changed files with 267 additions and 636 deletions

View File

@ -152,6 +152,7 @@ enum DecompilationStep : uint32_t {
//eStackTracing, // tracing stack depth across function calls //eStackTracing, // tracing stack depth across function calls
}; };
class Function : public std::enable_shared_from_this<Function> class Function : public std::enable_shared_from_this<Function>
{ {
typedef llvm::iplist<BB> BasicBlockListType; typedef llvm::iplist<BB> BasicBlockListType;
@ -232,7 +233,6 @@ public:
void markImpure(); void markImpure();
void findImmedDom(); void findImmedDom();
void process_operands(ICODE &pIcode, STATE *pstate); void process_operands(ICODE &pIcode, STATE *pstate);
bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
void freeCFG(); void freeCFG();
void codeGen(QIODevice & fs); void codeGen(QIODevice & fs);
void mergeFallThrough(BB *pBB); void mergeFallThrough(BB *pBB);
@ -256,7 +256,6 @@ public:
void switchState(DecompilationStep s); void switchState(DecompilationStep s);
protected: protected:
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table); void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b); bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b);
bool Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB); bool Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
bool Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB); bool Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB);
@ -283,7 +282,7 @@ protected:
void genLiveKtes(); void genLiveKtes();
bool findDerivedSeq(derSeq &derivedGi); bool findDerivedSeq(derSeq &derivedGi);
bool nextOrderGraph(derSeq &derivedGi); bool nextOrderGraph(derSeq &derivedGi);
void addOutEdgesForConditionalJump(BB* pBB, int next_ip, LLInst *ll); void addOutEdgesForConditionalJump(BB *pBB, int next_ip, LLInst *ll);
}; };
typedef std::list<PtrFunction> FunctionListType; typedef std::list<PtrFunction> FunctionListType;

View File

@ -309,7 +309,7 @@ struct LLOperand
Op.regi = (eReg)Val; Op.regi = (eReg)Val;
return Op; return Op;
} }
bool isSet() bool isSet() const
{ {
return not (*this == LLOperand()); return not (*this == LLOperand());
} }
@ -322,84 +322,90 @@ struct LLOperand
struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst> struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
{ {
protected: protected:
uint32_t flg; /* icode flags */ uint32_t flg; /* icode flags */
LLOperand m_src; /* source operand */ LLOperand m_src; /* source operand */
public: public:
int codeIdx; /* Index into cCode.code */ int codeIdx; /* Index into cCode.code */
uint8_t numBytes; /* Number of bytes this instr */ uint8_t numBytes; /* Number of bytes this instr */
uint32_t label; /* offset in image (20-bit adr) */ uint32_t label; /* offset in image (20-bit adr) */
LLOperand m_dst; /* destination operand */ LLOperand m_dst; /* destination operand */
DU flagDU; /* def/use of flags */ DU flagDU; /* def/use of flags */
int caseEntry; int caseEntry;
std::vector<uint32_t> caseTbl2; std::vector<uint32_t> caseTbl2;
int hllLabNum; /* label # for hll codegen */ int hllLabNum; /* label # for hll codegen */
bool conditionalJump() bool conditionalJump()
{ {
return (getOpcode() >= iJB) and (getOpcode() < iJCXZ); return (getOpcode() >= iJB) and (getOpcode() < iJCXZ);
} }
bool testFlags(uint32_t x) const { return (flg & x)!=0;} bool testFlags(uint32_t x) const { return (flg & x)!=0;}
void setFlags(uint32_t flag) {flg |= flag;} void setFlags(uint32_t flag) {flg |= flag;}
void clrFlags(uint32_t flag); void clrFlags(uint32_t flag);
uint32_t getFlag() const {return flg;} uint32_t getFlag() const {return flg;}
uint32_t GetLlLabel() const { return label;} uint32_t GetLlLabel() const { return label;}
void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);} void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);}
bool match(llIcode op) bool match(llIcode op)
{ {
return (getOpcode()==op); return (getOpcode()==op);
} }
bool matchWithRegDst(llIcode op) bool matchWithRegDst(llIcode op)
{ {
return (getOpcode()==op) and m_dst.isReg(); return match(op) and m_dst.isReg();
} }
bool match(llIcode op,eReg dest) bool match(llIcode op,eReg dest)
{ {
return (getOpcode()==op) and match(dest); return match(op) and match(dest);
} }
bool match(llIcode op,eReg dest,uint32_t flgs) bool match(llIcode op,eReg dest,uint32_t flgs)
{ {
return match(op) and match(dest) and testFlags(flgs); return match(op) and match(dest) and testFlags(flgs);
} }
bool match(llIcode op,eReg dest,eReg src_reg) bool match(llIcode op,eReg dest,eReg src_reg)
{ {
return match(op) and match(dest) and (m_src.regi==src_reg); return match(op) and match(dest) and (m_src.regi==src_reg);
} }
bool match(eReg dest,eReg src_reg) bool match(eReg dest,eReg src_reg)
{ {
return match(dest) and (m_src.regi==src_reg); return match(dest) and (m_src.regi==src_reg);
} }
bool match(eReg dest) bool matchAny(std::initializer_list<llIcode> ops) {
{ for(llIcode op : ops) {
return (m_dst.regi==dest); if(match(op))
} return true;
bool match(llIcode op,uint32_t flgs) }
{ return false;
return match(op) and testFlags(flgs); }
} bool match(eReg dest)
void set(llIcode op,uint32_t flags) {
{ return (m_dst.regi==dest);
setOpcode(op); }
flg =flags; bool match(llIcode op,uint32_t flgs)
} {
void set(llIcode op,uint32_t flags,eReg dst_reg) return match(op) and testFlags(flgs);
{ }
setOpcode(op); void set(llIcode op,uint32_t flags)
m_dst = LLOperand::CreateReg2(dst_reg); {
flg =flags; setOpcode(op);
} flg =flags;
void set(llIcode op,uint32_t flags,eReg dst_reg,const LLOperand &src_op) }
{ void set(llIcode op,uint32_t flags,eReg dst_reg)
setOpcode(op); {
m_dst = LLOperand::CreateReg2(dst_reg); setOpcode(op);
m_src = src_op; m_dst = LLOperand::CreateReg2(dst_reg);
flg =flags; flg =flags;
} }
void set(llIcode op,uint32_t flags,eReg dst_reg,const LLOperand &src_op)
{
setOpcode(op);
m_dst = LLOperand::CreateReg2(dst_reg);
m_src = src_op;
flg =flags;
}
void emitGotoLabel(int indLevel); void emitGotoLabel(int indLevel);
void findJumpTargets(CIcodeRec &_pc); void findJumpTargets(CIcodeRec &_pc);
void writeIntComment(QTextStream & s); void writeIntComment(QTextStream & s);
void dis1Line(int loc_ip, int pass); void dis1Line(int loc_ip, int pass);
QTextStream & strSrc(QTextStream & os, bool skip_comma=false);
void flops(QTextStream & out); void flops(QTextStream & out);
bool isJmpInst(); bool isJmpInst();
@ -408,18 +414,30 @@ public:
{ {
setOpcode(0); setOpcode(0);
} }
const LLOperand & dst() const { return m_dst; }
LLOperand & dst() { return m_dst; }
const LLOperand & src() const { return m_src; } const LLOperand & src() const { return m_src; }
LLOperand & src() { return m_src; } LLOperand & src() { return m_src; }
void replaceSrc(const LLOperand &with) { m_src = with; } void replaceSrc(const LLOperand &with) { m_src = with; }
void replaceSrc(eReg r) { m_src = LLOperand::CreateReg2(r); } void replaceSrc(eReg r) { m_src = LLOperand::CreateReg2(r); }
void replaceSrc(int64_t r) { m_src = LLOperand::CreateImm2(r); } void replaceSrc(int64_t r) { m_src = LLOperand::CreateImm2(r); }
void replaceDst(const LLOperand &with) { m_dst = with; } void replaceDst(const LLOperand &with) { m_dst = with; }
bool srcIsImmed() const { return (flg & I)!=0; }
condId idType(opLoc sd) const; condId idType(opLoc sd) const;
const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &m_dst; } const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &m_dst; }
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &m_dst; } LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &m_dst; }
ICODE * m_link; ICODE * m_link;
}; };
struct ADDRESS {
};
struct BinaryArea {
ADDRESS start;
ADDRESS fin;
};
#include <boost/icl/interval_set.hpp>
#include <boost/icl/interval_map.hpp>
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */ /* Icode definition: LOW_LEVEL and HIGH_LEVEL */
struct ICODE struct ICODE
@ -427,7 +445,7 @@ struct ICODE
// use llvm names at least // use llvm names at least
typedef BB MachineBasicBlock; typedef BB MachineBasicBlock;
protected: protected:
LLInst m_ll; LLInst *m_ll;
HLTYPE m_hl; HLTYPE m_hl;
MachineBasicBlock * Parent; /* BB to which this icode belongs */ MachineBasicBlock * Parent; /* BB to which this icode belongs */
bool invalid; /* Has no HIGH_LEVEL equivalent */ bool invalid; /* Has no HIGH_LEVEL equivalent */
@ -530,8 +548,8 @@ public:
DU1 du1; /* du chain 1 */ DU1 du1; /* du chain 1 */
int loc_ip; // used by CICodeRec to number ICODEs int loc_ip; // used by CICodeRec to number ICODEs
LLInst * ll() { return &m_ll;} LLInst * ll() { return m_ll;}
const LLInst * ll() const { return &m_ll;} const LLInst * ll() const { return m_ll;}
HLTYPE * hlU() { HLTYPE * hlU() {
// assert(type==HIGH_LEVEL); // assert(type==HIGH_LEVEL);
@ -571,8 +589,46 @@ public:
{ {
return hlU()->call.newStkArg(exp,opcode,pproc); return hlU()->call.newStkArg(exp,opcode,pproc);
} }
ICODE() : m_ll(this),Parent(0),invalid(false),type(NOT_SCANNED),loc_ip(0) ICODE() :Parent(0),invalid(false),type(NOT_SCANNED),loc_ip(0)
{ {
m_ll = new LLInst(this);
}
~ICODE() {
delete m_ll;
}
ICODE(const ICODE &v) {
m_ll = new LLInst(*v.m_ll);
m_hl = v.m_hl;
Parent = v.Parent;
insn = v.insn;
type = v.type;
du = v.du;
du1 = v.du1;
loc_ip = v.loc_ip;
}
ICODE & operator=(const ICODE &v) {
delete m_ll;
m_ll = v.m_ll;
m_hl = v.m_hl;
Parent = v.Parent;
insn = v.insn;
type = v.type;
du = v.du;
du1 = v.du1;
loc_ip = v.loc_ip;
return *this;
}
ICODE & operator=(ICODE &&v) {
std::swap(m_ll,v.m_ll);
std::swap(m_hl,v.m_hl);
std::swap(Parent , v.Parent);
std::swap(insn , v.insn);
std::swap(type , v.type);
std::swap(du , v.du);
std::swap(du1 , v.du1);
std::swap(loc_ip , v.loc_ip);
return *this;
} }
public: public:
const MachineBasicBlock* getParent() const { return Parent; } const MachineBasicBlock* getParent() const { return Parent; }
@ -594,12 +650,12 @@ struct MappingLLtoML
class CIcodeRec : public std::list<ICODE> class CIcodeRec : public std::list<ICODE>
{ {
public: public:
CIcodeRec(); // Constructor CIcodeRec(); // Constructor
ICODE * addIcode(const ICODE * pIcode); ICODE * addIcode(const ICODE * pIcode);
void SetInBB(rCODE &rang, BB* pnewBB); void SetInBB(rCODE &rang, BB* pnewBB);
bool labelSrch(uint32_t target, uint32_t &pIndex); bool labelSrch(uint32_t target, uint32_t &pIndex);
iterator labelSrch(uint32_t target); iterator labelSrch(uint32_t target);
ICODE * GetIcode(size_t ip); ICODE * GetIcode(size_t ip);
bool alreadyDecoded(uint32_t target); bool alreadyDecoded(uint32_t target);
}; };

View File

@ -9,6 +9,7 @@
#include <QtCore/QString> #include <QtCore/QString>
#include <string> #include <string>
#include <vector>
#include <stdint.h> #include <stdint.h>
class QTextStream; class QTextStream;

View File

@ -222,7 +222,7 @@ AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f,
{ {
AstIdent *newExp; AstIdent *newExp;
/* Check for long constant and save it as a constant expression */ /* Check for long constant and save it as a constant expression */
if ((sd == SRC) and pIcode->ll()->testFlags(I)) /* constant */ if ((sd == SRC) and pIcode->ll()->srcIsImmed()) /* constant */
{ {
int value; int value;
if (f == HIGH_FIRST) if (f == HIGH_FIRST)
@ -313,7 +313,7 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
duIcode.setRegDU(rTMP, (operDu)eUSE); duIcode.setRegDU(rTMP, (operDu)eUSE);
} }
else if ((sd == SRC) and ll_insn.testFlags(I)) /* constant */ else if ((sd == SRC) and ll_insn.srcIsImmed()) /* constant */
newExp = new Constant(ll_insn.src().getImm2(), 2); newExp = new Constant(ll_insn.src().getImm2(), 2);
else if (pm.regi == rUNDEF) /* global variable */ else if (pm.regi == rUNDEF) /* global variable */
newExp = new GlobalVariable(pm.segValue, pm.off); newExp = new GlobalVariable(pm.segValue, pm.off);
@ -377,7 +377,7 @@ condId LLInst::idType(opLoc sd) const
{ {
const LLOperand &pm((sd == SRC) ? src() : m_dst); const LLOperand &pm((sd == SRC) ? src() : m_dst);
if ((sd == SRC) and testFlags(I)) if ((sd == SRC) and srcIsImmed())
return (CONSTANT); return (CONSTANT);
else if (pm.regi == 0) else if (pm.regi == 0)
return (GLOB_VAR); return (GLOB_VAR);

View File

@ -113,7 +113,7 @@ static vector<POSSTACK_ENTRY> posStack; /* position stack */
void LLInst::findJumpTargets(CIcodeRec &_pc) void LLInst::findJumpTargets(CIcodeRec &_pc)
{ {
if (testFlags(I) and not testFlags(JMP_ICODE) and isJmpInst()) if (srcIsImmed() and not testFlags(JMP_ICODE) and isJmpInst())
{ {
/* Replace the immediate operand with an icode index */ /* Replace the immediate operand with an icode index */
iICODE labTgt=_pc.labelSrch(src().getImm2()); iICODE labTgt=_pc.labelSrch(src().getImm2());
@ -214,364 +214,7 @@ void Disassembler::disassem(PtrFunction ppProc)
****************************************************************************/ ****************************************************************************/
void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
{ {
PROG &prog(Project::get()->prog); assert(false);
QString oper_contents;
QTextStream oper_stream(&oper_contents);
QString hex_bytes;
QString result_contents;
QTextStream result_stream(&result_contents);
QString opcode_with_mods;
QString operands_contents;
QTextStream operands_s(&operands_contents);
oper_stream.setNumberFlags(QTextStream::UppercaseBase|QTextStream::UppercaseDigits);
/* 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) and
( inst.testFlags(NO_CODE) or
(inst.testFlags(SYNTHETIC) and (inst.getOpcode() != iJMP))))
{
return;
}
else if (inst.testFlags(NO_CODE))
{
return;
}
if (inst.testFlags(TARGET | CASE))
{
if (pass == 3)
cCode.appendCode("\n"); /* Print to c code buffer */
else
m_fp<< "\n"; /* No, print to the stream */
}
/* Find next instruction label and print hex bytes */
if (inst.testFlags(SYNTHETIC))
nextInst = inst.label;
else
{
cb = (uint32_t) inst.numBytes;
nextInst = inst.label + cb;
/* Output hex code in program image */
if (pass != 3)
{
for (j = 0; j < cb; j++)
{
hex_bytes += QString("%1").arg(uint16_t(prog.image()[inst.label + j]),2,16,QChar('0')).toUpper();
}
hex_bytes += ' ';
}
}
oper_stream.setFieldWidth(POS_LAB);
oper_stream.setFieldAlignment(QTextStream::AlignLeft);
oper_stream << hex_bytes;
/* Check if there is a symbol here */
selectTable(Label);
oper_stream.setFieldWidth(5); // align for the labels
{
QString lab_contents;
QTextStream lab_stream(&lab_contents);
if (readVal(lab_stream, inst.label, nullptr))
{
lab_stream << ':'; /* Also removes the null */
}
else if (inst.testFlags(TARGET)) /* Symbols override Lnn labels */
{
/* Print label */
if (pl.count(loc_ip)==0)
{
pl[loc_ip] = ++g_lab;
}
lab_stream<< "L"<<pl[loc_ip]<<':';
}
lab_stream.flush();
oper_stream << lab_contents;
oper_stream.setFieldWidth(0);
}
if ((inst.getOpcode()==iSIGNEX )and inst.testFlags(B))
{
inst.setOpcode(iCBW);
}
opcode_with_mods += Machine_X86::opcodeName(inst.getOpcode());
switch ( inst.getOpcode() )
{
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
strDst(operands_s,inst.getFlag(), inst.m_dst);
inst.strSrc(operands_s);
break;
case iESC:
inst.flops(operands_s);
break;
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
case iROR:
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
if(inst.testFlags(I))
inst.strSrc(operands_s);
else
operands_s<<", cl";
break;
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
break;
case iPUSH:
if (inst.testFlags(I))
{
operands_s<<strHex(inst.src().getImm2());
}
else
{
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
}
break;
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
if (inst.testFlags(I))
{
strDst(operands_s,inst.getFlag(), inst.m_dst) <<", ";
formatRM(operands_s, inst.src());
inst.strSrc(operands_s);
}
else
strDst(operands_s,inst.getFlag() | I, inst.src());
break;
case iLDS: case iLES: case iBOUND:
strDst(operands_s,inst.getFlag(), inst.m_dst)<<", dword ptr";
inst.strSrc(operands_s,true);
break;
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:case iLOOP: case iLOOPE:case iLOOPNE:
case iJMP: case iJMPF:
/* Check if there is a symbol here */
{
ICODE *lab=pc.GetIcode(inst.src().getImm2());
selectTable(Label);
if ((inst.src().getImm2() < (uint32_t)numIcode) and /* Ensure in range */
readVal(operands_s, lab->ll()->label, nullptr))
{
break; /* Symbolic label. Done */
}
}
if (inst.testFlags(NO_LABEL))
{
//strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op));
operands_s<<strHex(inst.src().getImm2());
}
else if (inst.testFlags(I) )
{
j = inst.src().getImm2();
if (pl.count(j)==0) /* Forward jump */
{
pl[j] = ++g_lab;
}
if (inst.getOpcode() == iJMPF)
{
operands_s<<" far ptr ";
}
operands_s<<"L"<<pl[j];
}
else if (inst.getOpcode() == iJMPF)
{
operands_s<<"dword ptr";
inst.strSrc(operands_s,true);
}
else
{
strDst(operands_s,I, inst.src());
}
break;
case iCALL: case iCALLF:
if (inst.testFlags(I))
{
QString oper = QString("%1 ptr %2")
.arg((inst.getOpcode() == iCALL) ? "near" : "far")
.arg((inst.src().proc.proc)->name);
operands_s<< qPrintable(oper);
}
else if (inst.getOpcode() == iCALLF)
{
operands_s<<"dword ptr ";
inst.strSrc(operands_s,true);
}
else
strDst(operands_s,I, inst.src());
break;
case iENTER:
operands_s<<strHex(inst.m_dst.off) << ", " << strHex(inst.src().getImm2());
break;
case iRET: case iRETF: case iINT:
if (inst.testFlags(I))
{
operands_s<<strHex(inst.src().getImm2());
}
break;
case iCMPS: case iREPNE_CMPS: case iREPE_CMPS:
case iSCAS: case iREPNE_SCAS: case iREPE_SCAS:
case iSTOS: case iREP_STOS:
case iLODS: case iREP_LODS:
case iMOVS: case iREP_MOVS:
case iINS: case iREP_INS:
case iOUTS: case iREP_OUTS:
if (inst.src().segOver)
{
bool is_dx_src=(inst.getOpcode() == iOUTS or inst.getOpcode() == iREP_OUTS);
if(is_dx_src)
operands_s<<"dx, "<<szPtr[inst.getFlag() & B];
else
operands_s<<szPtr[inst.getFlag() & B];
if (inst.getOpcode() == iLODS or
inst.getOpcode() == iREP_LODS or
inst.getOpcode() == iOUTS or
inst.getOpcode() == iREP_OUTS)
{
operands_s<<Machine_X86::regName(inst.src().segOver); // szWreg[src.segOver-rAX]
}
else
{
operands_s<<"es:[di], "<<Machine_X86::regName(inst.src().segOver);
}
operands_s<<":[si]";
}
else
{
if(inst.getFlag() & B)
opcode_with_mods+='B';
else
opcode_with_mods+='W';
}
break;
case iXLAT:
if (inst.src().segOver)
{
operands_s<<" "<<szPtr[1];
operands_s<<Machine_X86::regName(inst.src().segOver)<<":[bx]";
}
break;
case iIN:
(inst.getFlag() & B)? operands_s<<"al, " : operands_s<< "ax, ";
(inst.testFlags(I))? operands_s << strHex(inst.src().getImm2()) : operands_s<< "dx";
break;
case iOUT:
{
QString d1=((inst.testFlags(I))? strHex(inst.src().getImm2()): "dx");
QString d2=((inst.getFlag() & B) ? ", al": ", ax");
operands_s<<d1 << d2;
}
break;
default:
break;
}
oper_stream.setFieldWidth(15);
operands_s.flush();
oper_stream << qSetFieldWidth(15) << opcode_with_mods << qSetFieldWidth(0) << operands_contents;
/* Comments */
if (inst.testFlags(SYNTHETIC))
{
fImpure = false;
}
else
{
for (j = inst.label, fImpure = 0; j > 0 and j < (int)nextInst; j++)
{
fImpure |= BITMAP(j, BM_DATA);
}
}
result_stream.setFieldWidth(54);
result_stream.setFieldAlignment(QTextStream::AlignLeft);
oper_stream.flush();
result_stream << oper_contents;
result_stream.setFieldWidth(0);
/* Check for user supplied comment */
selectTable(Comment);
QString cbuf_contents;
QTextStream cbuf(&cbuf_contents);
if (readVal(cbuf, inst.label, nullptr))
{
cbuf.flush();
result_stream <<"; "<<*cbuf.string();
}
else if (fImpure or (inst.testFlags(SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES)))
{
if (inst.testFlags(CASE))
{
result_stream << ";Case l"<< inst.caseEntry;
}
if (inst.testFlags(SWITCH))
{
result_stream << ";Switch ";
}
if (fImpure)
{
result_stream << ";Accessed as data ";
}
if (inst.testFlags(IMPURE))
{
result_stream << ";Impure operand ";
}
if (inst.testFlags(SEG_IMMED))
{
result_stream << ";Segment constant";
}
if (inst.testFlags(TERMINATES))
{
result_stream << ";Exit to DOS";
}
}
/* Comment on iINT icodes */
if (inst.getOpcode() == iINT)
inst.writeIntComment(result_stream);
/* Display output line */
if(pass==3)
{
/* output to .b code buffer */
if (inst.testFlags(SYNTHETIC))
result_stream<<";Synthetic inst";
if (pass == 3) { /* output to .b code buffer */
cCode.appendCode("%s\n", qPrintable(result_contents));
}
}
else
{
char buf[12];
/* output to .a1 or .a2 file */
if (not inst.testFlags(SYNTHETIC) )
{
sprintf(buf,"%03d %06X",loc_ip, inst.label);
}
else /* SYNTHETIC instruction */
{
sprintf(buf,"%03d ",loc_ip);
result_stream<<";Synthetic inst";
}
result_stream.flush();
m_fp<<buf<< " " << result_contents << "\n";
}
} }
@ -630,19 +273,19 @@ static QTextStream & strDst(QTextStream &os,uint32_t flg, const LLOperand &pm)
/**************************************************************************** /****************************************************************************
* strSrc * * strSrc *
****************************************************************************/ ****************************************************************************/
QTextStream &LLInst::strSrc(QTextStream &os,bool skip_comma) //QTextStream &LLInst::strSrc(QTextStream &os,bool skip_comma)
{ //{
if(false==skip_comma) // if(false==skip_comma)
os<<", "; // os<<", ";
if (testFlags(I)) // if (srcIsImmed())
os<<strHex(src().getImm2()); // os<<strHex(src().getImm2());
else if (testFlags(IM_SRC)) /* level 2 */ // else if (testFlags(IM_SRC)) /* level 2 */
os<<"dx:ax"; // os<<"dx:ax";
else // else
formatRM(os, src()); // formatRM(os, src());
return os; // return os;
} //}
@ -769,62 +412,55 @@ void LLInst::flops(QTextStream &out)
} }
} }
} }
/**************************************************************************** struct AsmFormatter {
* formatRM IStructuredTextTarget * target;
***************************************************************************/ int operand_count;
static void formatRM(IStructuredTextTarget *out,const LLOperand &pm) void visitOperand(const LLOperand &pm) {
{ if(not pm.isSet())
if (pm.segOver) return;
{ if(operand_count>0) {
out->prtt(Machine_X86::regName(pm.segOver)+':'); target->prtt(", ");
} }
operand_count++;
if (pm.immed and not pm.isReg()) {
//target->addTaggedString(XT_Keyword,szPtr[flg&B]);
target->addTaggedString(XT_Number,strHex(pm.getImm2()));
return;
}
if (pm.regi == rUNDEF) if (pm.segOver)
{
out->prtt(QString("[")+strHex((uint32_t)pm.off)+"]");
}
else if (pm.isReg())
{
out->prtt(Machine_X86::regName(pm.regi));
}
else if (pm.off)
{
if (pm.off < 0)
{ {
out->prtt("["+Machine_X86::regName(pm.regi)+"-"+strHex((uint32_t)(- pm.off))+"]"); target->prtt(Machine_X86::regName(pm.segOver)+':');
}
if (pm.regi == rUNDEF)
{
target->prtt(QString("[")+strHex((uint32_t)pm.off)+"]");
}
else if (pm.isReg())
{
target->prtt(Machine_X86::regName(pm.regi));
}
else if (pm.off)
{
if (pm.off < 0)
{
target->prtt("["+Machine_X86::regName(pm.regi)+"-"+strHex((uint32_t)(- pm.off))+"]");
}
else
{
target->prtt("["+Machine_X86::regName(pm.regi)+"+"+strHex((uint32_t)(pm.off))+"]");
}
} }
else else
{ target->prtt("["+Machine_X86::regName(pm.regi)+"]");
out->prtt("["+Machine_X86::regName(pm.regi)+"+"+strHex((uint32_t)(pm.off))+"]");
}
} }
else };
out->prtt("["+Machine_X86::regName(pm.regi)+"]");
}
static void strDst(IStructuredTextTarget *out,uint32_t flg, const LLOperand &pm)
{
/* Immediates to memory require size descriptor */
//os << setw(WID_PTR);
if ((flg & I) and not pm.isReg()) {
out->addTaggedString(XT_Keyword,szPtr[flg&B]);
}
formatRM(out,pm);
}
static void strSrc(IStructuredTextTarget *out,LLInst *insn,bool skip_comma=false)
{
if(false==skip_comma)
out->prtt(", ");
if (insn->testFlags(I))
out->addTaggedString(XT_Number,strHex(insn->src().getImm2()));
else if (insn->testFlags(IM_SRC)) /* level 2 */
out->addTaggedString(XT_Symbol,"dx:ax");
else
formatRM(out,insn->src());
}
void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) { void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
AsmFormatter formatter {out};
const LLInst &inst(*insn); const LLInst &inst(*insn);
QString opcode = Machine_X86::opcodeName(insn->getOpcode()); QString opcode = Machine_X86::opcodeName(insn->getOpcode());
out->addSpace(4); out->addSpace(4);
@ -837,50 +473,32 @@ void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
switch(insn->getOpcode()) { switch(insn->getOpcode()) {
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR: case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG: case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
strDst(out,insn->getFlag(), insn->m_dst);
strSrc(out,insn);
break;
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL: case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
case iROR: case iROR:
strDst(out,insn->getFlag() | I, insn->m_dst); formatter.visitOperand(insn->dst());
if(insn->testFlags(I)) formatter.visitOperand(insn->src());
strSrc(out,insn);
else {
out->prtt(", ");
out->addTaggedString(XT_Symbol,"cl");
}
break; break;
case iINC: case iDEC: case iNEG: case iNOT: case iPOP: case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
strDst(out,insn->getFlag() | I, insn->m_dst); formatter.visitOperand(insn->dst());
break; break;
case iPUSH: case iPUSH:
if (inst.testFlags(I)) formatter.visitOperand(insn->dst());
{
out->addTaggedString(XT_Number,strHex(inst.src().getImm2()));
}
else
{
strDst(out,insn->getFlag() | I, insn->m_dst);
}
break; break;
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD: case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
if (inst.testFlags(I)) if (inst.srcIsImmed())
{ {
strDst(out,insn->getFlag(), insn->m_dst); formatter.visitOperand(insn->dst());
out->prtt(", "); formatter.visitOperand(insn->src());
formatRM(out, inst.src());
strSrc(out,insn);
} }
else else
strDst(out,insn->getFlag() | I, insn->m_dst); formatter.visitOperand(insn->dst());
break; break;
case iLDS: case iLES: case iBOUND: case iLDS: case iLES: case iBOUND:
strDst(out,inst.getFlag(), inst.m_dst); formatter.visitOperand(insn->dst());
out->prtt(", "); formatter.visitOperand(insn->src());
out->addTaggedString(XT_Keyword,"dword ptr");
strSrc(out,insn,true);
break; break;
case iJB: case iJBE: case iJAE: case iJA: case iJB: case iJBE: case iJAE: case iJA:
case iJL: case iJLE: case iJGE: case iJG: case iJL: case iJLE: case iJGE: case iJG:
@ -904,7 +522,7 @@ void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
//strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op)); //strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op));
out->addTaggedString(XT_AsmLabel,strHex(inst.src().getImm2())); out->addTaggedString(XT_AsmLabel,strHex(inst.src().getImm2()));
} }
else if (inst.testFlags(I) ) else if (inst.srcIsImmed() )
{ {
int64_t tgt_addr = inst.src().getImm2(); int64_t tgt_addr = inst.src().getImm2();
if (inst.getOpcode() == iJMPF) if (inst.getOpcode() == iJMPF)
@ -916,16 +534,16 @@ void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
else if (inst.getOpcode() == iJMPF) else if (inst.getOpcode() == iJMPF)
{ {
out->addTaggedString(XT_Keyword,"dword ptr"); out->addTaggedString(XT_Keyword,"dword ptr");
strSrc(out,insn,true); formatter.visitOperand(inst.src());
} }
else else
{ {
strDst(out,I,inst.src()); formatter.visitOperand(inst.src());
} }
break; break;
case iCALL: case iCALLF: case iCALL: case iCALLF:
if (inst.testFlags(I)) if (inst.srcIsImmed())
{ {
out->addTaggedString(XT_Keyword,QString("%1 ptr ").arg((inst.getOpcode() == iCALL) ? "near" : "far")); out->addTaggedString(XT_Keyword,QString("%1 ptr ").arg((inst.getOpcode() == iCALL) ? "near" : "far"));
out->addTaggedString(XT_AsmLabel,(inst.src().proc.proc)->name); out->addTaggedString(XT_AsmLabel,(inst.src().proc.proc)->name);
@ -933,25 +551,21 @@ void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
else if (inst.getOpcode() == iCALLF) else if (inst.getOpcode() == iCALLF)
{ {
out->addTaggedString(XT_Keyword,"dword ptr "); out->addTaggedString(XT_Keyword,"dword ptr ");
strSrc(out,insn,true); formatter.visitOperand(inst.src());
} }
else else
strDst(out,I,inst.src()); formatter.visitOperand(inst.src());
break; break;
case iENTER: case iENTER:
out->addTaggedString(XT_AsmOffset,strHex(inst.m_dst.off)); formatter.visitOperand(inst.dst());
out->prtt(", "); formatter.visitOperand(inst.src());
out->addTaggedString(XT_AsmOffset,strHex(inst.src().getImm2()));
break; break;
case iRET: case iRET:
case iRETF: case iRETF:
case iINT: case iINT:
if (inst.testFlags(I)) formatter.visitOperand(inst.src());
{
out->addTaggedString(XT_Number,strHex(inst.src().getImm2()));
}
break; break;
case iCMPS: case iREPNE_CMPS: case iREPE_CMPS: case iCMPS: case iREPNE_CMPS: case iREPE_CMPS:
@ -1009,15 +623,13 @@ void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
case iIN: case iIN:
out->addTaggedString(XT_Symbol, (inst.getFlag() & B)? "al" : "ax"); out->addTaggedString(XT_Symbol, (inst.getFlag() & B)? "al" : "ax");
out->prtt(", "); out->prtt(", ");
if(inst.testFlags(I)) formatter.visitOperand(inst.src());
out->addTaggedString(XT_Number, strHex(inst.src().getImm2()));
else
out->addTaggedString(XT_Symbol, "dx");
break; break;
case iOUT: case iOUT:
{ {
if(inst.testFlags(I)) formatter.visitOperand(inst.src());
if(inst.srcIsImmed())
out->addTaggedString(XT_Number, strHex(inst.src().getImm2())); out->addTaggedString(XT_Number, strHex(inst.src().getImm2()));
else else
out->addTaggedString(XT_Symbol, "dx"); out->addTaggedString(XT_Symbol, "dx");

View File

@ -93,7 +93,7 @@ void Function::createCFG()
pBB->addOutEdge(elem); pBB->addOutEdge(elem);
hasCase = true; hasCase = true;
} }
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT else if (ll->srcIsImmed() and not ll->testFlags(NO_LABEL)) //TODO: WHY NO_LABEL TESTIT
{ {
pBB = BB::Create(current_range, ONE_BRANCH, this); pBB = BB::Create(current_range, ONE_BRANCH, this);
pBB->addOutEdge(ll->src().getImm2()); pBB->addOutEdge(ll->src().getImm2());

View File

@ -332,7 +332,7 @@ void Function::highLevelGen()
lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE); lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
} }
if(ll->getOpcode()==iPUSH) { if(ll->getOpcode()==iPUSH) {
if(ll->testFlags(I)) { if(ll->srcIsImmed()) {
lhs = new Constant(src_ll->opz,src_ll->byteWidth()); lhs = new Constant(src_ll->opz,src_ll->byteWidth());
} }
// lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE); // lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);

View File

@ -15,10 +15,8 @@ CIcodeRec::CIcodeRec()
{ {
} }
/* Copies the icode that is pointed to by pIcode to the icode array. /* Copies the icode that is pointed to by pIcode to the icode array. */
* If there is need to allocate extra memory, it is done so, and ICODE * CIcodeRec::addIcode(const ICODE *pIcode)
* the alloc variable is adjusted. */
ICODE * CIcodeRec::addIcode(ICODE *pIcode)
{ {
push_back(*pIcode); push_back(*pIcode);
back().loc_ip = size()-1; back().loc_ip = size()-1;
@ -84,8 +82,7 @@ void LLInst::emitGotoLabel (int indLevel)
hllLabNum = getNextLabel(); hllLabNum = getNextLabel();
setFlags(HLL_LABEL); setFlags(HLL_LABEL);
/* Node has been traversed already, so backpatch this label into /* Node has been traversed already, so backpatch this label into the code */
* the code */
cCode.code.addLabelBundle (codeIdx, hllLabNum); cCode.code.addLabelBundle (codeIdx, hllLabNum);
} }
cCode.appendCode( "%sgoto L%ld;\n", indentStr(indLevel), hllLabNum); cCode.appendCode( "%sgoto L%ld;\n", indentStr(indLevel), hllLabNum);

View File

@ -237,7 +237,7 @@ void Function::bindIcodeOff()
for(ICODE &c : Icode) // TODO: use filtered here for(ICODE &c : Icode) // TODO: use filtered here
{ {
LLInst *ll=c.ll(); LLInst *ll=c.ll();
if (ll->testFlags(I) and ll->isJmpInst()) if (ll->srcIsImmed() and ll->isJmpInst())
{ {
iICODE loc=Icode.labelSrch(ll->src().getImm2()); iICODE loc=Icode.labelSrch(ll->src().getImm2());
if (loc!=Icode.end()) if (loc!=Icode.end())
@ -254,7 +254,7 @@ void Function::bindIcodeOff()
LLInst *ll=icode.ll(); LLInst *ll=icode.ll();
if (not ll->isJmpInst()) if (not ll->isJmpInst())
continue; continue;
if (ll->testFlags(I) ) if (ll->srcIsImmed())
{ {
uint32_t found; uint32_t found;
if (not Icode.labelSrch(ll->src().getImm2(), found)) if (not Icode.labelSrch(ll->src().getImm2(), found))

View File

@ -25,7 +25,7 @@ bool Idiom3::match(iICODE picode)
/* Match ADD SP, immed */ /* Match ADD SP, immed */
for(int i=0; i<2; ++i) for(int i=0; i<2; ++i)
m_icodes[i] = picode++; m_icodes[i] = picode++;
if ( m_icodes[1]->ll()->testFlags(I) and m_icodes[1]->ll()->match(iADD,rSP)) if ( m_icodes[1]->ll()->srcIsImmed() and m_icodes[1]->ll()->match(iADD,rSP))
{ {
m_param_count = m_icodes[1]->ll()->src().getImm2(); m_param_count = m_icodes[1]->ll()->src().getImm2();
return true; return true;
@ -39,7 +39,7 @@ bool Idiom3::match(iICODE picode)
} }
int Idiom3::action() int Idiom3::action()
{ {
if (m_icodes[0]->ll()->testFlags(I) ) if (m_icodes[0]->ll()->srcIsImmed())
{ {
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C); m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
} }
@ -97,7 +97,7 @@ bool Idiom17::match(iICODE picode)
} }
int Idiom17::action() int Idiom17::action()
{ {
if (m_icodes[0]->ll()->testFlags(I)) if (m_icodes[0]->ll()->srcIsImmed())
{ {
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C); m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
for(size_t idx=1; idx<m_icodes.size(); ++idx) for(size_t idx=1; idx<m_icodes.size(); ++idx)

View File

@ -48,7 +48,7 @@ bool Idiom2::match(iICODE pIcode)
iICODE nicode; iICODE nicode;
if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0 if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0
return false; return false;
if ( pIcode->ll()->testFlags(I) or (not pIcode->ll()->match(rSP,rBP)) ) if ( pIcode->ll()->srcIsImmed() or (not pIcode->ll()->match(rSP,rBP)) )
return false; return false;
if(distance(pIcode,m_end)<3) if(distance(pIcode,m_end)<3)
return false; return false;
@ -63,7 +63,7 @@ bool Idiom2::match(iICODE pIcode)
} }
if(nicode == m_end) if(nicode == m_end)
return false; return false;
//TODO: strange test here - 'I' means instruction has immediate source operand
if (nicode->ll()->match(iPOP,rBP) and not (nicode->ll()->testFlags(I | TARGET | CASE)) ) if (nicode->ll()->match(iPOP,rBP) and not (nicode->ll()->testFlags(I | TARGET | CASE)) )
{ {
m_icodes.push_back(nicode++); // Matched POP BP m_icodes.push_back(nicode++); // Matched POP BP
@ -71,7 +71,7 @@ bool Idiom2::match(iICODE pIcode)
/* Match RET(F) */ /* Match RET(F) */
if ( nicode != m_end and if ( nicode != m_end and
not (nicode->ll()->testFlags(I | TARGET | CASE)) and not (nicode->ll()->testFlags(I | TARGET | CASE)) and
(nicode->ll()->match(iRET) or nicode->ll()->match(iRETF)) nicode->ll()->matchAny({iRET,iRETF})
) )
{ {
m_icodes.push_back(nicode); // Matched RET m_icodes.push_back(nicode); // Matched RET
@ -120,7 +120,7 @@ bool Idiom4::match(iICODE pIcode)
{ {
iICODE prev1 = --iICODE(pIcode); iICODE prev1 = --iICODE(pIcode);
/* Check for POP BP */ /* Check for POP BP */
if (prev1->ll()->match(iPOP,rBP) and not prev1->ll()->testFlags(I) ) if (prev1->ll()->match(iPOP,rBP) and not prev1->ll()->srcIsImmed() )
m_icodes.push_back(prev1); m_icodes.push_back(prev1);
else if(prev1!=m_func->Icode.begin()) else if(prev1!=m_func->Icode.begin())
{ {
@ -131,7 +131,7 @@ bool Idiom4::match(iICODE pIcode)
} }
/* Check for RET(F) immed */ /* Check for RET(F) immed */
if (pIcode->ll()->testFlags(I) ) if (pIcode->ll()->srcIsImmed() )
{ {
m_param_count = (int16_t)pIcode->ll()->src().getImm2(); m_param_count = (int16_t)pIcode->ll()->src().getImm2();
return true; return true;

View File

@ -63,7 +63,7 @@ bool Idiom1::match(iICODE picode)
m_icodes.clear(); m_icodes.clear();
m_min_off = 0; m_min_off = 0;
/* PUSH BP as first instruction of procedure */ /* PUSH BP as first instruction of procedure */
if ( (not picode->ll()->testFlags(I)) and picode->ll()->src().regi == rBP) if ( (not picode->ll()->srcIsImmed()) and picode->ll()->src().regi == rBP)
{ {
m_icodes.push_back( picode++ ); // insert iPUSH m_icodes.push_back( picode++ ); // insert iPUSH
if(picode==m_end) if(picode==m_end)

View File

@ -33,10 +33,10 @@ bool Idiom14::match(iICODE pIcode)
LLInst * matched [] {m_icodes[0]->ll(),m_icodes[1]->ll()}; LLInst * matched [] {m_icodes[0]->ll(),m_icodes[1]->ll()};
/* Check for regL */ /* Check for regL */
m_regL = matched[0]->m_dst.regi; m_regL = matched[0]->m_dst.regi;
if (not matched[0]->testFlags(I) and ((m_regL == rAX) or (m_regL ==rBX))) if (not matched[0]->srcIsImmed() and ((m_regL == rAX) or (m_regL ==rBX)))
{ {
/* Check for XOR regH, regH */ /* Check for XOR regH, regH */
if (matched[1]->match(iXOR) and not matched[1]->testFlags(I)) if (matched[1]->match(iXOR) and not matched[1]->srcIsImmed())
{ {
m_regH = matched[1]->m_dst.regi; m_regH = matched[1]->m_dst.regi;
if (m_regH == matched[1]->src().getReg2()) if (m_regH == matched[1]->src().getReg2())
@ -84,7 +84,7 @@ bool Idiom13::match(iICODE pIcode)
/* Check for regL */ /* Check for regL */
regi = m_icodes[0]->ll()->m_dst.regi; regi = m_icodes[0]->ll()->m_dst.regi;
if (not m_icodes[0]->ll()->testFlags(I) and (regi >= rAL) and (regi <= rBH)) if (not m_icodes[0]->ll()->srcIsImmed() and (regi >= rAL) and (regi <= rBH))
{ {
/* Check for MOV regH, 0 */ /* Check for MOV regH, 0 */
if (m_icodes[1]->ll()->match(iMOV,I) and (m_icodes[1]->ll()->src().getImm2() == 0)) if (m_icodes[1]->ll()->match(iMOV,I) and (m_icodes[1]->ll()->src().getImm2() == 0))

View File

@ -21,7 +21,7 @@ bool Idiom8::match(iICODE pIcode)
return false; return false;
m_icodes[0]=pIcode++; m_icodes[0]=pIcode++;
m_icodes[1]=pIcode++; m_icodes[1]=pIcode++;
if (m_icodes[0]->ll()->testFlags(I) and (m_icodes[0]->ll()->src().getImm2() == 1)) if (m_icodes[0]->ll()->srcIsImmed() and (m_icodes[0]->ll()->src().getImm2() == 1))
if ( m_icodes[1]->ll()->match(iRCR,I) and if ( m_icodes[1]->ll()->match(iRCR,I) and
(m_icodes[1]->ll()->src().getImm2() == 1)) (m_icodes[1]->ll()->src().getImm2() == 1))
return true; return true;
@ -65,7 +65,7 @@ bool Idiom15::match(iICODE pIcode)
if(distance(pIcode,m_end)<2) if(distance(pIcode,m_end)<2)
return false; return false;
/* Match SHL reg, 1 */ /* Match SHL reg, 1 */
if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1)) if (not pIcode->ll()->srcIsImmed() or (pIcode->ll()->src().getImm2() != 1))
return false; return false;
m_icodes.clear(); m_icodes.clear();
regi = pIcode->ll()->m_dst.regi; regi = pIcode->ll()->m_dst.regi;
@ -110,7 +110,7 @@ bool Idiom12::match(iICODE pIcode)
return false; return false;
m_icodes[0]=pIcode++; m_icodes[0]=pIcode++;
m_icodes[1]=pIcode++; m_icodes[1]=pIcode++;
if (m_icodes[0]->ll()->testFlags(I) and (m_icodes[0]->ll()->src().getImm2() == 1)) if (m_icodes[0]->ll()->srcIsImmed() and (m_icodes[0]->ll()->src().getImm2() == 1))
if (m_icodes[1]->ll()->match(iRCL,I) and (m_icodes[1]->ll()->src().getImm2() == 1)) if (m_icodes[1]->ll()->match(iRCL,I) and (m_icodes[1]->ll()->src().getImm2() == 1))
return true; return true;
return false; return false;
@ -150,7 +150,7 @@ bool Idiom9::match(iICODE pIcode)
return false; return false;
m_icodes[0]=pIcode++; m_icodes[0]=pIcode++;
m_icodes[1]=pIcode++; m_icodes[1]=pIcode++;
if (m_icodes[0]->ll()->testFlags(I) and (m_icodes[0]->ll()->src().getImm2() == 1)) if (m_icodes[0]->ll()->srcIsImmed() and (m_icodes[0]->ll()->src().getImm2() == 1))
if (m_icodes[1]->ll()->match(iRCR,I) and (m_icodes[1]->ll()->src().getImm2() == 1)) if (m_icodes[1]->ll()->match(iRCR,I) and (m_icodes[1]->ll()->src().getImm2() == 1))
return true; return true;
return false; return false;

View File

@ -26,7 +26,7 @@ bool Idiom21::match (iICODE picode)
m_icodes[0]=picode++; m_icodes[0]=picode++;
m_icodes[1]=picode++; m_icodes[1]=picode++;
if (not m_icodes[1]->ll()->testFlags(I)) if (not m_icodes[1]->ll()->srcIsImmed())
return false; return false;
dst = &m_icodes[0]->ll()->m_dst; dst = &m_icodes[0]->ll()->m_dst;
@ -87,8 +87,8 @@ bool Idiom7::match(iICODE picode)
} }
int Idiom7::action() int Idiom7::action()
{ {
Expr *lhs; Expr *lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2)); m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
m_icode->du.use.reset(); /* clear register used in iXOR */ m_icode->du.use.reset(); /* clear register used in iXOR */
m_icode->ll()->setFlags(I); m_icode->ll()->setFlags(I);
@ -117,7 +117,7 @@ bool Idiom10::match(iICODE pIcode)
m_icodes[0]=pIcode++; m_icodes[0]=pIcode++;
m_icodes[1]=pIcode++; m_icodes[1]=pIcode++;
/* Check OR reg, reg */ /* Check OR reg, reg */
if (not m_icodes[0]->ll()->testFlags(I) and if (not m_icodes[0]->ll()->srcIsImmed() and
m_icodes[0]->ll()->src().isReg() and m_icodes[0]->ll()->src().isReg() and
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2())) (m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump() if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()

View File

@ -33,6 +33,7 @@ using namespace std;
static void setBits(int16_t type, uint32_t start, uint32_t len); static void setBits(int16_t type, uint32_t start, uint32_t len);
static void process_MOV(LLInst &ll, STATE * pstate); static void process_MOV(LLInst &ll, STATE * pstate);
static bool process_JMP(const PtrFunction &func,ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph); static bool process_JMP(const PtrFunction &func,ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph);
static bool process_CALL(const PtrFunction &func,ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *pstate);
static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag); static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag);
//void interactDis(Function * initProc, int ic); //void interactDis(Function * initProc, int ic);
@ -257,7 +258,7 @@ void FollowCtrl(Function &func,CALL_GRAPH * pcallGraph, STATE *pstate)
/* This sets up range check for indexed JMPs hopefully /* This sets up range check for indexed JMPs hopefully
* Handles JA/JAE for fall through and JB/JBE on branch * Handles JA/JAE for fall through and JB/JBE on branch
*/ */
if (ip > 0 and prev.ll()->getOpcode() == iCMP and (prev.ll()->testFlags(I))) if (ip > 0 and prev.ll()->match(iCMP,I) )
{ {
pstate->JCond.immed = (int16_t)prev.ll()->src().getImm2(); pstate->JCond.immed = (int16_t)prev.ll()->src().getImm2();
if (ll->match(iJA) or ll->match(iJBE) ) if (ll->match(iJA) or ll->match(iJBE) )
@ -290,7 +291,7 @@ void FollowCtrl(Function &func,CALL_GRAPH * pcallGraph, STATE *pstate)
/*** Calls ***/ /*** Calls ***/
case iCALL: case iCALL:
case iCALLF: case iCALLF:
done = func.process_CALL (*pIcode, pcallGraph, pstate); done = process_CALL(func.shared_from_this(),*pIcode, pcallGraph, pstate);
pstate->kill(rBX); pstate->kill(rBX);
pstate->kill(rCX); pstate->kill(rCX);
break; break;
@ -319,7 +320,7 @@ void FollowCtrl(Function &func,CALL_GRAPH * pcallGraph, STATE *pstate)
case iSHL: case iSHL:
if (pstate->JCond.regi == ll->m_dst.regi) if (pstate->JCond.regi == ll->m_dst.regi)
{ {
if ((ll->testFlags(I)) and ll->src().getImm2() == 1) if (ll->srcIsImmed() and ll->src().getImm2() == 1)
pstate->JCond.immed *= 2; pstate->JCond.immed *= 2;
else else
pstate->JCond.regi = 0; pstate->JCond.regi = 0;
@ -375,33 +376,6 @@ void Function::extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &ta
table.finish = table.start + 2; 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();
Project::get()->addCommand(shared_from_this(),new FollowControlFlow(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;
}
static bool decodeIndirectJMP(const PtrFunction &func,ICODE & pIcode, STATE *pstate) static bool decodeIndirectJMP(const PtrFunction &func,ICODE & pIcode, STATE *pstate)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
@ -651,11 +625,12 @@ static bool decodeIndirectJMP0(const PtrFunction &func,ICODE & pIcode, STATE *ps
} }
return false; return false;
} }
/* process_JMP - Handles JMPs, returns true if we should end recursion */
static bool process_JMP(const PtrFunction &func,ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) static bool process_JMP(const PtrFunction &func,ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
if (pIcode.ll()->testFlags(I)) if (pIcode.ll()->srcIsImmed())
{ {
if (pIcode.ll()->getOpcode() == iJMPF) if (pIcode.ll()->getOpcode() == iJMPF)
pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
@ -699,17 +674,16 @@ static bool process_JMP(const PtrFunction &func,ICODE & pIcode, STATE *pstate, C
* programmer expected it to come back - otherwise surely a JMP would * programmer expected it to come back - otherwise surely a JMP would
* have been used. */ * have been used. */
bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *pstate) bool process_CALL(const PtrFunction &func,ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *pstate)
{ {
Project &project(*Project::get()); Project &project(*Project::get());
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
ICODE &last_insn(Icode.back()); ICODE &last_insn(func->Icode.back());
STATE localState; /* Local copy of the machine state */
uint32_t off; uint32_t off;
/* For Indirect Calls, find the function address */ /* For Indirect Calls, find the function address */
bool indirect = false; bool indirect = false;
//pIcode.ll()->immed.proc.proc=fakeproc; //pIcode.ll()->immed.proc.proc=fakeproc;
if ( not pIcode.ll()->testFlags(I) ) if ( not pIcode.ll()->srcIsImmed() )
{ {
/* Not immediate, i.e. indirect call */ /* Not immediate, i.e. indirect call */
@ -754,14 +728,14 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
if (pIcode.ll()->getOpcode() == iCALLF) if (pIcode.ll()->getOpcode() == iCALLF)
tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(LH(&prog.image()[off+2])) << 4); tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(LH(&prog.image()[off+2])) << 4);
else else
tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(uint16_t)state.r[rCS] << 4); tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(uint16_t)pstate->r[rCS] << 4);
pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) ); pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) );
pIcode.ll()->setFlags(I); pIcode.ll()->setFlags(I);
indirect = true; indirect = true;
} }
/* Process CALL. Function address is located in pIcode.ll()->immed.op */ /* Process CALL. Function address is located in pIcode.ll()->immed.op */
if (pIcode.ll()->testFlags(I)) if (pIcode.ll()->srcIsImmed())
{ {
/* Search procedure list for one with appropriate entry point */ /* Search procedure list for one with appropriate entry point */
PtrFunction iter = Project::get()->findByEntry(pIcode.ll()->src().getImm2()); PtrFunction iter = Project::get()->findByEntry(pIcode.ll()->src().getImm2());
@ -777,7 +751,7 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
if (x.flg & PROC_ISLIB) if (x.flg & PROC_ISLIB)
{ {
/* A library function. No need to do any more to it */ /* A library function. No need to do any more to it */
pcallGraph->insertCallGraph (this->shared_from_this(), iter); pcallGraph->insertCallGraph (func, iter);
//iter = (++pProcList.rbegin()).base(); //iter = (++pProcList.rbegin()).base();
last_insn.ll()->src().proc.proc = &x; last_insn.ll()->src().proc.proc = &x;
return false; return false;
@ -793,29 +767,21 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
x.depth = x.depth + 1; x.depth = x.depth + 1;
x.flg |= TERMINATES; x.flg |= TERMINATES;
/* Save machine state in localState, load up IP and CS.*/
localState = *pstate;
pstate->IP = pIcode.ll()->src().getImm2(); pstate->IP = pIcode.ll()->src().getImm2();
if (pIcode.ll()->getOpcode() == iCALLF) if (pIcode.ll()->getOpcode() == iCALLF)
pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
x.state = *pstate; x.state = *pstate;
/* Insert new procedure in call graph */ /* Insert new procedure in call graph */
pcallGraph->insertCallGraph (this->shared_from_this(), iter); pcallGraph->insertCallGraph (func, iter);
/* Process new procedure */ /* Process new procedure */
Project::get()->addCommand(iter,new FollowControlFlow(*pstate)); Project::get()->addCommand(iter,new FollowControlFlow(*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 else
Project::get()->callGraph->insertCallGraph (this->shared_from_this(), iter); Project::get()->callGraph->insertCallGraph (func, iter);
last_insn.ll()->src().proc.proc = &(*iter); // ^ target proc last_insn.ll()->src().proc.proc = &(*iter); // ^ target proc
@ -834,7 +800,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
uint8_t srcReg = ll.src().regi; uint8_t srcReg = ll.src().regi;
if (dstReg > 0 and dstReg < INDEX_BX_SI) if (dstReg > 0 and dstReg < INDEX_BX_SI)
{ {
if (ll.testFlags(I)) if (ll.srcIsImmed())
pstate->setState( dstReg, (int16_t)ll.src().getImm2()); pstate->setState( dstReg, (int16_t)ll.src().getImm2());
else if (srcReg == 0) /* direct memory offset */ else if (srcReg == 0) /* direct memory offset */
{ {
@ -1096,7 +1062,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
} }
/* Use of register */ /* Use of register */
else if ((d == DST) or ((d == SRC) and (not pIcode.ll()->testFlags(I)))) else if ((d == DST) or ((d == SRC) and (not pIcode.ll()->srcIsImmed())))
pIcode.du.use.addReg(pm->regi); pIcode.du.use.addReg(pm->regi);
} }
@ -1145,7 +1111,7 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
} }
} }
/* Definition of register */ /* Definition of register */
else if ((d == DST) or ((d == SRC) and (not pIcode.ll()->testFlags(I)))) else if ((d == DST) or ((d == SRC) and (not pIcode.ll()->srcIsImmed())))
{ {
assert(not pIcode.ll()->match(iPUSH)); assert(not pIcode.ll()->match(iPUSH));
pIcode.du1.addDef(pm->regi); pIcode.du1.addDef(pm->regi);
@ -1182,7 +1148,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
int sseg = (ll_ins.src().seg)? ll_ins.src().seg: rDS; int sseg = (ll_ins.src().seg)? ll_ins.src().seg: rDS;
int cb = pIcode.ll()->testFlags(B) ? 1: 2; int cb = pIcode.ll()->testFlags(B) ? 1: 2;
//x86_op_t *im= pIcode.insn.x86_get_imm(); //x86_op_t *im= pIcode.insn.x86_get_imm();
bool Imm = (pIcode.ll()->testFlags(I)); bool Imm = (pIcode.ll()->srcIsImmed());
switch (pIcode.ll()->getOpcode()) { switch (pIcode.ll()->getOpcode()) {
case iAND: case iOR: case iXOR: case iAND: case iOR: case iXOR:

View File

@ -1068,7 +1068,7 @@ static void none1(int )
****************************************************************************/ ****************************************************************************/
static void none2(int ) static void none2(int )
{ {
if ( pIcode->ll()->testFlags(I) ) if ( pIcode->ll()->srcIsImmed() )
pIcode->ll()->setFlags(NO_OPS); pIcode->ll()->setFlags(NO_OPS);
} }