Fixes to libdisasm, also use it a bit more

This commit is contained in:
Artur K
2012-07-19 19:37:30 +02:00
parent c1eb8df114
commit d5e1fc733f
46 changed files with 1463 additions and 1331 deletions

View File

@@ -26,9 +26,9 @@ bool Idiom5::match(iICODE pIcode)
int Idiom5::action()
{
AstIdent *rhs,*lhs;
COND_EXPR *expr;
lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = AstIdent::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
Expr *expr;
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
expr = new BinaryOperator(ADD,lhs, rhs);
m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate();
@@ -61,9 +61,9 @@ int Idiom6::action()
{
AstIdent *rhs,*lhs;
COND_EXPR *expr;
lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = AstIdent::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
Expr *expr;
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
expr = new BinaryOperator(SUB,lhs, rhs);
m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate();
@@ -102,7 +102,13 @@ bool Idiom18::match(iICODE picode)
m_is_dec = m_icodes[1]->ll()->match(iDEC);
uint8_t regi; /* register of the MOV */
if(not (m_icodes[0]->ll()->match(iMOV) and m_icodes[0]->ll()->dst.isReg() ))
return false;
regi = m_icodes[0]->ll()->dst.regi;
if( not ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
m_icodes[3]->ll()->conditionalJump() ) )
return false;
// Simple matching finished, select apropriate matcher based on dst type
/* Get variable */
if (m_icodes[1]->ll()->dst.regi == 0) /* global variable */
{
@@ -111,10 +117,11 @@ bool Idiom18::match(iICODE picode)
}
else if ( m_icodes[1]->ll()->dst.isReg() ) /* register */
{
if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
m_idiom_type = 1;
else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
m_idiom_type = 1;
m_idiom_type = 1;
// if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
// m_idiom_type = 1;
// else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
// m_idiom_type = 1;
}
else if (m_icodes[1]->ll()->dst.off) /* local variable */
m_idiom_type = 2;
@@ -134,31 +141,23 @@ bool Idiom18::match(iICODE picode)
break;
case 1: /* register variable */
/* Check previous instruction for a MOV */
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi))
if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi))
{
regi = m_icodes[0]->ll()->dst.regi;
if ( m_icodes[0]->ll()->dst.isReg() )
{
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
m_icodes[3]->ll()->conditionalJump() )
return true;
}
return true;
}
break;
case 2: /* local */
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off))
if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off))
{
regi = m_icodes[0]->ll()->dst.regi;
if ( m_icodes[0]->ll()->dst.isReg() )
{
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
m_icodes[3]->ll()->conditionalJump() )
return true;
}
return true;
}
break;
case 3: // indexed
printf("Unsupported idiom18 type: indexed");
printf("Untested idiom18 type: indexed\n");
if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->dst))
{
return true;
}
break;
}
return false;
@@ -166,8 +165,8 @@ bool Idiom18::match(iICODE picode)
int Idiom18::action() // action length
{
COND_EXPR *rhs,*lhs;/* Pointers to left and right hand side exps */
COND_EXPR *expr;
Expr *rhs,*lhs;/* Pointers to left and right hand side exps */
Expr *expr;
lhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE);
lhs = UnaryOperator::Create(m_is_dec ? POST_DEC : POST_INC, lhs);
rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE);
@@ -195,38 +194,40 @@ bool Idiom19::match(iICODE picode)
if(std::distance(picode,m_end)<2)
return false;
ICODE &ic(*picode);
int type;
for(int i=0; i<2; ++i)
m_icodes[i] =picode++;
m_is_dec = m_icodes[0]->ll()->match(iDEC);
if ( not m_icodes[1]->ll()->conditionalJump() )
return false;
if (m_icodes[0]->ll()->dst.regi == 0) /* global variable */
/* not supported yet */ ;
else if ( m_icodes[0]->ll()->dst.isReg() ) /* register */
{
// if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
// ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
if (m_icodes[1]->ll()->conditionalJump())
return true;
return true;
}
else if (m_icodes[0]->ll()->dst.off) /* stack variable */
{
if ( m_icodes[1]->ll()->conditionalJump() )
return true;
return true;
}
else /* indexed */
{
fprintf(stderr,"idiom19 : Untested type [indexed]\n");
return true;
/* not supported yet */
}
return false;
}
int Idiom19::action()
{
COND_EXPR *lhs,*rhs,*expr;
ICODE &ic1(*m_icodes[1]);
Expr *lhs,*expr;
lhs = AstIdent::id (*m_icodes[0]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE);
lhs = UnaryOperator::Create(m_is_dec ? PRE_DEC : PRE_INC, lhs);
rhs = AstIdent::Kte (0, 2);
expr = new BinaryOperator(condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB],lhs, rhs);
expr = new BinaryOperator(condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB],lhs, new Constant(0, 2));
m_icodes[1]->setJCond(expr);
m_icodes[0]->invalidate();
return 2;
@@ -255,6 +256,9 @@ bool Idiom20::match(iICODE picode)
return false;
for(int i=0; i<4; ++i)
m_icodes[i] =picode++;
/* Check second instruction for a MOV */
if(not (m_icodes[1]->ll()->match(iMOV) && m_icodes[1]->ll()->dst.isReg()))
return false;
m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC;
@@ -266,53 +270,52 @@ bool Idiom20::match(iICODE picode)
}
else if ( ll_dest.isReg() ) /* register */
{
if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR))
type = 1;
else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR))
type = 1;
type = 1;
// if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR))
// type = 1;
// else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR))
// type = 1;
}
else if (ll_dest.off) /* local variable */
type = 2;
else /* indexed */
{
printf("idiom20 : Unsupported type [indexed]\n");
printf("idiom20 : Untested type [indexed]\n");
type = 3;
/* not supported yet */ ;
}
/* Check previous instruction for a MOV */
if (type == 1) /* register variable */
regi = m_icodes[1]->ll()->dst.regi;
const LLOperand &mov_src(m_icodes[1]->ll()->src());
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump())
{
if (m_icodes[1]->ll()->match(iMOV) &&
(m_icodes[1]->ll()->src().regi == ll_dest.regi))
switch(type)
{
regi = m_icodes[1]->ll()->dst.regi;
if ( m_icodes[1]->ll()->dst.isReg() )
{
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
m_icodes[3]->ll()->conditionalJump())
case 1: /* register variable */
if ((mov_src.regi == ll_dest.regi))
{
return true;
}
}
}
else if (type == 2) /* local */
{
if ( m_icodes[0]->ll()->match(iMOV) &&
(m_icodes[1]->ll()->src().off == ll_dest.off))
{
regi = m_icodes[1]->ll()->dst.regi;
if ( m_icodes[1]->ll()->dst.isReg() )
{
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
m_icodes[3]->ll()->conditionalJump())
}
break;
case 2: // local
if ((mov_src.off == ll_dest.off))
{
return true;
}
}
break;
case 3:
fprintf(stderr,"Test 3 ");
if ((mov_src == ll_dest))
{
return true;
}
break;
}
}
return false;
}
int Idiom20::action()
{
COND_EXPR *lhs,*rhs,*expr;
Expr *lhs,*rhs,*expr;
lhs = AstIdent::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE);
lhs = UnaryOperator::Create(m_is_dec, lhs);
rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE);

