SootMethod m = e.tgt(); s.addTag(new LinkTag("CallGraph: Type: " + e.kind() + " Target Method/Context: " + e.getTgt().toString(), m, m.getDeclaringClass().getName(), "Call Graph")); while (callerEdges.hasNext()) { Edge callEdge = (Edge) callerEdges.next(); SootMethod methodCaller = callEdge.src(); Host src = methodCaller; if (callEdge.srcUnit() != null) { src = callEdge.srcUnit(); "CallGraph: Source Type: " + callEdge.kind() + " Source Method/Context: " + callEdge.getSrc().toString(), src, methodCaller.getDeclaringClass().getName(), "Call Graph"));
String tgtMethod = e.tgt().toString(); String tgtClass = e.tgt().getDeclaringClass().toString(); String srcMethod = e.src().toString(); String srcClass = e.src().getDeclaringClass().toString(); && e.tgt().toString().endsWith("boolean equals(java.lang.Object)>")) { return false; if (e.tgt().isSynchronized()) { return false; while (tnIt.hasNext()) { CriticalSection tn = tnIt.next(); if (tn != exemptTn && tn.units.contains(e.srcStmt())) // if this method call originates inside a transaction...
/** * Swaps an invocation statement. All edges that previously went from the given statement to some callee now go from the * new statement to the same callee. This method is intended to be used when a Jimple statement is replaced, but the * replacement does not semantically affect the edges. * * @param out * The old statement * @param in * The new statement * @return True if at least one edge was affected by this operation */ public boolean swapEdgesOutOf(Stmt out, Stmt in) { boolean hasSwapped = false; for (QueueReader<Edge> edgeRdr = listener(); edgeRdr.hasNext();) { Edge e = edgeRdr.next(); if (e.srcUnit() == out) { removeEdge(e); addEdge(new Edge(e.getSrc(), in, e.getTgt())); hasSwapped = true; } } return hasSwapped; }
@Override public boolean want(Edge e) { if (e.kind() == Kind.CLINIT) return false; else if (e.kind() == Kind.VIRTUAL) { if (!e.src().isStatic() && e.srcStmt().getInvokeExpr() instanceof InstanceInvokeExpr) { SootMethod refMethod = e.srcStmt().getInvokeExpr().getMethod(); InstanceInvokeExpr iinv = (InstanceInvokeExpr) e.srcStmt().getInvokeExpr(); if (iinv.getBase() == e.src().getActiveBody().getThisLocal()) { SootClass targetClass = e.getTgt().method().getDeclaringClass(); return targetClass == originalComponent || Scene.v().getFastHierarchy().isSubclass(targetClass, originalComponent); if (e.kind() == Kind.THREAD || e.kind() == Kind.EXECUTOR) return false; if (e.tgt().getName().equals("run")) if (Scene.v().getFastHierarchy().canStoreType(e.tgt().getDeclaringClass().getType(), RefType.v("java.lang.Runnable"))) return false;
public void addCallTarget(Edge e) { if (!e.passesParameters()) { return; MethodPAG srcmpag = MethodPAG.v(this, e.src()); MethodPAG tgtmpag = MethodPAG.v(this, e.tgt()); Pair<Node, Node> pval; if (e.isExplicit() || e.kind() == Kind.THREAD || e.kind() == Kind.ASYNCTASK) { addCallTarget(srcmpag, tgtmpag, (Stmt) e.srcUnit(), e.srcCtxt(), e.tgtCtxt(), e); } else if (e.kind() == Kind.EXECUTOR) { InvokeExpr ie = e.srcStmt().getInvokeExpr(); boolean virtualCall = callAssigns.containsKey(ie); parm = srcmpag.parameterize(parm, e.srcCtxt()); parm = parm.getReplacement(); thiz = tgtmpag.parameterize(thiz, e.tgtCtxt()); thiz = thiz.getReplacement(); } else if (e.kind() == Kind.HANDLER) { InvokeExpr ie = e.srcStmt().getInvokeExpr(); boolean virtualCall = callAssigns.containsKey(ie); assert virtualCall == true; base = srcmpag.parameterize(base, e.srcCtxt()); base = base.getReplacement(); thiz = tgtmpag.parameterize(thiz, e.tgtCtxt()); thiz = thiz.getReplacement();
/** * Used to add an edge to the call graph. Returns true iff the edge was not already present. */ public boolean addEdge(Edge e) { if (!edges.add(e)) { return false; } stream.add(e); Edge position = null; position = srcUnitToEdge.get(e.srcUnit()); if (position == null) { srcUnitToEdge.put(e.srcUnit(), e); position = dummy; } e.insertAfterByUnit(position); position = srcMethodToEdge.get(e.getSrc()); if (position == null) { srcMethodToEdge.put(e.getSrc(), e); position = dummy; } e.insertAfterBySrc(position); position = tgtToEdge.get(e.getTgt()); if (position == null) { tgtToEdge.put(e.getTgt(), e); position = dummy; } e.insertAfterByTgt(position); return true; }
while (edgeList.hasNext()) { Edge edge = edgeList.next(); if (edge.isClinit()) { continue; SootMethod src_func = edge.src(); SootMethod tgt_func = edge.tgt(); s = func2int.get(src_func); t = func2int.get(tgt_func); Stmt callsite = edge.srcStmt(); if (edge.isThreadRunCall() || edge.kind().isExecutor() || edge.kind().isAsyncTask()) { } else if (edge.isInstance() && !edge.isSpecial()) {
return false; e.remove(); if (srcUnitToEdge.get(e.srcUnit()) == e) { if (e.nextByUnit().srcUnit() == e.srcUnit()) { srcUnitToEdge.put(e.srcUnit(), e.nextByUnit()); } else { srcUnitToEdge.put(e.srcUnit(), null); if (srcMethodToEdge.get(e.getSrc()) == e) { if (e.nextBySrc().getSrc() == e.getSrc()) { srcMethodToEdge.put(e.getSrc(), e.nextBySrc()); } else { srcMethodToEdge.put(e.getSrc(), null); if (tgtToEdge.get(e.getTgt()) == e) { if (e.nextByTgt().getTgt() == e.getTgt()) { tgtToEdge.put(e.getTgt(), e.nextByTgt()); } else { tgtToEdge.put(e.getTgt(), null);
protected void internalTransform(Body b, String phaseName, Map options) { ClinitElimAnalysis a = new ClinitElimAnalysis(new BriefUnitGraph(b)); CallGraph cg = Scene.v().getCallGraph(); SootMethod m = b.getMethod(); Iterator edgeIt = cg.edgesOutOf(m); while (edgeIt.hasNext()) { Edge e = (Edge) edgeIt.next(); if (e.srcStmt() == null) { continue; } if (!e.isClinit()) { continue; } FlowSet methods = (FlowSet) a.getFlowBefore(e.srcStmt()); if (methods.contains(e.tgt())) { cg.removeEdge(e); } } } }
/** * Find the specific call edge that is going out from the callsite u and the call target is callee. Without advanced data * structure, we can only sequentially search for the match. Fortunately, the number of outgoing edges for a unit is not * too large. * * @param u * @param callee * @return */ public Edge findEdge(Unit u, SootMethod callee) { Edge e = srcUnitToEdge.get(u); while (e.srcUnit() == u && e.kind() != Kind.INVALID) { if (e.tgt() == callee) { return e; } e = e.nextByUnit(); } return null; }
while (edgeIt.hasNext()) { Edge e = (Edge) edgeIt.next(); SootMethod node = e.src(); if (!path.containsMethod(node) && e.isExplicit() && e.srcStmt().containsInvokeExpr()) {
private ArrayList<MethInfo> getSrcMethods(SootMethod method, boolean recurse) { // logger.debug("meth for srcs: "+method); ArrayList<MethInfo> list = new ArrayList<MethInfo>(); for (Iterator momcIt = methodToContexts.get(method).iterator(); momcIt.hasNext();) { final MethodOrMethodContext momc = (MethodOrMethodContext) momcIt.next(); Iterator callerEdges = cg.edgesInto(momc); while (callerEdges.hasNext()) { Edge callEdge = (Edge) callerEdges.next(); SootMethod methodCaller = callEdge.src(); if (methodCaller.getDeclaringClass().isLibraryClass()) { if (isShowLibMeths()) { if (recurse) { list.add( new MethInfo(methodCaller, hasTgtMethods(methodCaller) | hasSrcMethods(methodCaller), callEdge.kind())); } else { list.add(new MethInfo(methodCaller, true, callEdge.kind())); } } } else { if (recurse) { list.add(new MethInfo(methodCaller, hasTgtMethods(methodCaller) | hasSrcMethods(methodCaller), callEdge.kind())); } else { list.add(new MethInfo(methodCaller, true, callEdge.kind())); } } } } return list; }
protected void flowThrough(Object inVal, Object stmt, Object outVal) { FlowSet in = (FlowSet) inVal; FlowSet out = (FlowSet) outVal; Stmt s = (Stmt) stmt; in.copy(out); CallGraph cg = Scene.v().getCallGraph(); Iterator edges = cg.edgesOutOf(s); while (edges.hasNext()) { Edge e = (Edge) edges.next(); if (e.isClinit()) { out.add(e.tgt()); } } }
public List<SootMethod> find(Unit unit, CallGraph cg, boolean canBeNullList, boolean canBeNative) { List<SootMethod> target = new ArrayList<SootMethod>(); Iterator<Edge> it = cg.edgesOutOf(unit); while (it.hasNext()) { Edge edge = it.next(); SootMethod targetMethod = edge.tgt(); if (targetMethod.isNative() && !canBeNative) { continue; } if (edge.kind() == Kind.CLINIT) { continue; } target.add(targetMethod); } if (target.size() < 1 && !canBeNullList) { throw new RuntimeException("No target method for: " + unit); } return target; } }