Move XCHG and DIV rewriters from Function class

Preliminary work for #19
This commit is contained in:
nemerle 2016-05-10 13:07:05 +02:00
parent 41e9faec0e
commit ae27258e3c
3 changed files with 69 additions and 69 deletions

View File

@ -253,8 +253,6 @@ public:
Expr * adjustActArgType(Expr *_exp, hlType forType); Expr * adjustActArgType(Expr *_exp, hlType forType);
QString writeCall(Function *tproc, STKFRAME &args, int *numLoc); QString writeCall(Function *tproc, STKFRAME &args, int *numLoc);
void processDosInt(STATE *pstate, PROG &prog, bool done); void processDosInt(STATE *pstate, PROG &prog, bool done);
ICODE *translate_DIV(LLInst *ll, ICODE &_Icode);
ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode);
void switchState(DecompilationStep s); void switchState(DecompilationStep s);
protected: protected:

View File

@ -596,7 +596,7 @@ class CIcodeRec : public std::list<ICODE>
public: public:
CIcodeRec(); // Constructor CIcodeRec(); // Constructor
ICODE * addIcode(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);

View File

@ -44,80 +44,81 @@ int strSize (const uint8_t *sym, char delim)
const uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim); const uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim);
return end_ptr-sym+1; return end_ptr-sym+1;
} }
ICODE * Function::translate_DIV(LLInst *ll, ICODE &_Icode)
static std::vector<ICODE> rewrite_DIV(LLInst *ll, ICODE &_Icode)
{ {
/* MOV rTMP, reg */ ICODE synth_mov = ICODE(); // MOV rTMP, reg
ICODE synth_mod = ICODE(); // MOD
ICODE eIcode = ICODE(); synth_mov.type = LOW_LEVEL;
synth_mov.ll()->set(iMOV,0,rTMP);
eIcode.type = LOW_LEVEL;
eIcode.ll()->set(iMOV,0,rTMP);
if (ll->testFlags(B) ) if (ll->testFlags(B) )
{ {
eIcode.ll()->setFlags( B ); synth_mov.ll()->setFlags( B );
eIcode.ll()->replaceSrc(rAX); synth_mov.ll()->replaceSrc(rAX);
} }
else /* implicit dx:ax */ else /* implicit dx:ax */
{ {
eIcode.ll()->setFlags( IM_SRC ); synth_mov.ll()->setFlags( IM_SRC );
eIcode.setRegDU( rDX, eUSE); synth_mov.setRegDU( rDX, eUSE);
} }
eIcode.setRegDU( rAX, eUSE); synth_mov.setRegDU( rAX, eUSE);
eIcode.setRegDU( rTMP, eDEF); synth_mov.setRegDU( rTMP, eDEF);
eIcode.ll()->setFlags( SYNTHETIC ); synth_mov.ll()->setFlags( SYNTHETIC );
/* eIcode.ll()->label = Project::get()->SynthLab++; */ /* eIcode.ll()->label = Project::get()->SynthLab++; */
eIcode.ll()->label = _Icode.ll()->label; synth_mov.ll()->label = _Icode.ll()->label;
Icode.addIcode(&eIcode);
/* iDIV, iIDIV */
Icode.addIcode(&_Icode);
/* iMOD */ /* iMOD */
eIcode = ICODE(); synth_mod.type = LOW_LEVEL;
eIcode.type = LOW_LEVEL; synth_mod.ll()->set(iMOD,ll->getFlag() | SYNTHETIC | IM_TMP_DST);
eIcode.ll()->set(iMOD,ll->getFlag() | SYNTHETIC | IM_TMP_DST); synth_mod.ll()->replaceSrc(_Icode.ll()->src());
eIcode.ll()->replaceSrc(_Icode.ll()->src()); synth_mod.du = _Icode.du;
eIcode.du = _Icode.du; synth_mod.ll()->label = Project::get()->SynthLab++;
eIcode.ll()->label = Project::get()->SynthLab++; return {
return Icode.addIcode(&eIcode); synth_mov,
_Icode,
synth_mod
};
} }
ICODE *Function::translate_XCHG(LLInst *ll,ICODE &_Icode) static std::vector<ICODE> rewrite_XCHG(LLInst *ll,ICODE &_Icode)
{ {
/* MOV rTMP, regDst */ /* MOV rTMP, regDst */
ICODE eIcode; ICODE mov_tmp_dst;
eIcode.type = LOW_LEVEL; mov_tmp_dst.type = LOW_LEVEL;
eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,ll->m_dst); mov_tmp_dst.ll()->set(iMOV,SYNTHETIC,rTMP,ll->m_dst);
eIcode.setRegDU( rTMP, eDEF); mov_tmp_dst.setRegDU( rTMP, eDEF);
if(eIcode.ll()->src().getReg2()) if(mov_tmp_dst.ll()->src().getReg2())
{ {
eReg srcreg=eIcode.ll()->src().getReg2(); eReg srcreg=mov_tmp_dst.ll()->src().getReg2();
eIcode.setRegDU( srcreg, eUSE); mov_tmp_dst.setRegDU( srcreg, eUSE);
if((srcreg>=rAL) and (srcreg<=rBH)) if((srcreg>=rAL) and (srcreg<=rBH))
eIcode.ll()->setFlags( B ); mov_tmp_dst.ll()->setFlags( B );
} }
eIcode.ll()->label = ll->label; mov_tmp_dst.ll()->label = ll->label;
Icode.addIcode(&eIcode);
/* MOV regDst, regSrc */ /* MOV regDst, regSrc */
ll->set(iMOV,SYNTHETIC|ll->getFlag()); ICODE mov_dst_src = _Icode; // copy all XCHG things, but set opcode to iMOV and mark it as synthetic insn
Icode.addIcode(&_Icode); mov_dst_src.ll()->set(iMOV,SYNTHETIC|ll->getFlag());
ll->setOpcode(iXCHG); /* for next case */
/* MOV regSrc, rTMP */ /* MOV regSrc, rTMP */
eIcode = ICODE();
eIcode.type = LOW_LEVEL; ICODE mov_src_tmp;
eIcode.ll()->set(iMOV,SYNTHETIC); mov_src_tmp.type = LOW_LEVEL;
eIcode.ll()->replaceDst(ll->src()); mov_src_tmp.ll()->set(iMOV,SYNTHETIC);
if(eIcode.ll()->m_dst.regi) mov_src_tmp.ll()->replaceDst(ll->src());
if(mov_src_tmp.ll()->m_dst.regi)
{ {
if((eIcode.ll()->m_dst.regi>=rAL) and (eIcode.ll()->m_dst.regi<=rBH)) if((mov_src_tmp.ll()->m_dst.regi>=rAL) and (mov_src_tmp.ll()->m_dst.regi<=rBH))
eIcode.ll()->setFlags( B ); mov_src_tmp.ll()->setFlags( B );
eIcode.setRegDU( eIcode.ll()->m_dst.regi, eDEF); mov_src_tmp.setRegDU( mov_src_tmp.ll()->m_dst.regi, eDEF);
} }
eIcode.ll()->replaceSrc(rTMP); mov_src_tmp.ll()->replaceSrc(rTMP);
eIcode.setRegDU( rTMP, eUSE); mov_src_tmp.setRegDU( rTMP, eUSE);
eIcode.ll()->label = Project::get()->SynthLab++; mov_src_tmp.ll()->label = Project::get()->SynthLab++;
return Icode.addIcode(&eIcode); return {
mov_tmp_dst,
mov_dst_src,
mov_src_tmp
};
} }
/** /**
* @brief resolveOSServices * @brief resolveOSServices
@ -125,8 +126,8 @@ ICODE *Function::translate_XCHG(LLInst *ll,ICODE &_Icode)
* @param pstate * @param pstate
* @return true if given OS service will terminate the program * @return true if given OS service will terminate the program
*/ */
//TODO: convert into command //TODO: convert into Command class
bool resolveOSServices(LLInst *ll, STATE *pstate) static bool resolveOSServices(LLInst *ll, STATE *pstate)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
SYMTAB &global_symbol_table(Project::get()->symtab); SYMTAB &global_symbol_table(Project::get()->symtab);
@ -222,12 +223,19 @@ void FollowCtrl(Function &func,CALL_GRAPH * pcallGraph, STATE *pstate)
} }
/* Copy Icode to Proc */ /* Copy Icode to Proc */
if ((ll->getOpcode() == iDIV) or (ll->getOpcode() == iIDIV)) if ((ll->getOpcode() == iDIV) or (ll->getOpcode() == iIDIV)) {
pIcode = func.translate_DIV(ll, _Icode); std::vector<ICODE> translated = rewrite_DIV(ll,_Icode);
else if (_Icode.ll()->getOpcode() == iXCHG) for(const ICODE &ic : translated)
pIcode = func.translate_XCHG(ll, _Icode); pIcode = func.Icode.addIcode(&ic);
else }
else if (_Icode.ll()->getOpcode() == iXCHG) {
std::vector<ICODE> translated = rewrite_XCHG(ll,_Icode);
for(const ICODE &ic : translated)
pIcode = func.Icode.addIcode(&ic);
}
else {
pIcode = func.Icode.addIcode(&_Icode); pIcode = func.Icode.addIcode(&_Icode);
}
switch (ll->getOpcode()) { switch (ll->getOpcode()) {
/*** Conditional jumps ***/ /*** Conditional jumps ***/
@ -307,12 +315,6 @@ void FollowCtrl(Function &func,CALL_GRAPH * pcallGraph, STATE *pstate)
case iMOV: case iMOV:
process_MOV(*pIcode->ll(), pstate); process_MOV(*pIcode->ll(), pstate);
break; break;
/* case iXCHG:
process_MOV (pIcode, pstate);
break; **** HERE ***/
case iSHL: case iSHL:
if (pstate->JCond.regi == ll->m_dst.regi) if (pstate->JCond.regi == ll->m_dst.regi)
{ {