use of soot.Unit in project soot by Sable.
the class SynchronizerManager method synchronizeStmtOn.
/**
* Wraps stmt around a monitor associated with local lock. When inlining or
* static method binding, this is the former base of the invoke expression.
*/
public void synchronizeStmtOn(Stmt stmt, JimpleBody b, Local lock) {
Chain units = b.getUnits();
// TrapManager.splitTrapsAgainst(b, stmt, (Stmt)units.getSuccOf(stmt));
units.insertBefore(Jimple.v().newEnterMonitorStmt(lock), stmt);
Stmt exitMon = Jimple.v().newExitMonitorStmt(lock);
units.insertAfter(exitMon, stmt);
// Ok. That was the easy part.
// We also need to modify exception blocks to exit the monitor
// (they have conveniently been pre-split)
// Actually, we don't need to do this.
// {
// List traps = TrapManager.getTrapsAt(stmt, b);
// Iterator trapsIt = traps.iterator();
// while (trapsIt.hasNext())
// {
// Trap t = (Trap)trapsIt.next();
// Stmt s = (Stmt)units.getLast();
// Stmt newCaughtRef = (Stmt)t.getHandlerUnit().clone();
// List l = new ArrayList();
// l.add(newCaughtRef);
// l.add(exitMon.clone());
// l.add(Jimple.v().newGotoStmt((Stmt)units.getSuccOf((Stmt)t.getHandlerUnit())));
// units.insertAfter(l, s);
// t.setHandlerUnit(newCaughtRef);
// }
// }
// and also we must add a catch Throwable exception block in the
// appropriate place.
{
Stmt newGoto = Jimple.v().newGotoStmt((Stmt) units.getSuccOf(exitMon));
units.insertAfter(newGoto, exitMon);
List<Unit> l = new ArrayList<Unit>();
Local eRef = Jimple.v().newLocal("__exception", RefType.v("java.lang.Throwable"));
b.getLocals().add(eRef);
Stmt handlerStmt = Jimple.v().newIdentityStmt(eRef, Jimple.v().newCaughtExceptionRef());
l.add(handlerStmt);
l.add((Stmt) exitMon.clone());
l.add(Jimple.v().newThrowStmt(eRef));
units.insertAfter(l, newGoto);
Trap newTrap = Jimple.v().newTrap(Scene.v().getSootClass("java.lang.Throwable"), stmt, (Stmt) units.getSuccOf(stmt), handlerStmt);
b.getTraps().addFirst(newTrap);
}
}
use of soot.Unit in project soot by Sable.
the class DexArrayInitDetector method constructArrayInitializations.
/**
* Constructs packed array initializations from the individual element
* assignments in the given body
* @param body The body in which to look for element assignments
*/
public void constructArrayInitializations(Body body) {
// Find an array construction followed by consecutive element
// assignments
Unit arrayInitStmt = null;
List<Value> arrayValues = null;
Set<Unit> curIgnoreUnits = null;
int arraySize = 0;
for (Unit u : body.getUnits()) {
if (!(u instanceof AssignStmt)) {
arrayValues = null;
continue;
}
AssignStmt assignStmt = (AssignStmt) u;
if (assignStmt.getRightOp() instanceof NewArrayExpr) {
NewArrayExpr newArrayExp = (NewArrayExpr) assignStmt.getRightOp();
if (newArrayExp.getSize() instanceof IntConstant) {
IntConstant intConst = (IntConstant) newArrayExp.getSize();
arrayValues = new ArrayList<Value>();
arraySize = intConst.value;
curIgnoreUnits = new HashSet<Unit>();
} else {
arrayValues = null;
}
} else if (assignStmt.getLeftOp() instanceof ArrayRef && assignStmt.getRightOp() instanceof IntConstant && /*NumericConstant*/
arrayValues != null) {
ArrayRef aref = (ArrayRef) assignStmt.getLeftOp();
if (aref.getIndex() instanceof IntConstant) {
IntConstant intConst = (IntConstant) aref.getIndex();
if (intConst.value == arrayValues.size()) {
arrayValues.add(assignStmt.getRightOp());
if (intConst.value == 0)
arrayInitStmt = u;
else if (intConst.value == arraySize - 1) {
curIgnoreUnits.add(u);
checkAndSave(arrayInitStmt, arrayValues, arraySize, curIgnoreUnits);
arrayValues = null;
} else
curIgnoreUnits.add(u);
} else {
arrayValues = null;
}
} else {
arrayValues = null;
}
} else {
arrayValues = null;
}
}
}
use of soot.Unit in project soot by Sable.
the class StmtVisitor method caseTableSwitchStmt.
@Override
public void caseTableSwitchStmt(TableSwitchStmt stmt) {
exprV.setOrigStmt(stmt);
constantV.setOrigStmt(stmt);
// create payload that references the switch's targets
int firstKey = stmt.getLowIndex();
List<Unit> targets = stmt.getTargets();
PackedSwitchPayload payload = new PackedSwitchPayload(firstKey, targets);
payloads.add(payload);
// create packed-switch instruction that references the payload
Value key = stmt.getKey();
Stmt defaultTarget = (Stmt) stmt.getDefaultTarget();
addInsn(buildSwitchInsn(Opcode.PACKED_SWITCH, key, defaultTarget, payload, stmt), stmt);
}
use of soot.Unit in project soot by Sable.
the class TrapTransformer method getUnitsWithMonitor.
public Set<Unit> getUnitsWithMonitor(UnitGraph ug) {
// Idea: Associate each unit with a set of monitors held at that
// statement
MultiMap<Unit, Value> unitMonitors = new HashMultiMap<>();
// Start at the heads of the unit graph
List<Unit> workList = new ArrayList<>();
Set<Unit> doneSet = new HashSet<>();
for (Unit head : ug.getHeads()) {
workList.add(head);
}
while (!workList.isEmpty()) {
Unit curUnit = workList.remove(0);
boolean hasChanged = false;
Value exitValue = null;
if (curUnit instanceof EnterMonitorStmt) {
// We enter a new monitor
EnterMonitorStmt ems = (EnterMonitorStmt) curUnit;
hasChanged = unitMonitors.put(curUnit, ems.getOp());
} else if (curUnit instanceof ExitMonitorStmt) {
// We leave a monitor
ExitMonitorStmt ems = (ExitMonitorStmt) curUnit;
exitValue = ems.getOp();
}
// Copy over the monitors from the predecessors
for (Unit pred : ug.getPredsOf(curUnit)) for (Value v : unitMonitors.get(pred)) if (v != exitValue)
if (unitMonitors.put(curUnit, v))
hasChanged = true;
// Work on the successors
if (doneSet.add(curUnit) || hasChanged)
workList.addAll(ug.getSuccsOf(curUnit));
}
return unitMonitors.keySet();
}
use of soot.Unit in project soot by Sable.
the class TrapTightener method internalTransform.
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
if (this.throwAnalysis == null)
this.throwAnalysis = Scene.v().getDefaultThrowAnalysis();
if (Options.v().verbose())
logger.debug("[" + body.getMethod().getName() + "] Tightening trap boundaries...");
Chain<Trap> trapChain = body.getTraps();
Chain<Unit> unitChain = body.getUnits();
if (trapChain.size() > 0) {
ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body, throwAnalysis);
Set<Unit> unitsWithMonitor = getUnitsWithMonitor(graph);
for (Iterator<Trap> trapIt = trapChain.iterator(); trapIt.hasNext(); ) {
Trap trap = trapIt.next();
boolean isCatchAll = trap.getException().getName().equals("java.lang.Throwable");
Unit firstTrappedUnit = trap.getBeginUnit();
Unit firstTrappedThrower = null;
Unit firstUntrappedUnit = trap.getEndUnit();
Unit lastTrappedUnit = unitChain.getPredOf(firstUntrappedUnit);
Unit lastTrappedThrower = null;
for (Unit u = firstTrappedUnit; u != null && u != firstUntrappedUnit; u = unitChain.getSuccOf(u)) {
if (mightThrowTo(graph, u, trap)) {
firstTrappedThrower = u;
break;
}
// active monitor, we need to keep the block
if (isCatchAll && unitsWithMonitor.contains(u)) {
if (firstTrappedThrower == null)
firstTrappedThrower = u;
break;
}
}
if (firstTrappedThrower != null) {
for (Unit u = lastTrappedUnit; u != null; u = unitChain.getPredOf(u)) {
if (mightThrowTo(graph, u, trap)) {
lastTrappedThrower = u;
break;
}
// has an, active monitor, we need to keep the block
if (isCatchAll && unitsWithMonitor.contains(u)) {
lastTrappedThrower = u;
break;
}
}
}
// remove the complete trap.
if (firstTrappedThrower == null)
trapIt.remove();
else {
if (firstTrappedThrower != null && firstTrappedUnit != firstTrappedThrower) {
trap.setBeginUnit(firstTrappedThrower);
}
if (lastTrappedThrower == null) {
lastTrappedThrower = firstTrappedUnit;
}
if (lastTrappedUnit != lastTrappedThrower) {
trap.setEndUnit(unitChain.getSuccOf(lastTrappedThrower));
}
}
}
}
}
Aggregations