private boolean callEdgesReasonable() { Set<VarNode> vars = contextSensitiveAssignEdges.keySet(); for (VarNode node : vars) { ArraySet<AssignEdge> assigns = contextSensitiveAssignEdges.get(node); for (AssignEdge edge : assigns) { if (edge.isCallEdge()) { if (edge.getCallSite() == null) { G.v().out.println(edge + " is weird!!"); return false; } } } } return true; }
public Set<Integer> getVirtCallSitesForReceiver(LocalVarNode receiver) { return receiverToVirtCallSites.get(receiver); }
public ArraySet<SootMethod> getCallSiteTargets(Integer callSite) { return callSiteToTargets.get(callSite); }
public ArraySet<AssignEdge> getCallSiteEdges(Integer callSite) { return callSiteToEdges.get(callSite); }
public Set<Integer> getCallSitesInvokingMethod(SootMethod method) { return callSitesInvokingMethod.get(method); }
/** * @param method * @return */ public ArraySet<Integer> getCallSitesInMethod(SootMethod method) { return callSitesInMethod.get(method); }
public ArraySet<VarNode> getOutPortsForMethod(SootMethod method) { return methodToOutPorts.get(method); }
public ArraySet<VarNode> getNodesForMethod(SootMethod method) { return methodToNodes.get(method); }
public Set<SootMethod> methods() { return methodToNodes.keySet(); }
/** * @param node * @return edges capturing assign flow <em>into</em> node */ public ArraySet<AssignEdge> getAssignEdges(VarNode node) { return contextSensitiveAssignBarEdges.get(node); }
/** * @param assignSource * @param assignTarget */ private void addAssignEdge(AssignEdge assignEdge) { contextSensitiveAssignEdges.put(assignEdge.getSrc(), assignEdge); contextSensitiveAssignBarEdges.put(assignEdge.getDst(), assignEdge); }
public ContextSensitiveInfo(PAG pag) { // set up method to node map for (Iterator iter = pag.getVarNodeNumberer().iterator(); iter.hasNext(); ) { VarNode varNode = (VarNode) iter.next(); if (varNode instanceof LocalVarNode) { LocalVarNode local = (LocalVarNode) varNode; SootMethod method = local.getMethod(); assert method != null : local; methodToNodes.put(method, local); if (SootUtil.isRetNode(local)) { methodToOutPorts.put(method, local); } if (SootUtil.isParamNode(local)) { methodToInPorts.put(method, local); } } } int callSiteNum = 0; // first, add regular assigns Set assignSources = pag.simpleSources(); for (Iterator iter = assignSources.iterator(); iter.hasNext(); ) { VarNode assignSource = (VarNode) iter.next(); if (skipNode(assignSource)) { continue; } boolean sourceGlobal = assignSource instanceof GlobalVarNode; Node[] assignTargets = pag.simpleLookup(assignSource); for (int i = 0; i < assignTargets.length; i++) { VarNode assignTarget = (VarNode) assignTargets[i]; if (skipNode(assignTarget)) continue; boolean isFinalizerNode = false; if (assignTarget instanceof LocalVarNode) { LocalVarNode local = (LocalVarNode) assignTarget; SootMethod method = local.getMethod(); if (method.toString().indexOf("finalize()") != -1 && SootUtil.isThisNode(local)) { isFinalizerNode = true; } } boolean targetGlobal = assignTarget instanceof GlobalVarNode; AssignEdge assignEdge = new AssignEdge(assignSource, assignTarget); // handle weird finalizers if (isFinalizerNode) { assignEdge.setParamEdge(); Integer callSite = new Integer(callSiteNum++); assignEdge.setCallSite(callSite); } addAssignEdge(assignEdge); if (sourceGlobal) { if (targetGlobal) { // System.err.println("G2G " + assignSource + " --> " // + assignTarget); } else { SootMethod method = ((LocalVarNode) assignTarget).getMethod(); // don't want to include things assigned something that // is already an in port if (!methodToInPorts.get(method).contains(assignTarget)) { methodToInPorts.put(method, assignSource); } } } else { if (targetGlobal) { SootMethod method = ((LocalVarNode) assignSource).getMethod(); // don't want to include things assigned from something // that // is already an out port if (!methodToOutPorts.get(method).contains(assignSource)) { methodToOutPorts.put(method, assignTarget); } } } } } // now handle calls HashMultiMap callAssigns = pag.callAssigns; PrintWriter callSiteWriter = null; if (PRINT_CALL_SITE_INFO) { try { callSiteWriter = new PrintWriter(new FileWriter("callSiteInfo"), true); } catch (IOException e) { e.printStackTrace(); } } for (Iterator iter = callAssigns.keySet().iterator(); iter.hasNext(); ) { InvokeExpr ie = (InvokeExpr) iter.next(); Integer callSite = new Integer(callSiteNum++); callSiteToInvokedMethod.put(callSite, ie.getMethod()); SootMethod invokingMethod = pag.callToMethod.get(ie); callSiteToInvokingMethod.put(callSite, invokingMethod); if (PRINT_CALL_SITE_INFO) { callSiteWriter.println(callSite + " " + callSiteToInvokingMethod.get(callSite) + " " + ie); } if (pag.virtualCallsToReceivers.containsKey(ie)) { LocalVarNode receiver = (LocalVarNode) pag.virtualCallsToReceivers.get(ie); assert receiver != null; virtCallSiteToReceiver.put(callSite, receiver); receiverToVirtCallSites.put(receiver, callSite); } Set curEdges = callAssigns.get(ie); for (Iterator iterator = curEdges.iterator(); iterator.hasNext(); ) { Pair callAssign = (Pair) iterator.next(); VarNode src = (VarNode) callAssign.getO1(); VarNode dst = (VarNode) callAssign.getO2(); if (skipNode(src)) { continue; } ArraySet edges = getAssignBarEdges(src); AssignEdge edge = null; for (int i = 0; i < edges.size() && edge == null; i++) { AssignEdge curEdge = (AssignEdge) edges.get(i); if (curEdge.getDst() == dst) { edge = curEdge; } } assert edge != null : "no edge from " + src + " to " + dst; boolean edgeFromOtherCallSite = edge.isCallEdge(); if (edgeFromOtherCallSite) { edge = new AssignEdge(src, dst); } edge.setCallSite(callSite); callSiteToEdges.put(callSite, edge); if (SootUtil.isParamNode(dst)) { // assert src instanceof LocalVarNode : src + " " + dst; edge.setParamEdge(); SootMethod invokedMethod = ((LocalVarNode) dst).getMethod(); callSiteToTargets.put(callSite, invokedMethod); callSitesInvokingMethod.put(invokedMethod, callSite); // assert src instanceof LocalVarNode : src + " NOT LOCAL"; if (src instanceof LocalVarNode) { callSitesInMethod.put(((LocalVarNode) src).getMethod(), callSite); } } else if (SootUtil.isRetNode(src)) { edge.setReturnEdge(); SootMethod invokedMethod = ((LocalVarNode) src).getMethod(); callSiteToTargets.put(callSite, invokedMethod); callSitesInvokingMethod.put(invokedMethod, callSite); if (dst instanceof LocalVarNode) { callSitesInMethod.put(((LocalVarNode) dst).getMethod(), callSite); } } else { assert false : "weird call edge " + callAssign; } if (edgeFromOtherCallSite) { addAssignEdge(edge); } } } // System.err.println(callSiteNum + " call sites"); assert callEdgesReasonable(); if (PRINT_CALL_SITE_INFO) { callSiteWriter.close(); } // assert assignEdgesWellFormed(pag) == null : // assignEdgesWellFormed(pag); }