View Javadoc

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