View Javadoc

1   // PrimitiveGenRelations.java, created Jun 24, 2004 3:31:53 PM 2004 by jwhaley
2   // Copyright (C) 2004 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
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          // Make sure we have the BDD library in our classpath.
66          try {
67              Class.forName("net.sf.javabdd.BDD");
68          } catch (ClassNotFoundException x) {
69              ClassLoader cl = addBDDLibraryToClasspath(args);
70              // Reflective invocation under the new class loader.
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          // Just call it directly.
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 }