@SuppressWarnings("unused") private String assignEdgesWellFormed(PAG pag) { for (Iterator iter = pag.getVarNodeNumberer().iterator(); iter.hasNext(); ) { VarNode v = (VarNode) iter.next(); Set<AssignEdge> outgoingAssigns = getAssignBarEdges(v); for (AssignEdge edge : outgoingAssigns) { if (edge.getSrc() != v) return edge + " src should be " + v; } Set<AssignEdge> incomingAssigns = getAssignEdges(v); for (AssignEdge edge : incomingAssigns) { if (edge.getDst() != v) return edge + " dst should be " + v; } } return null; }
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); }