use of soot.jimple.MonitorStmt in project soot by Sable.
the class AsmMethodSource method convertInsn.
private void convertInsn(InsnNode insn) {
int op = insn.getOpcode();
if (op == NOP) {
/*
* We can ignore NOP instructions, but
* for completeness, we handle them
*/
if (!units.containsKey(insn))
units.put(insn, Jimple.v().newNopStmt());
} else if (op >= ACONST_NULL && op <= DCONST_1) {
convertConstInsn(insn);
} else if (op >= IALOAD && op <= SALOAD) {
convertArrayLoadInsn(insn);
} else if (op >= IASTORE && op <= SASTORE) {
convertArrayStoreInsn(insn);
} else if (op == POP) {
popImmediate();
} else if (op == POP2) {
popImmediate();
if (peek() == DWORD_DUMMY)
pop();
else
popImmediate();
} else if (op >= DUP && op <= DUP2_X2) {
convertDupInsn((InsnNode) insn);
} else if (op == SWAP) {
Operand o1 = popImmediate();
Operand o2 = popImmediate();
push(o1);
push(o2);
} else if ((op >= IADD && op <= DREM) || (op >= ISHL && op <= LXOR) || (op >= LCMP && op <= DCMPG)) {
convertBinopInsn((InsnNode) insn);
} else if ((op >= INEG && op <= DNEG) || op == ARRAYLENGTH) {
convertUnopInsn(insn);
} else if (op >= I2L && op <= I2S) {
convertPrimCastInsn(insn);
} else if (op >= IRETURN && op <= ARETURN) {
convertReturnInsn(insn);
} else if (op == RETURN) {
if (!units.containsKey(insn))
setUnit(insn, Jimple.v().newReturnVoidStmt());
} else if (op == ATHROW) {
StackFrame frame = getFrame(insn);
Operand opr;
if (!units.containsKey(insn)) {
opr = popImmediate();
ThrowStmt ts = Jimple.v().newThrowStmt(opr.stackOrValue());
opr.addBox(ts.getOpBox());
frame.in(opr);
frame.out(opr);
frame.boxes(ts.getOpBox());
setUnit(insn, ts);
} else {
opr = pop();
frame.mergeIn(opr);
}
push(opr);
} else if (op == MONITORENTER || op == MONITOREXIT) {
StackFrame frame = getFrame(insn);
if (!units.containsKey(insn)) {
Operand opr = popStackConst();
MonitorStmt ts = op == MONITORENTER ? Jimple.v().newEnterMonitorStmt(opr.stackOrValue()) : Jimple.v().newExitMonitorStmt(opr.stackOrValue());
opr.addBox(ts.getOpBox());
frame.in(opr);
frame.boxes(ts.getOpBox());
setUnit(insn, ts);
} else {
frame.mergeIn(pop());
}
} else {
throw new AssertionError("Unknown insn op: " + op);
}
}
use of soot.jimple.MonitorStmt in project soot by Sable.
the class DavaBody method copy_Body.
/*
* Copy and patch a GrimpBody so that it can be used to output Java.
*/
private void copy_Body(Body body) {
if (!(body instanceof GrimpBody))
throw new RuntimeException("You can only create a DavaBody from a GrimpBody!");
GrimpBody grimpBody = (GrimpBody) body;
/*
* Import body contents from Grimp.
*/
{
HashMap<Switchable, Switchable> bindings = new HashMap<Switchable, Switchable>();
HashMap<Unit, Unit> reverse_binding = new HashMap<Unit, Unit>();
// Clone units in body's statement list
for (Unit original : grimpBody.getUnits()) {
Unit copy = (Unit) original.clone();
// Add cloned unit to our unitChain.
getUnits().addLast(copy);
// Build old <-> new map to be able to patch up references to other units
// within the cloned units. (these are still refering to the original
// unit objects).
bindings.put(original, copy);
reverse_binding.put(copy, original);
}
// patch up the switch statments
for (Unit u : getUnits()) {
Stmt s = (Stmt) u;
if (s instanceof TableSwitchStmt) {
TableSwitchStmt ts = (TableSwitchStmt) s;
TableSwitchStmt original_switch = (TableSwitchStmt) reverse_binding.get(u);
ts.setDefaultTarget((Unit) bindings.get(original_switch.getDefaultTarget()));
LinkedList<Unit> new_target_list = new LinkedList<Unit>();
int target_count = ts.getHighIndex() - ts.getLowIndex() + 1;
for (int i = 0; i < target_count; i++) new_target_list.add((Unit) bindings.get(original_switch.getTarget(i)));
ts.setTargets(new_target_list);
}
if (s instanceof LookupSwitchStmt) {
LookupSwitchStmt ls = (LookupSwitchStmt) s;
LookupSwitchStmt original_switch = (LookupSwitchStmt) reverse_binding.get(u);
ls.setDefaultTarget((Unit) bindings.get(original_switch.getDefaultTarget()));
Unit[] new_target_list = new Unit[original_switch.getTargetCount()];
for (int i = 0; i < original_switch.getTargetCount(); i++) new_target_list[i] = (Unit) (bindings.get(original_switch.getTarget(i)));
ls.setTargets(new_target_list);
ls.setLookupValues(original_switch.getLookupValues());
}
}
// Clone locals.
for (Local original : grimpBody.getLocals()) {
Local copy = Dava.v().newLocal(original.getName(), original.getType());
getLocals().add(copy);
// Build old <-> new mapping.
bindings.put(original, copy);
}
// Patch up references within units using our (old <-> new) map.
for (UnitBox box : getAllUnitBoxes()) {
Unit newObject, oldObject = box.getUnit();
// it's clone.
if ((newObject = (Unit) bindings.get(oldObject)) != null)
box.setUnit(newObject);
}
// backpatch all local variables.
for (ValueBox vb : getUseAndDefBoxes()) {
if (vb.getValue() instanceof Local)
vb.setValue((Value) bindings.get(vb.getValue()));
}
// clone the traps
for (Trap originalTrap : grimpBody.getTraps()) {
Trap cloneTrap = (Trap) originalTrap.clone();
Unit handlerUnit = (Unit) bindings.get(originalTrap.getHandlerUnit());
cloneTrap.setHandlerUnit(handlerUnit);
cloneTrap.setBeginUnit((Unit) bindings.get(originalTrap.getBeginUnit()));
cloneTrap.setEndUnit((Unit) bindings.get(originalTrap.getEndUnit()));
getTraps().add(cloneTrap);
}
}
/*
* Add one level of indirection to "if", "switch", and exceptional control flow.
* This allows for easy handling of breaks, continues and exceptional loops.
*/
{
PatchingChain<Unit> units = getUnits();
Iterator<Unit> it = units.snapshotIterator();
while (it.hasNext()) {
Unit u = it.next();
Stmt s = (Stmt) u;
if (s instanceof IfStmt) {
IfStmt ifs = (IfStmt) s;
JGotoStmt jgs = new JGotoStmt((Unit) units.getSuccOf(u));
units.insertAfter(jgs, u);
JGotoStmt jumper = new JGotoStmt((Unit) ifs.getTarget());
units.insertAfter(jumper, jgs);
ifs.setTarget((Unit) jumper);
} else if (s instanceof TableSwitchStmt) {
TableSwitchStmt tss = (TableSwitchStmt) s;
int targetCount = tss.getHighIndex() - tss.getLowIndex() + 1;
for (int i = 0; i < targetCount; i++) {
JGotoStmt jgs = new JGotoStmt((Unit) tss.getTarget(i));
units.insertAfter(jgs, tss);
tss.setTarget(i, (Unit) jgs);
}
JGotoStmt jgs = new JGotoStmt((Unit) tss.getDefaultTarget());
units.insertAfter(jgs, tss);
tss.setDefaultTarget((Unit) jgs);
} else if (s instanceof LookupSwitchStmt) {
LookupSwitchStmt lss = (LookupSwitchStmt) s;
for (int i = 0; i < lss.getTargetCount(); i++) {
JGotoStmt jgs = new JGotoStmt((Unit) lss.getTarget(i));
units.insertAfter(jgs, lss);
lss.setTarget(i, (Unit) jgs);
}
JGotoStmt jgs = new JGotoStmt((Unit) lss.getDefaultTarget());
units.insertAfter(jgs, lss);
lss.setDefaultTarget((Unit) jgs);
}
}
for (Trap t : getTraps()) {
JGotoStmt jgs = new JGotoStmt((Unit) t.getHandlerUnit());
units.addLast(jgs);
t.setHandlerUnit((Unit) jgs);
}
}
/*
* Fix up the grimp representations of statements so they can be compiled as java.
*/
{
for (Local l : getLocals()) {
Type t = l.getType();
if (t instanceof RefType) {
RefType rt = (RefType) t;
String className = rt.getSootClass().toString();
String packageName = rt.getSootClass().getJavaPackageName();
String classPackageName = packageName;
if (className.lastIndexOf('.') > 0) {
// 0 doesnt make sense
classPackageName = className.substring(0, className.lastIndexOf('.'));
}
if (!packageName.equals(classPackageName))
throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
addToImportList(className);
// addPackage(rt.getSootClass().getJavaPackageName());
}
}
for (Unit u : getUnits()) {
Stmt s = (Stmt) u;
if (s instanceof IfStmt)
javafy(((IfStmt) s).getConditionBox());
else if (s instanceof ThrowStmt)
javafy(((ThrowStmt) s).getOpBox());
else if (s instanceof TableSwitchStmt)
javafy(((TableSwitchStmt) s).getKeyBox());
else if (s instanceof LookupSwitchStmt)
javafy(((LookupSwitchStmt) s).getKeyBox());
else if (s instanceof MonitorStmt)
javafy(((MonitorStmt) s).getOpBox());
else if (s instanceof DefinitionStmt) {
DefinitionStmt ds = (DefinitionStmt) s;
javafy(ds.getRightOpBox());
javafy(ds.getLeftOpBox());
if (ds.getRightOp() instanceof IntConstant)
ds.getRightOpBox().setValue(DIntConstant.v(((IntConstant) ds.getRightOp()).value, ds.getLeftOp().getType()));
} else if (s instanceof ReturnStmt) {
ReturnStmt rs = (ReturnStmt) s;
if (rs.getOp() instanceof IntConstant)
rs.getOpBox().setValue(DIntConstant.v(((IntConstant) rs.getOp()).value, body.getMethod().getReturnType()));
else
javafy(rs.getOpBox());
} else if (s instanceof InvokeStmt)
javafy(((InvokeStmt) s).getInvokeExprBox());
}
}
/*
* Convert references to "this" and parameters.
*/
{
for (Unit u : getUnits()) {
Stmt s = (Stmt) u;
if (s instanceof IdentityStmt) {
IdentityStmt ids = (IdentityStmt) s;
Value ids_rightOp = ids.getRightOp();
Value ids_leftOp = ids.getLeftOp();
if ((ids_leftOp instanceof Local) && (ids_rightOp instanceof ThisRef)) {
Local thisLocal = (Local) ids_leftOp;
thisLocals.add(thisLocal);
thisLocal.setName("this");
}
}
if (s instanceof DefinitionStmt) {
DefinitionStmt ds = (DefinitionStmt) s;
Value rightOp = ds.getRightOp();
if (rightOp instanceof ParameterRef)
pMap.put(((ParameterRef) rightOp).getIndex(), ds.getLeftOp());
if (rightOp instanceof CaughtExceptionRef)
caughtrefs.add((CaughtExceptionRef) rightOp);
}
}
}
/*
* Fix up the calls to other constructors. Note, this is seriously underbuilt.
*/
{
for (Unit u : getUnits()) {
Stmt s = (Stmt) u;
if (s instanceof InvokeStmt) {
InvokeStmt ivs = (InvokeStmt) s;
Value ie = ivs.getInvokeExpr();
if (ie instanceof InstanceInvokeExpr) {
InstanceInvokeExpr iie = (InstanceInvokeExpr) ie;
Value base = iie.getBase();
if ((base instanceof Local) && (((Local) base).getName().equals("this"))) {
SootMethodRef m = iie.getMethodRef();
String name = m.name();
if ((name.equals(SootMethod.constructorName)) || (name.equals(SootMethod.staticInitializerName))) {
if (constructorUnit != null)
throw new RuntimeException("More than one candidate for constructor found.");
constructorExpr = iie;
constructorUnit = (Unit) s;
}
}
}
}
}
}
}
use of soot.jimple.MonitorStmt in project soot by Sable.
the class NullnessAnalysis method flowThrough.
/**
* {@inheritDoc}
*/
@Override
protected void flowThrough(AnalysisInfo in, Unit u, List<AnalysisInfo> fallOut, List<AnalysisInfo> branchOuts) {
AnalysisInfo out = new AnalysisInfo(in);
AnalysisInfo outBranch = new AnalysisInfo(in);
Stmt s = (Stmt) u;
// or for an instanceof expression
if (s instanceof JIfStmt) {
JIfStmt ifStmt = (JIfStmt) s;
handleIfStmt(ifStmt, in, out, outBranch);
} else // in case of a monitor statement, we know that if it succeeds, we have a non-null value
if (s instanceof MonitorStmt) {
MonitorStmt monitorStmt = (MonitorStmt) s;
out.put(monitorStmt.getOp(), NON_NULL);
}
// if we have an array ref, set the base to non-null
if (s.containsArrayRef()) {
ArrayRef arrayRef = s.getArrayRef();
handleArrayRef(arrayRef, out);
}
// for field refs, set the receiver object to non-null, if there is one
if (s.containsFieldRef()) {
FieldRef fieldRef = s.getFieldRef();
handleFieldRef(fieldRef, out);
}
// for invoke expr, set the receiver object to non-null, if there is one
if (s.containsInvokeExpr()) {
InvokeExpr invokeExpr = s.getInvokeExpr();
handleInvokeExpr(invokeExpr, out);
}
// x=y, copy the info for y (for locals x,y)
if (s instanceof DefinitionStmt) {
DefinitionStmt defStmt = (DefinitionStmt) s;
if (defStmt.getLeftOp().getType() instanceof RefLikeType) {
handleRefTypeAssignment(defStmt, out);
}
}
// now copy the computed info to all successors
for (Iterator<AnalysisInfo> it = fallOut.iterator(); it.hasNext(); ) {
copy(out, it.next());
}
for (Iterator<AnalysisInfo> it = branchOuts.iterator(); it.hasNext(); ) {
copy(outBranch, it.next());
}
}
use of soot.jimple.MonitorStmt in project soot by Sable.
the class Aggregator method internalAggregate.
private static boolean internalAggregate(StmtBody body, Map<ValueBox, Zone> boxToZone, boolean onlyStackVars) {
boolean hadAggregation = false;
Chain<Unit> units = body.getUnits();
ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body);
LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(graph);
LocalUses localUses = LocalUses.Factory.newLocalUses(body, localDefs);
List<Unit> unitList = new PseudoTopologicalOrderer<Unit>().newList(graph, false);
for (Unit u : unitList) {
if (!(u instanceof AssignStmt))
continue;
AssignStmt s = (AssignStmt) u;
Value lhs = s.getLeftOp();
if (!(lhs instanceof Local))
continue;
Local lhsLocal = (Local) lhs;
if (onlyStackVars && !lhsLocal.getName().startsWith("$"))
continue;
List<UnitValueBoxPair> lu = localUses.getUsesOf(s);
if (lu.size() != 1)
continue;
UnitValueBoxPair usepair = lu.get(0);
Unit use = usepair.unit;
ValueBox useBox = usepair.valueBox;
List<Unit> ld = localDefs.getDefsOfAt(lhsLocal, use);
if (ld.size() != 1)
continue;
// Check to make sure aggregation pair in the same zone
if (boxToZone.get(s.getRightOpBox()) != boxToZone.get(usepair.valueBox)) {
continue;
}
/* we need to check the path between def and use */
/* to see if there are any intervening re-defs of RHS */
/* in fact, we should check that this path is unique. */
/*
* if the RHS uses only locals, then we know what to do; if RHS has
* a method invocation f(a, b, c) or field access, we must ban field
* writes, other method calls and (as usual) writes to a, b, c.
*/
boolean cantAggr = false;
boolean propagatingInvokeExpr = false;
boolean propagatingFieldRef = false;
boolean propagatingArrayRef = false;
List<FieldRef> fieldRefList = new ArrayList<FieldRef>();
List<Value> localsUsed = new ArrayList<Value>();
for (ValueBox vb : s.getUseBoxes()) {
Value v = vb.getValue();
if (v instanceof Local) {
localsUsed.add(v);
} else if (v instanceof InvokeExpr) {
propagatingInvokeExpr = true;
} else if (v instanceof ArrayRef) {
propagatingArrayRef = true;
} else if (v instanceof FieldRef) {
propagatingFieldRef = true;
fieldRefList.add((FieldRef) v);
}
}
// look for a path from s to use in graph.
// only look in an extended basic block, though.
List<Unit> path = graph.getExtendedBasicBlockPathBetween(s, use);
if (path == null)
continue;
Iterator<Unit> pathIt = path.iterator();
// skip s.
if (pathIt.hasNext())
pathIt.next();
while (pathIt.hasNext() && !cantAggr) {
Stmt between = (Stmt) (pathIt.next());
if (between != use) {
for (ValueBox vb : between.getDefBoxes()) {
Value v = vb.getValue();
if (localsUsed.contains(v)) {
cantAggr = true;
break;
}
if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) {
if (v instanceof FieldRef) {
if (propagatingInvokeExpr) {
cantAggr = true;
break;
} else if (propagatingFieldRef) {
// aliased
for (FieldRef fieldRef : fieldRefList) {
if (isSameField((FieldRef) v, fieldRef)) {
cantAggr = true;
break;
}
}
}
} else if (v instanceof ArrayRef) {
if (propagatingInvokeExpr) {
// Cannot aggregate an invoke expr past an
// array write
cantAggr = true;
break;
} else if (propagatingArrayRef) {
// cannot aggregate an array read past a
// write
// this is somewhat conservative
// (if types differ they may not be aliased)
cantAggr = true;
break;
}
}
}
}
// Make sure not propagating past a {enter,exit}Monitor
if (propagatingInvokeExpr && between instanceof MonitorStmt)
cantAggr = true;
}
// Check for intervening side effects due to method calls
if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) {
for (final ValueBox box : between.getUseBoxes()) {
if (between == use && box == useBox) {
// side effects
break;
}
Value v = box.getValue();
if (v instanceof InvokeExpr || (propagatingInvokeExpr && (v instanceof FieldRef || v instanceof ArrayRef))) {
cantAggr = true;
break;
}
}
}
}
// we give up: can't aggregate.
if (cantAggr) {
continue;
}
/* assuming that the d-u chains are correct, */
/* we need not check the actual contents of ld */
Value aggregatee = s.getRightOp();
if (usepair.valueBox.canContainValue(aggregatee)) {
boolean wasSimpleCopy = isSimpleCopy(usepair.unit);
usepair.valueBox.setValue(aggregatee);
units.remove(s);
hadAggregation = true;
// followed by an invoke, the invoke gets the tags.
if (wasSimpleCopy) {
// usepair.unit.removeAllTags();
usepair.unit.addAllTagsOf(s);
}
} else {
/*
* if(Options.v().verbose()) {
* logger.debug("[debug] failed aggregation");
* logger.debug("[debug] tried to put "+aggregatee+
* " into "+usepair.stmt +
* ": in particular, "+usepair.valueBox);
* logger.debug("[debug] aggregatee instanceof Expr: "
* +(aggregatee instanceof Expr)); }
*/
}
}
return hadAggregation;
}
use of soot.jimple.MonitorStmt in project soot by Sable.
the class NullnessAssumptionAnalysis method flowThrough.
/**
* {@inheritDoc}
*/
protected void flowThrough(Object inValue, Object unit, Object outValue) // protected void flowThrough(Object flowin, Unit u, List fallOut, List branchOuts)
{
AnalysisInfo in = (AnalysisInfo) inValue;
AnalysisInfo out = new AnalysisInfo(in);
Stmt s = (Stmt) unit;
// in case of a monitor statement, we know that the programmer assumes we have a non-null value
if (s instanceof MonitorStmt) {
MonitorStmt monitorStmt = (MonitorStmt) s;
out.put(monitorStmt.getOp(), NON_NULL);
}
// cause we need to be conservative here
if (s.containsArrayRef()) {
ArrayRef arrayRef = s.getArrayRef();
handleArrayRef(arrayRef, out);
}
// same for field refs, but also set the receiver object to non-null, if there is one
if (s.containsFieldRef()) {
FieldRef fieldRef = s.getFieldRef();
handleFieldRef(fieldRef, out);
}
// same for invoke expr., also set the receiver object to non-null, if there is one
if (s.containsInvokeExpr()) {
InvokeExpr invokeExpr = s.getInvokeExpr();
handleInvokeExpr(invokeExpr, out);
}
// allow sublasses to define certain values as always-non-null
for (Iterator outIter = out.entrySet().iterator(); outIter.hasNext(); ) {
Entry entry = (Entry) outIter.next();
Value v = (Value) entry.getKey();
if (isAlwaysNonNull(v)) {
entry.setValue(NON_NULL);
}
}
// if we have a definition (assignment) statement to a ref-like type, handle it,
if (s instanceof DefinitionStmt) {
// need to copy the current out set because we need to assign under this assumption;
// so this copy becomes the in-set to handleRefTypeAssignment
AnalysisInfo temp = new AnalysisInfo(out);
DefinitionStmt defStmt = (DefinitionStmt) s;
if (defStmt.getLeftOp().getType() instanceof RefLikeType) {
handleRefTypeAssignment(defStmt, temp, out);
}
}
// save memory by only retaining information about locals
for (Iterator outIter = out.keySet().iterator(); outIter.hasNext(); ) {
Value v = (Value) outIter.next();
if (!(v instanceof Local)) {
outIter.remove();
}
}
// for (Iterator outBranchIter = outBranch.keySet().iterator(); outBranchIter.hasNext();) {
// Value v = (Value) outBranchIter.next();
// if(!(v instanceof Local)) {
// outBranchIter.remove();
// }
// }
// now copy the computed info to out
copy(out, outValue);
}
Aggregations