00001 package edu.ksu.cis.bandera.bofa; 00002 00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00004 * Bandera, a Java(TM) analysis and transformation toolkit * 00005 * Copyright (C) 1998, 1999 Robby (robby@cis.ksu.edu) * 00006 * All rights reserved. * 00007 * * 00008 * This work was done as a project in the SAnToS Laboratory, * 00009 * Department of Computing and Information Sciences, Kansas State * 00010 * University, USA (http://www.cis.ksu.edu/santos). * 00011 * It is understood that any modification not identified as such is * 00012 * not covered by the preceding statement. * 00013 * * 00014 * This work is free software; you can redistribute it and/or * 00015 * modify it under the terms of the GNU Library General Public * 00016 * License as published by the Free Software Foundation; either * 00017 * version 2 of the License, or (at your option) any later version. * 00018 * * 00019 * This work is distributed in the hope that it will be useful, * 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00022 * Library General Public License for more details. * 00023 * * 00024 * You should have received a copy of the GNU Library General Public * 00025 * License along with this toolkit; if not, write to the * 00026 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * 00027 * Boston, MA 02111-1307, USA. * 00028 * * 00029 * Java is a trademark of Sun Microsystems, Inc. * 00030 * * 00031 * To submit a bug report, send a comment, or get the latest news on * 00032 * this project and other SAnToS projects, please visit the web-site * 00033 * http://www.cis.ksu.edu/santos * 00034 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00035 00036 import java.io.*; 00037 import java.util.Enumeration; 00038 import java.util.Hashtable; 00039 import ca.mcgill.sable.soot.*; 00040 import ca.mcgill.sable.soot.baf.*; 00041 import ca.mcgill.sable.soot.jimple.*; 00042 import ca.mcgill.sable.util.*; 00043 import org.apache.log4j.Category; 00044 import org.apache.log4j.Priority; 00045 00046 /* 00047 * FA.java 00048 * $Id: FA.java,v 1.1.1.1 2002/01/24 03:42:07 pserver Exp $ 00049 */ 00050 00051 /** 00052 * This static class provides the entry point to Object Flow analysis. All the 00053 * managers and the WorkList is managed in this class. 00054 * 00055 * Running the analysis with 00056 * different levels of precision yields different classes of 00057 * value variants, e.g., value variants indexed by 00058 * allocator site, or by a single "point" index, etc. 00059 * 00060 * @author <a href="mailto:robby@cis.ksu.edu">Robby</a> 00061 * @author 00062 * <a href="http://www.cis.ksu.edu/~rvprasad">Venkatesh Prasad Ranganath</a> 00063 * @version $Name: $($Revision: 1.1.1.1 $) 00064 */ 00065 public class FA { 00066 00067 /** 00068 * The class manager which is queried to get information regarding various 00069 * classes. 00070 */ 00071 static SootClassManager classManager; 00072 00073 /** 00074 * The WorkList object used for object flow analysis. 00075 * 00076 */ 00077 static WorkList workList; 00078 00079 /** 00080 * Provides logging capability through log4j. 00081 * 00082 */ 00083 private static Category cat; 00084 00085 static { 00086 cat = Category.getInstance(FA.class.getName()); 00087 } 00088 00089 /** 00090 * In this method we initialize the various IndexManagers which partition 00091 * the data. We also, create the required sets for the static and instance 00092 * variables via <code>initClassInfo</code>. This needs to be dynamic as we 00093 * donot know before hand how the variables need to be tracked, per 00094 * class or per object or any other way. We also trigger the creation of 00095 * the FlowGraph here, which will create the initial work in the WorkList 00096 * and then we get into an infinite loop, till the WorkList is emptied, 00097 * calling doWork() on each work object. 00098 * 00099 * @param classManager the class manager that provides the soot classes 00100 * comprising the system being analyzed. 00101 * @param rootSootClass the class from which to start the analysis 00102 * @param rootSootMethod the method from which to start the analysis 00103 */ 00104 public static void init(SootClassManager classManager, 00105 SootClass rootSootClass, 00106 SootMethod rootSootMethod) { 00107 SootClass sootClass; 00108 00109 FA.classManager = classManager; 00110 Collection storedClasses = classManager.getClasses(); 00111 00112 /* Initialize the various managers used. We need to implement a 00113 * framework where the Managers are provided from outside and we just 00114 * use them instead of creating them here. */ 00115 MethodVariantManager.init(new MethodIndexManagerPoint()); 00116 StaticFieldManager.init(); 00117 InstanceVariantManager.init(new InstanceIndexManagerPoint()); 00118 ValueVariantManager.init(new ValueIndexManagerAlloc(), new 00119 CodeIndexManagerAlloc()); 00120 ArrayVariantManager.init(new ArrayIndexManagerValueVariant()); 00121 00122 workList = new WorkList(); 00123 00124 /* 00125 * Request a classtoken for the root class and plugin the variant for 00126 * the method from where the analysis needs to start. 00127 */ 00128 ClassTokenSimple.select(rootSootClass); 00129 MethodVariantManager.select(rootSootMethod); 00130 } 00131 /** 00132 * Tells whether a given method is hooked into the FlowGraph or not. In 00133 * simple terms whether the method is reachable in the system. 00134 * 00135 * @param sootMethod the method which needs to be checked for reachability. 00136 * @return a value indicating the reachability of the given method. 00137 * <code>true</code> - method will be reached. 00138 * <code>false</code> - method will not be reached. 00139 */ 00140 static boolean isReachable(SootMethod sootMethod) 00141 { 00142 return MethodVariantManager.isManaged(sootMethod); 00143 } 00144 /** 00145 * Reset the data structures. Clear all the stored data pertaining to any 00146 * analysis performed in the past. 00147 * 00148 */ 00149 public static void reset() { 00150 classManager = null; 00151 ArrayVariantManager.reset(); 00152 InstanceVariantManager.reset(); 00153 MethodVariantManager.reset(); 00154 StaticFieldManager.reset(); 00155 ValueVariantManager.reset(); 00156 if (workList != null) { 00157 workList.clear(); 00158 } // end of if (workList != null) 00159 } 00160 /** 00161 * Triggers the flow in the FlowGraph. 00162 * 00163 */ 00164 public static void run() { 00165 workList.doWork(); 00166 } 00167 /** 00168 * Iterates through each of the variants of the given method and unions the 00169 * value variants produced by the given expression. Thus, the results of a 00170 * (possibly polymorphic) analysis are collected into a set for the 00171 * specified expression. 00172 * 00173 * @param sootMethod the method containing the given expression 00174 * @param expr the expression for which the value variants need to be 00175 * summarized. 00176 * @return returns a set of value variants. 00177 * @see edu.ksu.cis.bandera.bofa.ValueVariant 00178 */ 00179 public static Set summarizeExprValueVariants(SootMethod sootMethod, 00180 Expr expr) 00181 { 00182 Set valueVariantSummarySet; 00183 00184 valueVariantSummarySet = new HashSet(); 00185 00186 for (Iterator i = MethodVariantManager.getVariants(sootMethod) 00187 .iterator(); 00188 i.hasNext();) { 00189 MethodVariant methodVariant = (MethodVariant) i.next(); 00190 valueVariantSummarySet.addAll(methodVariant.getASTValues(expr)); 00191 } 00192 00193 return valueVariantSummarySet; 00194 } 00195 /** 00196 * Iterates over all the variants of the instance variable and collects the 00197 * possible values that may flow into the instance variable. 00198 * 00199 * @param sootField the instance field of the class. 00200 * @return set of values that may flow into the instance variables. 00201 */ 00202 public static Set summarizeInstanceFieldVariants(SootField sootField) 00203 { 00204 Set valueVariantSummarySet; 00205 FGNodeField node; 00206 valueVariantSummarySet = new HashSet(); 00207 for (Iterator variants = 00208 InstanceVariantManager.getVariants(sootField).iterator(); 00209 variants.hasNext();) { 00210 node = (FGNodeField)((InstanceVariant)variants.next()).getNode(); 00211 valueVariantSummarySet.addAll(node.getValues()); 00212 } // end of for () 00213 return valueVariantSummarySet; 00214 } 00215 /** 00216 * Iterates through each of the variants of the given method and unions the 00217 * value variants returned from the method 00218 * 00219 * @param sootMethod the method for which the return value variants are 00220 * requested. 00221 * @return returns a set of value variants. 00222 * @see edu.ksu.cis.bandera.bofa.ValueVariant 00223 */ 00224 00225 public static Set summarizeLastValueVariants(SootMethod sootMethod) 00226 { 00227 Set valueVariantSummarySet; 00228 00229 valueVariantSummarySet = new HashSet(); 00230 00231 for (Iterator i = MethodVariantManager.getVariants(sootMethod) 00232 .iterator(); 00233 i.hasNext();) 00234 { 00235 MethodVariant methodVariant = (MethodVariant) i.next(); 00236 valueVariantSummarySet.addAll(methodVariant.getReturnValues()); 00237 } 00238 00239 return valueVariantSummarySet; 00240 } 00241 /** 00242 * Iterates through each of the variants of the given method and unions the 00243 * value variants flowing into the given locals. 00244 * 00245 * @param sootMethod the method enclosing the given expression 00246 * @param local the value variants are summarized for the given local 00247 * variable. 00248 * @return returns a set of value variants. 00249 * @see edu.ksu.cis.bandera.bofa.ValueVariant 00250 */ 00251 public static Set summarizeLocalValueVariants(SootMethod sootMethod, 00252 Local local) 00253 { 00254 Set valueVariantSummarySet; 00255 MethodVariant methodVariant; 00256 00257 valueVariantSummarySet = new HashSet(); 00258 00259 for (Iterator i = MethodVariantManager.getVariants(sootMethod) 00260 .iterator(); i.hasNext();) { 00261 methodVariant = (MethodVariant)i.next(); 00262 valueVariantSummarySet.addAll(methodVariant. 00263 getLocalValues(local)); 00264 } 00265 return valueVariantSummarySet; 00266 } 00267 /** 00268 * Iterates through each of the variants of the given method and unions the 00269 * value variants flowing into parameter number <code>n</code>. 00270 * 00271 * <p> Note: Not sure how error is handled when <code>n</code> exceeds the 00272 * the number of parameters. </p> 00273 * 00274 * @param sootMethod the method enclosing the given expression 00275 * @param n the value variants are summarized for the given parameter number 00276 * @return returns a set of value variants. 00277 * @see edu.ksu.cis.bandera.bofa.ValueVariant 00278 */ 00279 public static Set summarizeParameterValueVariants(SootMethod sootMethod, 00280 int n) 00281 { 00282 Set valueVariantSummarySet; 00283 00284 valueVariantSummarySet = new HashSet(); 00285 00286 for (Iterator i = 00287 MethodVariantManager.getVariants(sootMethod).iterator(); 00288 i.hasNext();) { 00289 MethodVariant methodVariant = (MethodVariant) i.next(); 00290 valueVariantSummarySet.addAll(methodVariant. 00291 getParameterValues(n)); 00292 } 00293 return valueVariantSummarySet; 00294 } 00295 /** 00296 * Gathers all the values that may flow into the static field variable 00297 * specified. 00298 * 00299 * @param sootField the static field for which the summary set is requested. 00300 * @return set of values that may flow into the static field. */ 00301 public static Set summarizeStaticFieldVariants(SootField sootField) 00302 { 00303 Set valueVariantSummarySet; 00304 00305 valueVariantSummarySet = new HashSet(); 00306 valueVariantSummarySet.addAll(StaticFieldManager. 00307 get(sootField).getValues()); 00308 return valueVariantSummarySet; 00309 } 00310 /** 00311 * Iterates through each of the variants of the given method and unions the 00312 * value variants flowing into the implicit <code>this</code> parameter. 00313 * 00314 * @param sootMethod the method corresponding to <code>this</code> parameter. 00315 * @return returns a set of value variants. 00316 * @see edu.ksu.cis.bandera.bofa.ValueVariant 00317 */ 00318 public static Set summarizeThisValueVariants(SootMethod sootMethod) 00319 { 00320 Set valueVariantSummarySet; 00321 MethodVariant methodVariant; 00322 valueVariantSummarySet = new HashSet(); 00323 00324 for (Iterator i = MethodVariantManager.getVariants(sootMethod) 00325 .iterator(); 00326 i.hasNext();) { 00327 methodVariant = (MethodVariant) i.next(); 00328 valueVariantSummarySet.addAll(methodVariant.getThisValues()); 00329 } 00330 return valueVariantSummarySet; 00331 } 00332 }