use of soot.jimple.AssignStmt in project soot by Sable.
the class SynchronizerManager method createClassFetcherFor.
/**
* Creates a method which calls java.lang.Class.forName(String).
*
* The method should look like the following:
*
* <pre>
* .static java.lang.Class class$(java.lang.String)
* {
* java.lang.String r0, $r5;
* java.lang.ClassNotFoundException r1, $r3;
* java.lang.Class $r2;
* java.lang.NoClassDefFoundError $r4;
*
* r0 := @parameter0: java.lang.String;
*
* label0:
* $r2 = .staticinvoke <java.lang.Class: java.lang.Class forName(java.lang.String)>(r0);
* .return $r2;
*
* label1:
* $r3 := @caughtexception;
* r1 = $r3;
* $r4 = .new java.lang.NoClassDefFoundError;
* $r5 = .virtualinvoke r1.<java.lang.Throwable: java.lang.String getMessage()>();
* .specialinvoke $r4.<java.lang.NoClassDefFoundError: .void <init>(java.lang.String)>($r5);
* .throw $r4;
*
* .catch java.lang.ClassNotFoundException .from label0 .to label1 .with label1;
* }
* </pre>
*/
public SootMethod createClassFetcherFor(SootClass c, String methodName) {
// Create the method
SootMethod method = Scene.v().makeSootMethod(methodName, Arrays.asList(new Type[] { RefType.v("java.lang.String") }), RefType.v("java.lang.Class"), Modifier.STATIC);
c.addMethod(method);
// Create the method body
{
JimpleBody body = Jimple.v().newBody(method);
method.setActiveBody(body);
Chain units = body.getUnits();
Local l_r0, l_r1, l_r2, l_r3, l_r4, l_r5;
// Add some locals
l_r0 = Jimple.v().newLocal("r0", RefType.v("java.lang.String"));
l_r1 = Jimple.v().newLocal("r1", RefType.v("java.lang.ClassNotFoundException"));
l_r2 = Jimple.v().newLocal("$r2", RefType.v("java.lang.Class"));
l_r3 = Jimple.v().newLocal("$r3", RefType.v("java.lang.ClassNotFoundException"));
l_r4 = Jimple.v().newLocal("$r4", RefType.v("java.lang.NoClassDefFoundError"));
l_r5 = Jimple.v().newLocal("$r5", RefType.v("java.lang.String"));
body.getLocals().add(l_r0);
body.getLocals().add(l_r1);
body.getLocals().add(l_r2);
body.getLocals().add(l_r3);
body.getLocals().add(l_r4);
body.getLocals().add(l_r5);
// add "r0 := @parameter0: java.lang.String"
units.add(Jimple.v().newIdentityStmt(l_r0, Jimple.v().newParameterRef(RefType.v("java.lang.String"), 0)));
// add "$r2 = .staticinvoke <java.lang.Class: java.lang.Class
// forName(java.lang.String)>(r0);
AssignStmt asi;
units.add(asi = Jimple.v().newAssignStmt(l_r2, Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<java.lang.Class: java.lang.Class" + " forName(java.lang.String)>").makeRef(), Arrays.asList(new Value[] { l_r0 }))));
// insert "return $r2;"
units.add(Jimple.v().newReturnStmt(l_r2));
// add "r3 := @caughtexception;"
Stmt handlerStart;
units.add(handlerStart = Jimple.v().newIdentityStmt(l_r3, Jimple.v().newCaughtExceptionRef()));
// add "r1 = r3;"
units.add(Jimple.v().newAssignStmt(l_r1, l_r3));
// add "$r4 = .new java.lang.NoClassDefFoundError;"
units.add(Jimple.v().newAssignStmt(l_r4, Jimple.v().newNewExpr(RefType.v("java.lang.NoClassDefFoundError"))));
// add "$r5 = virtualinvoke r1.<java.lang.Throwable:
// java.lang.String getMessage()>();"
units.add(Jimple.v().newAssignStmt(l_r5, Jimple.v().newVirtualInvokeExpr(l_r1, Scene.v().getMethod("<java.lang.Throwable: java.lang.String getMessage()>").makeRef(), new LinkedList())));
// add .specialinvoke $r4.<java.lang.NoClassDefFoundError: .void
// <init>(java.lang.String)>($r5);
units.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(l_r4, Scene.v().getMethod("<java.lang.NoClassDefFoundError: void" + " <init>(java.lang.String)>").makeRef(), Arrays.asList(new Value[] { l_r5 }))));
// add .throw $r4;
units.add(Jimple.v().newThrowStmt(l_r4));
body.getTraps().add(Jimple.v().newTrap(Scene.v().getSootClass("java.lang.ClassNotFoundException"), asi, handlerStart, handlerStart));
}
return method;
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class SynchronizerManager method getClassFetcherFor.
/**
* Finds a method which calls java.lang.Class.forName(String). Searches for
* names class$, _class$, __class$, etc. If no such method is found, creates
* one and returns it.
*
* Uses dumb matching to do search. Not worth doing symbolic analysis for
* this!
*/
public SootMethod getClassFetcherFor(SootClass c) {
String methodName = "class$";
for (; true; methodName = "_" + methodName) {
SootMethod m = c.getMethodByNameUnsafe(methodName);
if (m == null)
return createClassFetcherFor(c, methodName);
// Check signature.
if (!m.getSignature().equals("<" + c.getName().replace('.', '$') + ": java.lang.Class " + methodName + "(java.lang.String)>"))
continue;
Body b = null;
b = m.retrieveActiveBody();
Iterator unitsIt = b.getUnits().iterator();
if (!unitsIt.hasNext())
continue;
Stmt s = (Stmt) unitsIt.next();
if (!(s instanceof IdentityStmt))
continue;
IdentityStmt is = (IdentityStmt) s;
Value lo = is.getLeftOp(), ro = is.getRightOp();
if (!(ro instanceof ParameterRef))
continue;
ParameterRef pr = (ParameterRef) ro;
if (pr.getIndex() != 0)
continue;
if (!unitsIt.hasNext())
continue;
s = (Stmt) unitsIt.next();
if (!(s instanceof AssignStmt))
continue;
AssignStmt as = (AssignStmt) s;
Value retVal = as.getLeftOp(), ie = as.getRightOp();
if (!ie.toString().equals(".staticinvoke <java.lang.Class: java.lang.Class forName(java.lang.String)>(" + lo + ")"))
continue;
if (!unitsIt.hasNext())
continue;
s = (Stmt) unitsIt.next();
if (!(s instanceof ReturnStmt))
continue;
ReturnStmt rs = (ReturnStmt) s;
if (!rs.getOp().equivTo(retVal))
continue;
/* in particular, it certainly returns Class.forName(arg). */
return m;
}
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class BusyCodeMotion method internalTransform.
/**
* performs the busy code motion.
*/
protected void internalTransform(Body b, String phaseName, Map<String, String> opts) {
BCMOptions options = new BCMOptions(opts);
HashMap<EquivalentValue, Local> expToHelper = new HashMap<EquivalentValue, Local>();
Chain<Unit> unitChain = b.getUnits();
if (Options.v().verbose())
logger.debug("[" + b.getMethod().getName() + "] performing Busy Code Motion...");
CriticalEdgeRemover.v().transform(b, phaseName + ".cer");
UnitGraph graph = new BriefUnitGraph(b);
/* map each unit to its RHS. only take binary expressions */
Map<Unit, EquivalentValue> unitToEquivRhs = new UnitMap<EquivalentValue>(b, graph.size() + 1, 0.7f) {
protected EquivalentValue mapTo(Unit unit) {
Value tmp = SootFilter.noInvokeRhs(unit);
Value tmp2 = SootFilter.binop(tmp);
if (tmp2 == null)
tmp2 = SootFilter.concreteRef(tmp);
return SootFilter.equiVal(tmp2);
}
};
/* same as before, but without exception-throwing expressions */
Map<Unit, EquivalentValue> unitToNoExceptionEquivRhs = new UnitMap<EquivalentValue>(b, graph.size() + 1, 0.7f) {
protected EquivalentValue mapTo(Unit unit) {
Value tmp = SootFilter.binopRhs(unit);
tmp = SootFilter.noExceptionThrowing(tmp);
return SootFilter.equiVal(tmp);
}
};
/* if a more precise sideeffect-tester comes out, please change it here! */
SideEffectTester sideEffect;
if (Scene.v().hasCallGraph() && !options.naive_side_effect()) {
sideEffect = new PASideEffectTester();
} else {
sideEffect = new NaiveSideEffectTester();
}
sideEffect.newMethod(b.getMethod());
UpSafetyAnalysis upSafe = new UpSafetyAnalysis(graph, unitToEquivRhs, sideEffect);
DownSafetyAnalysis downSafe = new DownSafetyAnalysis(graph, unitToNoExceptionEquivRhs, sideEffect);
EarliestnessComputation earliest = new EarliestnessComputation(graph, upSafe, downSafe, sideEffect);
LocalCreation localCreation = new LocalCreation(b.getLocals(), PREFIX);
Iterator<Unit> unitIt = unitChain.snapshotIterator();
{
/* insert the computations at the earliest positions */
while (unitIt.hasNext()) {
Unit currentUnit = unitIt.next();
for (EquivalentValue equiVal : earliest.getFlowBefore(currentUnit)) {
// Value exp = equiVal.getValue();
/* get the unic helper-name for this expression */
Local helper = expToHelper.get(equiVal);
// the beginning of the method
if (currentUnit instanceof IdentityStmt)
currentUnit = getFirstNonIdentityStmt(b);
if (helper == null) {
helper = localCreation.newLocal(equiVal.getType());
expToHelper.put(equiVal, helper);
}
/* insert a new Assignment-stmt before the currentUnit */
Value insertValue = Jimple.cloneIfNecessary(equiVal.getValue());
Unit firstComp = Jimple.v().newAssignStmt(helper, insertValue);
unitChain.insertBefore(firstComp, currentUnit);
}
}
}
{
/* replace old computations by the helper-vars */
unitIt = unitChain.iterator();
while (unitIt.hasNext()) {
Unit currentUnit = unitIt.next();
EquivalentValue rhs = unitToEquivRhs.get(currentUnit);
if (rhs != null) {
Local helper = expToHelper.get(rhs);
if (helper != null)
((AssignStmt) currentUnit).setRightOp(helper);
}
}
}
if (Options.v().verbose())
logger.debug("[" + b.getMethod().getName() + "] Busy Code Motion done!");
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class IdentityCastEliminator method internalTransform.
@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
for (Iterator<Unit> unitIt = b.getUnits().iterator(); unitIt.hasNext(); ) {
Unit curUnit = unitIt.next();
if (curUnit instanceof AssignStmt) {
AssignStmt assignStmt = (AssignStmt) curUnit;
if (assignStmt.getLeftOp() instanceof Local && assignStmt.getRightOp() instanceof CastExpr) {
CastExpr ce = (CastExpr) assignStmt.getRightOp();
Type orgType = ce.getOp().getType();
Type newType = ce.getCastType();
// with a normal assignment.
if (orgType == newType) {
if (assignStmt.getLeftOp() == ce.getOp())
unitIt.remove();
else
assignStmt.setRightOp(ce.getOp());
}
}
}
}
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class AccessManager method createAccessorMethod.
/**
* Turns a field access or method call into a call to an accessor method.
* Reuses existing accessors based on name mangling (see createAccessorName)
*
* @param container
* @param stmt
*/
public static void createAccessorMethod(SootMethod container, Stmt stmt) {
// System.out.println("Creating accessor method: \n" +
// " method: " + container + " \n" +
// " stmt: " + stmt);
Body containerBody = container.getActiveBody();
soot.util.Chain containerStmts = containerBody.getUnits();
if (!containerStmts.contains(stmt))
throw new RuntimeException();
if (stmt.containsInvokeExpr()) {
createInvokeAccessor(container, stmt);
} else if (stmt instanceof AssignStmt) {
AssignStmt as = (AssignStmt) stmt;
FieldRef ref;
if (as.getLeftOp() instanceof FieldRef) {
// set
ref = (FieldRef) as.getLeftOp();
createSetAccessor(container, as, ref);
} else if (as.getRightOp() instanceof FieldRef) {
// get
ref = (FieldRef) as.getRightOp();
createGetAccessor(container, as, ref);
} else {
throw new RuntimeException("Expected class member access");
}
} else
throw new RuntimeException("Expected class member access");
}
Aggregations