1
2
3
4 package joeq.Compiler.Analysis.Primitive;
5
6 import java.io.File;
7 import java.io.IOException;
8 import java.net.URL;
9 import joeq.Class.PrimordialClassLoader;
10 import joeq.Compiler.Quad.BasicBlockVisitor;
11 import joeq.Compiler.Quad.CodeCache;
12 import joeq.Compiler.Quad.ControlFlowGraphVisitor;
13 import joeq.Compiler.Quad.QuadVisitor;
14 import jwutil.classloader.HijackingClassLoader;
15 import jwutil.reflect.Reflect;
16
17 /***
18 * Generate initial relations for BDD pointer analysis.
19 *
20 * @author jwhaley
21 * @version $Id: PrimitiveGenRelations.java 2318 2005-09-26 07:45:22Z livshits $
22 */
23 public class PrimitiveGenRelations {
24 public static URL getFileURL(String filename) throws IOException {
25 File f = new File(filename);
26 if (f.exists()) return f.toURL();
27 else return null;
28 }
29
30 public static ClassLoader addBDDLibraryToClasspath(String[] args) throws IOException {
31 System.out.println("BDD library is not in classpath! Adding it.");
32 String sep = System.getProperty("file.separator");
33 URL url;
34 url = getFileURL("joeq" + sep + "Support" + sep + "javabdd.jar");
35 if (url == null) url = getFileURL("joeq" + sep + "Support" + sep + "javabdd_0.6.jar");
36 if (url == null) url = getFileURL("javabdd.jar");
37 if (url == null) {
38 System.err.println("Cannot find JavaBDD library!");
39 System.exit(-1);
40 return null;
41 }
42 URL url2 = new File(".").toURL();
43
44 URL[] urls = new URL[args.length + 2];
45 urls[0] = url; urls[1] = url2;
46 for(int i = 0; i < args.length; i++){
47 urls[2+i] = new File(args[i]).toURL();
48 }
49
50 return new HijackingClassLoader(urls);
51 }
52
53 public static void addClassesToClasspath(PrimordialClassLoader loader, String[] args) throws IOException {
54 for(int i = 0; i < args.length; i++){
55 String arg = args[i];
56 if(arg.startsWith("-I")){
57 arg = arg.substring(2, arg.length());
58 loader.addToClasspath(arg);
59 System.out.println("New classpath is " + loader.classpathToString());
60 }
61 }
62 }
63
64 public static void main(String[] args) throws IOException {
65
66 try {
67 Class.forName("net.sf.javabdd.BDD");
68 } catch (ClassNotFoundException x) {
69 ClassLoader cl = addBDDLibraryToClasspath(args);
70
71 Reflect.invoke(cl, PrimitiveGenRelations.class.getName(), "main2", new Class[] {String[].class}, new Object[] {args});
72 return;
73 }
74
75 addClassesToClasspath(PrimordialClassLoader.loader, args);
76
77 main2(args);
78 }
79
80 public static void main2(String[] args) throws IOException {
81 if (args.length == 0) {
82 printUsage();
83 return;
84 }
85 boolean CS = false;
86 boolean FLY = false;
87 boolean SSA = false;
88 boolean PARTIAL = false;
89 int i;
90 for (i = 0; i < args.length; ++i) {
91 if (args[i].equalsIgnoreCase("addpass")) {
92 String passname = args[++i];
93 ControlFlowGraphVisitor mv = null;
94 BasicBlockVisitor bbv = null;
95 QuadVisitor qv = null;
96 Object o;
97 try {
98 Class c = Class.forName(passname);
99 o = c.newInstance();
100 if (o instanceof ControlFlowGraphVisitor) {
101 mv = (ControlFlowGraphVisitor) o;
102 } else {
103 if (o instanceof BasicBlockVisitor) {
104 bbv = (BasicBlockVisitor) o;
105 } else {
106 if (o instanceof QuadVisitor) {
107 qv = (QuadVisitor) o;
108 } else {
109 System.err.println("Unknown pass type " + c);
110 }
111 bbv = new QuadVisitor.AllQuadVisitor(qv, false);
112 }
113 mv = new BasicBlockVisitor.AllBasicBlockVisitor(bbv, false);
114 }
115 CodeCache.passes.add(mv);
116 } catch (java.lang.ClassNotFoundException x) {
117 System.err.println("Cannot find pass named " + passname + ".");
118 System.err.println("Check your classpath and make sure you compiled your pass.");
119 } catch (java.lang.InstantiationException x) {
120 System.err.println("Cannot instantiate pass " + passname + ": " + x);
121 } catch (java.lang.IllegalAccessException x) {
122 System.err.println("Cannot access pass " + passname + ": " + x);
123 System.err.println("Be sure that you made your class public?");
124 }
125 } else if (args[i].equals("-cs")) CS = true;
126 else if (args[i].equals("-fly")) FLY = true;
127 else if (args[i].equals("-ssa")) SSA = true;
128 else if (args[i].equals("-partial")) PARTIAL = true;
129 else break;
130 }
131 if (i > 0) {
132 String[] args2 = new String[args.length - i];
133 System.arraycopy(args, i, args2, 0, args2.length);
134 args = args2;
135 }
136 System.setProperty("pa.skipsolve", "yes");
137 System.setProperty("pa.dumpinitial", "yes");
138 System.setProperty("pa.dumpresults", "no");
139 if (CS) System.setProperty("pa.cs", "yes");
140 if (FLY) System.setProperty("pa.dumpfly", "yes");
141 if (SSA) {
142 System.setProperty("ssa", "yes");
143 System.setProperty("pa.dumpssa", "yes");
144 }
145 if (PARTIAL) {
146 System.setProperty("pa.publicplaceholders", "5");
147 System.setProperty("pa.autodiscover", "no");
148 System.setProperty("pa.addinstancemethods", "yes");
149 }
150 String dumppath = System.getProperty("pa.dumppath");
151 if (dumppath != null) {
152 if (dumppath.length() > 0) {
153 File f = new File(dumppath);
154 if (!f.exists()) f.mkdirs();
155 String sep = System.getProperty("file.separator");
156 if (!dumppath.endsWith(sep)) dumppath += sep;
157 }
158 if (System.getProperty("pa.callgraph") == null) {
159 System.setProperty("pa.callgraph", dumppath + "callgraph");
160 }
161 File f = new File(dumppath);
162 if (!f.exists()) f.mkdirs();
163 }
164 PrimitivePA.main(args);
165 }
166
167 public static void printUsage() {
168 System.out.println("Usage: java " + PrimitiveGenRelations.class.getName()
169 + " <options> <class> (<method>)");
170 System.out.println("Usage: java " + PrimitiveGenRelations.class.getName()
171 + " <options> @<classlist>");
172 System.out.println("Valid options:");
173 System.out.println(" -cs context-sensitive");
174 System.out.println(" -fly on-the-fly call graph");
175 System.out.println(" -ssa also dump SSA representation");
176 System.out.println(" -partial partial program analysis");
177 System.out.println("Other system properties:");
178 System.out.println(" -Dpa.dumppath where to save the relations");
179 System.out.println(" -Dpa.icallgraph location to load initial call graph, blank to force callgraph regeneration");
180 System.out.println(" -Dpa.dumpdotgraph dump the call graph in dot graph format");
181 }
182 }