00001 package edu.ksu.cis.bandera.bofa;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 import ca.mcgill.sable.soot.*;
00038 import ca.mcgill.sable.soot.baf.*;
00039 import ca.mcgill.sable.soot.jimple.*;
00040 import ca.mcgill.sable.util.*;
00041
00042 import edu.ksu.cis.bandera.annotation.*;
00043 import edu.ksu.cis.bandera.jjjc.CompilationManager;
00044 import edu.ksu.cis.bandera.jjjc.exception.CompilerException;
00045 import edu.ksu.cis.bandera.util.*;
00046
00047 import java.io.*;
00048 import java.util.Enumeration;
00049 import java.util.Hashtable;
00050 import java.util.Vector;
00051 import java.net.URL;
00052
00053 import org.apache.log4j.PropertyConfigurator;
00054 import org.apache.log4j.PatternLayout;
00055 import org.apache.log4j.FileAppender;
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 public class BOFA
00075 {
00076
00077
00078
00079
00080
00081 private static boolean dump = false;
00082
00083
00084
00085
00086
00087 private static SootClass rootSootClass;
00088
00089
00090
00091
00092
00093 private static SootMethod rootSootMethod;
00094
00095
00096
00097
00098
00099
00100
00101
00102 private static Collection storedClasses = null;
00103
00104
00105
00106
00107
00108 static SootClassManager sootClassManager = null;
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 static CallBackRegistry callbackReg = new CallBackRegistry();
00120
00121
00122
00123
00124 static {
00125 try {
00126 URL t = callbackReg.getClass().getClassLoader()
00127 .getResource("edu/ksu/cis/bandera/bofa/log4j.properties");
00128 PropertyConfigurator.configure(t);
00129 } catch (Exception e) {
00130 System.out.println("##########################################" +
00131 "############################");
00132 System.out.println("Failed to initialize log4j.");
00133 e.printStackTrace();
00134 System.out.println("##########################################" +
00135 "############################");
00136 }
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 public static void analyze()
00155 {
00156 SootClass sc;
00157
00158 if (sootClassManager == null)
00159 sootClassManager = CompilationManager.getSootClassManager();
00160 if (storedClasses == null)
00161 storedClasses = Util.convert("ca.mcgill.sable.util.VectorList",
00162 CompilationManager.getCompiledClasses()
00163 .values());
00164 if (storedClasses == null || storedClasses.size() == 0) {
00165 System.out.println("You need to compile before you do Flow Analysis"
00166 + storedClasses + " ******** " +
00167 storedClasses.size());
00168 class ClassesNotCompiledException extends RuntimeException
00169 {
00170 ClassesNotCompiledException() {}
00171 }
00172 throw new ClassesNotCompiledException();
00173 }
00174
00175 System.out.println("Running BOFA...");
00176
00177
00178
00179 for (Iterator e = storedClasses.iterator(); e.hasNext();) {
00180 sc = (SootClass) e.next();
00181 if (sc.declaresMethod("main")) {
00182 rootSootClass = sc;
00183 rootSootMethod = sc.getMethod("main");
00184 break;
00185 }
00186 }
00187
00188
00189
00190
00191
00192 callbackReg.regVInvoke(new VInvokeCallBack());
00193 FA.init(sootClassManager, rootSootClass, rootSootMethod);
00194 FA.run();
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 public static void analyze(SootClassManager sootClassManager,
00210 Collection storedClasses)
00211 {
00212 BOFA.storedClasses = storedClasses;
00213 BOFA.sootClassManager = sootClassManager;
00214 analyze();
00215 }
00216
00217
00218
00219
00220
00221
00222
00223 public static void compile(String classPath, LinkedList classNames,
00224 LinkedList packageNames)
00225 {
00226 String[] packages = new String[packageNames.size()];
00227 SootClass sc;
00228 int j = 0;
00229
00230 System.out.println("Adding relevant classes...");
00231 for (Iterator i = packageNames.iterator(); i.hasNext(); j++) {
00232 packages[j] = (String) i.next();
00233 }
00234
00235 CompilationManager.setClasspath(classPath);
00236 CompilationManager.setIncludedPackagesOrTypes(packages);
00237 try {
00238 for (Iterator i = classNames.iterator(); i.hasNext();) {
00239 CompilationManager.setFilename((String)i.next());
00240 CompilationManager.compile();
00241 CompilationManager.compile();
00242 }
00243 } catch (Exception e) {
00244 }
00245 Hashtable exceptions = CompilationManager.getExceptions();
00246 if (exceptions.size() > 0) {
00247 System.out.println("Compilation failed:");
00248 for (Enumeration e = exceptions.keys(); e.hasMoreElements();) {
00249 Object filename = e.nextElement();
00250 System.out.println("- " + filename);
00251 Vector es = (Vector) exceptions.get(filename);
00252 for (java.util.Iterator i = es.iterator(); i.hasNext();) {
00253 System.out.println(" * " + i.next());
00254 }
00255 }
00256 }
00257 storedClasses =
00258 Util.convert("ca.mcgill.sable.util.VectorList",
00259 CompilationManager.getCompiledClasses().values());
00260 sootClassManager = CompilationManager.getSootClassManager();
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 static void dumpFile(String outputPath)
00273 {
00274 StoredBody bd = new StoredBody(Jimple.v());
00275 String className;
00276 File jimpFile;
00277 FileOutputStream jimpOut;
00278 SootClass sc;
00279 for (Iterator e = storedClasses.iterator(); e.hasNext();) {
00280 sc = (SootClass) e.next();
00281 className = sc.getName();
00282 try {
00283 jimpFile = new File(outputPath + File.separator + className +
00284 ".original.jimple");
00285 jimpOut = new FileOutputStream(jimpFile);
00286 sc.printTo(bd, new PrintWriter(jimpOut, true));
00287 } catch (IOException ex) {
00288 throw new RuntimeException("Could not dump jimple file (" +
00289 className + ")");
00290 }
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301 public static void main(String[] args)
00302 {
00303 LinkedList packageNames = new LinkedList();
00304 LinkedList classNames = new LinkedList();
00305 String classPath = ".";
00306 String outputPath = ".";
00307 if (args.length == 0)
00308 printUsage();
00309
00310
00311 try {
00312 for (int i = 0; i < args.length; i++) {
00313 if (args[i].equals("--help")) {
00314 printUsage();
00315 } else if (args[i].equals("--dump")) {
00316 dump = true;
00317 } else if (args[i].equals("--package")) {
00318 i++;
00319 while ((i < args.length) && (!args[i].startsWith("--"))) {
00320 packageNames.addLast(args[i].trim());
00321 i++;
00322 }
00323 i--;
00324 } else if (args[i].equals("--classpath")) {
00325 i++;
00326 if (i < args.length) {
00327 classPath = args[i];
00328 } else {
00329 printUsage();
00330 }
00331 } else if (args[i].equals("--outputdir")) {
00332 i++;
00333 if (i < args.length) {
00334 outputPath = args[i];
00335 } else {
00336 printUsage();
00337 }
00338 } else if (args[i].equals("--source")) {
00339 i++;
00340 while ((i < args.length) && (!args[i].startsWith("--"))) {
00341 classNames.addLast(args[i].trim());
00342 i++;
00343 }
00344 i--;
00345 } else {
00346 System.out.println("Error parsing argument: " + args[i]);
00347 printUsage();
00348 }
00349 }
00350 } catch (Exception ex) {
00351 System.out.println("Error in parsing arguments (" + ex + ")");
00352 printUsage();
00353 }
00354
00355
00356 compile(classPath, classNames, packageNames);
00357
00358 if (dump)
00359 dumpFile(outputPath);
00360
00361
00362 analyze();
00363 }
00364
00365
00366
00367 static void printUsage()
00368 {
00369 System.out.println("Wrong usage");
00370 System.out.println("java edu.ksu.cis.bandera.bofa.BOFA --source " +
00371 "<source> [--dump] [--classpath <path>] " +
00372 "[--package <package>] [--outpurdir <dir>]");
00373 System.exit(0);
00374 }
00375
00376
00377
00378
00379 public static void reset() {
00380 rootSootClass = null;
00381 rootSootMethod = null;
00382 sootClassManager = null;
00383 storedClasses = null;
00384 FA.reset();
00385 }
00386 }