use of soot.Unit in project soot by Sable.
the class IFDSLiveVariables method createFlowFunctionsFactory.
@Override
public FlowFunctions<Unit, Value, SootMethod> createFlowFunctionsFactory() {
return new FlowFunctions<Unit, Value, SootMethod>() {
@Override
public FlowFunction<Value> getNormalFlowFunction(Unit curr, Unit succ) {
if (curr.getUseAndDefBoxes().isEmpty())
return Identity.v();
final Stmt s = (Stmt) curr;
return new FlowFunction<Value>() {
public Set<Value> computeTargets(Value source) {
// kill defs
List<ValueBox> defs = s.getDefBoxes();
if (!defs.isEmpty()) {
if (defs.get(0).getValue().equivTo(source)) {
return Collections.emptySet();
}
}
// gen uses out of zero value
if (source.equals(zeroValue())) {
Set<Value> liveVars = new HashSet<Value>();
for (ValueBox useBox : s.getUseBoxes()) {
Value value = useBox.getValue();
liveVars.add(value);
}
return liveVars;
}
// else just propagate
return Collections.singleton(source);
}
};
}
@Override
public FlowFunction<Value> getCallFlowFunction(Unit callStmt, final SootMethod destinationMethod) {
final Stmt s = (Stmt) callStmt;
return new FlowFunction<Value>() {
public Set<Value> computeTargets(Value source) {
if (!s.getDefBoxes().isEmpty()) {
Value callerSideReturnValue = s.getDefBoxes().get(0).getValue();
if (callerSideReturnValue.equivTo(source)) {
Set<Value> calleeSideReturnValues = new HashSet<Value>();
for (Unit calleeUnit : interproceduralCFG().getStartPointsOf(destinationMethod)) {
if (calleeUnit instanceof ReturnStmt) {
ReturnStmt returnStmt = (ReturnStmt) calleeUnit;
calleeSideReturnValues.add(returnStmt.getOp());
}
}
return calleeSideReturnValues;
}
}
// no return value, nothing to propagate
return Collections.emptySet();
}
};
}
@Override
public FlowFunction<Value> getReturnFlowFunction(final Unit callSite, SootMethod calleeMethod, final Unit exitStmt, Unit returnSite) {
Stmt s = (Stmt) callSite;
InvokeExpr ie = s.getInvokeExpr();
final List<Value> callArgs = ie.getArgs();
final List<Local> paramLocals = new ArrayList<Local>();
for (int i = 0; i < calleeMethod.getParameterCount(); i++) {
paramLocals.add(calleeMethod.getActiveBody().getParameterLocal(i));
}
return new FlowFunction<Value>() {
public Set<Value> computeTargets(Value source) {
Set<Value> liveParamsAtCallee = new HashSet<Value>();
for (int i = 0; i < paramLocals.size(); i++) {
if (paramLocals.get(i).equivTo(source)) {
liveParamsAtCallee.add(callArgs.get(i));
}
}
return liveParamsAtCallee;
}
};
}
@Override
public FlowFunction<Value> getCallToReturnFlowFunction(Unit callSite, Unit returnSite) {
if (callSite.getUseAndDefBoxes().isEmpty())
return Identity.v();
final Stmt s = (Stmt) callSite;
return new FlowFunction<Value>() {
public Set<Value> computeTargets(Value source) {
// kill defs
List<ValueBox> defs = s.getDefBoxes();
if (!defs.isEmpty()) {
if (defs.get(0).getValue().equivTo(source)) {
return Collections.emptySet();
}
}
// gen uses out of zero value
if (source.equals(zeroValue())) {
Set<Value> liveVars = new HashSet<Value>();
// only "gen" those values that are not parameter values;
// the latter are taken care of by the return-flow function
List<Value> args = s.getInvokeExpr().getArgs();
for (ValueBox useBox : s.getUseBoxes()) {
Value value = useBox.getValue();
if (!args.contains(value)) {
liveVars.add(value);
}
}
return liveVars;
}
// else just propagate
return Collections.singleton(source);
}
};
}
};
}
use of soot.Unit in project soot by Sable.
the class IFDSUninitializedVariables method createFlowFunctionsFactory.
@Override
public FlowFunctions<Unit, Local, SootMethod> createFlowFunctionsFactory() {
return new FlowFunctions<Unit, Local, SootMethod>() {
@Override
public FlowFunction<Local> getNormalFlowFunction(Unit curr, Unit succ) {
final SootMethod m = interproceduralCFG().getMethodOf(curr);
if (Scene.v().getEntryPoints().contains(m) && interproceduralCFG().isStartPoint(curr)) {
return new FlowFunction<Local>() {
@Override
public Set<Local> computeTargets(Local source) {
if (source == zeroValue()) {
Set<Local> res = new LinkedHashSet<Local>();
res.addAll(m.getActiveBody().getLocals());
for (int i = 0; i < m.getParameterCount(); i++) res.remove(m.getActiveBody().getParameterLocal(i));
return res;
}
return Collections.emptySet();
}
};
}
if (curr instanceof DefinitionStmt) {
final DefinitionStmt definition = (DefinitionStmt) curr;
final Value leftOp = definition.getLeftOp();
if (leftOp instanceof Local) {
final Local leftOpLocal = (Local) leftOp;
return new FlowFunction<Local>() {
@Override
public Set<Local> computeTargets(final Local source) {
List<ValueBox> useBoxes = definition.getUseBoxes();
for (ValueBox valueBox : useBoxes) {
if (valueBox.getValue().equivTo(source)) {
LinkedHashSet<Local> res = new LinkedHashSet<Local>();
res.add(source);
res.add(leftOpLocal);
return res;
}
}
if (leftOp.equivTo(source))
return Collections.emptySet();
return Collections.singleton(source);
}
};
}
}
return Identity.v();
}
@Override
public FlowFunction<Local> getCallFlowFunction(Unit callStmt, final SootMethod destinationMethod) {
Stmt stmt = (Stmt) callStmt;
InvokeExpr invokeExpr = stmt.getInvokeExpr();
final List<Value> args = invokeExpr.getArgs();
final List<Local> localArguments = new ArrayList<Local>();
for (Value value : args) if (value instanceof Local)
localArguments.add((Local) value);
return new FlowFunction<Local>() {
@Override
public Set<Local> computeTargets(final Local source) {
// Do not map parameters for <clinit> edges
if (destinationMethod.getName().equals("<clinit>") || destinationMethod.getSubSignature().equals("void run()"))
return Collections.emptySet();
for (Local localArgument : localArguments) {
if (source.equivTo(localArgument)) {
return Collections.<Local>singleton(destinationMethod.getActiveBody().getParameterLocal(args.indexOf(localArgument)));
}
}
if (source == zeroValue()) {
// gen all locals that are not parameter locals
Collection<Local> locals = destinationMethod.getActiveBody().getLocals();
LinkedHashSet<Local> uninitializedLocals = new LinkedHashSet<Local>(locals);
for (int i = 0; i < destinationMethod.getParameterCount(); i++) {
uninitializedLocals.remove(destinationMethod.getActiveBody().getParameterLocal(i));
}
return uninitializedLocals;
}
return Collections.emptySet();
}
};
}
@Override
public FlowFunction<Local> getReturnFlowFunction(final Unit callSite, SootMethod calleeMethod, final Unit exitStmt, Unit returnSite) {
if (callSite instanceof DefinitionStmt) {
final DefinitionStmt definition = (DefinitionStmt) callSite;
if (definition.getLeftOp() instanceof Local) {
final Local leftOpLocal = (Local) definition.getLeftOp();
if (exitStmt instanceof ReturnStmt) {
final ReturnStmt returnStmt = (ReturnStmt) exitStmt;
return new FlowFunction<Local>() {
@Override
public Set<Local> computeTargets(Local source) {
if (returnStmt.getOp().equivTo(source))
return Collections.singleton(leftOpLocal);
return Collections.emptySet();
}
};
} else if (exitStmt instanceof ThrowStmt) {
// if we throw an exception, LHS of call is undefined
return new FlowFunction<Local>() {
@Override
public Set<Local> computeTargets(final Local source) {
if (source == zeroValue())
return Collections.singleton(leftOpLocal);
else
return Collections.emptySet();
}
};
}
}
}
return KillAll.v();
}
@Override
public FlowFunction<Local> getCallToReturnFlowFunction(Unit callSite, Unit returnSite) {
if (callSite instanceof DefinitionStmt) {
DefinitionStmt definition = (DefinitionStmt) callSite;
if (definition.getLeftOp() instanceof Local) {
final Local leftOpLocal = (Local) definition.getLeftOp();
return new Kill<Local>(leftOpLocal);
}
}
return Identity.v();
}
};
}
use of soot.Unit in project soot by Sable.
the class JimpleBasedInterproceduralCFG method initializeUnitToOwner.
public void initializeUnitToOwner(SootMethod m) {
if (m.hasActiveBody()) {
Body b = m.getActiveBody();
PatchingChain<Unit> units = b.getUnits();
for (Unit unit : units) {
unitToOwner.put(unit, b);
}
}
}
use of soot.Unit in project soot by Sable.
the class ReflectionTraceInfo method inferSource.
private Set<SootMethod> inferSource(String source, int lineNumber) {
String className = source.substring(0, source.lastIndexOf("."));
String methodName = source.substring(source.lastIndexOf(".") + 1);
if (!Scene.v().containsClass(className)) {
Scene.v().addBasicClass(className, SootClass.BODIES);
Scene.v().loadBasicClasses();
if (!Scene.v().containsClass(className)) {
throw new RuntimeException("Trace file refers to unknown class: " + className);
}
}
SootClass sootClass = Scene.v().getSootClass(className);
Set<SootMethod> methodsWithRightName = new LinkedHashSet<SootMethod>();
for (SootMethod m : sootClass.getMethods()) {
if (m.isConcrete() && m.getName().equals(methodName)) {
methodsWithRightName.add(m);
}
}
if (methodsWithRightName.isEmpty()) {
throw new RuntimeException("Trace file refers to unknown method with name " + methodName + " in Class " + className);
} else if (methodsWithRightName.size() == 1) {
return Collections.singleton(methodsWithRightName.iterator().next());
} else {
// more than one method with that name
for (SootMethod sootMethod : methodsWithRightName) {
if (coversLineNumber(lineNumber, sootMethod)) {
return Collections.singleton(sootMethod);
}
if (sootMethod.isConcrete()) {
if (!sootMethod.hasActiveBody())
sootMethod.retrieveActiveBody();
Body body = sootMethod.getActiveBody();
if (coversLineNumber(lineNumber, body)) {
return Collections.singleton(sootMethod);
}
for (Unit u : body.getUnits()) {
if (coversLineNumber(lineNumber, u)) {
return Collections.singleton(sootMethod);
}
}
}
}
// be conservative and return all method that we found
return methodsWithRightName;
}
}
use of soot.Unit in project soot by Sable.
the class ThisInliner method internalTransform.
public void internalTransform(Body b, String phaseName, Map options) {
// assure body is a constructor
if (!b.getMethod().getName().equals("<init>"))
return;
// if the first invoke is a this() and not a super() inline the this()
InvokeStmt invokeStmt = getFirstSpecialInvoke(b);
if (invokeStmt == null)
return;
SpecialInvokeExpr specInvokeExpr = (SpecialInvokeExpr) invokeStmt.getInvokeExpr();
if (specInvokeExpr.getMethod().getDeclaringClass().equals(b.getMethod().getDeclaringClass())) {
// put locals from inlinee into container
if (!specInvokeExpr.getMethod().hasActiveBody()) {
specInvokeExpr.getMethod().retrieveActiveBody();
}
HashMap<Local, Local> oldLocalsToNew = new HashMap<Local, Local>();
for (Local l : specInvokeExpr.getMethod().getActiveBody().getLocals()) {
Local newLocal = (Local) l.clone();
b.getLocals().add(newLocal);
oldLocalsToNew.put(l, newLocal);
}
// find identity stmt of original method
IdentityStmt origIdStmt = findIdentityStmt(b);
HashMap<Stmt, Stmt> oldStmtsToNew = new HashMap<Stmt, Stmt>();
// System.out.println("locals: "+b.getLocals());
Chain<Unit> containerUnits = b.getUnits();
for (Unit u : specInvokeExpr.getMethod().getActiveBody().getUnits()) {
Stmt inlineeStmt = (Stmt) u;
// handle identity stmts
if (inlineeStmt instanceof IdentityStmt) {
IdentityStmt idStmt = (IdentityStmt) inlineeStmt;
if (idStmt.getRightOp() instanceof ThisRef) {
Stmt newThis = Jimple.v().newAssignStmt((Local) oldLocalsToNew.get(idStmt.getLeftOp()), origIdStmt.getLeftOp());
containerUnits.insertBefore(newThis, invokeStmt);
oldStmtsToNew.put(inlineeStmt, newThis);
} else if (idStmt.getRightOp() instanceof CaughtExceptionRef) {
Stmt newInlinee = (Stmt) inlineeStmt.clone();
for (ValueBox next : newInlinee.getUseAndDefBoxes()) {
if (next.getValue() instanceof Local) {
next.setValue((Local) oldLocalsToNew.get(next.getValue()));
}
}
containerUnits.insertBefore(newInlinee, invokeStmt);
oldStmtsToNew.put(inlineeStmt, newInlinee);
} else if (idStmt.getRightOp() instanceof ParameterRef) {
Stmt newParam = Jimple.v().newAssignStmt((Local) oldLocalsToNew.get(idStmt.getLeftOp()), specInvokeExpr.getArg(((ParameterRef) idStmt.getRightOp()).getIndex()));
containerUnits.insertBefore(newParam, invokeStmt);
oldStmtsToNew.put(inlineeStmt, newParam);
}
} else // from a constructor)
if (inlineeStmt instanceof ReturnVoidStmt) {
Stmt newRet = Jimple.v().newGotoStmt((Stmt) containerUnits.getSuccOf(invokeStmt));
containerUnits.insertBefore(newRet, invokeStmt);
System.out.println("adding to stmt map: " + inlineeStmt + " and " + newRet);
oldStmtsToNew.put(inlineeStmt, newRet);
} else {
Stmt newInlinee = (Stmt) inlineeStmt.clone();
for (ValueBox next : newInlinee.getUseAndDefBoxes()) {
if (next.getValue() instanceof Local) {
next.setValue((Local) oldLocalsToNew.get(next.getValue()));
}
}
containerUnits.insertBefore(newInlinee, invokeStmt);
oldStmtsToNew.put(inlineeStmt, newInlinee);
}
}
// handleTraps
for (Trap t : specInvokeExpr.getMethod().getActiveBody().getTraps()) {
System.out.println("begin: " + t.getBeginUnit());
Stmt newBegin = oldStmtsToNew.get(t.getBeginUnit());
System.out.println("end: " + t.getEndUnit());
Stmt newEnd = oldStmtsToNew.get(t.getEndUnit());
System.out.println("handler: " + t.getHandlerUnit());
Stmt newHandler = oldStmtsToNew.get(t.getHandlerUnit());
if (newBegin == null || newEnd == null || newHandler == null)
throw new RuntimeException("couldn't map trap!");
b.getTraps().add(Jimple.v().newTrap(t.getException(), newBegin, newEnd, newHandler));
}
// patch gotos
for (Unit u : specInvokeExpr.getMethod().getActiveBody().getUnits()) {
Stmt inlineeStmt = (Stmt) u;
if (inlineeStmt instanceof GotoStmt) {
System.out.println("inlinee goto target: " + ((GotoStmt) inlineeStmt).getTarget());
((GotoStmt) oldStmtsToNew.get(inlineeStmt)).setTarget(oldStmtsToNew.get(((GotoStmt) inlineeStmt).getTarget()));
}
}
// remove original invoke
containerUnits.remove(invokeStmt);
// resolve name collisions
LocalNameStandardizer.v().transform(b, "ji.lns");
}
// System.out.println("locals: "+b.getLocals());
// System.out.println("units: "+b.getUnits());
}
Aggregations