/**
* This file is licensed under the University of Illinois/NCSA Open Source License. See LICENSE.TXT for details.
*/
package edu.illinois.keshmesh.walaconfig;
import java.util.Iterator;
import java.util.Set;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.ShrikeCTMethod;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
import com.ibm.wala.ipa.callgraph.ContextSelector;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint;
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXCFABuilder;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.annotations.Annotation;
import com.ibm.wala.util.collections.HashSetFactory;
import edu.illinois.keshmesh.annotations.EntryPoint;
import edu.illinois.keshmesh.detector.util.AnalysisUtils;
/**
*
* @author Mohsen Vakilian
* @author Stas Negara
*
*/
public class KeshmeshAnalysisEngine {
public static Iterable<Entrypoint> makeDefaultEntrypoints(ClassLoaderReference classLoaderReference, IClassHierarchy classHierarchy) {
//Iterable<Entrypoint> mainEntrypoints = Util.makeMainEntrypoints(analysisScope.getApplicationLoader(), classHierarchy);
// return new FilteredIterable(mainEntrypoints);
// return Util.makeMainEntrypoints(classLoaderReference, classHierarchy);
return toIterable(findEntryPoints(classHierarchy));
}
public static CallGraphBuilder getCallGraphBuilder(AnalysisScope analysisScope, IClassHierarchy classHierarchy, AnalysisOptions analysisOptions, AnalysisCache analysisCache,
int objectSensitivityLevel) {
ContextSelector contextSelector = new KObjectSensitiveContextSelector(objectSensitivityLevel);
// Util.addDefaultSelectors(analysisOptions, classHierarchy);
// Util.addDefaultBypassLogic(analysisOptions, analysisScope, Util.class.getClassLoader(), classHierarchy);
// return new KeshmeshCFABuilder(classHierarchy, analysisOptions, analysisCache, contextSelector, null);
return makeZeroOneCFABuilder(analysisOptions, analysisCache, classHierarchy, analysisScope, contextSelector, null);
}
public static SSAPropagationCallGraphBuilder makeZeroOneCFABuilder(AnalysisOptions options, AnalysisCache cache, IClassHierarchy cha, AnalysisScope scope, ContextSelector customSelector,
SSAContextInterpreter customInterpreter) {
if (options == null) {
throw new IllegalArgumentException("options is null");
}
// Util.addDefaultSelectors(options, cha);
// Util.addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
return ZeroXCFABuilder.make(cha, options, cache, customSelector, customInterpreter, ZeroXInstanceKeys.ALLOCATIONS | ZeroXInstanceKeys.SMUSH_MANY | ZeroXInstanceKeys.SMUSH_THROWABLES);
}
public static Iterable<Entrypoint> toIterable(final Set<Entrypoint> entryPoints) {
return new Iterable<Entrypoint>() {
public Iterator<Entrypoint> iterator() {
return entryPoints.iterator();
}
};
}
public static Set<Entrypoint> findEntryPoints(IClassHierarchy classHierarchy) {
final Set<Entrypoint> result = HashSetFactory.make();
Iterator<IClass> classIterator = classHierarchy.iterator();
while (classIterator.hasNext()) {
IClass klass = classIterator.next();
if (!AnalysisUtils.isJDKClass(klass)) {
// Logger.log("Visiting class " + klass);
for (IMethod method : klass.getDeclaredMethods()) {
try {
if (!(method instanceof ShrikeCTMethod)) {
throw new RuntimeException("@EntryPoint only works for byte code.");
}
// Logger.log("Visiting method " + method);
for (Annotation annotation : ((ShrikeCTMethod) method).getAnnotations(true)) {
// Logger.log("Visiting annotation " + annotation);
if (isEntryPointClass(annotation.getType().getName())) {
result.add(new DefaultEntrypoint(method, classHierarchy));
break;
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
return result;
}
private static boolean isEntryPointClass(TypeName typeName) {
return (AnalysisUtils.walaTypeNameToJavaName(typeName).equals(EntryPoint.class.getName()));
}
}