use of soot.jimple.AssignStmt in project soot by Sable.
the class ReflectiveCallsInliner method inlineRelectiveCalls.
private void inlineRelectiveCalls(SootMethod m, Set<String> targets, Kind callKind) {
if (!m.hasActiveBody())
m.retrieveActiveBody();
Body b = m.getActiveBody();
PatchingChain<Unit> units = b.getUnits();
Iterator<Unit> iter = units.snapshotIterator();
LocalGenerator localGen = new LocalGenerator(b);
// for all units
while (iter.hasNext()) {
Chain<Unit> newUnits = new HashChain<Unit>();
Stmt s = (Stmt) iter.next();
// reflective invoke expression
if (s.containsInvokeExpr()) {
InvokeExpr ie = s.getInvokeExpr();
boolean found = false;
Type fieldSetGetType = null;
if (callKind == Kind.ClassForName && (ie.getMethodRef().getSignature().equals("<java.lang.Class: java.lang.Class forName(java.lang.String)>") || ie.getMethodRef().getSignature().equals("<java.lang.Class: java.lang.Class forName(java.lang.String,boolean,java.lang.ClassLoader)>"))) {
found = true;
Value classNameValue = ie.getArg(0);
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownClassForName(int,java.lang.String)>").makeRef(), IntConstant.v(callSiteId), classNameValue)));
} else if (callKind == Kind.ClassNewInstance && ie.getMethodRef().getSignature().equals("<java.lang.Class: java.lang.Object newInstance()>")) {
found = true;
Local classLocal = (Local) ((InstanceInvokeExpr) ie).getBase();
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownClassNewInstance(int,java.lang.Class)>").makeRef(), IntConstant.v(callSiteId), classLocal)));
} else if (callKind == Kind.ConstructorNewInstance && ie.getMethodRef().getSignature().equals("<java.lang.reflect.Constructor: java.lang.Object newInstance(java.lang.Object[])>")) {
found = true;
Local constrLocal = (Local) ((InstanceInvokeExpr) ie).getBase();
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownConstructorNewInstance(int,java.lang.reflect.Constructor)>").makeRef(), IntConstant.v(callSiteId), constrLocal)));
} else if (callKind == Kind.MethodInvoke && ie.getMethodRef().getSignature().equals("<java.lang.reflect.Method: java.lang.Object invoke(java.lang.Object,java.lang.Object[])>")) {
found = true;
Local methodLocal = (Local) ((InstanceInvokeExpr) ie).getBase();
Value recv = ie.getArg(0);
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownMethodInvoke(int,java.lang.Object,java.lang.reflect.Method)>").makeRef(), IntConstant.v(callSiteId), recv, methodLocal)));
} else if (callKind == Kind.FieldSet) {
SootMethod sootMethod = ie.getMethodRef().resolve();
if (sootMethod.getDeclaringClass().getName().equals("java.lang.reflect.Field") && fieldSets.contains(sootMethod.getName())) {
found = true;
// assign
fieldSetGetType = sootMethod.getParameterType(1);
// type
// of
// 2nd
// parameter
// (1st
// is
// receiver
// object)
Value recv = ie.getArg(0);
Value field = ((InstanceInvokeExpr) ie).getBase();
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownFieldSet(int,java.lang.Object,java.lang.reflect.Field)>").makeRef(), IntConstant.v(callSiteId), recv, field)));
}
} else if (callKind == Kind.FieldGet) {
SootMethod sootMethod = ie.getMethodRef().resolve();
if (sootMethod.getDeclaringClass().getName().equals("java.lang.reflect.Field") && fieldGets.contains(sootMethod.getName())) {
found = true;
// assign
fieldSetGetType = sootMethod.getReturnType();
// return
// type
// of
// get
Value recv = ie.getArg(0);
Value field = ((InstanceInvokeExpr) ie).getBase();
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownFieldSet(int,java.lang.Object,java.lang.reflect.Field)>").makeRef(), IntConstant.v(callSiteId), recv, field)));
}
}
if (!found)
continue;
NopStmt endLabel = Jimple.v().newNopStmt();
// for all recorded targets
for (String target : targets) {
NopStmt jumpTarget = Jimple.v().newNopStmt();
// boolean predLocal = Opaque.getFalse();
Local predLocal = localGen.generateLocal(BooleanType.v());
StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(UNINTERPRETED_METHOD);
newUnits.add(Jimple.v().newAssignStmt(predLocal, staticInvokeExpr));
// if predLocal == 0 goto <original reflective call>
newUnits.add(Jimple.v().newIfStmt(Jimple.v().newEqExpr(IntConstant.v(0), predLocal), jumpTarget));
SootMethod newMethod = createNewMethod(callKind, target, fieldSetGetType);
List<Value> args = new LinkedList<Value>();
switch(callKind) {
case ClassForName:
case ClassNewInstance:
// no arguments
break;
case ConstructorNewInstance:
// add Object[] argument
args.add((Value) ie.getArgs().get(0));
break;
case MethodInvoke:
// add Object argument
args.add((Value) ie.getArgs().get(0));
// add Object[] argument
args.add((Value) ie.getArgs().get(1));
break;
case FieldSet:
// add Object argument
args.add((Value) ie.getArgs().get(0));
// add value argument
args.add((Value) ie.getArgs().get(1));
break;
case FieldGet:
// add Object argument
args.add((Value) ie.getArgs().get(0));
break;
default:
throw new IllegalStateException();
}
StaticInvokeExpr methodInvokeExpr = Jimple.v().newStaticInvokeExpr(newMethod.makeRef(), args);
Local retLocal = localGen.generateLocal(newMethod.getReturnType());
newUnits.add(Jimple.v().newAssignStmt(retLocal, methodInvokeExpr));
if (s instanceof AssignStmt) {
AssignStmt assignStmt = (AssignStmt) s;
Value leftOp = assignStmt.getLeftOp();
AssignStmt newAssignStmt = Jimple.v().newAssignStmt(leftOp, retLocal);
newUnits.add(newAssignStmt);
}
GotoStmt gotoStmt = Jimple.v().newGotoStmt(endLabel);
newUnits.add(gotoStmt);
newUnits.add(jumpTarget);
}
Unit end = newUnits.getLast();
units.insertAfter(newUnits, s);
units.remove(s);
units.insertAfter(s, end);
units.insertAfter(endLabel, s);
}
}
callSiteId++;
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class TypeResolverBV method split_new.
private void split_new() {
LocalDefs defs = LocalDefs.Factory.newLocalDefs(stmtBody);
PatchingChain<Unit> units = stmtBody.getUnits();
Stmt[] stmts = new Stmt[units.size()];
units.toArray(stmts);
for (Stmt stmt : stmts) {
if (stmt instanceof InvokeStmt) {
InvokeStmt invoke = (InvokeStmt) stmt;
if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) {
SpecialInvokeExpr special = (SpecialInvokeExpr) invoke.getInvokeExpr();
if (special.getMethodRef().name().equals("<init>")) {
List<Unit> deflist = defs.getDefsOfAt((Local) special.getBase(), invoke);
while (deflist.size() == 1) {
Stmt stmt2 = (Stmt) deflist.get(0);
if (stmt2 instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) stmt2;
if (assign.getRightOp() instanceof Local) {
deflist = defs.getDefsOfAt((Local) assign.getRightOp(), assign);
continue;
} else if (assign.getRightOp() instanceof NewExpr) {
// We split the local.
// logger.debug("split: [" + assign + "] and [" + stmt + "]");
Local newlocal = Jimple.v().newLocal("tmp", null);
stmtBody.getLocals().add(newlocal);
special.setBase(newlocal);
units.insertAfter(Jimple.v().newAssignStmt(assign.getLeftOp(), newlocal), assign);
assign.setLeftOp(newlocal);
}
}
break;
}
}
}
}
}
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class SideEffectAnalysis method ntWriteSet.
private RWSet ntWriteSet(SootMethod method, Stmt stmt) {
if (stmt instanceof AssignStmt) {
AssignStmt a = (AssignStmt) stmt;
Value l = a.getLeftOp();
return addValue(l, method, stmt);
}
return null;
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class UseChecker method caseAssignStmt.
public void caseAssignStmt(AssignStmt stmt) {
Value lhs = stmt.getLeftOp();
Value rhs = stmt.getRightOp();
Type tlhs = null;
if (lhs instanceof Local)
tlhs = this.tg.get((Local) lhs);
else if (lhs instanceof ArrayRef) {
ArrayRef aref = (ArrayRef) lhs;
Local base = (Local) aref.getBase();
// Try to force Type integrity. The left side must agree on the
// element type of the right side array reference.
ArrayType at = null;
Type tgType = this.tg.get(base);
if (tgType instanceof ArrayType)
at = (ArrayType) tgType;
else {
// is java.lang.Object
if (tgType == Scene.v().getObjectType() && rhs instanceof Local) {
Type rhsType = this.tg.get((Local) rhs);
if (rhsType instanceof PrimType) {
if (defs == null) {
defs = LocalDefs.Factory.newLocalDefs(jb);
uses = LocalUses.Factory.newLocalUses(jb, defs);
}
// Check the original type of the array from the alloc site
for (Unit defU : defs.getDefsOfAt(base, stmt)) {
if (defU instanceof AssignStmt) {
AssignStmt defUas = (AssignStmt) defU;
if (defUas.getRightOp() instanceof NewArrayExpr) {
at = (ArrayType) defUas.getRightOp().getType();
break;
}
}
}
}
}
if (at == null)
at = tgType.makeArrayType();
}
tlhs = ((ArrayType) at).getElementType();
this.handleArrayRef(aref, stmt);
aref.setBase((Local) this.uv.visit(aref.getBase(), at, stmt));
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
stmt.setLeftOp(this.uv.visit(lhs, tlhs, stmt));
} else if (lhs instanceof FieldRef) {
tlhs = ((FieldRef) lhs).getFieldRef().type();
if (lhs instanceof InstanceFieldRef)
this.handleInstanceFieldRef((InstanceFieldRef) lhs, stmt);
}
// They may have been changed above
lhs = stmt.getLeftOp();
rhs = stmt.getRightOp();
if (rhs instanceof Local)
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
else if (rhs instanceof ArrayRef) {
ArrayRef aref = (ArrayRef) rhs;
Local base = (Local) aref.getBase();
// try to force Type integrity
ArrayType at = null;
Type et = null;
if (this.tg.get(base) instanceof ArrayType)
at = (ArrayType) this.tg.get(base);
else {
Type bt = this.tg.get(base);
// For some fixed type T, we assume that we can fix the array to T[].
if (bt instanceof RefType || bt instanceof NullType) {
RefType rt = bt instanceof NullType ? null : (RefType) bt;
if (rt == null || rt.getSootClass().getName().equals("java.lang.Object") || rt.getSootClass().getName().equals("java.io.Serializable") || rt.getSootClass().getName().equals("java.lang.Cloneable")) {
if (defs == null) {
defs = LocalDefs.Factory.newLocalDefs(jb);
uses = LocalUses.Factory.newLocalUses(jb, defs);
}
outer: for (UnitValueBoxPair usePair : uses.getUsesOf(stmt)) {
Stmt useStmt = (Stmt) usePair.getUnit();
// from the callee's signature=
if (useStmt.containsInvokeExpr()) {
for (int i = 0; i < useStmt.getInvokeExpr().getArgCount(); i++) {
if (useStmt.getInvokeExpr().getArg(i) == usePair.getValueBox().getValue()) {
et = useStmt.getInvokeExpr().getMethod().getParameterType(i);
at = et.makeArrayType();
break outer;
}
}
} else // if the other value is a primitive.
if (useStmt instanceof IfStmt) {
IfStmt ifStmt = (IfStmt) useStmt;
if (ifStmt.getCondition() instanceof EqExpr) {
EqExpr expr = (EqExpr) ifStmt.getCondition();
final Value other;
if (expr.getOp1() == usePair.getValueBox().getValue())
other = expr.getOp2();
else
other = expr.getOp1();
Type newEt = getTargetType(other);
if (newEt != null)
et = newEt;
}
} else if (useStmt instanceof AssignStmt) {
// For binary expressions, we can look for type information in the
// other operands
AssignStmt useAssignStmt = (AssignStmt) useStmt;
if (useAssignStmt.getRightOp() instanceof BinopExpr) {
BinopExpr binOp = (BinopExpr) useAssignStmt.getRightOp();
final Value other;
if (binOp.getOp1() == usePair.getValueBox().getValue())
other = binOp.getOp2();
else
other = binOp.getOp1();
Type newEt = getTargetType(other);
if (newEt != null)
et = newEt;
}
} else if (useStmt instanceof ReturnStmt) {
et = jb.getMethod().getReturnType();
}
}
}
}
if (at == null)
at = et.makeArrayType();
}
Type trhs = ((ArrayType) at).getElementType();
this.handleArrayRef(aref, stmt);
aref.setBase((Local) this.uv.visit(aref.getBase(), at, stmt));
stmt.setRightOp(this.uv.visit(rhs, trhs, stmt));
} else if (rhs instanceof InstanceFieldRef) {
this.handleInstanceFieldRef((InstanceFieldRef) rhs, stmt);
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
} else if (rhs instanceof BinopExpr)
this.handleBinopExpr((BinopExpr) rhs, stmt, tlhs);
else if (rhs instanceof InvokeExpr) {
this.handleInvokeExpr((InvokeExpr) rhs, stmt);
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
} else if (rhs instanceof CastExpr)
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
else if (rhs instanceof InstanceOfExpr) {
InstanceOfExpr ioe = (InstanceOfExpr) rhs;
ioe.setOp(this.uv.visit(ioe.getOp(), RefType.v("java.lang.Object"), stmt));
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
} else if (rhs instanceof NewArrayExpr) {
NewArrayExpr nae = (NewArrayExpr) rhs;
nae.setSize(this.uv.visit(nae.getSize(), IntType.v(), stmt));
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
} else if (rhs instanceof NewMultiArrayExpr) {
NewMultiArrayExpr nmae = (NewMultiArrayExpr) rhs;
for (int i = 0; i < nmae.getSizeCount(); i++) nmae.setSize(i, this.uv.visit(nmae.getSize(i), IntType.v(), stmt));
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
} else if (rhs instanceof LengthExpr) {
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
} else if (rhs instanceof NegExpr) {
((NegExpr) rhs).setOp(this.uv.visit(((NegExpr) rhs).getOp(), tlhs, stmt));
} else if (rhs instanceof Constant)
if (!(rhs instanceof NullConstant))
stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class TypeResolver method split_new.
private void split_new() {
LocalDefs defs = LocalDefs.Factory.newLocalDefs(stmtBody);
PatchingChain<Unit> units = stmtBody.getUnits();
Stmt[] stmts = new Stmt[units.size()];
units.toArray(stmts);
for (Stmt stmt : stmts) {
if (stmt instanceof InvokeStmt) {
InvokeStmt invoke = (InvokeStmt) stmt;
if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) {
SpecialInvokeExpr special = (SpecialInvokeExpr) invoke.getInvokeExpr();
if ("<init>".equals(special.getMethodRef().name())) {
List<Unit> deflist = defs.getDefsOfAt((Local) special.getBase(), invoke);
while (deflist.size() == 1) {
Stmt stmt2 = (Stmt) deflist.get(0);
if (stmt2 instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) stmt2;
if (assign.getRightOp() instanceof Local) {
deflist = defs.getDefsOfAt((Local) assign.getRightOp(), assign);
continue;
} else if (assign.getRightOp() instanceof NewExpr) {
// We split the local.
// logger.debug("split: [" + assign + "] and [" + stmt + "]");
Local newlocal = Jimple.v().newLocal("tmp", null);
stmtBody.getLocals().add(newlocal);
special.setBase(newlocal);
units.insertAfter(Jimple.v().newAssignStmt(assign.getLeftOp(), newlocal), assign);
assign.setLeftOp(newlocal);
}
}
break;
}
}
}
}
}
}
Aggregations