能力值:
( LV6,RANK:90 )
6 楼
由于当时用的VC6编译的,没有任何问题。今天用VS2013,确实有问题。
解决1:用VC6,复制VS2013的BIN(注意备份),Include使用VS2010的(VS2010的xtree的NodePtr与VS2013不同)。LIB也用vs2010
解决2:用makefile。
CPP=cl.exe
allfile: OUTDIR=.\Release
INTDIR=.\Release
# Begin Custom Macros
OutDir=.\Release
# End Custom Macros
ALL : "$(OUTDIR)\hexrays_kai2.dll" CLEAN :
-@erase "$(INTDIR)\main.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\vc60.pdb"
-@erase "$(OUTDIR)\hexrays_kai2.dll"
-@erase "$(OUTDIR)\hexrays_kai2.exp"
-@erase "$(OUTDIR)\hexrays_kai2.ilk"
-@erase "$(OUTDIR)\hexrays_kai2.lib"
-@erase "$(OUTDIR)\hexrays_kai2.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
#CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HEXRAYS_KAI2_EXPORTS" /I"$(IDASDK)" /I"$(VCSDK)" /Fp"$(INTDIR)\hexrays_kai2.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
CPP_PROJ=/nologo /EHsc /MT /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HEXRAYS_KAI2_EXPORTS" /I"$(IDASDK)" /I"$(VCSDK)" /Fp"Release/hexrays_kai2.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
LINK32=link.exe
#LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "msvcprt.lib" /nologo /dll /incremental:no /pdb:"$(OUTDIR)\hexrays_kai.pdb" /machine:I386 /nodefaultlib:"LIBCMT" /out:"C:\Program Files\IDA 6.8\plugins\hexrays_kai.plw" /implib:"$(OUTDIR)\hexrays_kai.lib" /EXPORT:PLUGIN /LIBPATH:"$(VCLIB)" /LIBPATH:"C:\Program Files\Windows Kits\8.1\Lib\winv6.3\um\x86"
LINK32_FLAGS=/OUT:"C:\Program Files\IDA 6.8\plugins\hexrays_kai.plw" /MANIFEST /NXCOMPAT /PDB:"$(OUTDIR)\hexrays_kai.pdb" /DYNAMICBASE "ida.lib" "kernel32.lib" "msvcprt.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /nodefaultlib:libcmt /LIBPATH:"$(VCLIB)" /LIBPATH:"$(WINDOWSSDK)" /IMPLIB:"$(OUTDIR)\hexrays_kai.lib" /DEBUG /DLL /MACHINE:X86 /OPT:REF /INCREMENTAL:NO /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Release\hexrays_kai12.dll.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1 /EXPORT:PLUGIN
LINK32_OBJS= \
"$(INTDIR)\main.obj"
"$(OUTDIR)\hexrays_kai2.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<< .c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<< SOURCE=.\main.cpp
"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)" makefile:
IDASDK=C:\we\IDAPro68\idasdk68\include
VCSDK=C:\Program Files\Microsoft Visual Studio 10.0\VC\include
VCLIB=C:\Program Files\Microsoft Visual Studio 10.0\VC\lib
WINDOWSSDK=C:\Program Files\Windows Kits\8.1\Lib\winv6.3\um\x86 include allmake 再发一个PSP的demo插件的源码(仅供参考)
mips.h
enum RegNo
{
ZERO,AT,
V0,V1,
A0,A1,A2,A3,
T0,T1,T2,T3,T4,T5,T6,T7,
S0,S1,S2,S3,S4,S5,S6,S7,
T8,T9,
K0,K1,
GP,SP,FP,RA,
F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,F14,F15,
F16,F17,F18,F19,F20,F21,F22,F23,F24,F25,F26,F27,F28,F29,F30,F31,
PC,CS,DS,MIPS16,
}; #define o_fpreg o_idpspec1
main.cpp
//#pragma comment(lib,"hexray68")
/*
* This is a sample plugin module
*
* It can be compiled by any of the supported compilers:
*
* - Borland C++, CBuilder, free C++
* - Watcom C++ for DOS32
* - Watcom C++ for OS/2
* - Visual C++
*
*/
#define __NT__
#define __IDP__
#include <windows.h>
#include <ida.hpp>
#include <idp.hpp>
#include <expr.hpp>
#include <bytes.hpp>
#include <loader.hpp>
#include <kernwin.hpp>
#include "hexrays.hpp"
#include <gdl.hpp>
#include <allins.hpp>
#include <frame.hpp>
#pragma comment(lib,"hexray68.lib")
#pragma comment(lib,"ida")
#pragma comment(lib,"msvcrt")
//#pragma comment(lib,"libcmt")
//#pragma comment(linker,"/entry:DllEntry")
//extern plugin_t PLUGIN;
//plugin_t PLUGIN;
#include "hdr.h"
#include "mips.h"
extern "C" hexplugin_t thePlugin; #define BADMREG 0x12345678 extern "C"
{
tinfo_t g_tifStocks[12];
}; CBitRange tmprgRange,varregRange; bool may_be_base(minsn_t* minsn)
{
if(minsn->z.type!=mot_reg)
return false;
insn_t tmp=cmd;
if(decode_prev_insn(minsn->ea)==-1)
{
cmd=tmp;
return false;
}
switch(cmd.itype)
{
case MIPS_beql:
case MIPS_beqzl:
cmd=tmp;
return false;
}
cmd=tmp;
return true;
}
int idaapi mreg_to_regnum(sval_t reg, int size);
struct mipsopt_visitor_t:public mmba_visitor_t
{
mipsopt_visitor_t(mblock_t* _mblk=NULL,minsn_t* _parentInsn=NULL):mmba_visitor_t(_mblk,_parentInsn)
{
dwCombineNum=0;
}
int dwCombineNum;
virtual int visit( void )
{
switch(curinsn->mtype)
{
case mit_jmpindirect:
if(curinsn->z.is_reg(MIPS_RA))
{
curinsn->mtype=mit_retn;
curinsn->x.put_number(0,4);
curinsn->y.~mexpr_t();
curinsn->z.~mexpr_t();
dwCombineNum++;
return 0;
}
break;
}
return 0;
}
};
struct mips_combinecallback_t:public hxcombine_callback_t
{
virtual int __stdcall combine( mblock_t * mblk, minsn_t * minsn)
{
mipsopt_visitor_t t(mblk,minsn);
minsn->apply_to(&t);
return t.dwCombineNum;
return 0;
}
}theMipsCombine; int calc_psp_retloc(const tinfo_t * rettype,cm_t cc,argloc_t* retloc)
{
if(rettype->is_void())
return 1;
if(rettype->is_integral()||rettype->is_enum())
{
if(rettype->get_size()==8)
{
retloc->_set_reg2(V0,V1);
}
else
{
retloc->_set_reg1(V0);
}
return 1;
}
else if(rettype->is_float())
{
retloc->_set_reg1(F0);
}
else if(rettype->is_double())
{
retloc->_set_reg2(V0,V1); //PSP:V0,V1
}
else
{
retloc->_set_reg1(V0);
}
return 1;
}
bool calc_psp_argloc(funcarg_t* fa,int& indArg,int& fltIndArg)
{
if(!fa->type.is_float())
{
bool bInt64=fa->type.get_size()==8;
if(bInt64)
{
if((indArg%2)!=0)
indArg++;
}
if(!bInt64)
{
fa->argloc._set_reg1(A0+indArg);
indArg++;
}
else
{
fa->argloc._set_reg2(A0+indArg,A0+indArg+1);
indArg+=2;;
}
}
else
{
if(fa->type.is_float())
{
//warning("calc_psp_argloc float");
fa->argloc._set_reg1(F12+fltIndArg);
fltIndArg++;
}
else if(fa->type.is_double())
{
if((indArg%2)!=0)
indArg++;
fa->argloc._set_reg2(A0+indArg,A0+indArg+1);
indArg+=2;
//warning("calc_psp_argloc double");
}
else
{
warning("fgghjkj");
}
}
return true;
} bool calc_psp_arglocs(func_type_data_t* fti)
{
if(!calc_psp_retloc(&fti->rettype,fti->cc,&fti->retloc))
return 0;
int indArg=0;
int nRegArg=8;
int purge_size=0;
int elsize=4;
int fltIndArg=0;
for (funcargvec_t::iterator it=fti->begin();it!=fti->end();it++)
{
int size=it->type.get_size();
if(size==-1)return false;
int size_up=align_up(size,elsize);
if(indArg<nRegArg)
{
if(!calc_psp_argloc(it,indArg,fltIndArg))
{
it->argloc.set_stkoff(0x10);
purge_size+=8;
indArg++;
}
}
else
{
if(1)
{
it->argloc.set_stkoff(elsize*(indArg-nRegArg));
}
else
{
}
indArg+=size_up/elsize;
}
}
if(1)
{
fti->stkargs=indArg<=nRegArg?0:elsize*(indArg-nRegArg);
}
return true;
}
//PSP 参数,返回值fix
int idaapi callhook_proc(void *user_data, int notification_code, va_list va)
{
switch(notification_code)
{
case processor_t::calc_retloc3: /////< Calculate return value location.
///< The kernel uses this callback only if #PR_TINFO is set.
///< \param rettype (const tinfo_t *)
///< \param cc (::cm_t)
///< \param[out] retloc (::argloc_t *)
///< \return 1 not implemented
///< \return 2 ok,
///< \return -1 error
//break;
{
const tinfo_t *rettype=va_arg(va,const tinfo_t*);
cm_t cc=va_arg(va,cm_t);
argloc_t* retloc=va_arg(va,argloc_t*);
return calc_psp_retloc(rettype,cc,retloc)?2:-1;
}
case processor_t::calc_arglocs3:
//break;
///< Calculate function argument locations.
///< This callback should fill retloc, all arglocs, and stkargs.
///< This callback supersedes calc_argloc2.
///< This callback is never called for ::CM_CC_SPECIAL functions.
///< The kernel uses this callback only if #PR_TINFO is set.
///< \param fti (::func_type_data_t *) points to the func type info
///< \retval 1 not implemented
///< \retval 2 ok
///< \retval -1 error
{
func_type_data_t* fti=va_arg(va,func_type_data_t*);
return calc_psp_arglocs(fti)?2:-1;
}
case processor_t::get_fastcall_regs3:
{
callregs_t *callregs = va_arg(va, callregs_t *);
static int regs[]={A0,A1,A2,A3,T0,T1,T2,T3,-1};
//static int fpregs[]={T0,T1,T2,T3,-1};
callregs->set(ARGREGS_INDEPENDENT, regs, NULL);
return callregs->nregs + 2;
}
case processor_t::get_varcall_regs3:
{
callregs_t *callregs = va_arg(va, callregs_t *);
static int regs[]={A0,A1,A2,A3,T0,T1,T2,T3,-1};
//static int fpregs[]={T0,T1,T2,T3,-1};
callregs->set(ARGREGS_INDEPENDENT, regs, NULL);
return callregs->nregs + 2;
}
//case processor_t::calc_cdecl_purged_bytes2:
//return 4+2;
}
return 0;
}
bool idaapi init()
{
install_hxcombine_callback(&theMipsCombine);
hook_to_notification_point(HT_IDP,callhook_proc,NULL);
tmprgRange.combine_bit(MIPS_S0,MIPS_S7-MIPS_S0+4);
tmprgRange.combine_bit(MIPS_T8,MIPS_T9-MIPS_T8+4);
varregRange.combine_bit(MIPS_T4,MIPS_T5-MIPS_T4+4);
return true;
}
void idaapi term()
{
remove_hxcombine_callback(&theMipsCombine);
unhook_from_notification_point(HT_IDP,callhook_proc);
}
void LoadImmOpnum(mblock_t* mblk,op_t& op,ea_t ea,char dtype,uint32 value,mreg_t loc)
{
mexpr_t x;
int size=get_dtyp_size(dtype);
if(x.put_offset(ea,op,value,size))
{
mexpr_t z;
z.set_reg(loc,size);
mblk->build_any_insn(mit_asg,&x,NULL,&z);
}
else
{
mblk->build_samesize_insn(mit_asgconst,size,value,BADMREG,loc,op.n);
}
}
int idaapi regnum_to_mreg(int regnum);
bool get_itype_sign(uint16 itype); mreg_t LoadOpnum(mblock_t* mblk,insn_t* insn,mreg_t mreg,int n)
{
op_t& op=insn->Operands[n];
switch(op.type)
{
case o_void:
return -1;
case o_displ:
{
mexpr_t addrExpr,offExpr,regExpr;
op_t tmpOp=op;
uint32 v=op.addr;
offExpr.set_reg(MIPS_off,4);
bool bNeg=false;
if(v>=0x8000)
{
v|=0xFFFF0000;
}
addrExpr.put_offset(insn->ea,op,v,4);
mreg_t mbasereg;
if(op.reg==ZERO)
{
mblk->build_samesize_insn(mit_asgconst,4,0,BADMREG,mreg);
mbasereg=mreg;
}
else
{
mbasereg=regnum_to_mreg(op.reg);
}
regExpr.set_reg(mbasereg,4);
mblk->build_any_insn(mit_add,&addrExpr,®Expr,&offExpr);
}
return MIPS_off;
case o_reg:
if(op.reg==ZERO)
{
mblk->build_samesize_insn(mit_asgconst,4,0,BADMREG,mreg);
return mreg;
}
else
{
return regnum_to_mreg(op.reg);
}
case o_fpreg:
return regnum_to_mreg(F0+op.reg);
case o_imm:
{
uval_t v=op.value;
char dtyp=op.dtyp;
switch(insn->itype)
{
case MIPS_lui:
v<<=16;
break;
case MIPS_ext:
if(n==3)
v=(1<<v)-1;
break;
default:
if(dtyp==dt_word&&get_itype_sign(insn->itype))
{
if(v>=0x8000)v|=0xFFFF0000;
}
break;
}
dtyp=dt_dword;
LoadImmOpnum(mblk,op,insn->ea,dtyp,v,mreg);
}
return mreg;
case o_near:
LoadImmOpnum(mblk,op,insn->ea,dt_dword,op.addr,MIPS_off);
return MIPS_off;
case o_mem:
LoadImmOpnum(mblk,op,insn->ea,dt_dword,op.addr,MIPS_off);
return MIPS_off;
default:
warning("LoadOpnum %X",op.type);
}
}
ea_t eaMemOp=BADADDR;
bool get_itype_sign(uint16 itype)
{
switch(itype)
{
case MIPS_lb:
case MIPS_lh:
case MIPS_slt:
case MIPS_slti:
case MIPS_addi:
case MIPS_addiu:
return true;
default:
return false;
}
}
mreg_t LoadInsn(mblock_t* mblk,insn_t* insn,int n)
{
op_t& op=insn->Operands[n];
mreg_t opLoc;
switch(n)
{
case 0:
opLoc=MIPS_tmp0;
break;
case 1:
opLoc=MIPS_tmp1;
break;
case 2:
opLoc=MIPS_tmp2;
break;
case 3:
opLoc=MIPS_tmp3;
break;
default:
warning("LoadInsn");
}
mreg_t offLoc=LoadOpnum(mblk,insn,opLoc,n);
if(offLoc!=MIPS_off||(op.type!=o_mem&&op.type!=o_phrase&&op.type!=o_displ))
{
return offLoc;
}
eaMemOp=insn->ea;
int size=get_dtyp_size(op.dtyp);
mblk->build_samesize_insn(mit_ptr,size,MIPS_ds,MIPS_off,opLoc,4);
if(size<4)
mblk->build_asgop(op.dtyp,dt_dword,opLoc,opLoc,get_itype_sign(insn->itype));
//warning("off");
return opLoc;
}
bool SaveInsn(mblock_t* mblk,mreg_t oploc,insn_t* insn,int n)
{
mreg_t mreg=MIPS_off;
op_t& op=insn->Operands[n];
if(eaMemOp==insn->ea&&(op.type>=o_mem&&op.type<=o_phrase))
{
mreg=MIPS_off;
}
else
{
mreg=LoadOpnum(mblk,insn,MIPS_tmpt,n);
if(mreg==-1)
return false;
}
if(mreg==MIPS_off)
{
//warning("ptrrev %X=4",oploc);
//mblk->build_asgop(dt_dword,dt_word,oploc,oploc,false);
/*
mexpr_t opExpr,segExpr,offExpr;
opExpr.set_reg(oploc,4);
segExpr.set_reg(MIPS_ds,2);
offExpr.set_reg(MIPS_off,4);
*/
//mblk->build_any_insn(mit_ptrrev,&opExpr,&segExpr,&offExpr);
//warning("%X",op.type);
if(op.dtyp!=dt_dword)
{
mexpr_t opExpr,opExprlow;
opExpr.set_reg(oploc,4);
opExprlow.set_reg(oploc,get_dtyp_size(op.dtyp));
//mblk->build_any_insn(mit_low,&opExpr,NULL,&opExprlow);
//mblk->build_asgop(op.dtyp,dt_dword,oploc,oploc,false);
}
mblk->build_samesize_insn(mit_ptrrev,get_dtyp_size(op.dtyp),oploc,MIPS_ds,MIPS_off,4);
}
else if(mreg!=oploc)
{
//warning("asg %X,%X",mreg,oploc);
mblk->build_samesize_insn(mit_asg,4,oploc,BADMREG,mreg);
}
return true;
} ea_t eaIp=BADADDR;
int idaapi do_microcode(mblock_t *mblk, insn_t *insn, int im);
//jump later
void do_nextmicrocode(mblock_t* mblk,int im)
{
insn_t tmpInsn=cmd;
decode_insn(cmd.ea+cmd.size);
insn_t nextInsn=cmd;
cmd=tmpInsn;
do_microcode(mblk,&nextInsn,im);
}
enum
{
jlt_null=0,
jlt_jr=1,
jlt_jcc,
jlt_j, //j,jal
};
struct jmplater_t
{
jmplater_t(){reset();}
char type;
bool bEnable;
union
{
char dummy[32];
struct
{
mreg_t mreg; //jr ra
bool bJalr; //jalr
};
//jcc
struct
{
mreg_t cndReg;
ea_t jccaddr;
bool bLikely;
};
struct
{
ea_t jmpaddr; //j,jal
bool bCall;
};
};
void reset()
{
type=jlt_null;
bEnable=false;
memset(dummy,0,sizeof(dummy));
}
void set_jcc(mreg_t _cndReg,ea_t _addr)
{
type=jlt_jcc;
cndReg=_cndReg;
jccaddr=_addr;
bLikely=false;
}
void set_j(ea_t _addr)
{
type=jlt_j;
jmpaddr=_addr;
bCall=false;
}
}g_jmplater;
void build_bool_op(mblock_t* mblk,insn_t* insn,minsntype_t mtype,mreg_t srcreg,char dtype,mreg_t dstreg); bool is_mips_reg(op_t& op)
{
return op.type==o_reg||op.type==o_fpreg;
} bool is_asm_insn(insn_t* insn)
{
switch(insn->itype)
{
case MIPS_lwr:
case MIPS_lwl:
case MIPS_swl:
case MIPS_swr:
//case MIPS_break:
return true;
}
return false;
}
int idaapi do_microcode(mblock_t *mblk, insn_t *insn, int im)
{
static int stat=0;
//if(insn->ea>=0x8900334&&insn->ea<0x89008B4)
{
uint32 feature=insn->get_canon_feature();
mreg_t op1Loc,op2Loc,op3Loc,op4Loc;
mreg_t cndLoc;
if(is_asm_insn(insn))
{
//mblk->mba->nothllfloat_eaList.insert(insn->ea);
}
if((feature&CF_USE1)||is_mips_reg(insn->Operands[0]))
{
op1Loc=LoadInsn(mblk,insn,0);
}
else
op1Loc=MIPS_tmp0;
if((feature&CF_USE2)||is_mips_reg(insn->Operands[1]))
{
op2Loc=LoadInsn(mblk,insn,1);
}
else
op2Loc=MIPS_tmp1;
if((feature&CF_USE3)||is_mips_reg(insn->Operands[2]))
{
op3Loc=LoadInsn(mblk,insn,2);
}
else
op3Loc=MIPS_tmp2;
if((feature&CF_USE4)||is_mips_reg(insn->Operands[3]))
{
op4Loc=LoadInsn(mblk,insn,3);
}
else
op4Loc=MIPS_tmp3;
if(is_asm_insn(insn))
{
mblk->build_samesize_insn(mit_asm,4,-1,-1,-1);
return 1;
}
int code=MERR_BLOCK;
const char* name;
switch(insn->itype)
{
//x=y
case MIPS_lui:
case MIPS_li:
case MIPS_mov:
case MIPS_lw:
case MIPS_lh:
case MIPS_lb:
case MIPS_la:
case MIPS_lbu:
case MIPS_lhu:
case MIPS_lwc1:
mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,op1Loc);
break;
case MIPS_movz:
case MIPS_movn:
//movz rd,rs,rt if(rt==0)rd=rs
/*
label: if(rt!=0)jmp label+2;
label+1: rd=rs
label+2:
*/
//warning("MIPS_movz %X,%X,%X",op1Loc,op2Loc,op3Loc);
{
mexpr_t zeroExpr,op3Expr,flowExpr;
zeroExpr.put_number(0,4,-1,0);
op3Expr.set_reg(op3Loc,4);
flowExpr.set_label(mblk->label_num+2);
mblk->build_any_insn(insn->itype==MIPS_movz?mit_nejmp:mit_eqjmp,&op3Expr,&zeroExpr,&flowExpr);
//jmp后不能有指令
mblk=mblk->mba->append_blk(insn->ea);
mblk->build_samesize_insn(mit_asg,4,LoadInsn(mblk,insn,1),BADMREG,op1Loc);
mblk=mblk->mba->append_blk(insn->ea);
}
break;
//y=x
case MIPS_sw:
case MIPS_sh:
case MIPS_sb:
case MIPS_swc1:
case MIPS_mtc1:
mblk->build_samesize_insn(mit_asg,4,op1Loc,BADMREG,op2Loc);
break;
case MIPS_sltiu:
case MIPS_slti:
case MIPS_sltu:
case MIPS_slt:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
//rt<-rs<imm rt=(rs<imm)&1
//mblk->build_asgop(dt_word,dt_dword,op3Loc,op3Loc,true);
mblk->build_samesize_insn(get_itype_sign(insn->itype)?mit_slt:mit_ult,4,op2Loc,op3Loc,op1Loc);
{
mexpr_t op1Expr,numExpr;
op1Expr.type=mot_reg;
op1Expr.mreg=op1Loc;
op1Expr.size=4; numExpr.put_number(1,4,-1,0);
mblk->build_any_insn(mit_band,&op1Expr,&numExpr,&op1Expr);
}
//warning("sltiu");
break;
//op1=(op2Loc>>op3Loc)&op4Loc
case MIPS_ext:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_ushr,4,op2Loc,op3Loc,MIPS_tmpt);
mblk->build_samesize_insn(mit_band,4,MIPS_tmpt,op4Loc,MIPS_tmpt);
mblk->build_samesize_insn(mit_asg,4,MIPS_tmpt,BADMREG,op1Loc);
break;
case MIPS_srl:
case MIPS_srlv:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_ushr,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_sra:
case MIPS_srav:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_sshr,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_sll:
case MIPS_sllv:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_shl,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_addiu:
case MIPS_addi:
case MIPS_addu:
if(insn->itype==MIPS_addi)
{
warning("MIPS_addi");
}
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_add,4,op2Loc,op3Loc,op1Loc);
//build_bool_op(mblk,insn,mit_SETP,op1Loc,dt_dword,MIPS_pf);
break;
case MIPS_subu:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_sub,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_or:
case MIPS_ori:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_bor,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_nor:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_bor,4,op2Loc,op3Loc,MIPS_tmp3);
mblk->build_samesize_insn(mit_bnot,4,MIPS_tmp3,BADMREG,op1Loc);
break;
case MIPS_andi:
case MIPS_and:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_band,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_xori:
case MIPS_xor:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_xor,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_negu:
mblk->build_samesize_insn(mit_neg,4,op2Loc,BADMREG,op1Loc);
break;
case MIPS_ins:
{
uint32 mask=((1<<insn->Operands[3].value)-1)<<insn->Operands[2].value;
mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,MIPS_tmp4);
mblk->build_samesize_insn(mit_asgconst,4,mask,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_band,4,MIPS_tmp4,MIPS_tmpt,MIPS_tmp4);
mblk->build_samesize_insn(mit_asg,4,op1Loc,BADMREG,MIPS_tmp3);
mblk->build_samesize_insn(mit_asgconst,4,~mask,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_band,4,MIPS_tmp3,MIPS_tmpt,MIPS_tmp3);
mblk->build_samesize_insn(mit_bor,4,MIPS_tmp3,MIPS_tmp4,op1Loc);
break;
}
mblk->build_samesize_insn(mit_asg,4,op1Loc,BADMREG,op1Loc);
/*
mblk->build_samesize_insn(mit_band,4,op2Loc,op4Loc,MIPS_tmpt);
mblk->build_samesize_insn(mit_band,4,op2Loc,op4Loc,MIPS_tmpt);
mblk->build_samesize_insn(mit_shl,4,MIPS_tmpt,op3Loc,MIPS_tmpt);
mblk->build_samesize_insn(mit_bor,4,MIPS_tmpt,op1Loc,op1Loc);
*/
break;
case PSP_max:
case PSP_min:
//rd=rs>=rt?rs:rt;
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
{
mexpr_t l3Expr,l4Expr,cndExpr;
cndExpr.set_reg(MIPS_zf,1);
l3Expr.set_label(mblk->label_num+2);
l4Expr.set_label(mblk->label_num+3);
mblk->build_samesize_insn(insn->itype==PSP_max?mit_sgt:mit_sle,4,op2Loc,op3Loc,MIPS_zf);
//break;
mblk->build_any_insn(mit_jcc,&cndExpr,NULL,&l3Expr);
mblk=mblk->mba->append_blk(insn->ea);
mblk->build_samesize_insn(mit_asg,4,op3Loc,BADMREG,op1Loc);
//warning("");
mblk->build_any_insn(mit_jmp,&l4Expr);
mblk=mblk->mba->append_blk(insn->ea);
mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,op1Loc);
}
break;
case MIPS_mult:
case MIPS_multu:
{
bool sign=insn->itype==MIPS_mul?true:false;
mblk->build_asgop(dt_dword,dt_qword,op1Loc,MIPS_tmp2,sign);
mblk->build_asgop(dt_dword,dt_qword,op2Loc,MIPS_tmp3,sign);
}
op1Loc=MIPS_tmp2;
op2Loc=MIPS_tmp3;
mblk->build_samesize_insn(mit_mul,8,op1Loc,op2Loc,MIPS_LO);
break;
case MIPS_seb:
case MIPS_seh:
mblk->build_asgop(insn->itype==MIPS_seb?dt_byte:dt_word,dt_dword,op2Loc,op1Loc,true);
break;
case MIPS_mflo:
mblk->build_samesize_insn(mit_asg,4,MIPS_LO,BADMREG,op1Loc);
break;
case MIPS_mfhi:
mblk->build_samesize_insn(mit_asg,4,MIPS_HI,BADMREG,op1Loc);
break;
//case MIPS_fmul:
// break;
case MIPS_lwl:
case MIPS_lwr:
mblk->build_samesize_insn(mit_asm,4,op1Loc,op2Loc,-1);
break;
case MIPS_swl:
case MIPS_swr:
//warning("%x,%x,%x",op1Loc,op2Loc,op3Loc);
mblk->build_samesize_insn(mit_asg,4,op1Loc,BADMREG,op2Loc);
return 0;
break;
case MIPS_break:
{
marg_t arg;
arg.set_reg(op1Loc,4);
arg.tif=tinfo_t(BTF_INT32);
arg.ea=insn->ea;
minsn_t* p=create_fastcall_helpfunc(insn->ea,"break",tinfo_t(BT_VOID),1,&arg,false);
//p->z.a->flags|=8;
//p->flags|=0x400;
mblk->safe_build_insn(p);
//mblk->mba->nothllfloat_eaList.erase(insn->ea);
}
break;
case MIPS_cache:
{
marg_t arg[2];
arg[0].set_reg(op1Loc,4);
arg[0].tif=tinfo_t(BTF_INT32);
arg[0].ea=insn->ea;
arg[1]=arg[0];
arg[1].set_reg(op2Loc,4);
minsn_t* p=create_fastcall_helpfunc(insn->ea,"cache",tinfo_t(BT_VOID),2,arg,false);
//p->z.a->flags|=8;
//p->flags|=0x400;
mblk->safe_build_insn(p);
//mblk->mba->nothllfloat_eaList.erase(insn->ea);
}
break;
case MIPS_clz:
{
marg_t arg;
arg.set_reg(op2Loc,4);
arg.tif=tinfo_t(BTF_UINT32);
arg.ea=insn->ea;
minsn_t* p=create_fastcall_helpfunc(insn->ea,"clz",tinfo_t(BTF_UINT32),1,&arg,false);
mexpr_t xExpr,resExpr;
xExpr.type=mot_insn;
xExpr.minsn=p;
xExpr.size=p->z.size;
resExpr.set_reg(op1Loc,4);
mblk->build_any_insn(mit_asg,&xExpr,NULL,&resExpr);
}
break;
case MIPS_div:
case MIPS_divu:
//LO=rs/rt,HI=rs%rt
mblk->build_asgop(dt_dword,dt_qword,op1Loc,MIPS_tmp2,insn->itype==MIPS_div?true:false);
mblk->build_asgop(dt_dword,dt_qword,op2Loc,MIPS_tmp3,insn->itype==MIPS_div?true:false);
op1Loc=MIPS_tmp2;
op2Loc=MIPS_tmp3;
mblk->build_samesize_insn(insn->itype==MIPS_div?mit_sdiv:mit_udiv,8,op1Loc,op2Loc,MIPS_LO);
mblk->build_samesize_insn(insn->itype==MIPS_div?mit_smod:mit_umod,8,op1Loc,op2Loc,MIPS_HI);
break;
case MIPS_fmul:
//warning("%X,%X,%X",op1Loc,op2Loc,op3Loc);
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_fmul,4,op3Loc,op2Loc,op1Loc);
break;
case MIPS_fcvt_s:
mblk->build_samesize_insn(mit_intfloatasg,4,op2Loc,BADMREG,op1Loc);
break;
case MIPS_fdiv:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_fdiv,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_mfc1:
//mblk->build_samesize_insn(mit_intfloatasg,4,op2Loc,BADMREG,op2Loc);
mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,op1Loc);
//mblk->build_samesize_insn(mit_asg,4,MIPS_F0,BADMREG,MIPS_V1);
//mblk->build_samesize_insn(mit_add,4,op2Loc,op2Loc,op1Loc);
break;
case MIPS_fc_le:
mblk->build_samesize_insn(mit_ule,4,op1Loc,op2Loc,MIPS_CC,-1); //-1-->浮点指令
break;
case MIPS_fc_eq:
mblk->build_samesize_insn(mit_eq,4,op1Loc,op2Loc,MIPS_CC,-1); //-1-->浮点指令
break;
case MIPS_fc_lt:
mblk->build_samesize_insn(mit_ult,4,op1Loc,op2Loc,MIPS_CC,-1);
break;
case MIPS_fmov:
mblk->build_samesize_insn(mit_asg,4,op2Loc,BADMREG,op1Loc);
break;
case MIPS_fadd:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_fadd,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_fsub:
if(insn->Operands[2].type==o_void)
{
op3Loc=op2Loc;
op2Loc=op1Loc;
}
mblk->build_samesize_insn(mit_fsub,4,op2Loc,op3Loc,op1Loc);
break;
case MIPS_fneg:
mblk->build_samesize_insn(mit_fneg,4,op2Loc,BADMREG,op1Loc);
break;
case MIPS_fsqrt:
{
mexpr_t resExpr;
marg_t arg;
arg.set_reg(op2Loc,4);
arg.ea=insn->ea;
arg.tif=tinfo_t(BT_FLOAT);
minsn_t* p=create_fastcall_helpfunc(insn->ea,"sqrt",tinfo_t(BT_FLOAT),1,&arg,false);
resExpr.set_reg(op1Loc,4);
mexpr_t xExpr;
xExpr.type=mot_insn;
xExpr.minsn=p;
xExpr.size=p->z.size;
mblk->build_any_insn(mit_asg,&xExpr,NULL,&resExpr);
}
break;
case MIPS_ftrunc_w:
mblk->build_samesize_insn(mit_floatintasg,4,op2Loc,BADMREG,op1Loc);
//mblk->build_samesize_insn(mit_asgconst,4,6,BADMREG,op1Loc);
break;
case MIPS_bc1t:
case MIPS_bc1f:
g_jmplater.set_jcc(MIPS_zf,insn->Operands[0].addr);
build_bool_op(mblk,insn,insn->itype==MIPS_bc1t?mit_ne:mit_eq,MIPS_CC,dt_byte,g_jmplater.cndReg);
//mblk->build_samesize_insn(mit_eq,4,MIPS_CC,op2Loc,g_jmplater.cndReg);
break;
case MIPS_beq:
//if(rs==rt) branch
g_jmplater.set_jcc(MIPS_zf,insn->Operands[2].addr);
mblk->build_samesize_insn(mit_eq,4,op1Loc,op2Loc,g_jmplater.cndReg);
//code=MERR_OK;
break;
case MIPS_bne:
//if(rs==rt) branch
g_jmplater.set_jcc(MIPS_zf,insn->Operands[2].addr);
mblk->build_samesize_insn(mit_ne,4,op1Loc,op2Loc,g_jmplater.cndReg);
break;
case MIPS_bnez:
g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
{
build_bool_op(mblk,insn,mit_ne,op1Loc,dt_dword,g_jmplater.cndReg);
//mblk->build_samesize_insn(mit_asgconst,4,0,BADMREG,MIPS_tmpt);
//mblk->build_samesize_insn(mit_ne,4,op1Loc,MIPS_tmpt,g_jmplater.cndReg);
}
break;
case MIPS_beqz:
g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
build_bool_op(mblk,insn,mit_eq,op1Loc,dt_dword,g_jmplater.cndReg);
//mblk->build_samesize_insn(mit_asg,4,MIPS_V0,BADMREG,MIPS_A0);
//mblk->build_samesize_insn(mit_lnot,1,op1Loc,BADMREG,g_jmplater.cndReg);
//build_bool_op(mblk,insn,mit_ne,op1Loc,dt_dword,g_jmplater.cndReg);
//mblk->build_samesize_insn(mit_lnot,1,op1Loc,BADMREG,g_jmplater.cndReg);
//code=MERR_OK;
break;
case MIPS_bltz:
g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
mblk->build_samesize_insn(mit_SETS,4,op1Loc,BADMREG,g_jmplater.cndReg);
break;
case MIPS_bgtz:
g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
build_bool_op(mblk,insn,mit_sgt,op1Loc,dt_dword,g_jmplater.cndReg);
break;
case MIPS_bgez:
g_jmplater.set_jcc(MIPS_zf,insn->Operands[1].addr);
build_bool_op(mblk,insn,mit_sge,op1Loc,dt_dword,g_jmplater.cndReg);
break;
case MIPS_blez:
//op1<=0
g_jmplater.set_jcc(MIPS_sf,insn->Operands[1].addr);
build_bool_op(mblk,insn,mit_sle,op1Loc,dt_dword,g_jmplater.cndReg);
//mblk->build_samesize_insn(mit_SETS,1,op1Loc,BADMREG,g_jmplater.cndReg);
//code=MERR_OK;
break;
case MIPS_bnezl:
g_jmplater.set_j(insn->Operands[1].addr);
//zf=op1Loc!=0 if(!zf)jmp nextAddr
build_bool_op(mblk,insn,mit_ne,op1Loc,dt_dword,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_beqzl:
g_jmplater.set_j(insn->Operands[1].addr);
build_bool_op(mblk,insn,mit_eq,op1Loc,dt_dword,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_beql:
g_jmplater.set_j(insn->Operands[2].addr);
mblk->build_samesize_insn(mit_eq,4,op1Loc,op2Loc,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_bnel:
g_jmplater.set_j(insn->Operands[2].addr);
mblk->build_samesize_insn(mit_ne,4,op1Loc,op2Loc,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_bgezl:
g_jmplater.set_j(insn->Operands[1].addr);
build_bool_op(mblk,insn,mit_sge,op1Loc,dt_dword,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_blezl:
g_jmplater.set_j(insn->Operands[1].addr);
build_bool_op(mblk,insn,mit_sle,op1Loc,dt_dword,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_bgtzl:
g_jmplater.set_j(insn->Operands[1].addr);
build_bool_op(mblk,insn,mit_sgt,op1Loc,dt_dword,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_bltzl:
g_jmplater.set_j(insn->Operands[1].addr);
mblk->build_samesize_insn(mit_SETS,4,op1Loc,BADMREG,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_bc1tl:
g_jmplater.set_j(insn->Operands[0].addr);
build_bool_op(mblk,insn,mit_ne,MIPS_CC,1,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_bc1fl:
g_jmplater.set_j(insn->Operands[0].addr);
build_bool_op(mblk,insn,mit_eq,MIPS_CC,1,MIPS_zf);
mblk->build_samesize_insn(mit_lnot,1,MIPS_zf,BADMREG,MIPS_tmpt);
mblk->build_samesize_insn(mit_jcc,1,MIPS_tmpt,BADMREG,insn->ea+8);
break;
case MIPS_jal:
case MIPS_j:
case MIPS_b:
if(insn->itype==MIPS_jal)
{
//mblk->build_samesize_insn(mit_asgconst,4,insn->ea+8,BADMREG,MIPS_RA);
}
g_jmplater.set_j(insn->Operands[0].addr);
if(insn->itype==MIPS_jal)
g_jmplater.bCall=true;
//g_jmplater.bEnable=true;
//code=MERR_OK;
break;
case MIPS_jr:
case MIPS_jalr:
//if(op1Loc==MIPS_RA)
{
g_jmplater.type=jlt_jr;
g_jmplater.mreg=op1Loc;
if(insn->itype==MIPS_jalr||(insn->itype==MIPS_jr&&(!insn->Operands[0].is_reg(RA))))
g_jmplater.bJalr=true;
//code=MERR_OK;
}
break;
case MIPS_nop:
//code=MERR_OK;
break;
default:
warning("itype %X,%X",insn->itype,insn->ea);
}
bool ret=true;
if(feature&CF_CHG1)
{
if(!SaveInsn(mblk,op1Loc,insn,0))
ret=false;
}
if(feature&CF_CHG2)
{
if(!SaveInsn(mblk,op2Loc,insn,1))
ret=false;
}
if(!ret)
{
mblk->mba->errea=insn->ea;
return MERR_INSN;
}
if(g_jmplater.bEnable)
{
switch(g_jmplater.type)
{
case jlt_jr:
//if(g_jmplater.mreg==MIPS_RA)
if(g_jmplater.bJalr)
{
mexpr_t segExpr,regExpr;
segExpr.set_reg(MIPS_cs,4);
regExpr.set_reg(g_jmplater.mreg,4);
mblk->build_any_insn(mit_callindirect,&segExpr,®Expr,NULL);
}
else
{
mblk->build_samesize_insn(mit_jmpindirect,4,BADMREG,MIPS_cs,g_jmplater.mreg,4);
//mblk=mblk->mba->append_blk(insn->ea);
}
if(!g_jmplater.bJalr)
{
//mblk=mblk->mba->append_blk(insn->ea);
//mblk->build_samesize_insn(mit_retn,4,0,BADMREG,BADMREG);
}
//mblk->build_samesize_insn(mit_retn,4,0,BADMREG,BADMREG);
//else
// warning("");
g_jmplater.reset();
break;
case jlt_jcc:
if(g_jmplater.bLikely)
{
mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jccaddr,BADMREG,BADMREG);
}
else
{
//mblk->build_samesize_insn(mit_asgconst,4,g_jmplater.jccaddr,BADMREG,MIPS_off);
//mblk->build_samesize_insn(mit_jccindirect,1,g_jmplater.cndReg,MIPS_ds,MIPS_off,4);
mblk->build_samesize_insn(mit_jcc,1,g_jmplater.cndReg,BADMREG,g_jmplater.jccaddr);
//mblk=mblk->mba->append_blk(insn->ea);
//mblk->build_samesize_insn(mit_jmp,4,insn->ea+4,BADMREG,BADMREG);
}
//mblk=mblk->mba->append_blk(insn->ea);
/*
mblk->build_samesize_insn(mit_lnot,1,g_jmplater.cndReg,BADMREG,g_jmplater.cndReg);
mblk->build_samesize_insn(mit_jcc,1,g_jmplater.cndReg,BADMREG,insn->ea+insn->size);
//mblk->build_samesize_insn(mit_jcc,1,g_jmplater.cndReg,BADMREG,g_jmplater.jccaddr);
//mblk->build_samesize_insn(mit_jcc,1,g_jmplater.cndReg,BADMREG,g_jmplater.jccaddr);
mblk=mblk->mba->append_blk(insn->ea);
mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jccaddr,BADMREG,BADMREG);
//mblk->build_samesize_insn(mit_asg,4,)
//mblk->build_samesize_insn(mit_jmp,-1,0x12,BADMREG,BADMREG);
*/
g_jmplater.reset();
break;
case jlt_j:
//mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jmpaddr,BADMREG,BADMREG);
if(g_jmplater.bCall)
{
/*
if(build_float_func(mblk,insn,g_jmplater.jmpaddr))
{
g_jmplater.reset();
return MERR_OK;
}
*/
mexpr_t x;
x.set_obj(g_jmplater.jmpaddr,-1);
mblk->build_any_insn(mit_call,&x,NULL,NULL);
//mblk=mblk->mba->append_blk(insn->ea);
//mblk->build_samesize_insn(mit_jmp,4,insn->ea+4,BADMREG,BADMREG);
//mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jmpaddr,BADMREG,BADMREG);
}
else
{
//warning("jmp:%X",g_jmplater.jmpaddr);
mblk->build_samesize_insn(mit_jmp,4,g_jmplater.jmpaddr,BADMREG,BADMREG);
mblk=mblk->mba->append_blk(insn->ea);
}
//mblk=mblk->mba->append_blk(insn->ea);
//mblk->build_samesize_insn(mit_asgconst,4,4,BADMREG,MIPS_V0);
g_jmplater.reset();
break;
}
}
if((!g_jmplater.bEnable)&&(g_jmplater.type!=jlt_null))
{
g_jmplater.bEnable=true;
}
return code;
}
return MERR_OK;
}
bool calc_stkvar_offset(mbl_array_t* mba,ea_t ea,mreg_t mreg,sval_t& off)
{
func_t* pfn=get_func(ea);
if(!pfn)
return false;
if(mreg==MIPS_SP)
{
off+=pfn->frsize+pfn->frregs+get_effective_spd(pfn,ea)+mba->stk_delta;
return true;
}
return false;
}
bool calcinsn_stkvar_offset(mbl_array_t* mba,minsn_t* minsn,ea_t ea,sval_t& off)
{
mreg_t mreg=-1;
sval_t t;
switch(minsn->mtype)
{
case mit_add:
if(minsn->x.type==mot_reg&&minsn->y.type==mot_num)
{
t=minsn->y.n->value;
if(t<=0xFFFFFFFF)
mreg=minsn->x.mreg;
//warning("calcinsn_stkvar_offset::add reg,num");
}
if(minsn->y.type==mot_reg&&minsn->x.type==mot_num)
{
t=minsn->x.n->value;
if(t<=0xFFFFFFFF)
mreg=minsn->y.mreg;
}
break;
case mit_sub:
if(!minsn->x.is_reg(MIPS_BP))
return false;
warning("calcinsn_stkvar_offset::sub bp,");
default:
return false;
}
if(mreg==-1)
return false;
off=t;
return calc_stkvar_offset(mba,ea,mreg,off); }
bool idaapi combine_mem_expr(HEXFUNC *mba, minsn_t *minsn, mexpr_t *meSeg, mexpr_t *me2, mexpr_t *meRet, int size, int bWarn, int *bObjOff)
{
segment_t* s=getseg(minsn->ea);
if(s)
{
if(me2->size==s->abytes()&&(!meSeg||meSeg->is_reg(MIPS_ss)))
{
sval_t off=0;
switch(me2->type)
{
case mot_reg:
if(!meSeg)
return false;
if(!calc_stkvar_offset(mba,minsn->ea,me2->mreg,off)||off<0)
return false;
setstkvar:
meRet->~mexpr_t();
meRet->type=mot_stkvar;
meRet->stkvar=new mstkvar_t(mba,off);
return true;
break;
case mot_num:
if(!meSeg)
return false;
meRet->~mexpr_t();
meRet->type=mot_obj;
meRet->obj_ea=me2->n->value;
return true;
break;
case mot_insn:
if(!meSeg)
return false;
//analyze_minsn(me2->minsn,true);
if(calcinsn_stkvar_offset(mba,me2->minsn,minsn->ea,off)&&off>=0)
goto setstkvar;
break;
case mot_obj:
return false;
case mot_ref:
{
mexpr_t t(*me2->me);
meRet->swap(t);
}
return true;
case mot_stkvar:
case mot_str:
return false;
default:
warning("combine_mem_expr::%X",me2->type);
}
}
}
return false;
} struct RegDesc
{
mreg_t mreg;
char name[4];
int minsize,maxsize;
}
g_RegDescs[]=
{
MIPS_zf,"zf",1,1,
MIPS_sf,"sf",1,1,
MIPS_AT,"at",4,4,
MIPS_V0,"v0",4,8,
MIPS_V1,"v1",4,4,
MIPS_A0,"a0",4,8,
MIPS_A1,"a1",4,4,
MIPS_A2,"a2",4,8,
MIPS_A3,"a3",4,4,
MIPS_T0,"t0",4,8,
MIPS_T1,"t1",4,4,
MIPS_T2,"t2",4,8,
MIPS_T3,"t3",4,4,
MIPS_T4,"t4",4,8,
MIPS_T5,"t5",4,4,
MIPS_T6,"t6",4,8,
MIPS_T7,"t7",4,4,
MIPS_S0,"s0",4,8,
MIPS_S1,"s1",4,4,
MIPS_S2,"s2",4,8,
MIPS_S3,"s3",4,4,
MIPS_S4,"s4",4,8,
MIPS_S5,"s5",4,4,
MIPS_S6,"s6",4,8,
MIPS_S7,"s7",4,4,
MIPS_T8,"t8",4,8,
MIPS_T9,"t9",4,4,
MIPS_K0,"k0",4,4,
MIPS_K1,"k1",4,4,
MIPS_GP,"gp",4,4,
MIPS_SP,"sp",4,4,
MIPS_FP,"fp",4,4,
MIPS_RA,"ra",4,4,
MIPS_LO,"lo",4,8,
MIPS_HI,"hi",4,4,
MIPS_F0,"f0",4,4,
MIPS_F1,"f1",4,4,
MIPS_F2,"f2",4,4,
MIPS_F3,"f3",4,4,
MIPS_F4,"f4",4,4,
MIPS_F5,"f5",4,4,
MIPS_F6,"f6",4,4,
MIPS_F7,"f7",4,4,
MIPS_F8,"f8",4,4,
MIPS_F9,"f9",4,4,
MIPS_F10,"f10",4,4,
MIPS_F11,"f11",4,4,
MIPS_F12,"f12",4,4,
MIPS_F13,"f13",4,4,
MIPS_F14,"f14",4,4,
MIPS_F15,"f15",4,4,
MIPS_F16,"f16",4,4,
MIPS_F17,"f17",4,4,
MIPS_F18,"f18",4,4,
MIPS_F19,"f19",4,4,
MIPS_F20,"f20",4,4,
MIPS_F21,"f21",4,4,
MIPS_F22,"f22",4,4,
MIPS_F23,"f23",4,4,
MIPS_F24,"f24",4,4,
MIPS_F25,"f25",4,4,
MIPS_F26,"f26",4,4,
MIPS_F27,"f27",4,4,
MIPS_F28,"f28",4,4,
MIPS_F29,"f29",4,4,
MIPS_F30,"f30",4,4,
MIPS_F31,"f31",4,4,
MIPS_CC,"cc",1,1,
MIPS_tmp0,"tm0",4,8,
MIPS_tmp1,"tm1",4,8,
MIPS_tmp2,"tm2",4,8,
MIPS_tmp3,"tm3",4,8,
MIPS_tmp4,"tm4",4,8,
MIPS_tmpt,"tmt",4,8,
MIPS_off,"off",4,4,
MIPS_ds,"ds",2,2,
MIPS_maxreg,"max",0,0,
};
int idaapi get_mreg_minsize(mreg_t mreg)
{
//warning("get_mreg_minsize");
RegDesc* p=g_RegDescs;
while(p->name[0]!=0)
{
if(p->mreg>mreg)
break;
p++;
}
p--;
return p->mreg==mreg?p->minsize:1;
return 0;
}
int idaapi print_mreg(int mreg, int size, char *buf, int bufsize)
{
RegDesc* p=g_RegDescs;
do
{
if(p->mreg>mreg)
break;
p++;
}while(p->name[0]!=0);
p--;
if(size>p->maxsize)
size=p->maxsize;
if(buf)
{
qstrncpy(buf,p->name,bufsize);
if(mreg!=p->mreg)
append_snprintf(buf,buf+bufsize,"^%d",mreg-p->mreg);
}
return size;
} int idaapi do_prolog_analysis(HEXFUNC *mba, qflow_chart_t *, bitset_t *)
{
//mba->bp_off=MIPS_BP;
mba->field_1A8=new hxpushpopregs_t;
func_t* pfn=get_func(mba->entry_ea);
//fix processor BUG
if(pfn)
{
if(pfn->frsize!=mba->minspd)
{
del_frame(pfn);
add_frame(pfn,mba->minspd,0,0);
return MERR_REDO;
}
}
return MERR_OK;
} bool idaapi hxcan_be_pair_x(int mreg, int size)
{
switch(mreg)
{
case MIPS_tmp0:
case MIPS_tmp1:
case MIPS_tmp2:
case MIPS_tmp3:
case MIPS_tmp4:
case MIPS_tmpt:
return true;
}
if(mreg>=MIPS_maxreg)
return true;
if(mreg<MIPS_GPR)
return false;
switch(mreg)
{
case MIPS_V0:
case MIPS_T0:
case MIPS_T2:
case MIPS_LO:
case MIPS_A0:
case MIPS_A2:
return true;
}
return false;
return false;
}
CBitRange& idaapi hxget_extmreg_range(void)
{
static CBitRange ext(MIPS_tmpbeg,MIPS_tmpend-MIPS_tmpbeg);
//LOG("hxget_extmreg_range %X::example\n",ext.get_value());
return ext;
} CBitRange& idaapi hxget_tempmreg_range(void)
{
//warning("hxget_tempmreg_range");
//static CBitRange r;
return tmprgRange;
}
CBitRange& idaapi hxget_varmreg_range(void)
{
return varregRange;
} CBitRange& idaapi hxget_argmreg_range(void)
{
//warning("hxget_argmreg_range");
static CBitRange r;
r.combine_bit(MIPS_A0,MIPS_T3-MIPS_A0+4);
r.combine_bit(MIPS_F12,MIPS_F17-MIPS_F12+4);
return r;
}
extern "C"
{
stackarea_t g_MaxArea={0,-1};
};
void idaapi hxget_call_chg_range(HEXFUNC *mba, signed int ea, tinfo_t *tif, CBitRange *retRange, CBitRange *spoiledRange)
{
func_type_data_t ftd;
int nArg=-1;
if(tif&&tif->get_func_details(&ftd))
nArg=ftd.size();
if(spoiledRange)
{
if(nArg>=0&&(ftd.flags&FTI_SPOILED))
{
warning("spoil");
spoiledRange->cleanup();
for (reginfovec_t::iterator it=ftd.spoiled.begin();it<ftd.spoiled.end();it++)
{
mreg_t mreg=thePlugin.regnum_to_mreg(it->reg);
if(mreg!=-1)
{
spoiledRange->combine_bit(mreg,it->size);
}
}
spoiledRange->combine_stackarea(g_MaxArea);
}
else
{
static CBitRange rangeArg;
if(rangeArg.empty())
{
rangeArg.combine_bit(MIPS_A0,MIPS_T3-MIPS_A0+4);
rangeArg.combine_bit(MIPS_F12,MIPS_F13-MIPS_F12+4);
rangeArg.combine_stackarea(g_MaxArea);
}
*spoiledRange=rangeArg;
//warning("hxget_call_chg_range nArg=%X,flags=%X",nArg,ftd.flags);
//warning("%X",tif!=0?tif->get_decltype():0x12345678);
}
}
CBitRange t;
if(nArg<0)
{
//t.combine_bit(MIPS_V0,MIPS_V1-MIPS_V0+4+4);
t.combine_bit(MIPS_V0,8);
t.combine_bit(MIPS_F0,4);
//t.combine_bit(MIPS_V1,8);
}
else
{
int size=ftd.rettype.get_size();
if(size!=-1)
{
vdloc_t vloc=mba->aloc2vloc(ftd.retloc,size);
vloc.combine_range(&t,size);
t.field_8.clear();
t.ext2DWORD(size);
//warning("hxget_call_chg_range ftd.rettype");
}
}
if(spoiledRange)
{
spoiledRange->combine(t);
}
if(retRange)
{
qswap(*retRange,t);
}
}
argloc_t idaapi hxget_def_retaloc(tinfo_t * tif)
{
argloc_t aloc;
if(tif->is_float())
{
aloc._set_reg1(F0);
}
else
{
aloc._set_reg1(V0);
}
return aloc;
}
bool idaapi hxand_if_retfloat(HEXFUNC *mba, mblock_t *mblk, minsn_t *minsn, CBitRange *andRange, bool *pandret)
{
if(minsn)
{
return false;
}
else
{
if(mba->flags&0x10)
{
msg("hxand_if_retfloat:mba->flags&0x10 %X",mba->flags);
return true;
}
if(!mba->func_type.empty())
{
func_type_data_t fti;
if(mba->func_type.get_func_details(&fti)&&fti.rettype.is_float())
{
msg("hxand_if_retfloat float");
vdloc_t vloc;
int size=fti.rettype.get_size();
mba->aloc2vloc(fti.retloc,size);
CBitRange t;
vloc.combine_range(&t,size);
*pandret=andRange->and(t);
return true;
}
}
*pandret=andRange->andnot(MIPS_F0,4);
}
//icon
//warning("hxand_if_retfloat");
return false;
}
void idaapi hxcombine_with_funcargsrange(CBitRange *r)
{
r->combine_bit(MIPS_RA,4);
} bool idaapi hx_is_defcall(marglist_t *a)
{
return !is_user_cc(a->cc);
} int idaapi regnum_to_mreg(int regnum)
{
switch(regnum)
{
case AT:
return MIPS_AT;
case A0:
return MIPS_A0;
case A1:
return MIPS_A1;
case A2:
return MIPS_A2;
case A3:
return MIPS_A3;
case T0:
return MIPS_T0;
case T1:
return MIPS_T1;
case T2:
return MIPS_T2;
case T3:
return MIPS_T3;
case T4:
return MIPS_T4;
case T5:
return MIPS_T5;
case T6:
return MIPS_T6;
case T7:
return MIPS_T7;
case T8:
return MIPS_T8;
case T9:
return MIPS_T9;
case S0:
return MIPS_S0;
case S1:
return MIPS_S1;
case S2:
return MIPS_S2;
case S3:
return MIPS_S3;
case S4:
return MIPS_S4;
case S5:
return MIPS_S5;
case S6:
return MIPS_S6;
case S7:
return MIPS_S7;
case V0:
return MIPS_V0;
case V1:
return MIPS_V1;
case RA:
return MIPS_RA;
case SP:
return MIPS_SP;
case FP:
return MIPS_FP;
case K0:
return MIPS_K0;
case ZERO:
return -1;
case F0:
return MIPS_F0;
case F1:
return MIPS_F1;
case F2:
return MIPS_F2;
case F3:
return MIPS_F3;
case F4:
return MIPS_F4;
case F5:
return MIPS_F5;
case F6:
return MIPS_F6;
case F7:
return MIPS_F7;
case F8:
return MIPS_F8;
case F9:
return MIPS_F9;
case F10:
return MIPS_F10;
case F11:
return MIPS_F11;
case F12:
return MIPS_F12;
case F13:
return MIPS_F13;
case F14:
return MIPS_F14;
case F15:
return MIPS_F15;
case F16:
return MIPS_F16;
case F17:
return MIPS_F17;
case F18:
return MIPS_F18;
case F19:
return MIPS_F19;
case F20:
return MIPS_F20;
case F21:
return MIPS_F21;
case F22:
return MIPS_F22;
case F23:
return MIPS_F23;
case F24:
return MIPS_F24;
case F25:
return MIPS_F25;
case F26:
return MIPS_F26;
case F27:
return MIPS_F27;
case F28:
return MIPS_F28;
case F29:
return MIPS_F29;
case F30:
return MIPS_F30;
case F31:
return MIPS_F31;
}
return 0;
} int idaapi mreg_to_regnum(sval_t reg, int size)
{
if((size&(size-1))!=0)
return -1;
if((reg%4)!=0)
return -1;
switch(reg)
{
case MIPS_A0:
return A0;
case MIPS_A1:
return A1;
case MIPS_V0:
return V0;
case MIPS_V1:
return V1;
case MIPS_A2:
return A2;
case MIPS_A3:
return A3;
case MIPS_T0:
return T0;
case MIPS_T1:
return T1;
case MIPS_T2:
return T2;
case MIPS_T3:
return T3;
case MIPS_T4:
return T4;
case MIPS_T5:
return T5;
case MIPS_T7:
return T7;
case MIPS_T8:
return T8;
case MIPS_T9:
return T9;
case MIPS_S0:
return S0;
case MIPS_S1:
return S1;
case MIPS_S2:
return S2;
case MIPS_S3:
return S3;
case MIPS_S4:
return S4;
case MIPS_S5:
return S5;
case MIPS_S6:
return S6;
case MIPS_S7:
return S7;
case MIPS_RA:
return RA;
case MIPS_SP:
return SP;
case MIPS_FP:
return FP;
case MIPS_K0:
return K0;
case MIPS_F0:
return F0;
case MIPS_F1:
return F1;
case MIPS_F2:
return F2;
case MIPS_F3:
return F3;
case MIPS_F4:
return F4;
case MIPS_F5:
return F5;
case MIPS_F6:
return F6;
case MIPS_F7:
return F7;
case MIPS_F8:
return F8;
case MIPS_F9:
return F9;
case MIPS_F10:
return F10;
case MIPS_F11:
return F11;
case MIPS_F12:
return F12;
case MIPS_F13:
return F13;
case MIPS_F14:
return F14;
case MIPS_F15:
return F15;
case MIPS_F16:
return F16;
case MIPS_F17:
return F17;
case MIPS_F18:
return F18;
case MIPS_F19:
return F19;
case MIPS_F20:
return F20;
case MIPS_F21:
return F21;
case MIPS_F22:
return F22;
case MIPS_F23:
return F23;
case MIPS_F24:
return F24;
case MIPS_F25:
return F25;
case MIPS_F26:
return F26;
case MIPS_F27:
return F27;
case MIPS_F28:
return F28;
case MIPS_F29:
return F29;
case MIPS_F30:
return F30;
case MIPS_F31:
return F31;
}
return -1;
}
argloc_t idaapi mreg_to_argloc(int mreg, int size)
{
argloc_t aloc;
int reg;
if(size==8)
{
int reg1,reg2;
reg1=mreg_to_regnum(mreg,4);
reg2=mreg_to_regnum(mreg+4,4);
QASSERT(50513,reg1!=-1&®2!=-1);
aloc._set_reg2(reg1,reg2);
}
else
{
reg=mreg_to_regnum(mreg,size);
if(reg!=-1)
aloc._set_reg1(reg);
}
return aloc;
}
int idaapi mregnum_align_down(sval_t mreg)
{
if(mreg>=MIPS_GPR&&mreg<MIPS_tmpbeg)
mreg&=0xFFFFFFFC;
return mreg;
switch(mreg)
{
case MIPS_A0:
case MIPS_A1:
case MIPS_A2:
case MIPS_A3:
case MIPS_V0:
case MIPS_V1:
case MIPS_T0:
case MIPS_T1:
case MIPS_T2:
case MIPS_T3:
case MIPS_S0:
case MIPS_RA:
return mreg;
}
return 0;
} bool idaapi hxis_fltmreg(sval_t mreg)
{
return mreg>=MIPS_F0&&mreg<MIPS_F31+4;
}
bool idaapi hxcan_advance_reg(int mreg)
{
if(mreg>=MIPS_F0&&mreg<MIPS_F31+4)
return false;
}
bool idaapi hxcan_be_regarg(int mreg)
{
switch(mreg)
{
case MIPS_A0:
case MIPS_A1:
case MIPS_A2:
case MIPS_A3:
case MIPS_T0:
case MIPS_T1:
case MIPS_T2:
case MIPS_T3:
case MIPS_F0:
case MIPS_F1:
case MIPS_F2:
return true;
}
return false;
}
bool idaapi hxis_use_reg(int reg, ea_t ea, ea_t maxea)
{
mreg_t mreg=regnum_to_mreg(reg);
for (;ea<maxea;ea=nextthat(ea,maxea,f_isCode,NULL))
{
if(decode_insn(ea))
{
for(int n=0;n<6;n++)
{
op_t& op=cmd.Operands[n];
switch(op.type)
{
case o_reg:
//warning("hxis_use_reg reg");
if(mreg==regnum_to_mreg(op.reg))
return true;
break;
case o_mem:
break;
case o_phrase:
warning("hxis_use_reg mem");
break;
case o_displ:
if(mreg==regnum_to_mreg(op.reg))
return true;
}
}
}
}
return false;
} int idaapi hxget_access_reg(int mreg)
{
return mreg;
return 0;
}
bool idaapi hxis_segrg(int mreg)
{
return mreg==MIPS_ds||mreg==MIPS_ss||mreg==MIPS_cs;
return false;
} extern "C" hexplugin_t thePlugin=
{
PLFM_MIPS, //id
"hexarm", //name
0x35B,
//0x1B44, //flags
MIPS_ds, //ds
MIPS_ss, //ss
MIPS_SP, //sp
MIPS_cs, //cs
MIPS_regext, //regext
MIPS_maxreg, //fps
8, //dummy
0x100000, //eaHole
init, //init
term, //term
do_microcode,
combine_mem_expr,
NULL,
get_mreg_minsize,
print_mreg,
NULL,
do_prolog_analysis,
NULL,
NULL,
NULL,
NULL,
hxcan_be_pair_x,
hxget_extmreg_range,
hxget_tempmreg_range,
hxget_varmreg_range,
hxget_argmreg_range,
hxget_call_chg_range,
hxget_def_retaloc,
NULL,
hxcombine_with_funcargsrange,
NULL,
hx_is_defcall,
NULL,
NULL,
NULL,
regnum_to_mreg,
mreg_to_regnum,
mreg_to_argloc,
mregnum_align_down,
NULL,
hxis_fltmreg,
hxcan_advance_reg,
hxcan_be_regarg,
NULL,
hxis_use_reg,
NULL,
hxget_access_reg,
hxis_segrg,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
}; 正常情况应该可以通过编译。
PS:活用Specify switch idiom,MIPS的宏指令可能会导致反编译失败,