use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class SootInfo method countCallEdgesForCallsite.
public static int countCallEdgesForCallsite(Stmt callsite, boolean stopForMutiple) {
CallGraph cg = Scene.v().getCallGraph();
int count = 0;
for (Iterator<Edge> it = cg.edgesOutOf(callsite); it.hasNext(); ) {
it.next();
++count;
if (stopForMutiple && count > 1)
break;
}
return count;
}
use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class ContextInsensitiveBuilder method build.
/**
* Fills in the pointer assignment graph returned by setup.
*/
public void build() {
QueueReader<Edge> callEdges;
if (ofcg != null) {
callEdges = ofcg.callGraph().listener();
ofcg.build();
reachables = ofcg.reachableMethods();
reachables.update();
} else {
callEdges = cgb.getCallGraph().listener();
cgb.build();
reachables = cgb.reachables();
}
for (final SootClass c : Scene.v().getClasses()) {
handleClass(c);
}
while (callEdges.hasNext()) {
Edge e = callEdges.next();
if (e.getTgt().method().getDeclaringClass().isConcrete()) {
if (e.tgt().isConcrete() || e.tgt().isNative())
MethodPAG.v(pag, e.tgt()).addToPAG(null);
pag.addCallTarget(e);
}
}
if (pag.getOpts().verbose()) {
logger.debug("Total methods: " + totalMethods);
logger.debug("Initially reachable methods: " + analyzedMethods);
logger.debug("Classes with at least one reachable method: " + classes);
}
}
use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class GeomQueries method kCFA.
/**
* Standard K-CFA querying for arbitrary K.
*
* @param callEdgeChain: last K call edges leading to the method that contains l. callEdgeChain[0] is the farthest call edge in the chain.
* @param l: the querying pointer
* @param visitor: the querying result container
* @return false, l does not have points-to information under the given context
*/
@SuppressWarnings("rawtypes")
public boolean kCFA(Edge[] callEdgeChain, Local l, PtSensVisitor visitor) {
// Prepare for initial contexts
SootMethod firstMethod = callEdgeChain[0].src();
int firstMethodID = geomPTA.getIDFromSootMethod(firstMethod);
if (firstMethodID == -1)
return false;
// Obtain the internal representation for querying pointer
LocalVarNode vn = geomPTA.findLocalVarNode(l);
if (vn == null) {
// Normally this could not happen, perhaps it's a bug
return false;
}
IVarAbstraction pn = geomPTA.findInternalNode(vn);
if (pn == null) {
// This pointer is no longer reachable
return false;
}
pn = pn.getRepresentative();
if (!pn.hasPTResult())
return false;
SootMethod sm = vn.getMethod();
if (geomPTA.getIDFromSootMethod(sm) == -1)
return false;
// Iterate the call edges and compute the contexts mapping iteratively
visitor.prepare();
long L = 1;
for (int i = 0; i < callEdgeChain.length; ++i) {
Edge sootEdge = callEdgeChain[i];
CgEdge ctxt = geomPTA.getInternalEdgeFromSootEdge(sootEdge);
if (ctxt == null || ctxt.is_obsoleted == true)
return false;
// Following searching procedure works for both methods in SCC and out of SCC
// with blocking scheme or without blocking scheme
int caller = geomPTA.getIDFromSootMethod(sootEdge.src());
// We obtain the block that contains current offset L
long block_size = max_context_size_block[rep_cg[caller]];
long in_block_offset = (L - 1) % block_size;
// Transfer to the target block with the same in-block offset
L = ctxt.map_offset + in_block_offset;
}
long ctxtLength = max_context_size_block[rep_cg[firstMethodID]];
long R = L + ctxtLength;
pn.get_all_context_sensitive_objects(L, R, visitor);
visitor.finish();
return visitor.numOfDiffObjects() != 0;
}
use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class StaticMethodBinder method internalTransform.
protected void internalTransform(String phaseName, Map opts) {
Filter instanceInvokesFilter = new Filter(new InstanceInvokeEdgesPred());
SMBOptions options = new SMBOptions(opts);
String modifierOptions = PhaseOptions.getString(opts, "allowed-modifier-changes");
HashMap instanceToStaticMap = new HashMap();
CallGraph cg = Scene.v().getCallGraph();
Hierarchy hierarchy = Scene.v().getActiveHierarchy();
Iterator classesIt = Scene.v().getApplicationClasses().iterator();
while (classesIt.hasNext()) {
SootClass c = (SootClass) classesIt.next();
LinkedList methodsList = new LinkedList();
for (Iterator it = c.methodIterator(); it.hasNext(); ) {
methodsList.add(it.next());
}
while (!methodsList.isEmpty()) {
SootMethod container = (SootMethod) methodsList.removeFirst();
if (!container.isConcrete())
continue;
if (!instanceInvokesFilter.wrap(cg.edgesOutOf(container)).hasNext())
continue;
JimpleBody b = (JimpleBody) container.getActiveBody();
List<Unit> unitList = new ArrayList<Unit>();
unitList.addAll(b.getUnits());
Iterator<Unit> unitIt = unitList.iterator();
while (unitIt.hasNext()) {
Stmt s = (Stmt) unitIt.next();
if (!s.containsInvokeExpr())
continue;
InvokeExpr ie = s.getInvokeExpr();
if (ie instanceof StaticInvokeExpr || ie instanceof SpecialInvokeExpr)
continue;
Iterator targets = new Targets(instanceInvokesFilter.wrap(cg.edgesOutOf(s)));
if (!targets.hasNext())
continue;
SootMethod target = (SootMethod) targets.next();
if (targets.hasNext())
continue;
if (!AccessManager.ensureAccess(container, target, modifierOptions))
continue;
if (!target.getDeclaringClass().isApplicationClass() || !target.isConcrete())
continue;
// Don't modify java.lang.Object
if (target.getDeclaringClass() == Scene.v().getSootClass("java.lang.Object"))
continue;
if (!instanceToStaticMap.containsKey(target)) {
List newParameterTypes = new ArrayList();
newParameterTypes.add(RefType.v(target.getDeclaringClass().getName()));
newParameterTypes.addAll(target.getParameterTypes());
// Check for signature conflicts.
String newName = target.getName() + "_static";
while (target.getDeclaringClass().declaresMethod(newName, newParameterTypes, target.getReturnType())) newName = newName + "_static";
SootMethod ct = Scene.v().makeSootMethod(newName, newParameterTypes, target.getReturnType(), target.getModifiers() | Modifier.STATIC, target.getExceptions());
target.getDeclaringClass().addMethod(ct);
methodsList.addLast(ct);
ct.setActiveBody((Body) target.getActiveBody().clone());
// Make the invoke graph take into account the
// newly-cloned body.
{
Iterator oldUnits = target.getActiveBody().getUnits().iterator();
Iterator newUnits = ct.getActiveBody().getUnits().iterator();
while (newUnits.hasNext()) {
Stmt oldStmt, newStmt;
oldStmt = (Stmt) oldUnits.next();
newStmt = (Stmt) newUnits.next();
Iterator edges = cg.edgesOutOf(oldStmt);
while (edges.hasNext()) {
Edge e = (Edge) edges.next();
cg.addEdge(new Edge(ct, newStmt, e.tgt(), e.kind()));
cg.removeEdge(e);
}
}
}
// Shift the parameter list to apply to the new this
// parameter.
// If the method uses this, then we replace
// the r0 := @this with r0 := @parameter0 & shift.
// Otherwise, just zap the r0 := @this.
{
Body newBody = ct.getActiveBody();
Chain units = newBody.getUnits();
Iterator unitsIt = newBody.getUnits().snapshotIterator();
while (unitsIt.hasNext()) {
Stmt st = (Stmt) unitsIt.next();
if (st instanceof IdentityStmt) {
IdentityStmt is = (IdentityStmt) st;
if (is.getRightOp() instanceof ThisRef) {
units.swapWith(st, Jimple.v().newIdentityStmt(is.getLeftOp(), Jimple.v().newParameterRef(is.getRightOp().getType(), 0)));
} else {
if (is.getRightOp() instanceof ParameterRef) {
ParameterRef ro = (ParameterRef) is.getRightOp();
ro.setIndex(ro.getIndex() + 1);
}
}
}
}
}
instanceToStaticMap.put(target, ct);
}
SootMethod clonedTarget = (SootMethod) instanceToStaticMap.get(target);
Value thisToAdd = ((InstanceInvokeExpr) ie).getBase();
// Insert casts to please the verifier.
if (options.insert_redundant_casts()) {
// The verifier will complain if targetUsesThis, and:
// the argument passed to the method is not the same
// type.
// For instance, Bottle.price_static takes a cost.
// Cost is an interface implemented by Bottle.
SootClass localType, parameterType;
localType = ((RefType) ((InstanceInvokeExpr) ie).getBase().getType()).getSootClass();
parameterType = target.getDeclaringClass();
if (localType.isInterface() || hierarchy.isClassSuperclassOf(localType, parameterType)) {
Local castee = Jimple.v().newLocal("__castee", parameterType.getType());
b.getLocals().add(castee);
b.getUnits().insertBefore(Jimple.v().newAssignStmt(castee, Jimple.v().newCastExpr(((InstanceInvokeExpr) ie).getBase(), parameterType.getType())), s);
thisToAdd = castee;
}
}
// Now rebind the method call & fix the invoke graph.
{
List newArgs = new ArrayList();
newArgs.add(thisToAdd);
newArgs.addAll(ie.getArgs());
StaticInvokeExpr sie = Jimple.v().newStaticInvokeExpr(clonedTarget.makeRef(), newArgs);
ValueBox ieBox = s.getInvokeExprBox();
ieBox.setValue(sie);
cg.addEdge(new Edge(container, s, clonedTarget));
}
// (If enabled), add a null pointer check.
if (options.insert_null_checks()) {
boolean caught = TrapManager.isExceptionCaughtAt(Scene.v().getSootClass("java.lang.NullPointerException"), s, b);
/* Ah ha. Caught again! */
if (caught) {
/*
* In this case, we don't use throwPoint; instead,
* put the code right there.
*/
Stmt insertee = Jimple.v().newIfStmt(Jimple.v().newNeExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), s);
b.getUnits().insertBefore(insertee, s);
// This sucks (but less than before).
((IfStmt) insertee).setTarget(s);
ThrowManager.addThrowAfter(b, insertee);
} else {
Stmt throwPoint = ThrowManager.getNullPointerExceptionThrower(b);
b.getUnits().insertBefore(Jimple.v().newIfStmt(Jimple.v().newEqExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), throwPoint), s);
}
}
// Add synchronizing stuff.
{
if (target.isSynchronized()) {
clonedTarget.setModifiers(clonedTarget.getModifiers() & ~Modifier.SYNCHRONIZED);
SynchronizerManager.v().synchronizeStmtOn(s, b, (Local) ((InstanceInvokeExpr) ie).getBase());
}
}
// Resolve name collisions.
LocalNameStandardizer.v().transform(b, phaseName + ".lns");
}
}
}
}
use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class InfoFlowAnalysis method getInvokeInfoFlowSummary.
protected HashMutableDirectedGraph<EquivalentValue> getInvokeInfoFlowSummary(InvokeExpr ie, Stmt is, SootMethod context) {
// get the data flow graph for each possible target of ie,
// then combine them conservatively and return the result.
HashMutableDirectedGraph<EquivalentValue> ret = null;
SootMethodRef methodRef = ie.getMethodRef();
String subSig = methodRef.resolve().getSubSignature();
CallGraph cg = Scene.v().getCallGraph();
for (Iterator<Edge> edges = cg.edgesOutOf(is); edges.hasNext(); ) {
Edge e = edges.next();
SootMethod target = e.getTgt().method();
// and not just a class initializer or other unintended control flow.
if (target.getSubSignature().equals(subSig)) {
HashMutableDirectedGraph<EquivalentValue> ifs = getMethodInfoFlowSummary(target, context.getDeclaringClass().isApplicationClass());
if (ret == null)
ret = ifs;
else {
for (EquivalentValue node : ifs.getNodes()) {
if (!ret.containsNode(node))
ret.addNode(node);
for (EquivalentValue succ : ifs.getSuccsOf(node)) ret.addEdge(node, succ);
}
}
}
}
return ret;
// return getMethodInfoFlowSummary(methodRef.resolve(), context.getDeclaringClass().isApplicationClass());
}
Aggregations