WIP - do not use.
This commit is contained in:
parent
bc654cbf76
commit
14ceb301c1
@ -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;
|
||||||
|
|||||||
216
include/icode.h
216
include/icode.h
@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
546
src/disassem.cpp
546
src/disassem.cpp
@ -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");
|
||||||
|
|||||||
@ -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());
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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))
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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))
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user