use of soot.jimple.BinopExpr in project soot by Sable.
the class DavaBody method javafy_binop_expr.
private void javafy_binop_expr(ValueBox vb) {
BinopExpr boe = (BinopExpr) vb.getValue();
ValueBox leftOpBox = boe.getOp1Box(), rightOpBox = boe.getOp2Box();
Value leftOp = leftOpBox.getValue(), rightOp = rightOpBox.getValue();
if (rightOp instanceof IntConstant) {
if ((leftOp instanceof IntConstant) == false) {
javafy(leftOpBox);
leftOp = leftOpBox.getValue();
if (boe instanceof ConditionExpr)
rightOpBox.setValue(DIntConstant.v(((IntConstant) rightOp).value, leftOp.getType()));
else
rightOpBox.setValue(DIntConstant.v(((IntConstant) rightOp).value, null));
}
} else if (leftOp instanceof IntConstant) {
javafy(rightOpBox);
rightOp = rightOpBox.getValue();
if (boe instanceof ConditionExpr)
leftOpBox.setValue(DIntConstant.v(((IntConstant) leftOp).value, rightOp.getType()));
else
leftOpBox.setValue(DIntConstant.v(((IntConstant) leftOp).value, null));
} else {
javafy(rightOpBox);
rightOp = rightOpBox.getValue();
javafy(leftOpBox);
leftOp = leftOpBox.getValue();
}
if (boe instanceof CmpExpr)
vb.setValue(new DCmpExpr(leftOp, rightOp));
else if (boe instanceof CmplExpr)
vb.setValue(new DCmplExpr(leftOp, rightOp));
else if (boe instanceof CmpgExpr)
vb.setValue(new DCmpgExpr(leftOp, rightOp));
}
use of soot.jimple.BinopExpr in project soot by Sable.
the class CP method handleMathematical.
/*
* x = b where b is in the before set of the statement as a constant then we
* can simply say x = that constant also
*
* TODO: DONT WANT TO DO IT:::: If right expr is a unary expression see if
* the stuff inside is a Local
*
* x = exp1 op exp2 (check if both exp1 and exp2 are int constants
*
* killedValuse is either the constant value which left had before this
* assignment stmt or null if left was Top or not in the set
*
* handle the special case when the inputset could not find a value because
* its the killed value //eg. x = x+1 since we top x first we will never get
* a match IMPORTANT
*/
private void handleMathematical(CPFlowSet toReturn, Local left, Value right, Object killedValue) {
// if right expr is a local or field
Object value = isANotTopConstantInInputSet(toReturn, right);
if (value != null) {
// right was a local or field with a value other than top
// dont send value SEND A CLONE OF VALUE.....IMPORTANT!!!!
Object toSend = CPHelper.wrapperClassCloner(value);
if (toSend != null) {
addOrUpdate(toReturn, left, toSend);
}
// primitive local assigned some value from the right
return;
}
// we could find in the set
if (right instanceof BinopExpr) {
Value op1 = ((BinopExpr) right).getOp1();
Value op2 = ((BinopExpr) right).getOp2();
Object op1Val = CPHelper.isAConstantValue(op1);
Object op2Val = CPHelper.isAConstantValue(op2);
if (op1Val == null)
op1Val = isANotTopConstantInInputSet(toReturn, op1);
if (op2Val == null)
op2Val = isANotTopConstantInInputSet(toReturn, op2);
if (op1 == left) {
// System.out.println("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>OP1 is the same as LHS");
op1Val = killedValue;
}
if (op2 == left) {
// System.out.println("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>OP2 is the same as LHS");
op2Val = killedValue;
}
if (op1Val != null && op2Val != null) {
// System.out.println("found constant values for both operands of binary expression");
if (left.getType() instanceof IntType && op1Val instanceof Integer && op2Val instanceof Integer) {
// only caring about operations on two integers and result
// is an integer
int op1IntValue = ((Integer) op1Val).intValue();
int op2IntValue = ((Integer) op2Val).intValue();
String tempStr = ((BinopExpr) right).getSymbol();
if (tempStr.length() > 1) {
char symbol = tempStr.charAt(1);
// System.out.println("found symbol "+symbol+" for the operands of binary expression");
int newValue = 0;
boolean set = false;
switch(symbol) {
case '+':
// System.out.println("Adding");
newValue = op1IntValue + op2IntValue;
set = true;
break;
case '-':
// System.out.println("Subtracting");
newValue = op1IntValue - op2IntValue;
set = true;
break;
case '*':
// System.out.println("Multiplying");
newValue = op1IntValue * op2IntValue;
set = true;
break;
}
if (set) {
// we have our new value
Integer newValueObject = new Integer(newValue);
addOrUpdate(toReturn, left, newValueObject);
return;
}
}
}
} else {
// System.out.println("atleast one value is not constant so cant simplify expression");
}
}
// System.out.println("DefinitionStmt checked right expr for mathematical stuff"+toReturn.toString());
}
use of soot.jimple.BinopExpr in project soot by Sable.
the class DexIfTransformer method internalTransform.
@Override
protected void internalTransform(final Body body, String phaseName, Map<String, String> options) {
final DexDefUseAnalysis localDefs = new DexDefUseAnalysis(body);
Set<IfStmt> ifSet = getNullIfCandidates(body);
for (IfStmt ifs : ifSet) {
ConditionExpr ifCondition = (ConditionExpr) ifs.getCondition();
Local[] twoIfLocals = new Local[] { (Local) ifCondition.getOp1(), (Local) ifCondition.getOp2() };
usedAsObject = false;
for (Local loc : twoIfLocals) {
Set<Unit> defs = localDefs.collectDefinitionsWithAliases(loc);
// process normally
doBreak = false;
for (Unit u : defs) {
// put correct local in l
if (u instanceof DefinitionStmt) {
l = (Local) ((DefinitionStmt) u).getLeftOp();
} else {
throw new RuntimeException("ERROR: def can not be something else than Assign or Identity statement! (def: " + u + " class: " + u.getClass() + "");
}
// check defs
u.apply(new // Alex: should also end
AbstractStmtSwitch() {
// as soon as detected
// as not used as an
// object
@Override
public void caseAssignStmt(AssignStmt stmt) {
Value r = stmt.getRightOp();
if (r instanceof FieldRef) {
usedAsObject = isObject(((FieldRef) r).getFieldRef().type());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) r;
if (ar.getType() instanceof UnknownType) {
// isObject
usedAsObject = stmt.hasTag("ObjectOpTag");
// (findArrayType
// (g,
// localDefs,
// localUses,
// stmt));
} else {
usedAsObject = isObject(ar.getType());
}
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof StringConstant || r instanceof NewExpr || r instanceof NewArrayExpr) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof CastExpr) {
usedAsObject = isObject(((CastExpr) r).getCastType());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof InvokeExpr) {
usedAsObject = isObject(((InvokeExpr) r).getType());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof LengthExpr) {
usedAsObject = false;
if (usedAsObject)
doBreak = true;
return;
}
}
@Override
public void caseIdentityStmt(IdentityStmt stmt) {
if (stmt.getLeftOp() == l) {
usedAsObject = isObject(stmt.getRightOp().getType());
if (usedAsObject)
doBreak = true;
return;
}
}
});
if (doBreak)
break;
// check uses
for (Unit use : localDefs.getUsesOf(l)) {
use.apply(new AbstractStmtSwitch() {
private boolean examineInvokeExpr(InvokeExpr e) {
List<Value> args = e.getArgs();
List<Type> argTypes = e.getMethodRef().parameterTypes();
assert args.size() == argTypes.size();
for (int i = 0; i < args.size(); i++) {
if (args.get(i) == l && isObject(argTypes.get(i))) {
return true;
}
}
// check for base
SootMethodRef sm = e.getMethodRef();
if (!sm.isStatic()) {
if (e instanceof AbstractInvokeExpr) {
AbstractInstanceInvokeExpr aiiexpr = (AbstractInstanceInvokeExpr) e;
Value b = aiiexpr.getBase();
if (b == l) {
return true;
}
}
}
return false;
}
@Override
public void caseInvokeStmt(InvokeStmt stmt) {
InvokeExpr e = stmt.getInvokeExpr();
usedAsObject = examineInvokeExpr(e);
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseAssignStmt(AssignStmt stmt) {
Value left = stmt.getLeftOp();
Value r = stmt.getRightOp();
if (left instanceof ArrayRef) {
if (((ArrayRef) left).getIndex() == l) {
// doBreak = true;
return;
}
}
// used to assign
if (stmt.getRightOp() == l) {
Value l = stmt.getLeftOp();
if (l instanceof StaticFieldRef && isObject(((StaticFieldRef) l).getFieldRef().type())) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (l instanceof InstanceFieldRef && isObject(((InstanceFieldRef) l).getFieldRef().type())) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (l instanceof ArrayRef) {
Type aType = ((ArrayRef) l).getType();
if (aType instanceof UnknownType) {
// isObject(
usedAsObject = stmt.hasTag("ObjectOpTag");
// findArrayType(g,
// localDefs,
// localUses,
// stmt));
} else {
usedAsObject = isObject(aType);
}
if (usedAsObject)
doBreak = true;
return;
}
}
// assignment)
if (r instanceof FieldRef) {
// isObject(((FieldRef)
usedAsObject = true;
// r).getFieldRef().type());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) r;
if (ar.getBase() == l) {
usedAsObject = true;
} else {
// used as index
usedAsObject = false;
}
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof StringConstant || r instanceof NewExpr) {
throw new RuntimeException("NOT POSSIBLE StringConstant or NewExpr at " + stmt);
} else if (r instanceof NewArrayExpr) {
usedAsObject = false;
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof CastExpr) {
usedAsObject = isObject(((CastExpr) r).getCastType());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof InvokeExpr) {
usedAsObject = examineInvokeExpr((InvokeExpr) stmt.getRightOp());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof LengthExpr) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof BinopExpr) {
usedAsObject = false;
if (usedAsObject)
doBreak = true;
return;
}
}
@Override
public void caseIdentityStmt(IdentityStmt stmt) {
if (stmt.getLeftOp() == l)
throw new RuntimeException("IMPOSSIBLE 0");
}
@Override
public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
usedAsObject = stmt.getOp() == l;
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
usedAsObject = stmt.getOp() == l;
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseReturnStmt(ReturnStmt stmt) {
usedAsObject = stmt.getOp() == l && isObject(body.getMethod().getReturnType());
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseThrowStmt(ThrowStmt stmt) {
usedAsObject = stmt.getOp() == l;
if (usedAsObject)
doBreak = true;
return;
}
});
if (doBreak)
break;
}
// for uses
if (doBreak)
break;
}
if (// as soon as one def or use refers to an object
doBreak)
// be updated
break;
}
// change values
if (usedAsObject) {
Set<Unit> defsOp1 = localDefs.collectDefinitionsWithAliases(twoIfLocals[0]);
Set<Unit> defsOp2 = localDefs.collectDefinitionsWithAliases(twoIfLocals[1]);
defsOp1.addAll(defsOp2);
for (Unit u : defsOp1) {
Stmt s = (Stmt) u;
// If we have a[x] = 0 and a is an object, we may not conclude 0 -> null
if (!s.containsArrayRef() || (!defsOp1.contains(s.getArrayRef().getBase()) && !defsOp2.contains(s.getArrayRef().getBase())))
replaceWithNull(u);
Local l = (Local) ((DefinitionStmt) u).getLeftOp();
for (Unit uuse : localDefs.getUsesOf(l)) {
Stmt use = (Stmt) uuse;
// If we have a[x] = 0 and a is an object, we may not conclude 0 -> null
if (!use.containsArrayRef() || (twoIfLocals[0] != use.getArrayRef().getBase()) && twoIfLocals[1] != use.getArrayRef().getBase())
replaceWithNull(use);
}
}
}
// end if
}
// for if statements
}
use of soot.jimple.BinopExpr in project soot by Sable.
the class CmpInstruction method jimplify.
@Override
public void jimplify(DexBody body) {
if (!(instruction instanceof Instruction23x))
throw new IllegalArgumentException("Expected Instruction23x but got: " + instruction.getClass());
Instruction23x cmpInstr = (Instruction23x) instruction;
int dest = cmpInstr.getRegisterA();
Local first = body.getRegisterLocal(cmpInstr.getRegisterB());
Local second = body.getRegisterLocal(cmpInstr.getRegisterC());
// Expr cmpExpr;
// Type type = null
Opcode opcode = instruction.getOpcode();
Expr cmpExpr = null;
Type type = null;
switch(opcode) {
case CMPL_DOUBLE:
setTag(new DoubleOpTag());
type = DoubleType.v();
cmpExpr = Jimple.v().newCmplExpr(first, second);
break;
case CMPL_FLOAT:
setTag(new FloatOpTag());
type = FloatType.v();
cmpExpr = Jimple.v().newCmplExpr(first, second);
break;
case CMPG_DOUBLE:
setTag(new DoubleOpTag());
type = DoubleType.v();
cmpExpr = Jimple.v().newCmpgExpr(first, second);
break;
case CMPG_FLOAT:
setTag(new FloatOpTag());
type = FloatType.v();
cmpExpr = Jimple.v().newCmpgExpr(first, second);
break;
case CMP_LONG:
setTag(new LongOpTag());
type = LongType.v();
cmpExpr = Jimple.v().newCmpExpr(first, second);
break;
default:
throw new RuntimeException("no opcode for CMP: " + opcode);
}
AssignStmt assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), cmpExpr);
assign.addTag(getTag());
setUnit(assign);
addTags(assign);
body.add(assign);
if (IDalvikTyper.ENABLE_DVKTYPER) {
getTag().getName();
BinopExpr bexpr = (BinopExpr) cmpExpr;
DalvikTyper.v().setType(bexpr.getOp1Box(), type, true);
DalvikTyper.v().setType(bexpr.getOp2Box(), type, true);
DalvikTyper.v().setType(((JAssignStmt) assign).leftBox, IntType.v(), false);
}
}
use of soot.jimple.BinopExpr in project soot by Sable.
the class IfTestInstruction method ifStatement.
@Override
protected IfStmt ifStatement(DexBody body) {
Instruction22t i = (Instruction22t) instruction;
Local one = body.getRegisterLocal(i.getRegisterA());
Local other = body.getRegisterLocal(i.getRegisterB());
BinopExpr condition = getComparisonExpr(one, other);
IfStmt jif = Jimple.v().newIfStmt(condition, targetInstruction.getUnit());
// setUnit() is called in ConditionalJumpInstruction
addTags(jif);
if (IDalvikTyper.ENABLE_DVKTYPER) {
// Debug.printDbg(IDalvikTyper.DEBUG, "constraint if: "+ jif +" condition: "+ condition);
DalvikTyper.v().addConstraint(condition.getOp1Box(), condition.getOp2Box());
}
return jif;
}
Aggregations