use of soot.jimple.toolkits.scalar.LocalCreation in project soot by Sable.
the class Util method addExceptionAfterUnit.
/**
* Insert a runtime exception before unit u of body b. Useful to analyze
* broken code (which make reference to inexisting class for instance)
* exceptionType: e.g., "java.lang.RuntimeException"
*/
public static void addExceptionAfterUnit(Body b, String exceptionType, Unit u, String m) {
LocalCreation lc = new LocalCreation(b.getLocals());
Local l = lc.newLocal(RefType.v(exceptionType));
List<Unit> newUnits = new ArrayList<Unit>();
Unit u1 = Jimple.v().newAssignStmt(l, Jimple.v().newNewExpr(RefType.v(exceptionType)));
Unit u2 = Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(l, Scene.v().makeMethodRef(Scene.v().getSootClass(exceptionType), "<init>", Collections.singletonList((Type) RefType.v("java.lang.String")), VoidType.v(), false), StringConstant.v(m)));
Unit u3 = Jimple.v().newThrowStmt(l);
newUnits.add(u1);
newUnits.add(u2);
newUnits.add(u3);
b.getUnits().insertBefore(newUnits, u);
}
use of soot.jimple.toolkits.scalar.LocalCreation 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.toolkits.scalar.LocalCreation in project soot by Sable.
the class DexNullArrayRefTransformer method internalTransform.
protected void internalTransform(final Body body, String phaseName, Map<String, String> options) {
final ExceptionalUnitGraph g = new ExceptionalUnitGraph(body, DalvikThrowAnalysis.v());
final LocalDefs defs = LocalDefs.Factory.newLocalDefs(g);
final LocalCreation lc = new LocalCreation(body.getLocals(), "ex");
boolean changed = false;
for (Iterator<Unit> unitIt = body.getUnits().snapshotIterator(); unitIt.hasNext(); ) {
Stmt s = (Stmt) unitIt.next();
if (s.containsArrayRef()) {
// Check array reference
Value base = s.getArrayRef().getBase();
if (isAlwaysNullBefore(s, (Local) base, defs)) {
createThrowStmt(body, s, lc);
changed = true;
}
} else if (s instanceof AssignStmt) {
AssignStmt ass = (AssignStmt) s;
Value rightOp = ass.getRightOp();
if (rightOp instanceof LengthExpr) {
// Check lengthof expression
LengthExpr l = (LengthExpr) ass.getRightOp();
Value base = l.getOp();
if (base instanceof IntConstant) {
IntConstant ic = (IntConstant) base;
if (ic.value == 0) {
createThrowStmt(body, s, lc);
changed = true;
}
} else if (base == NullConstant.v() || isAlwaysNullBefore(s, (Local) base, defs)) {
createThrowStmt(body, s, lc);
changed = true;
}
}
}
}
if (changed)
UnreachableCodeEliminator.v().transform(body);
}
use of soot.jimple.toolkits.scalar.LocalCreation in project soot by Sable.
the class DexReturnValuePropagator method internalTransform.
@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body, DalvikThrowAnalysis.v(), true);
LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(graph);
LocalUses localUses = null;
LocalCreation localCreation = null;
// a copy statement, we take the original operand
for (Unit u : body.getUnits()) if (u instanceof ReturnStmt) {
ReturnStmt retStmt = (ReturnStmt) u;
if (retStmt.getOp() instanceof Local) {
List<Unit> defs = localDefs.getDefsOfAt((Local) retStmt.getOp(), retStmt);
if (defs.size() == 1 && defs.get(0) instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) defs.get(0);
final Value rightOp = assign.getRightOp();
final Value leftOp = assign.getLeftOp();
// Copy over the left side if it is a local
if (rightOp instanceof Local) {
// to return a;
if (!isRedefined((Local) rightOp, u, assign, graph))
retStmt.setOp(rightOp);
} else if (rightOp instanceof Constant) {
retStmt.setOp(rightOp);
} else // we rename the local to help splitting
if (rightOp instanceof FieldRef) {
if (localUses == null)
localUses = LocalUses.Factory.newLocalUses(body, localDefs);
if (localUses.getUsesOf(assign).size() == 1) {
if (localCreation == null)
localCreation = new LocalCreation(body.getLocals(), "ret");
Local newLocal = localCreation.newLocal(leftOp.getType());
assign.setLeftOp(newLocal);
retStmt.setOp(newLocal);
}
}
}
}
}
}
Aggregations