use of soot.LongType in project soot by Sable.
the class DalvikTyper method assignType.
@Override
public void assignType(final Body b) {
// Debug.printDbg("assignTypes: before: \n", b);
constraints.clear();
localObjList.clear();
final Set<Unit> todoUnits = new HashSet<Unit>();
// put constraints:
for (Unit u : b.getUnits()) {
StmtSwitch ss = new StmtSwitch() {
@Override
public void caseBreakpointStmt(BreakpointStmt stmt) {
// nothing
}
@Override
public void caseInvokeStmt(InvokeStmt stmt) {
// add constraint
DalvikTyper.v().setInvokeType(stmt.getInvokeExpr());
}
@Override
public void caseAssignStmt(AssignStmt stmt) {
// add constraint
Value l = stmt.getLeftOp();
Value r = stmt.getRightOp();
// size in new array expression is of tye integer
if (r instanceof NewArrayExpr) {
NewArrayExpr nae = (NewArrayExpr) r;
ValueBox sb = nae.getSizeBox();
if (sb.getValue() instanceof Local) {
DalvikTyper.v().setType(sb, IntType.v(), true);
}
}
// array index is of type integer
if (stmt.containsArrayRef()) {
ArrayRef ar = stmt.getArrayRef();
ValueBox sb = ar.getIndexBox();
if (sb.getValue() instanceof Local) {
DalvikTyper.v().setType(sb, IntType.v(), true);
}
}
if (l instanceof Local && r instanceof Local) {
DalvikTyper.v().addConstraint(stmt.getLeftOpBox(), stmt.getRightOpBox());
return;
}
if (stmt.containsInvokeExpr()) {
DalvikTyper.v().setInvokeType(stmt.getInvokeExpr());
}
if (r instanceof Local) {
// l NOT local
Type leftType = stmt.getLeftOp().getType();
if (l instanceof ArrayRef && leftType instanceof UnknownType) {
// find type later
todoUnits.add(stmt);
return;
}
DalvikTyper.v().setType(stmt.getRightOpBox(), leftType, true);
return;
}
if (l instanceof Local) {
if (r instanceof UntypedConstant)
return;
for (Tag t : stmt.getTags()) {
if (r instanceof CastExpr) {
// do not check tag, since the tag is for the operand of the cast
break;
}
// Debug.printDbg("assign stmt tag: ", stmt, t);
if (t instanceof IntOpTag) {
checkExpr(r, IntType.v());
DalvikTyper.v().setType(stmt.getLeftOpBox(), IntType.v(), false);
return;
} else if (t instanceof FloatOpTag) {
checkExpr(r, FloatType.v());
DalvikTyper.v().setType(stmt.getLeftOpBox(), FloatType.v(), false);
return;
} else if (t instanceof DoubleOpTag) {
checkExpr(r, DoubleType.v());
DalvikTyper.v().setType(stmt.getLeftOpBox(), DoubleType.v(), false);
return;
} else if (t instanceof LongOpTag) {
checkExpr(r, LongType.v());
DalvikTyper.v().setType(stmt.getLeftOpBox(), LongType.v(), false);
return;
}
}
Type rightType = stmt.getRightOp().getType();
if (r instanceof ArrayRef && rightType instanceof UnknownType) {
// find type later
todoUnits.add(stmt);
return;
} else if (r instanceof CastExpr) {
CastExpr ce = (CastExpr) r;
Type castType = ce.getCastType();
if (castType instanceof PrimType) {
// check incoming primitive type
for (Tag t : stmt.getTags()) {
// Debug.printDbg("assign primitive type from stmt tag: ", stmt, t);
if (t instanceof IntOpTag) {
DalvikTyper.v().setType(ce.getOpBox(), IntType.v(), false);
return;
} else if (t instanceof FloatOpTag) {
DalvikTyper.v().setType(ce.getOpBox(), FloatType.v(), false);
return;
} else if (t instanceof DoubleOpTag) {
DalvikTyper.v().setType(ce.getOpBox(), DoubleType.v(), false);
return;
} else if (t instanceof LongOpTag) {
DalvikTyper.v().setType(ce.getOpBox(), LongType.v(), false);
return;
}
}
} else {
// incoming type is object
DalvikTyper.v().setType(ce.getOpBox(), RefType.v("java.lang.Object"), false);
}
}
DalvikTyper.v().setType(stmt.getLeftOpBox(), rightType, false);
return;
}
}
@Override
public void caseIdentityStmt(IdentityStmt stmt) {
DalvikTyper.v().setType(stmt.getLeftOpBox(), stmt.getRightOp().getType(), false);
}
@Override
public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
// add constraint
DalvikTyper.v().setType(stmt.getOpBox(), RefType.v("java.lang.Object"), true);
}
@Override
public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
// add constraint
DalvikTyper.v().setType(stmt.getOpBox(), RefType.v("java.lang.Object"), true);
}
@Override
public void caseGotoStmt(GotoStmt stmt) {
// nothing
}
@Override
public void caseIfStmt(IfStmt stmt) {
// add constraint
Value c = stmt.getCondition();
if (c instanceof BinopExpr) {
BinopExpr bo = (BinopExpr) c;
Value op1 = bo.getOp1();
Value op2 = bo.getOp2();
if (op1 instanceof Local && op2 instanceof Local) {
DalvikTyper.v().addConstraint(bo.getOp1Box(), bo.getOp2Box());
}
}
}
@Override
public void caseLookupSwitchStmt(LookupSwitchStmt stmt) {
// add constraint
DalvikTyper.v().setType(stmt.getKeyBox(), IntType.v(), true);
}
@Override
public void caseNopStmt(NopStmt stmt) {
// nothing
}
@Override
public void caseRetStmt(RetStmt stmt) {
// nothing
}
@Override
public void caseReturnStmt(ReturnStmt stmt) {
// add constraint
DalvikTyper.v().setType(stmt.getOpBox(), b.getMethod().getReturnType(), true);
}
@Override
public void caseReturnVoidStmt(ReturnVoidStmt stmt) {
// nothing
}
@Override
public void caseTableSwitchStmt(TableSwitchStmt stmt) {
// add constraint
DalvikTyper.v().setType(stmt.getKeyBox(), IntType.v(), true);
}
@Override
public void caseThrowStmt(ThrowStmt stmt) {
// add constraint
DalvikTyper.v().setType(stmt.getOpBox(), RefType.v("java.lang.Object"), true);
}
@Override
public void defaultCase(Object obj) {
throw new RuntimeException("error: unknown statement: " + obj);
}
};
u.apply(ss);
}
// <com.admob.android.ads.q: void a(android.os.Bundle,java.lang.String,java.lang.Object)>
if (!todoUnits.isEmpty()) {
// propagate array types
UnitGraph ug = new ExceptionalUnitGraph(b);
SimpleLocalDefs sld = new SimpleLocalDefs(ug);
SimpleLocalUses slu = new SimpleLocalUses(b, sld);
for (Unit u : b.getUnits()) {
if (u instanceof DefinitionStmt) {
// Debug.printDbg("U: ", u);
DefinitionStmt ass = (DefinitionStmt) u;
Value r = ass.getRightOp();
if (r instanceof UntypedConstant)
continue;
Type rType = r.getType();
if (rType instanceof ArrayType && ass.getLeftOp() instanceof Local) {
// Debug.printDbg("propagate-array: checking ", u);
// propagate array type through aliases
Set<Unit> done = new HashSet<Unit>();
Set<DefinitionStmt> toDo = new HashSet<DefinitionStmt>();
toDo.add(ass);
while (!toDo.isEmpty()) {
DefinitionStmt currentUnit = toDo.iterator().next();
if (done.contains(currentUnit)) {
toDo.remove(currentUnit);
continue;
}
done.add(currentUnit);
for (UnitValueBoxPair uvbp : slu.getUsesOf(currentUnit)) {
Unit use = uvbp.unit;
Value l2 = null;
Value r2 = null;
if (use instanceof AssignStmt) {
AssignStmt ass2 = (AssignStmt) use;
l2 = ass2.getLeftOp();
r2 = ass2.getRightOp();
if (!(l2 instanceof Local) || !(r2 instanceof Local || r2 instanceof ArrayRef)) {
// Debug.printDbg("propagate-array: skipping ", use);
continue;
}
Type newType = null;
if (r2 instanceof Local) {
List<LocalObj> lobjs = local2Obj.get(r2);
newType = lobjs.get(0).t;
} else if (r2 instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) r2;
// skip if use is in index
if (ar.getIndex() == currentUnit.getLeftOp()) {
// Debug.printDbg("skipping since local is used as index...");
continue;
}
Local arBase = (Local) ar.getBase();
List<LocalObj> lobjs = local2Obj.get(arBase);
Type baseT = lobjs.get(0).t;
if (baseT.toString().equals(("java.lang.Object"))) {
// look for an array type, because an TTT[] is also an Object...
ArrayType aTypeOtherThanObject = null;
for (LocalObj lo : local2Obj.get(arBase)) {
if (lo.t instanceof ArrayType) {
aTypeOtherThanObject = (ArrayType) lo.t;
}
}
if (aTypeOtherThanObject == null) {
throw new RuntimeException("error: did not found array type for base " + arBase + " " + local2Obj.get(arBase) + " \n " + b);
}
baseT = aTypeOtherThanObject;
}
ArrayType at = (ArrayType) baseT;
newType = at.getElementType();
} else {
throw new RuntimeException("error: expected Local or ArrayRef. Got " + r2);
}
toDo.add((DefinitionStmt) use);
DalvikTyper.v().setType(ass2.getLeftOpBox(), newType, true);
}
}
}
}
}
}
for (Unit u : todoUnits) {
// Debug.printDbg("todo unit: ", u);
}
while (!todoUnits.isEmpty()) {
Unit u = todoUnits.iterator().next();
if (!(u instanceof AssignStmt)) {
throw new RuntimeException("error: expecting assign stmt. Got " + u);
}
AssignStmt ass = (AssignStmt) u;
Value l = ass.getLeftOp();
Value r = ass.getRightOp();
ArrayRef ar = null;
Local loc = null;
if (l instanceof ArrayRef) {
ar = (ArrayRef) l;
loc = (Local) r;
} else if (r instanceof ArrayRef) {
ar = (ArrayRef) r;
loc = (Local) l;
} else {
throw new RuntimeException("error: expecting an array ref. Got " + u);
}
Local baselocal = (Local) ar.getBase();
if (!local2Obj.containsKey(baselocal)) {
// Debug.printDbg("b: ", b.getMethod(), " \n", b);
throw new RuntimeException("oups");
}
Type baseT = local2Obj.get(baselocal).get(0).t;
if (baseT.toString().equals(("java.lang.Object"))) {
// look for an array type, because an TTT[] is also an Object...
ArrayType aTypeOtherThanObject = null;
for (LocalObj lo : local2Obj.get(baselocal)) {
if (lo.t instanceof ArrayType) {
aTypeOtherThanObject = (ArrayType) lo.t;
}
}
if (aTypeOtherThanObject == null) {
throw new RuntimeException("did not found array type for base " + baselocal + " " + local2Obj.get(baselocal) + " \n " + b);
}
baseT = aTypeOtherThanObject;
}
ArrayType basetype = (ArrayType) baseT;
// Debug.printDbg("v: ", ar, " base:", ar.getBase(), " base type: ", basetype, " type: ", ar.getType());
Type t = basetype.getElementType();
if (t instanceof UnknownType) {
todoUnits.add(u);
continue;
} else {
DalvikTyper.v().setType(ar == l ? ass.getRightOpBox() : ass.getLeftOpBox(), t, true);
todoUnits.remove(u);
}
}
// throw new RuntimeException("ouppppp");
}
// Debug.printDbg(IDalvikTyper.DEBUG, "list of constraints:");
List<ValueBox> vbList = b.getUseAndDefBoxes();
// clear constraints after local splitting and dead code eliminator
List<Constraint> toRemove = new ArrayList<Constraint>();
for (Constraint c : constraints) {
if (!vbList.contains(c.l)) {
// Debug.printDbg(IDalvikTyper.DEBUG, "warning: ", c.l, " not in locals! removing...");
toRemove.add(c);
continue;
}
if (!vbList.contains(c.r)) {
// Debug.printDbg(IDalvikTyper.DEBUG, "warning: ", c.r, " not in locals! removing...");
toRemove.add(c);
continue;
}
}
for (Constraint c : toRemove) constraints.remove(c);
// keep only valid locals
for (LocalObj lo : localObjList) {
if (!vbList.contains(lo.vb)) {
// Debug.printDbg(IDalvikTyper.DEBUG, " -- removing vb: ", lo.vb, " with type ", lo.t);
continue;
}
Local l = lo.getLocal();
Type t = lo.t;
if (localTemp.contains(l) && lo.isUse) {
// Debug.printDbg(IDalvikTyper.DEBUG, " /!\\ def already added for local ", l, "! for vb: ", lo.vb);
} else {
// Debug.printDbg(IDalvikTyper.DEBUG, " * add type ", t, " to local ", l, " for vb: ", lo.vb);
localTemp.add(l);
typed.put(lo.vb, t);
}
}
for (ValueBox vb : typed.keySet()) {
if (vb.getValue() instanceof Local) {
Local l = (Local) vb.getValue();
localTyped.put(l, typed.get(vb));
}
}
for (Constraint c : constraints) // Debug.printDbg(IDalvikTyper.DEBUG, " -> constraint: ", c);
for (ValueBox vb : typed.keySet()) {
// Debug.printDbg(IDalvikTyper.DEBUG, " typed: ", vb, " -> ", typed.get(vb));
}
for (Local l : localTyped.keySet()) {
// Debug.printDbg(IDalvikTyper.DEBUG, " localTyped: ", l, " -> ", localTyped.get(l));
}
while (!constraints.isEmpty()) {
boolean update = false;
for (Constraint c : constraints) {
// Debug.printDbg(IDalvikTyper.DEBUG, "current constraint: ", c);
Value l = c.l.getValue();
Value r = c.r.getValue();
if (l instanceof Local && r instanceof Constant) {
Constant cst = (Constant) r;
if (!localTyped.containsKey(l))
continue;
Type lt = localTyped.get(l);
// Debug.printDbg(IDalvikTyper.DEBUG, "would like to set type ", lt, " to constant: ", c);
Value newValue = null;
if (lt instanceof IntType || lt instanceof BooleanType || lt instanceof ShortType || lt instanceof CharType || lt instanceof ByteType) {
UntypedIntOrFloatConstant uf = (UntypedIntOrFloatConstant) cst;
newValue = uf.toIntConstant();
} else if (lt instanceof FloatType) {
UntypedIntOrFloatConstant uf = (UntypedIntOrFloatConstant) cst;
newValue = uf.toFloatConstant();
} else if (lt instanceof DoubleType) {
UntypedLongOrDoubleConstant ud = (UntypedLongOrDoubleConstant) cst;
newValue = ud.toDoubleConstant();
} else if (lt instanceof LongType) {
UntypedLongOrDoubleConstant ud = (UntypedLongOrDoubleConstant) cst;
newValue = ud.toLongConstant();
} else {
if (cst instanceof UntypedIntOrFloatConstant && ((UntypedIntOrFloatConstant) cst).value == 0) {
newValue = NullConstant.v();
// Debug.printDbg("new null constant for constraint ", c, " with l type: ", localTyped.get(l));
} else {
throw new RuntimeException("unknow type for constance: " + lt);
}
}
c.r.setValue(newValue);
// Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
constraints.remove(c);
update = true;
break;
} else if (l instanceof Local && r instanceof Local) {
Local leftLocal = (Local) l;
Local rightLocal = (Local) r;
if (localTyped.containsKey(leftLocal)) {
Type leftLocalType = localTyped.get(leftLocal);
if (!localTyped.containsKey(rightLocal)) {
// Debug.printDbg(IDalvikTyper.DEBUG, "set type ", leftLocalType, " to local ", rightLocal);
rightLocal.setType(leftLocalType);
setLocalTyped(rightLocal, leftLocalType);
}
// Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
constraints.remove(c);
update = true;
break;
} else if (localTyped.containsKey(rightLocal)) {
Type rightLocalType = localTyped.get(rightLocal);
if (!localTyped.containsKey(leftLocal)) {
// Debug.printDbg(IDalvikTyper.DEBUG, "set type ", rightLocalType, " to local ", leftLocal);
leftLocal.setType(rightLocalType);
setLocalTyped(leftLocal, rightLocalType);
}
// Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
constraints.remove(c);
update = true;
break;
}
} else if (l instanceof ArrayRef && r instanceof Local) {
Local rightLocal = (Local) r;
ArrayRef ar = (ArrayRef) l;
Local base = (Local) ar.getBase();
// Debug.printDbg(IDalvikTyper.DEBUG, "index: ", ar.getIndex());
if (localTyped.containsKey(base)) {
Type t = localTyped.get(base);
// Debug.printDbg(IDalvikTyper.DEBUG, "type of local1: ", t, " ", t.getClass());
Type elementType = null;
if (t instanceof ArrayType) {
ArrayType at = (ArrayType) t;
elementType = at.getArrayElementType();
} else {
continue;
}
if (!localTyped.containsKey(rightLocal)) {
// Debug.printDbg(IDalvikTyper.DEBUG, "set type ", elementType, " to local ", r);
rightLocal.setType(elementType);
setLocalTyped(rightLocal, elementType);
}
// Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
constraints.remove(c);
update = true;
break;
}
} else if (l instanceof Local && r instanceof ArrayRef) {
Local leftLocal = (Local) l;
ArrayRef ar = (ArrayRef) r;
Local base = (Local) ar.getBase();
if (localTyped.containsKey(base)) {
Type t = localTyped.get(base);
// Debug.printDbg(IDalvikTyper.DEBUG, "type of local2: ", t, " ", t.getClass());
Type elementType = null;
if (t instanceof ArrayType) {
ArrayType at = (ArrayType) t;
elementType = at.getArrayElementType();
} else {
continue;
}
if (!localTyped.containsKey(leftLocal)) {
// Debug.printDbg(IDalvikTyper.DEBUG, "set type ", elementType, " to local ", l);
leftLocal.setType(elementType);
setLocalTyped(leftLocal, elementType);
}
// Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
constraints.remove(c);
update = true;
break;
}
} else {
throw new RuntimeException("error: do not handling this kind of constraint: " + c);
}
}
if (!update)
break;
}
for (Unit u : b.getUnits()) {
if (!(u instanceof AssignStmt))
continue;
AssignStmt ass = (AssignStmt) u;
if (!(ass.getLeftOp() instanceof Local))
continue;
if (!(ass.getRightOp() instanceof UntypedConstant))
continue;
UntypedConstant uc = (UntypedConstant) ass.getRightOp();
ass.setRightOp(uc.defineType(localTyped.get(ass.getLeftOp())));
}
//
for (Constraint c : constraints) {
// Debug.printDbg(IDalvikTyper.DEBUG, "current constraint: ", c);
Value l = c.l.getValue();
Value r = c.r.getValue();
if (l instanceof Local && r instanceof Constant) {
if (r instanceof UntypedIntOrFloatConstant) {
UntypedIntOrFloatConstant cst = (UntypedIntOrFloatConstant) r;
Value newValue = null;
if (cst.value != 0) {
// Debug.printDbg(IDalvikTyper.DEBUG, "[untyped constaints] set type int to non zero constant: ", c, " = ", cst.value);
newValue = cst.toIntConstant();
} else {
// check if used in cast, just in case...
for (Unit u : b.getUnits()) {
for (ValueBox vb1 : u.getUseBoxes()) {
Value v1 = vb1.getValue();
if (v1 == l) {
// Debug.printDbg("local used in ", u);
if (u instanceof AssignStmt) {
AssignStmt a = (AssignStmt) u;
Value right = a.getRightOp();
if (right instanceof CastExpr) {
newValue = NullConstant.v();
} else {
newValue = cst.toIntConstant();
}
} else if (u instanceof IfStmt) {
// TODO check this better
newValue = cst.toIntConstant();
}
}
}
}
}
if (newValue == null) {
throw new RuntimeException("error: no type found for local: " + l);
}
c.r.setValue(newValue);
} else if (r instanceof UntypedLongOrDoubleConstant) {
// Debug.printDbg(IDalvikTyper.DEBUG, "[untyped constaints] set type long to constant: ", c);
Value newValue = ((UntypedLongOrDoubleConstant) r).toLongConstant();
c.r.setValue(newValue);
}
}
}
// fix untypedconstants which have flown to an array index
for (Unit u : b.getUnits()) {
StmtSwitch sw = new StmtSwitch() {
@Override
public void caseBreakpointStmt(BreakpointStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseInvokeStmt(InvokeStmt stmt) {
changeUntypedConstantsInInvoke(stmt.getInvokeExpr());
}
@Override
public void caseAssignStmt(AssignStmt stmt) {
if (stmt.getRightOp() instanceof NewArrayExpr) {
NewArrayExpr nae = (NewArrayExpr) stmt.getRightOp();
if (nae.getSize() instanceof UntypedConstant) {
UntypedIntOrFloatConstant uc = (UntypedIntOrFloatConstant) nae.getSize();
nae.setSize(uc.defineType(IntType.v()));
}
} else if (stmt.getRightOp() instanceof UntypedConstant) {
UntypedConstant uc = (UntypedConstant) stmt.getRightOp();
Value l = stmt.getLeftOp();
Type lType = null;
if (l instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) l;
Local baseLocal = (Local) ar.getBase();
ArrayType arrayType = (ArrayType) localTyped.get(baseLocal);
lType = arrayType.getElementType();
} else {
lType = l.getType();
}
stmt.setRightOp(uc.defineType(lType));
} else if (stmt.getRightOp() instanceof InvokeExpr) {
changeUntypedConstantsInInvoke((InvokeExpr) stmt.getRightOp());
}
if (!stmt.containsArrayRef()) {
return;
}
ArrayRef ar = stmt.getArrayRef();
if ((ar.getIndex() instanceof UntypedConstant)) {
UntypedIntOrFloatConstant uc = (UntypedIntOrFloatConstant) ar.getIndex();
ar.setIndex(uc.toIntConstant());
}
if (stmt.getLeftOp() instanceof ArrayRef && stmt.getRightOp() instanceof UntypedConstant) {
UntypedConstant uc = (UntypedConstant) stmt.getRightOp();
Local baseLocal = (Local) stmt.getArrayRef().getBase();
ArrayType lType = (ArrayType) localTyped.get(baseLocal);
Type elemType = lType.getElementType();
stmt.setRightOp(uc.defineType(elemType));
}
}
@Override
public void caseIdentityStmt(IdentityStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseGotoStmt(GotoStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseIfStmt(IfStmt stmt) {
Value c = stmt.getCondition();
if (c instanceof BinopExpr) {
BinopExpr be = (BinopExpr) c;
Value op1 = be.getOp1();
Value op2 = be.getOp2();
if (op1 instanceof UntypedConstant || op2 instanceof UntypedConstant) {
if (op1 instanceof Local) {
Type t = localTyped.get(op1);
// Debug.printDbg("if op1 type: ", t);
UntypedConstant uc = (UntypedConstant) op2;
be.setOp2(uc.defineType(t));
} else if (op2 instanceof Local) {
Type t = localTyped.get(op2);
// Debug.printDbg("if op2 type: ", t);
UntypedConstant uc = (UntypedConstant) op1;
be.setOp1(uc.defineType(t));
} else if (op1 instanceof UntypedConstant && op2 instanceof UntypedConstant) {
if (op1 instanceof UntypedIntOrFloatConstant && op2 instanceof UntypedIntOrFloatConstant) {
UntypedIntOrFloatConstant uc1 = (UntypedIntOrFloatConstant) op1;
UntypedIntOrFloatConstant uc2 = (UntypedIntOrFloatConstant) op2;
// to int or float, it does not matter
be.setOp1(uc1.toIntConstant());
be.setOp2(uc2.toIntConstant());
} else if (op1 instanceof UntypedLongOrDoubleConstant && op2 instanceof UntypedLongOrDoubleConstant) {
UntypedLongOrDoubleConstant uc1 = (UntypedLongOrDoubleConstant) op1;
UntypedLongOrDoubleConstant uc2 = (UntypedLongOrDoubleConstant) op2;
// to long or double, it does not matter
be.setOp1(uc1.toLongConstant());
be.setOp2(uc2.toLongConstant());
} else {
throw new RuntimeException("error: expected same type of untyped constants. Got " + stmt);
}
} else if (op1 instanceof UntypedConstant || op2 instanceof UntypedConstant) {
if (op1 instanceof UntypedConstant) {
UntypedConstant uc = (UntypedConstant) op1;
be.setOp1(uc.defineType(op2.getType()));
} else if (op2 instanceof UntypedConstant) {
UntypedConstant uc = (UntypedConstant) op2;
be.setOp2(uc.defineType(op1.getType()));
}
} else {
throw new RuntimeException("error: expected local/untyped untyped/local or untyped/untyped. Got " + stmt);
}
}
} else if (c instanceof UnopExpr) {
} else {
throw new RuntimeException("error: expected binop or unop. Got " + stmt);
}
}
@Override
public void caseLookupSwitchStmt(LookupSwitchStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseNopStmt(NopStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseRetStmt(RetStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseReturnStmt(ReturnStmt stmt) {
if (stmt.getOp() instanceof UntypedConstant) {
UntypedConstant uc = (UntypedConstant) stmt.getOp();
Type type = b.getMethod().getReturnType();
stmt.setOp(uc.defineType(type));
}
}
@Override
public void caseReturnVoidStmt(ReturnVoidStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseTableSwitchStmt(TableSwitchStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseThrowStmt(ThrowStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void defaultCase(Object obj) {
// TODO Auto-generated method stub
}
};
u.apply(sw);
}
// fix untyped constants remaining
// Debug.printDbg("assignTypes: after: \n", b);
}
use of soot.LongType in project soot by Sable.
the class TypeCastingError method inASTStatementSequenceNode.
public void inASTStatementSequenceNode(ASTStatementSequenceNode node) {
for (AugmentedStmt as : node.getStatements()) {
Stmt s = as.get_Stmt();
if (!(s instanceof DefinitionStmt))
continue;
DefinitionStmt ds = (DefinitionStmt) s;
if (myDebug)
System.out.println("Definition stmt" + ds);
ValueBox rightBox = ds.getRightOpBox();
ValueBox leftBox = ds.getLeftOpBox();
Value right = rightBox.getValue();
Value left = leftBox.getValue();
if (!(left.getType() instanceof PrimType && right.getType() instanceof PrimType)) {
// only interested in prim type casting errors
if (myDebug)
System.out.println("\tDefinition stmt does not contain prims no need to modify");
continue;
}
Type leftType = left.getType();
Type rightType = right.getType();
if (myDebug)
System.out.println("Left type is: " + leftType);
if (myDebug)
System.out.println("Right type is: " + rightType);
if (leftType.equals(rightType)) {
if (myDebug)
System.out.println("\tTypes are the same");
if (myDebug)
System.out.println("Right value is of instance" + right.getClass());
}
if (!leftType.equals(rightType)) {
if (myDebug)
System.out.println("\tDefinition stmt has to be modified");
/*
* byte Byte-length integer 8-bit two's complement
* short Short integer 16-bit two's complement
* int Integer 32-bit two's complement
* long Long integer 64-bit two's complement
* float Single-precision floating point 32-bit IEEE 754
* double Double-precision floating point 64-bit IEEE 754
*/
if (leftType instanceof ByteType && (rightType instanceof DoubleType || rightType instanceof FloatType || rightType instanceof IntType || rightType instanceof LongType || rightType instanceof ShortType)) {
if (DEBUG)
System.out.println("Explicit casting to BYTE required");
rightBox.setValue(new GCastExpr(right, ByteType.v()));
if (DEBUG)
System.out.println("New right expr is " + rightBox.getValue().toString());
continue;
}
if (leftType instanceof ShortType && (rightType instanceof DoubleType || rightType instanceof FloatType || rightType instanceof IntType || rightType instanceof LongType)) {
if (DEBUG)
System.out.println("Explicit casting to SHORT required");
rightBox.setValue(new GCastExpr(right, ShortType.v()));
if (DEBUG)
System.out.println("New right expr is " + rightBox.getValue().toString());
continue;
}
if (leftType instanceof IntType && (rightType instanceof DoubleType || rightType instanceof FloatType || rightType instanceof LongType)) {
if (myDebug)
System.out.println("Explicit casting to INT required");
rightBox.setValue(new GCastExpr(right, IntType.v()));
if (myDebug)
System.out.println("New right expr is " + rightBox.getValue().toString());
continue;
}
if (leftType instanceof LongType && (rightType instanceof DoubleType || rightType instanceof FloatType)) {
if (DEBUG)
System.out.println("Explicit casting to LONG required");
rightBox.setValue(new GCastExpr(right, LongType.v()));
if (DEBUG)
System.out.println("New right expr is " + rightBox.getValue().toString());
continue;
}
if (leftType instanceof FloatType && rightType instanceof DoubleType) {
if (DEBUG)
System.out.println("Explicit casting to FLOAT required");
rightBox.setValue(new GCastExpr(right, FloatType.v()));
if (DEBUG)
System.out.println("New right expr is " + rightBox.getValue().toString());
continue;
}
}
}
}
use of soot.LongType in project soot by Sable.
the class DavaPrinter method printTo.
public void printTo(SootClass cl, PrintWriter out) {
// IterableSet packagesUsed = new IterableSet();
IterableSet importList = new IterableSet();
{
String curPackage = cl.getJavaPackageName();
if (!curPackage.equals("")) {
out.println("package " + curPackage + ";");
out.println();
}
if (cl.hasSuperclass()) {
SootClass superClass = cl.getSuperclass();
importList.add(superClass.toString());
// packagesUsed.add(superClass.getJavaPackageName());
}
Iterator<SootClass> interfaceIt = cl.getInterfaces().iterator();
while (interfaceIt.hasNext()) {
String interfacePackage = ((SootClass) interfaceIt.next()).toString();
if (!importList.contains(interfacePackage))
importList.add(interfacePackage);
// if (!packagesUsed.contains(interfacePackage))
// packagesUsed.add(interfacePackage);
}
Iterator<SootMethod> methodIt = cl.methodIterator();
while (methodIt.hasNext()) {
SootMethod dm = (SootMethod) methodIt.next();
if (dm.hasActiveBody()) {
// packagesUsed = packagesUsed.union(((DavaBody) dm.getActiveBody()).get_PackagesUsed());
importList = importList.union(((DavaBody) dm.getActiveBody()).getImportList());
}
Iterator<SootClass> eit = dm.getExceptions().iterator();
while (eit.hasNext()) {
String thrownPackage = eit.next().toString();
if (!importList.contains(thrownPackage))
importList.add(thrownPackage);
// if (!packagesUsed.contains(thrownPackage))
// packagesUsed.add(thrownPackage);
}
Iterator<Type> pit = dm.getParameterTypes().iterator();
while (pit.hasNext()) {
Type t = (Type) pit.next();
if (t instanceof RefType) {
String paramPackage = ((RefType) t).getSootClass().toString();
if (!importList.contains(paramPackage))
importList.add(paramPackage);
// if (packagesUsed.contains(paramPackage) == false)
// packagesUsed.add(paramPackage);
}
}
Type t = dm.getReturnType();
if (t instanceof RefType) {
String returnPackage = ((RefType) t).getSootClass().toString();
if (!importList.contains(returnPackage))
importList.add(returnPackage);
// if (packagesUsed.contains(returnPackage) == false)
// packagesUsed.add(returnPackage);
}
}
Iterator<SootField> fieldIt = cl.getFields().iterator();
while (fieldIt.hasNext()) {
SootField f = (SootField) fieldIt.next();
if (f.isPhantom())
continue;
Type t = f.getType();
if (t instanceof RefType) {
String fieldPackage = ((RefType) t).getSootClass().toString();
if (!importList.contains(fieldPackage))
importList.add(fieldPackage);
}
}
Iterator<String> pit = importList.iterator();
List<String> toImport = new ArrayList<String>();
while (pit.hasNext()) {
/*
* dont import any file which has currentPackage.className
* dont import any file which starts with java.lang
*/
String temp = (String) pit.next();
// System.out.println("temp is "+temp);
if (temp.indexOf("java.lang") > -1) {
// problem is that we need to import sub packages java.lang.ref
// for instance if the type is java.lang.ref.WeakReference
String tempClassName = RemoveFullyQualifiedName.getClassName(temp);
if (temp.equals("java.lang." + tempClassName)) {
// System.out.println("temp was not printed as it belongs to java.lang");
continue;
}
}
if (curPackage.length() > 0 && temp.indexOf(curPackage) > -1) {
// System.out.println("here "+temp);
continue;
}
if (cl.toString().equals(temp))
continue;
// System.out.println("printing"+);
toImport.add(temp);
}
/*
* Check that we are not importing two classes with the same last name
* If yes then remove explicit import and import the whole package
* else output explicit import statement
*/
Iterator it = toImport.iterator();
while (it.hasNext()) {
String temp = (String) it.next();
if (RemoveFullyQualifiedName.containsMultiple(toImport.iterator(), temp, null)) {
// import package add *
if (temp.lastIndexOf('.') > -1) {
temp = temp.substring(0, temp.lastIndexOf('.'));
out.println("import " + temp + ".*;");
} else
throw new DecompilationException("Cant find the DOT . for fullyqualified name");
} else {
if (temp.lastIndexOf('.') == -1) {
// dot not found this is a class belonging to this package so dont add
} else
out.println("import " + temp + ";");
}
}
boolean addNewLine = false;
addNewLine = true;
if (addNewLine)
out.println();
/*if (!packagesUsed.isEmpty())
out.println();
packagesUsed.add("java.lang");
packagesUsed.add(curPackage);
*/
Dava.v().set_CurrentPackageContext(importList);
// Dava.v().set_CurrentPackageContext(packagesUsed);
Dava.v().set_CurrentPackage(curPackage);
}
// Print class name + modifiers
{
String classPrefix = "";
classPrefix = classPrefix + " " + Modifier.toString(cl.getModifiers());
classPrefix = classPrefix.trim();
if (!cl.isInterface()) {
classPrefix = classPrefix + " class";
classPrefix = classPrefix.trim();
}
out.print(classPrefix + " " + cl.getShortJavaStyleName());
}
// Print extension
if (cl.hasSuperclass() && !(cl.getSuperclass().getName().equals("java.lang.Object"))) {
String superClassName = cl.getSuperclass().getName();
// Nomair Naeem 8th Feb 2006
// also check if the super class name is not a fully qualified
// name. in which case if the package is imported no need for
// the long name
superClassName = RemoveFullyQualifiedName.getReducedName(importList, superClassName, cl.getType());
out.print(" extends " + superClassName + "");
}
// Print interfaces
{
Iterator<SootClass> interfaceIt = cl.getInterfaces().iterator();
if (interfaceIt.hasNext()) {
if (cl.isInterface())
out.print(" extends ");
else
out.print(" implements ");
out.print("" + (interfaceIt.next()).getName() + "");
while (interfaceIt.hasNext()) out.print(", " + (interfaceIt.next()).getName() + "");
}
}
out.println();
out.println("{");
// Print fields
{
Iterator<SootField> fieldIt = cl.getFields().iterator();
if (fieldIt.hasNext()) {
while (fieldIt.hasNext()) {
SootField f = fieldIt.next();
if (f.isPhantom())
continue;
String declaration = null;
Type fieldType = f.getType();
String qualifiers = Modifier.toString(f.getModifiers()) + " ";
qualifiers += RemoveFullyQualifiedName.getReducedName(importList, fieldType.toString(), fieldType);
qualifiers = qualifiers.trim();
if (qualifiers.equals(""))
declaration = Scene.v().quotedNameOf(f.getName());
else
declaration = qualifiers + " " + Scene.v().quotedNameOf(f.getName()) + "";
if (f.isFinal() && f.isStatic()) {
if (fieldType instanceof DoubleType && f.hasTag("DoubleConstantValueTag")) {
double val = ((DoubleConstantValueTag) f.getTag("DoubleConstantValueTag")).getDoubleValue();
out.println(" " + declaration + " = " + val + ";");
} else if (fieldType instanceof FloatType && f.hasTag("FloatConstantValueTag")) {
float val = ((FloatConstantValueTag) f.getTag("FloatConstantValueTag")).getFloatValue();
out.println(" " + declaration + " = " + val + "f;");
} else if (fieldType instanceof LongType && f.hasTag("LongConstantValueTag")) {
long val = ((LongConstantValueTag) f.getTag("LongConstantValueTag")).getLongValue();
out.println(" " + declaration + " = " + val + "l;");
} else if (fieldType instanceof CharType && f.hasTag("IntegerConstantValueTag")) {
int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
out.println(" " + declaration + " = '" + ((char) val) + "';");
} else if (fieldType instanceof BooleanType && f.hasTag("IntegerConstantValueTag")) {
int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
if (val == 0)
out.println(" " + declaration + " = false;");
else
out.println(" " + declaration + " = true;");
} else if ((fieldType instanceof IntType || fieldType instanceof ByteType || fieldType instanceof ShortType) && f.hasTag("IntegerConstantValueTag")) {
int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
out.println(" " + declaration + " = " + val + ";");
} else if (f.hasTag("StringConstantValueTag")) {
String val = ((StringConstantValueTag) f.getTag("StringConstantValueTag")).getStringValue();
out.println(" " + declaration + " = \"" + val + "\";");
} else {
// System.out.println("Couldnt find type of
// field"+f.getDeclaration());
out.println(" " + declaration + ";");
}
} else // field is static final
{
out.println(" " + declaration + ";");
}
}
}
}
// Print methods
{
Iterator<SootMethod> methodIt = cl.methodIterator();
if (methodIt.hasNext()) {
if (cl.getMethodCount() != 0)
out.println();
while (methodIt.hasNext()) {
SootMethod method = (SootMethod) methodIt.next();
if (method.isPhantom())
continue;
if (!Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers())) {
if (!method.hasActiveBody())
throw new RuntimeException("method " + method.getName() + " has no active body!");
else
printTo(method.getActiveBody(), out);
if (methodIt.hasNext())
out.println();
} else {
// if method is abstract then print the declaration
out.print(" ");
out.print(method.getDavaDeclaration());
out.println(";");
if (methodIt.hasNext())
out.println();
}
}
}
}
if (G.v().SootClassNeedsDavaSuperHandlerClass.contains(cl)) {
out.println("\n private static class DavaSuperHandler{");
out.println(" java.util.Vector myVector = new java.util.Vector();");
out.println("\n public Object get(int pos){");
out.println(" return myVector.elementAt(pos);");
out.println(" }");
out.println("\n public void store(Object obj){");
out.println(" myVector.add(obj);");
out.println(" }");
out.println(" }");
}
out.println("}");
}
use of soot.LongType in project soot by Sable.
the class ExprVisitor method caseNegExpr.
@Override
public void caseNegExpr(NegExpr ne) {
Value source = ne.getOp();
constantV.setOrigStmt(origStmt);
Register sourceReg = regAlloc.asImmediate(source, constantV);
Opcode opc;
Type type = source.getType();
if (type instanceof IntegerType) {
opc = Opcode.NEG_INT;
} else if (type instanceof FloatType) {
opc = Opcode.NEG_FLOAT;
} else if (type instanceof DoubleType) {
opc = Opcode.NEG_DOUBLE;
} else if (type instanceof LongType) {
opc = Opcode.NEG_LONG;
} else {
throw new RuntimeException("unsupported value type for neg-* opcode: " + type);
}
stmtV.addInsn(new Insn12x(opc, destinationReg, sourceReg), origStmt);
}
use of soot.LongType in project soot by Sable.
the class ArithmeticTransformer method internalTransform.
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
int weight = soot.jbco.Main.getWeight(phaseName, b.getMethod().getSignature());
if (weight == 0) {
return;
}
PatchingChain<Unit> units = b.getUnits();
int localCount = 0;
Chain<Local> locals = b.getLocals();
if (output) {
out.println("*** Performing Arithmetic Transformation on " + b.getMethod().getSignature());
}
Iterator<Unit> it = units.snapshotIterator();
while (it.hasNext()) {
Unit u = it.next();
if (u instanceof AssignStmt) {
AssignStmt as = (AssignStmt) u;
Value v = as.getRightOp();
if (v instanceof MulExpr) {
total++;
MulExpr me = (MulExpr) v;
Value op1 = me.getOp1();
Value op = null, op2 = me.getOp2();
NumericConstant nc = null;
if (op1 instanceof NumericConstant) {
nc = (NumericConstant) op1;
op = op2;
} else if (op2 instanceof NumericConstant) {
nc = (NumericConstant) op2;
op = op1;
}
if (nc != null) {
if (output) {
out.println("Considering: " + as + "\r");
}
Type opType = op.getType();
int max = opType instanceof IntType ? 32 : opType instanceof LongType ? 64 : 0;
if (max != 0) {
Object[] shft_rem = checkNumericValue(nc);
if (shft_rem[0] != null && (Integer) shft_rem[0] < max && Rand.getInt(10) <= weight) {
List<Unit> unitsBuilt = new ArrayList<>();
int rand = Rand.getInt(16);
int shift = (Integer) shft_rem[0];
boolean neg = (Boolean) shft_rem[2];
if (rand % 2 == 0) {
shift += rand * max;
} else {
shift -= rand * max;
}
Expr e;
if (shft_rem[1] != null) {
// if there is an additive floating component
Local tmp2 = null, tmp1 = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, opType);
locals.add(tmp1);
// shift the integral portion
Unit newU = Jimple.v().newAssignStmt(tmp1, Jimple.v().newShlExpr(op, IntConstant.v(shift)));
unitsBuilt.add(newU);
units.insertBefore(newU, u);
// grab remainder (that not part of the 2^x)
double rem = (Double) shft_rem[1];
if (rem != 1) {
if (rem == ((int) rem) && opType instanceof IntType) {
nc = IntConstant.v((int) rem);
} else if (rem == ((long) rem) && opType instanceof LongType) {
nc = LongConstant.v((long) rem);
} else {
nc = DoubleConstant.v(rem);
}
if (nc instanceof DoubleConstant) {
tmp2 = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, DoubleType.v());
locals.add(tmp2);
newU = Jimple.v().newAssignStmt(tmp2, Jimple.v().newCastExpr(op, DoubleType.v()));
unitsBuilt.add(newU);
units.insertBefore(newU, u);
newU = Jimple.v().newAssignStmt(tmp2, Jimple.v().newMulExpr(tmp2, nc));
} else {
tmp2 = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, nc.getType());
locals.add(tmp2);
newU = Jimple.v().newAssignStmt(tmp2, Jimple.v().newMulExpr(op, nc));
}
unitsBuilt.add(newU);
units.insertBefore(newU, u);
}
if (tmp2 == null) {
e = Jimple.v().newAddExpr(tmp1, op);
} else if (tmp2.getType().getClass() != tmp1.getType().getClass()) {
Local tmp3 = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, tmp2.getType());
locals.add(tmp3);
newU = Jimple.v().newAssignStmt(tmp3, Jimple.v().newCastExpr(tmp1, tmp2.getType()));
unitsBuilt.add(newU);
units.insertBefore(newU, u);
e = Jimple.v().newAddExpr(tmp3, tmp2);
} else {
e = Jimple.v().newAddExpr(tmp1, tmp2);
}
} else {
e = Jimple.v().newShlExpr(op, IntConstant.v(shift));
}
if (e.getType().getClass() != as.getLeftOp().getType().getClass()) {
Local tmp = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, e.getType());
locals.add(tmp);
Unit newU = Jimple.v().newAssignStmt(tmp, e);
unitsBuilt.add(newU);
units.insertAfter(newU, u);
e = Jimple.v().newCastExpr(tmp, as.getLeftOp().getType());
}
as.setRightOp(e);
unitsBuilt.add(as);
if (neg) {
Unit newU = Jimple.v().newAssignStmt(as.getLeftOp(), Jimple.v().newNegExpr(as.getLeftOp()));
unitsBuilt.add(newU);
units.insertAfter(newU, u);
}
mulPerformed++;
printOutput(unitsBuilt);
}
}
}
} else if (v instanceof DivExpr) {
total++;
DivExpr de = (DivExpr) v;
Value op2 = de.getOp2();
NumericConstant nc;
if (op2 instanceof NumericConstant) {
nc = (NumericConstant) op2;
Type opType = de.getOp1().getType();
int max = opType instanceof IntType ? 32 : opType instanceof LongType ? 64 : 0;
if (max != 0) {
Object[] shft_rem = checkNumericValue(nc);
if (shft_rem[0] != null && (shft_rem[1] == null || (Double) shft_rem[1] == 0) && (Integer) shft_rem[0] < max && Rand.getInt(10) <= weight) {
List<Unit> unitsBuilt = new ArrayList<>();
int rand = Rand.getInt(16);
int shift = (Integer) shft_rem[0];
boolean neg = (Boolean) shft_rem[2];
if (Rand.getInt() % 2 == 0) {
shift += rand * max;
} else {
shift -= rand * max;
}
Expr e = Jimple.v().newShrExpr(de.getOp1(), IntConstant.v(shift));
if (e.getType().getClass() != as.getLeftOp().getType().getClass()) {
Local tmp = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, e.getType());
locals.add(tmp);
Unit newU = Jimple.v().newAssignStmt(tmp, e);
unitsBuilt.add(newU);
units.insertAfter(newU, u);
e = Jimple.v().newCastExpr(tmp, as.getLeftOp().getType());
}
as.setRightOp(e);
unitsBuilt.add(as);
if (neg) {
Unit newU = Jimple.v().newAssignStmt(as.getLeftOp(), Jimple.v().newNegExpr(as.getLeftOp()));
unitsBuilt.add(newU);
units.insertAfter(newU, u);
}
divPerformed++;
printOutput(unitsBuilt);
}
}
}
}
}
}
}
Aggregations