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
|
||||
|
||||
};
|
||||
|
||||
class Function : public std::enable_shared_from_this<Function>
|
||||
{
|
||||
typedef llvm::iplist<BB> BasicBlockListType;
|
||||
@ -232,7 +233,6 @@ public:
|
||||
void markImpure();
|
||||
void findImmedDom();
|
||||
void process_operands(ICODE &pIcode, STATE *pstate);
|
||||
bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||
void freeCFG();
|
||||
void codeGen(QIODevice & fs);
|
||||
void mergeFallThrough(BB *pBB);
|
||||
@ -256,7 +256,6 @@ public:
|
||||
void switchState(DecompilationStep s);
|
||||
protected:
|
||||
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 Case_X_and_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();
|
||||
bool findDerivedSeq(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;
|
||||
|
||||
@ -309,7 +309,7 @@ struct LLOperand
|
||||
Op.regi = (eReg)Val;
|
||||
return Op;
|
||||
}
|
||||
bool isSet()
|
||||
bool isSet() const
|
||||
{
|
||||
return not (*this == LLOperand());
|
||||
}
|
||||
@ -351,11 +351,11 @@ public:
|
||||
}
|
||||
bool matchWithRegDst(llIcode op)
|
||||
{
|
||||
return (getOpcode()==op) and m_dst.isReg();
|
||||
return match(op) and m_dst.isReg();
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -369,6 +369,13 @@ public:
|
||||
{
|
||||
return match(dest) and (m_src.regi==src_reg);
|
||||
}
|
||||
bool matchAny(std::initializer_list<llIcode> ops) {
|
||||
for(llIcode op : ops) {
|
||||
if(match(op))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool match(eReg dest)
|
||||
{
|
||||
return (m_dst.regi==dest);
|
||||
@ -399,7 +406,6 @@ public:
|
||||
void findJumpTargets(CIcodeRec &_pc);
|
||||
void writeIntComment(QTextStream & s);
|
||||
void dis1Line(int loc_ip, int pass);
|
||||
QTextStream & strSrc(QTextStream & os, bool skip_comma=false);
|
||||
|
||||
void flops(QTextStream & out);
|
||||
bool isJmpInst();
|
||||
@ -408,18 +414,30 @@ public:
|
||||
{
|
||||
setOpcode(0);
|
||||
}
|
||||
const LLOperand & dst() const { return m_dst; }
|
||||
LLOperand & dst() { return m_dst; }
|
||||
const LLOperand & src() const { return m_src; }
|
||||
LLOperand & src() { return m_src; }
|
||||
void replaceSrc(const LLOperand &with) { m_src = with; }
|
||||
void replaceSrc(eReg r) { m_src = LLOperand::CreateReg2(r); }
|
||||
void replaceSrc(int64_t r) { m_src = LLOperand::CreateImm2(r); }
|
||||
void replaceDst(const LLOperand &with) { m_dst = with; }
|
||||
bool srcIsImmed() const { return (flg & I)!=0; }
|
||||
condId idType(opLoc sd) const;
|
||||
const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &m_dst; }
|
||||
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &m_dst; }
|
||||
|
||||
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 */
|
||||
struct ICODE
|
||||
@ -427,7 +445,7 @@ struct ICODE
|
||||
// use llvm names at least
|
||||
typedef BB MachineBasicBlock;
|
||||
protected:
|
||||
LLInst m_ll;
|
||||
LLInst *m_ll;
|
||||
HLTYPE m_hl;
|
||||
MachineBasicBlock * Parent; /* BB to which this icode belongs */
|
||||
bool invalid; /* Has no HIGH_LEVEL equivalent */
|
||||
@ -530,8 +548,8 @@ public:
|
||||
DU1 du1; /* du chain 1 */
|
||||
int loc_ip; // used by CICodeRec to number ICODEs
|
||||
|
||||
LLInst * ll() { return &m_ll;}
|
||||
const LLInst * ll() const { return &m_ll;}
|
||||
LLInst * ll() { return m_ll;}
|
||||
const LLInst * ll() const { return m_ll;}
|
||||
|
||||
HLTYPE * hlU() {
|
||||
// assert(type==HIGH_LEVEL);
|
||||
@ -571,8 +589,46 @@ public:
|
||||
{
|
||||
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:
|
||||
const MachineBasicBlock* getParent() const { return Parent; }
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
class QTextStream;
|
||||
|
||||
@ -222,7 +222,7 @@ AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f,
|
||||
{
|
||||
AstIdent *newExp;
|
||||
/* Check for long constant and save it as a constant expression */
|
||||
if ((sd == SRC) and pIcode->ll()->testFlags(I)) /* constant */
|
||||
if ((sd == SRC) and pIcode->ll()->srcIsImmed()) /* constant */
|
||||
{
|
||||
int value;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
else if (pm.regi == rUNDEF) /* global variable */
|
||||
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);
|
||||
|
||||
if ((sd == SRC) and testFlags(I))
|
||||
if ((sd == SRC) and srcIsImmed())
|
||||
return (CONSTANT);
|
||||
else if (pm.regi == 0)
|
||||
return (GLOB_VAR);
|
||||
|
||||
512
src/disassem.cpp
512
src/disassem.cpp
@ -113,7 +113,7 @@ static vector<POSSTACK_ENTRY> posStack; /* position stack */
|
||||
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
PROG &prog(Project::get()->prog);
|
||||
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";
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
@ -630,19 +273,19 @@ static QTextStream & strDst(QTextStream &os,uint32_t flg, const LLOperand &pm)
|
||||
/****************************************************************************
|
||||
* strSrc *
|
||||
****************************************************************************/
|
||||
QTextStream &LLInst::strSrc(QTextStream &os,bool skip_comma)
|
||||
{
|
||||
if(false==skip_comma)
|
||||
os<<", ";
|
||||
if (testFlags(I))
|
||||
os<<strHex(src().getImm2());
|
||||
else if (testFlags(IM_SRC)) /* level 2 */
|
||||
os<<"dx:ax";
|
||||
else
|
||||
formatRM(os, src());
|
||||
//QTextStream &LLInst::strSrc(QTextStream &os,bool skip_comma)
|
||||
//{
|
||||
// if(false==skip_comma)
|
||||
// os<<", ";
|
||||
// if (srcIsImmed())
|
||||
// os<<strHex(src().getImm2());
|
||||
// else if (testFlags(IM_SRC)) /* level 2 */
|
||||
// os<<"dx:ax";
|
||||
// else
|
||||
// formatRM(os, src());
|
||||
|
||||
return os;
|
||||
}
|
||||
// return os;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
@ -769,62 +412,55 @@ void LLInst::flops(QTextStream &out)
|
||||
}
|
||||
}
|
||||
}
|
||||
/****************************************************************************
|
||||
* formatRM
|
||||
***************************************************************************/
|
||||
static void formatRM(IStructuredTextTarget *out,const LLOperand &pm)
|
||||
{
|
||||
struct AsmFormatter {
|
||||
IStructuredTextTarget * target;
|
||||
int operand_count;
|
||||
void visitOperand(const LLOperand &pm) {
|
||||
if(not pm.isSet())
|
||||
return;
|
||||
if(operand_count>0) {
|
||||
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.segOver)
|
||||
{
|
||||
out->prtt(Machine_X86::regName(pm.segOver)+':');
|
||||
target->prtt(Machine_X86::regName(pm.segOver)+':');
|
||||
}
|
||||
|
||||
if (pm.regi == rUNDEF)
|
||||
{
|
||||
out->prtt(QString("[")+strHex((uint32_t)pm.off)+"]");
|
||||
target->prtt(QString("[")+strHex((uint32_t)pm.off)+"]");
|
||||
}
|
||||
else if (pm.isReg())
|
||||
{
|
||||
out->prtt(Machine_X86::regName(pm.regi));
|
||||
target->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.regi)+"-"+strHex((uint32_t)(- pm.off))+"]");
|
||||
}
|
||||
else
|
||||
{
|
||||
out->prtt("["+Machine_X86::regName(pm.regi)+"+"+strHex((uint32_t)(pm.off))+"]");
|
||||
target->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]);
|
||||
target->prtt("["+Machine_X86::regName(pm.regi)+"]");
|
||||
|
||||
}
|
||||
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) {
|
||||
|
||||
AsmFormatter formatter {out};
|
||||
const LLInst &inst(*insn);
|
||||
QString opcode = Machine_X86::opcodeName(insn->getOpcode());
|
||||
out->addSpace(4);
|
||||
@ -837,50 +473,32 @@ void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
|
||||
switch(insn->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(out,insn->getFlag(), insn->m_dst);
|
||||
strSrc(out,insn);
|
||||
break;
|
||||
|
||||
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
|
||||
case iROR:
|
||||
strDst(out,insn->getFlag() | I, insn->m_dst);
|
||||
if(insn->testFlags(I))
|
||||
strSrc(out,insn);
|
||||
else {
|
||||
out->prtt(", ");
|
||||
out->addTaggedString(XT_Symbol,"cl");
|
||||
}
|
||||
formatter.visitOperand(insn->dst());
|
||||
formatter.visitOperand(insn->src());
|
||||
break;
|
||||
|
||||
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
||||
strDst(out,insn->getFlag() | I, insn->m_dst);
|
||||
formatter.visitOperand(insn->dst());
|
||||
break;
|
||||
case iPUSH:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
out->addTaggedString(XT_Number,strHex(inst.src().getImm2()));
|
||||
}
|
||||
else
|
||||
{
|
||||
strDst(out,insn->getFlag() | I, insn->m_dst);
|
||||
}
|
||||
formatter.visitOperand(insn->dst());
|
||||
break;
|
||||
|
||||
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
||||
if (inst.testFlags(I))
|
||||
if (inst.srcIsImmed())
|
||||
{
|
||||
strDst(out,insn->getFlag(), insn->m_dst);
|
||||
out->prtt(", ");
|
||||
formatRM(out, inst.src());
|
||||
strSrc(out,insn);
|
||||
formatter.visitOperand(insn->dst());
|
||||
formatter.visitOperand(insn->src());
|
||||
}
|
||||
else
|
||||
strDst(out,insn->getFlag() | I, insn->m_dst);
|
||||
formatter.visitOperand(insn->dst());
|
||||
break;
|
||||
case iLDS: case iLES: case iBOUND:
|
||||
strDst(out,inst.getFlag(), inst.m_dst);
|
||||
out->prtt(", ");
|
||||
out->addTaggedString(XT_Keyword,"dword ptr");
|
||||
strSrc(out,insn,true);
|
||||
formatter.visitOperand(insn->dst());
|
||||
formatter.visitOperand(insn->src());
|
||||
break;
|
||||
case iJB: case iJBE: case iJAE: case iJA:
|
||||
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));
|
||||
out->addTaggedString(XT_AsmLabel,strHex(inst.src().getImm2()));
|
||||
}
|
||||
else if (inst.testFlags(I) )
|
||||
else if (inst.srcIsImmed() )
|
||||
{
|
||||
int64_t tgt_addr = inst.src().getImm2();
|
||||
if (inst.getOpcode() == iJMPF)
|
||||
@ -916,16 +534,16 @@ void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
|
||||
else if (inst.getOpcode() == iJMPF)
|
||||
{
|
||||
out->addTaggedString(XT_Keyword,"dword ptr");
|
||||
strSrc(out,insn,true);
|
||||
formatter.visitOperand(inst.src());
|
||||
}
|
||||
else
|
||||
{
|
||||
strDst(out,I,inst.src());
|
||||
formatter.visitOperand(inst.src());
|
||||
}
|
||||
|
||||
break;
|
||||
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_AsmLabel,(inst.src().proc.proc)->name);
|
||||
@ -933,25 +551,21 @@ void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
|
||||
else if (inst.getOpcode() == iCALLF)
|
||||
{
|
||||
out->addTaggedString(XT_Keyword,"dword ptr ");
|
||||
strSrc(out,insn,true);
|
||||
formatter.visitOperand(inst.src());
|
||||
}
|
||||
else
|
||||
strDst(out,I,inst.src());
|
||||
formatter.visitOperand(inst.src());
|
||||
break;
|
||||
|
||||
case iENTER:
|
||||
out->addTaggedString(XT_AsmOffset,strHex(inst.m_dst.off));
|
||||
out->prtt(", ");
|
||||
out->addTaggedString(XT_AsmOffset,strHex(inst.src().getImm2()));
|
||||
formatter.visitOperand(inst.dst());
|
||||
formatter.visitOperand(inst.src());
|
||||
break;
|
||||
|
||||
case iRET:
|
||||
case iRETF:
|
||||
case iINT:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
out->addTaggedString(XT_Number,strHex(inst.src().getImm2()));
|
||||
}
|
||||
formatter.visitOperand(inst.src());
|
||||
break;
|
||||
|
||||
case iCMPS: case iREPNE_CMPS: case iREPE_CMPS:
|
||||
@ -1009,15 +623,13 @@ void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
|
||||
case iIN:
|
||||
out->addTaggedString(XT_Symbol, (inst.getFlag() & B)? "al" : "ax");
|
||||
out->prtt(", ");
|
||||
if(inst.testFlags(I))
|
||||
out->addTaggedString(XT_Number, strHex(inst.src().getImm2()));
|
||||
else
|
||||
out->addTaggedString(XT_Symbol, "dx");
|
||||
formatter.visitOperand(inst.src());
|
||||
break;
|
||||
|
||||
case iOUT:
|
||||
{
|
||||
if(inst.testFlags(I))
|
||||
formatter.visitOperand(inst.src());
|
||||
if(inst.srcIsImmed())
|
||||
out->addTaggedString(XT_Number, strHex(inst.src().getImm2()));
|
||||
else
|
||||
out->addTaggedString(XT_Symbol, "dx");
|
||||
|
||||
@ -93,7 +93,7 @@ void Function::createCFG()
|
||||
pBB->addOutEdge(elem);
|
||||
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->addOutEdge(ll->src().getImm2());
|
||||
|
||||
@ -332,7 +332,7 @@ void Function::highLevelGen()
|
||||
lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
|
||||
}
|
||||
if(ll->getOpcode()==iPUSH) {
|
||||
if(ll->testFlags(I)) {
|
||||
if(ll->srcIsImmed()) {
|
||||
lhs = new Constant(src_ll->opz,src_ll->byteWidth());
|
||||
}
|
||||
// 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.
|
||||
* If there is need to allocate extra memory, it is done so, and
|
||||
* the alloc variable is adjusted. */
|
||||
ICODE * CIcodeRec::addIcode(ICODE *pIcode)
|
||||
/* Copies the icode that is pointed to by pIcode to the icode array. */
|
||||
ICODE * CIcodeRec::addIcode(const ICODE *pIcode)
|
||||
{
|
||||
push_back(*pIcode);
|
||||
back().loc_ip = size()-1;
|
||||
@ -84,8 +82,7 @@ void LLInst::emitGotoLabel (int indLevel)
|
||||
hllLabNum = getNextLabel();
|
||||
setFlags(HLL_LABEL);
|
||||
|
||||
/* Node has been traversed already, so backpatch this label into
|
||||
* the code */
|
||||
/* Node has been traversed already, so backpatch this label into the code */
|
||||
cCode.code.addLabelBundle (codeIdx, 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
|
||||
{
|
||||
LLInst *ll=c.ll();
|
||||
if (ll->testFlags(I) and ll->isJmpInst())
|
||||
if (ll->srcIsImmed() and ll->isJmpInst())
|
||||
{
|
||||
iICODE loc=Icode.labelSrch(ll->src().getImm2());
|
||||
if (loc!=Icode.end())
|
||||
@ -254,7 +254,7 @@ void Function::bindIcodeOff()
|
||||
LLInst *ll=icode.ll();
|
||||
if (not ll->isJmpInst())
|
||||
continue;
|
||||
if (ll->testFlags(I) )
|
||||
if (ll->srcIsImmed())
|
||||
{
|
||||
uint32_t found;
|
||||
if (not Icode.labelSrch(ll->src().getImm2(), found))
|
||||
|
||||
@ -25,7 +25,7 @@ bool Idiom3::match(iICODE picode)
|
||||
/* Match ADD SP, immed */
|
||||
for(int i=0; i<2; ++i)
|
||||
m_icodes[i] = picode++;
|
||||
if ( m_icodes[1]->ll()->testFlags(I) 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();
|
||||
return true;
|
||||
@ -39,7 +39,7 @@ bool Idiom3::match(iICODE picode)
|
||||
}
|
||||
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);
|
||||
}
|
||||
@ -97,7 +97,7 @@ bool Idiom17::match(iICODE picode)
|
||||
}
|
||||
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);
|
||||
for(size_t idx=1; idx<m_icodes.size(); ++idx)
|
||||
|
||||
@ -48,7 +48,7 @@ bool Idiom2::match(iICODE pIcode)
|
||||
iICODE nicode;
|
||||
if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0
|
||||
return false;
|
||||
if ( pIcode->ll()->testFlags(I) or (not pIcode->ll()->match(rSP,rBP)) )
|
||||
if ( pIcode->ll()->srcIsImmed() or (not pIcode->ll()->match(rSP,rBP)) )
|
||||
return false;
|
||||
if(distance(pIcode,m_end)<3)
|
||||
return false;
|
||||
@ -63,7 +63,7 @@ bool Idiom2::match(iICODE pIcode)
|
||||
}
|
||||
if(nicode == m_end)
|
||||
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)) )
|
||||
{
|
||||
m_icodes.push_back(nicode++); // Matched POP BP
|
||||
@ -71,7 +71,7 @@ bool Idiom2::match(iICODE pIcode)
|
||||
/* Match RET(F) */
|
||||
if ( nicode != m_end 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
|
||||
@ -120,7 +120,7 @@ bool Idiom4::match(iICODE pIcode)
|
||||
{
|
||||
iICODE prev1 = --iICODE(pIcode);
|
||||
/* 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);
|
||||
else if(prev1!=m_func->Icode.begin())
|
||||
{
|
||||
@ -131,7 +131,7 @@ bool Idiom4::match(iICODE pIcode)
|
||||
}
|
||||
|
||||
/* Check for RET(F) immed */
|
||||
if (pIcode->ll()->testFlags(I) )
|
||||
if (pIcode->ll()->srcIsImmed() )
|
||||
{
|
||||
m_param_count = (int16_t)pIcode->ll()->src().getImm2();
|
||||
return true;
|
||||
|
||||
@ -63,7 +63,7 @@ bool Idiom1::match(iICODE picode)
|
||||
m_icodes.clear();
|
||||
m_min_off = 0;
|
||||
/* PUSH BP as first instruction of procedure */
|
||||
if ( (not picode->ll()->testFlags(I)) and picode->ll()->src().regi == rBP)
|
||||
if ( (not picode->ll()->srcIsImmed()) and picode->ll()->src().regi == rBP)
|
||||
{
|
||||
m_icodes.push_back( picode++ ); // insert iPUSH
|
||||
if(picode==m_end)
|
||||
|
||||
@ -33,10 +33,10 @@ bool Idiom14::match(iICODE pIcode)
|
||||
LLInst * matched [] {m_icodes[0]->ll(),m_icodes[1]->ll()};
|
||||
/* Check for regL */
|
||||
m_regL = matched[0]->m_dst.regi;
|
||||
if (not matched[0]->testFlags(I) 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 */
|
||||
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;
|
||||
if (m_regH == matched[1]->src().getReg2())
|
||||
@ -84,7 +84,7 @@ bool Idiom13::match(iICODE pIcode)
|
||||
|
||||
/* Check for regL */
|
||||
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 */
|
||||
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;
|
||||
m_icodes[0]=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))
|
||||
return true;
|
||||
@ -65,7 +65,7 @@ bool Idiom15::match(iICODE pIcode)
|
||||
if(distance(pIcode,m_end)<2)
|
||||
return false;
|
||||
/* 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;
|
||||
m_icodes.clear();
|
||||
regi = pIcode->ll()->m_dst.regi;
|
||||
@ -110,7 +110,7 @@ bool Idiom12::match(iICODE pIcode)
|
||||
return false;
|
||||
m_icodes[0]=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))
|
||||
return true;
|
||||
return false;
|
||||
@ -150,7 +150,7 @@ bool Idiom9::match(iICODE pIcode)
|
||||
return false;
|
||||
m_icodes[0]=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))
|
||||
return true;
|
||||
return false;
|
||||
|
||||
@ -26,7 +26,7 @@ bool Idiom21::match (iICODE picode)
|
||||
m_icodes[0]=picode++;
|
||||
m_icodes[1]=picode++;
|
||||
|
||||
if (not m_icodes[1]->ll()->testFlags(I))
|
||||
if (not m_icodes[1]->ll()->srcIsImmed())
|
||||
return false;
|
||||
|
||||
dst = &m_icodes[0]->ll()->m_dst;
|
||||
@ -87,8 +87,8 @@ bool Idiom7::match(iICODE picode)
|
||||
}
|
||||
int Idiom7::action()
|
||||
{
|
||||
Expr *lhs;
|
||||
lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
|
||||
Expr *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->du.use.reset(); /* clear register used in iXOR */
|
||||
m_icode->ll()->setFlags(I);
|
||||
@ -117,7 +117,7 @@ bool Idiom10::match(iICODE pIcode)
|
||||
m_icodes[0]=pIcode++;
|
||||
m_icodes[1]=pIcode++;
|
||||
/* Check OR reg, reg */
|
||||
if (not m_icodes[0]->ll()->testFlags(I) and
|
||||
if (not m_icodes[0]->ll()->srcIsImmed() and
|
||||
m_icodes[0]->ll()->src().isReg() and
|
||||
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
|
||||
if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
|
||||
|
||||
@ -33,6 +33,7 @@ using namespace std;
|
||||
static void setBits(int16_t type, uint32_t start, uint32_t len);
|
||||
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_CALL(const PtrFunction &func,ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *pstate);
|
||||
static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag);
|
||||
//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
|
||||
* 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();
|
||||
if (ll->match(iJA) or ll->match(iJBE) )
|
||||
@ -290,7 +291,7 @@ void FollowCtrl(Function &func,CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
/*** Calls ***/
|
||||
case iCALL:
|
||||
case iCALLF:
|
||||
done = func.process_CALL (*pIcode, pcallGraph, pstate);
|
||||
done = process_CALL(func.shared_from_this(),*pIcode, pcallGraph, pstate);
|
||||
pstate->kill(rBX);
|
||||
pstate->kill(rCX);
|
||||
break;
|
||||
@ -319,7 +320,7 @@ void FollowCtrl(Function &func,CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
case iSHL:
|
||||
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;
|
||||
else
|
||||
pstate->JCond.regi = 0;
|
||||
@ -375,33 +376,6 @@ void Function::extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &ta
|
||||
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)
|
||||
{
|
||||
PROG &prog(Project::get()->prog);
|
||||
@ -651,11 +625,12 @@ static bool decodeIndirectJMP0(const PtrFunction &func,ICODE & pIcode, STATE *ps
|
||||
}
|
||||
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)
|
||||
{
|
||||
PROG &prog(Project::get()->prog);
|
||||
|
||||
if (pIcode.ll()->testFlags(I))
|
||||
if (pIcode.ll()->srcIsImmed())
|
||||
{
|
||||
if (pIcode.ll()->getOpcode() == iJMPF)
|
||||
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
|
||||
* 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());
|
||||
PROG &prog(Project::get()->prog);
|
||||
ICODE &last_insn(Icode.back());
|
||||
STATE localState; /* Local copy of the machine state */
|
||||
ICODE &last_insn(func->Icode.back());
|
||||
uint32_t off;
|
||||
/* For Indirect Calls, find the function address */
|
||||
bool indirect = false;
|
||||
//pIcode.ll()->immed.proc.proc=fakeproc;
|
||||
if ( not pIcode.ll()->testFlags(I) )
|
||||
if ( not pIcode.ll()->srcIsImmed() )
|
||||
{
|
||||
/* 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)
|
||||
tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(LH(&prog.image()[off+2])) << 4);
|
||||
else
|
||||
tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(uint16_t)state.r[rCS] << 4);
|
||||
tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(uint16_t)pstate->r[rCS] << 4);
|
||||
pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) );
|
||||
pIcode.ll()->setFlags(I);
|
||||
indirect = true;
|
||||
}
|
||||
|
||||
/* Process CALL. Function address is located in pIcode.ll()->immed.op */
|
||||
if (pIcode.ll()->testFlags(I))
|
||||
if (pIcode.ll()->srcIsImmed())
|
||||
{
|
||||
/* Search procedure list for one with appropriate entry point */
|
||||
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)
|
||||
{
|
||||
/* 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();
|
||||
last_insn.ll()->src().proc.proc = &x;
|
||||
return false;
|
||||
@ -793,29 +767,21 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
|
||||
x.depth = x.depth + 1;
|
||||
x.flg |= TERMINATES;
|
||||
|
||||
/* Save machine state in localState, load up IP and CS.*/
|
||||
localState = *pstate;
|
||||
pstate->IP = pIcode.ll()->src().getImm2();
|
||||
if (pIcode.ll()->getOpcode() == iCALLF)
|
||||
pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
|
||||
x.state = *pstate;
|
||||
|
||||
/* Insert new procedure in call graph */
|
||||
pcallGraph->insertCallGraph (this->shared_from_this(), iter);
|
||||
pcallGraph->insertCallGraph (func, iter);
|
||||
|
||||
/* Process new procedure */
|
||||
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
|
||||
Project::get()->callGraph->insertCallGraph (this->shared_from_this(), iter);
|
||||
Project::get()->callGraph->insertCallGraph (func, iter);
|
||||
|
||||
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;
|
||||
if (dstReg > 0 and dstReg < INDEX_BX_SI)
|
||||
{
|
||||
if (ll.testFlags(I))
|
||||
if (ll.srcIsImmed())
|
||||
pstate->setState( dstReg, (int16_t)ll.src().getImm2());
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1145,7 +1111,7 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
||||
}
|
||||
}
|
||||
/* 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));
|
||||
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 cb = pIcode.ll()->testFlags(B) ? 1: 2;
|
||||
//x86_op_t *im= pIcode.insn.x86_get_imm();
|
||||
bool Imm = (pIcode.ll()->testFlags(I));
|
||||
bool Imm = (pIcode.ll()->srcIsImmed());
|
||||
|
||||
switch (pIcode.ll()->getOpcode()) {
|
||||
case iAND: case iOR: case iXOR:
|
||||
|
||||
@ -1068,7 +1068,7 @@ static void none1(int )
|
||||
****************************************************************************/
|
||||
static void none2(int )
|
||||
{
|
||||
if ( pIcode->ll()->testFlags(I) )
|
||||
if ( pIcode->ll()->srcIsImmed() )
|
||||
pIcode->ll()->setFlags(NO_OPS);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user