View File

@@ -50,7 +50,7 @@ int Idiom14::action()
{
int idx;
AstIdent *lhs;
COND_EXPR *rhs;
Expr *rhs;
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]);
lhs = AstIdent::LongIdx (idx);
@@ -101,8 +101,8 @@ bool Idiom13::match(iICODE pIcode)
int Idiom13::action()
{
AstIdent *lhs;
COND_EXPR *rhs;
lhs = AstIdent::Reg (m_loaded_reg, 0, &m_func->localId);
Expr *rhs;
lhs = new RegisterNode(m_loaded_reg, 0, &m_func->localId);
m_icodes[0]->setRegDU( m_loaded_reg, eDEF);
m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);

View File

@@ -53,8 +53,8 @@ bool Idiom11::match (iICODE picode)
int Idiom11::action()
{
AstIdent *lhs;
COND_EXPR *rhs;
lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
Expr *rhs;
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = UnaryOperator::Create(NEGATION, lhs);
m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate();
@@ -96,8 +96,8 @@ bool Idiom16::match (iICODE picode)
int Idiom16::action()
{
AstIdent *lhs;
COND_EXPR *rhs;
lhs = AstIdent::Reg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
Expr *rhs;
lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
rhs = UnaryOperator::Create(NEGATION, lhs->clone());
m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate();

View File

@@ -29,7 +29,7 @@ int Idiom8::action()
{
int idx;
AstIdent *lhs;
COND_EXPR *rhs,*expr;
Expr *expr;
eReg regH,regL;
regH=m_icodes[0]->ll()->dst.regi;
regL=m_icodes[1]->ll()->dst.regi;
@@ -37,8 +37,7 @@ int Idiom8::action()
lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( regL, USE_DEF);
rhs = AstIdent::Kte(1,2);
expr = new BinaryOperator(SHR,lhs, rhs);
expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate();
return 2;
@@ -81,11 +80,11 @@ int Idiom15::action()
{
AstIdent *lhs;
COND_EXPR *rhs,*_exp;
lhs = AstIdent::Reg (m_icodes[0]->ll()->dst.regi,
Expr *rhs,*_exp;
lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi,
m_icodes[0]->ll()->getFlag() & NO_SRC_B,
&m_func->localId);
rhs = AstIdent::Kte (m_icodes.size(), 2);
rhs = new Constant(m_icodes.size(), 2);
_exp = new BinaryOperator(SHL,lhs, rhs);
m_icodes[0]->setAsgn(lhs, _exp);
for (size_t i=1; i<m_icodes.size()-1; ++i)
@@ -119,7 +118,7 @@ bool Idiom12::match(iICODE pIcode)
int Idiom12::action()
{
int idx;
COND_EXPR *rhs,*expr;
Expr *expr;
AstIdent *lhs;
eReg regH,regL;
@@ -129,8 +128,7 @@ int Idiom12::action()
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]);
lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( regH, USE_DEF);
rhs = AstIdent::Kte (1, 2);
expr = new BinaryOperator(SHL,lhs, rhs);
expr = new BinaryOperator(SHL,lhs, new Constant(1, 2));
m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate();
return 2;
@@ -161,15 +159,14 @@ int Idiom9::action()
{
int idx;
AstIdent *lhs;
COND_EXPR *rhs,*expr;
Expr *rhs,*expr;
eReg regH,regL;
regL=m_icodes[1]->ll()->dst.regi;
regH=m_icodes[0]->ll()->dst.regi;
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]);
lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU(regL, USE_DEF);
rhs = AstIdent::Kte (1, 2);
expr = new BinaryOperator(SHR,lhs, rhs);
expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate();
return 2;

View File

@@ -39,11 +39,11 @@ bool Idiom21::match (iICODE picode)
}
int Idiom21::action()
{
COND_EXPR *rhs;
Expr *rhs;
AstIdent *lhs;
lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
rhs = AstIdent::Kte (m_icodes[1]->ll()->src().getImm2() , 4);
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4);
m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[0]->du.use = 0; /* clear register used in iXOR */
m_icodes[1]->invalidate();
@@ -84,11 +84,9 @@ bool Idiom7::match(iICODE picode)
}
int Idiom7::action()
{
COND_EXPR *lhs;
COND_EXPR *rhs;
Expr *lhs;
lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
rhs = AstIdent::Kte (0, 2);
m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), rhs);
m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
m_icode->du.use = 0; /* clear register used in iXOR */
m_icode->ll()->setFlags(I);
return 1;