private static void computeAliasVariant( final MoJo mojo, final MayAliasGraph alias, final IMethod method, final boolean ignoreExceptions, final String outDir) throws IllegalArgumentException, CancelException, PDGFormatException, WalaException, FileNotFoundException { final Logger debug = Log.getLogger(Log.L_MOJO_DEBUG); final Logger info = Log.getLogger(Log.L_MOJO_INFO); info.out("Preparing points-to config and call graph..."); final PointsTo pts = MoJo.computePointsTo(alias); if (debug.isEnabled()) { AliasGraphIO.dumpToDot(alias, outDir + ".alias.dot"); } AliasGraphIO.writeOut(alias, new FileOutputStream(outDir + ".alias")); final AnalysisOptions optPts = mojo.createAnalysisOptionsWithPTS(pts, method); final CallGraphResult cg = mojo.computeContextSensitiveCallGraph(optPts); if (debug.isEnabled()) { final PrintStream ssaOut = new PrintStream(outDir + ".ssa.txt"); Util.dumpSSA(cg.cg.getFakeRootNode().getIR(), ssaOut); Util.dumpPhiSSA(cg.cg.getFakeRootNode().getIR(), ssaOut); ssaOut.flush(); ssaOut.close(); Util.dumpHeapGraphToFile( outDir + ".heap.dot", cg.pts.getHeapGraph(), cg.cg.getFakeRootNode().getMethod()); } info.out("done, sdg... "); // run analysis on callgraph with minimal alias configuration // ... final edu.kit.joana.ifc.sdg.graph.SDG sdg = createSDG(cg, optPts, method, ignoreExceptions); SDGSerializer.toPDGFormat(sdg, new BufferedOutputStream(new FileOutputStream(outDir + ".pdg"))); info.out("(" + sdg.edgeSet().size() + " edges)"); if (debug.isEnabled()) { final int summary = outputSummaryEdges(sdg, method.getReference().getSignature(), outDir + ".sum.dot"); debug.out(" (" + summary + " sum)"); } info.outln(" done."); }
private static SDGNode searchEntry(SDG sdg, String bcMethodName) { for (SDGNode node : sdg.vertexSet()) { if (node.kind == Kind.ENTRY && bcMethodName.equals(node.getBytecodeName())) { return node; } } return null; }
public static void main(String[] args) throws Exception { // explicit configuration for (int i = 0; i < PDGs.pdgs.length; i++) { String file = PDGs.pdgs[i]; /* 1 */ g = SDG.readFrom(file); ThreadInstance ti = g.getThreadsInfo().iterator().next(); LinkedList<ThreadInstance> l = new LinkedList<ThreadInstance>(); l.add(ti); ThreadsInformation info = new ThreadsInformation(l); g.setThreadsInfo(info); int[] threads = new int[] {0}; for (SDGNode n : g.vertexSet()) { n.setThreadNumbers(threads); } System.out.println("initializing the slicers"); LinkedList<Slicer> array = new LinkedList<Slicer>(); array.addLast(new SummarySlicerBackward(g)); array.addLast(new Phase1SlicerBackward(g)); System.out.println(file); System.out.println("criteria: " + g.vertexSet().size()); String str = compare(array, g.vertexSet()); System.out.println(str); } }
private static void addEdgesForNode( SDG sdg, PDGNode node, Map<PDGNode, SDGNode> pdg2sdg, SDGBuilder b) { PDG pdg = b.getPDGforId(node.getPdgId()); SDGNode from = pdg2sdg.get(node); if (!pdg.containsVertex(node)) { throw new IllegalStateException(); } for (PDGEdge edge : pdg.outgoingEdgesOf(node)) { SDGNode to = pdg2sdg.get(edge.to); SDGEdge sdgEdge = createEdge(from, to, edge.kind, edge.getLabel()); sdg.addEdge(from, to, sdgEdge); } }
private static Map<PDGNode, SDGNode> convertNodes( SDG sdg, PDGNode[] nodes, SDGBuilder b, IProgressMonitor progress) throws CancelException { Map<PDGNode, SDGNode> map = new HashMap<PDGNode, SDGNode>(nodes.length); int i = 0; for (PDGNode node : nodes) { SDGNode snode = convertNode(b, node); sdg.addVertex(snode); map.put(node, snode); if (i++ % 100 == 0) { progress.worked(1); MonitorUtil.throwExceptionIfCanceled(progress); } } return map; }
/** * Loads a graph from harddrive and creates a Graph object. * * @param file The Java source file for the Graph. * @param filename The filename of the SDG to load. * @return The created Graph object. Can return null if the SDG file is corrupt. * @throws IOException */ public static Graph loadGraph(ICompilationUnit file, String filename) throws IOException { // Parse the SDG file. SDG sdg = SDG.readFrom(filename); return new Graph(sdg, file, filename); }
/** * Accepts and interprets parameters from command line and displays results * * @param args */ public static void main(String[] args) { System.out.println("Start " + System.currentTimeMillis()); File latticefile = null; File pdgfile = null; /** * * comment that block out for debugging and testing **** if (args.length == 0) { * System.out.println("use 'java NJSec.parsing.IFlowCheck -h' for some help"); System.exit(0); } * /******************************************************* */ for (int i = 0; i < args.length; i++) { if (args[i].equals("-lattice")) { latticefile = new File(args[i + 1]); } else if (args[i].equals("-pdg")) { pdgfile = new File(args[i + 1]); } else if (args[i].equals("-h") || args[i].equals("--help")) { System.out.println( "use: java NJSec.parsing.IFlowCheck -lattice <latticefile> -pdg <pdgfile>"); System.out.println( "example: java NJSec.parsing.IFlowCheck -lattice IPIFlow.lat -pdg IPIFlow.pdg"); System.exit(0); // } else if (args[i].equals("-debug")) { // debug = true; //not used at the moment } } /** * some code for debugging and testing ********* */ // latticefile = new File ("Kalibrierung.lat"); // stanclass = "standard"; // outstanclass = "standard"; // pdgfile = new File("NJSec\\pdgs\\KalibrierungOK.pdg"); latticefile = new File("bin\\de\\naxan\\NJSec\\iflowchecking\\test\\IPIFlow.lat"); pdgfile = new File("bin\\de\\naxan\\NJSec\\iflowchecking\\test\\IPIFlow.pdg"); // System.out.println(latticefile.getAbsolutePath()); /** **** */ if (!latticefile.exists()) System.err.println("Error: lattice-file doesn't exist"); if (!pdgfile.exists()) System.err.println("Error: SDG-file doesn't exist"); if (!latticefile.exists() || !pdgfile.exists()) System.exit(1); IStaticLattice<String> l = null; try { l = LatticeUtil.compileBitsetLattice(new FileInputStream(latticefile)); } catch (IOException e) { System.out.println("Couldn't read given file " + latticefile + "\n" + e.toString()); } catch (WrongLatticeDefinitionException e) { System.out.println("Invalid lattice defintion in file: " + latticefile + "\n" + e.toString()); } SDG g = null; try { g = SDG.readFrom(new FileReader(pdgfile)); } catch (FileNotFoundException e1) { System.out.println("Couldn't find given file " + pdgfile + "\n" + e1.toString()); } catch (IOException e) { e.printStackTrace(); } InterFlowChecker7 ifc = new InterFlowChecker7(g, l); System.out.println("Starte ViolationCheck " + System.currentTimeMillis()); Collection<Violation> violations = ifc.checkIFlow(true); System.out.println("Start Output " + System.currentTimeMillis()); System.out.println(toText(violations)); }
@Override public Collection<SDGNode> slice(Collection<SDGNode> criteria) { LinkedList<SDGNode> worklist_0 = new LinkedList<SDGNode>(); LinkedList<SDGNode> worklist_1 = new LinkedList<SDGNode>(); LinkedList<SDGNode> worklist_2 = new LinkedList<SDGNode>(); HashSet<SDGNode> visited_0_1 = new HashSet<SDGNode>(); HashSet<SDGNode> visited_2 = new HashSet<SDGNode>(); worklist_0.addAll(criteria); visited_0_1.addAll(criteria); // System.out.println("searching for data channels"); edgeListener.init(); // die basis bildet ein iterierter zwei-phasen slice while (!worklist_0.isEmpty()) { // init the next iteration visited_2.clear(); worklist_1.add(worklist_0.poll()); visited_0_1.add(worklist_1.peek()); // === phase 1 === // only ascend to calling procedures while (!worklist_1.isEmpty()) { SDGNode next = worklist_1.poll(); for (SDGEdge edge : g.incomingEdgesOf(next)) { edgeListener.edgeEncountered(edge); SDGNode adjacent = edge.getSource(); if (edge.getKind() == SDGEdge.Kind.INTERFERENCE || edge.getKind() == SDGEdge.Kind.FORK_IN || edge.getKind() == SDGEdge.Kind.FORK_OUT || edge.getKind() == SDGEdge.Kind.FORK) { // handle thread edges - concurrency edges have to be // traversed in the next iteration // TODO: what about join edges? Why are thread numbers // not taken into account? // I suspect that this is not critical for correctness // but rather for precision... if (visited_0_1.add(adjacent)) { worklist_0.add(adjacent); } } else if (edge.getKind() == SDGEdge.Kind.PARAMETER_OUT) { // descend into called procedure in phase two! if (visited_2.add(adjacent)) { worklist_2.add(adjacent); } } else if (edge.getKind().isSDGEdge()) { // note that return // edges are no // sdg edges! // intra-procedural or ascending edge if (visited_0_1.add(adjacent)) { worklist_1.add(adjacent); } } } } // === phase 2 === // visit all procedures called underway while (!worklist_2.isEmpty()) { SDGNode next = worklist_2.poll(); for (SDGEdge edge : g.incomingEdgesOf(next)) { edgeListener.edgeEncountered(edge); SDGNode adjacent = edge.getSource(); if (edge.getKind() == SDGEdge.Kind.INTERFERENCE) { // handle interference edges: create new elements for // worklist_0 if (visited_0_1.add(adjacent)) { worklist_0.add(adjacent); } } else if (edge.getKind().isSDGEdge() && edge.getKind() != SDGEdge.Kind.CALL && edge.getKind() != SDGEdge.Kind.PARAMETER_IN && edge.getKind() != SDGEdge.Kind.FORK && edge.getKind() != SDGEdge.Kind.FORK_IN) { // intra-procedural or param-out edge if (visited_2.add(adjacent)) { worklist_2.add(adjacent); } } } } } return visited_0_1; }
public static SDG convert(SDGBuilder b, IProgressMonitor progress) throws CancelException { SDG sdg = new SDG(PrettyWalaNames.methodName(b.getEntry())); progress.subTask("Building utility edges"); addUtilityEdges(b); progress.worked(1); MonitorUtil.throwExceptionIfCanceled(progress); progress.done(); progress.subTask("Sorting all nodes by their id"); PDGNode allNodes[] = getAllNodesSorted(b, progress); progress.done(); progress.subTask("Inserting " + allNodes.length + " nodes"); Map<PDGNode, SDGNode> pdg2sdg = convertNodes(sdg, allNodes, b, progress); progress.done(); progress.subTask("Inserting edges for " + allNodes.length + " nodes"); for (int i = 0; i < allNodes.length; i++) { addEdgesForNode(sdg, allNodes[i], pdg2sdg, b); if (i % 100 == 0) { progress.worked(1); MonitorUtil.throwExceptionIfCanceled(progress); } } sdg.setNode2Instr(b.getPDGNode2IIndex()); sdg.setEntryToCGNode(b.getEntryNode2CGNode()); progress.done(); return sdg; }
private static Set<SDGNode> filterStatic(final SDG sdg, final Set<SDGNode> nodes) { final Set<SDGNode> filtered = new HashSet<SDGNode>(); for (SDGNode n : nodes) { if (n.getBytecodeIndex() == BytecodeLocation.ROOT_PARAMETER) { filtered.add(n); } } LinkedList<SDGNode> work = new LinkedList<SDGNode>(); work.addAll(filtered); while (!work.isEmpty()) { final SDGNode n = work.removeFirst(); for (SDGEdge edge : sdg.getOutgoingEdgesOfKind(n, SDGEdge.Kind.PARAMETER_STRUCTURE)) { final SDGNode tgt = edge.getTarget(); if (!filtered.contains(tgt)) { filtered.add(tgt); work.add(tgt); } } } return filtered; }
private static int outputSummaryEdges( final SDG sdg, final String bcMethodName, final String filename) throws FileNotFoundException { final SDGNode entry = searchEntry(sdg, bcMethodName); Set<SDGNode> formIn = sdg.getFormalInsOfProcedure(entry); formIn = filterStatic(sdg, formIn); Set<SDGNode> formOut = sdg.getFormalOutsOfProcedure(entry); formOut = filterStatic(sdg, formOut); final SummaryGraph summary = IntraprocSummaryEdges.compute(sdg, entry, formIn, formOut); IntraprocSummaryEdges.writeToDotFile(summary, filename, summary.toString()); return summary.edgeSet().size(); }