dalvik test infrastructure

This commit is contained in:
Julian Dolby 2015-04-05 21:22:55 -04:00
parent d85347f231
commit 22ad339fd9
30 changed files with 71677 additions and 300 deletions

View File

@ -37,7 +37,9 @@ public final class WalaProperties {
public final static String ECLIPSE_PLUGINS_DIR = "eclipse_plugins_dir"; //$NON-NLS-1$
public final static String ANDROID_RT_JAR = "android_rt_jar";
public final static String ANDROID_RT_DEX_DIR = "android_rt_dir";
public final static String ANDROID_RT_JAVA_JAR = "android_rt_jar";
public final static String ANDROID_DEX_TOOL = "android_dx_tool";

1
com.ibm.wala.dalvik.test/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/lib/

View File

@ -0,0 +1,3 @@
/android.jar
/sample.lex
/troff2html.cup

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@ import java.io.File;
import java.util.Set;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.dalvik.test.DalvikTestBase;
import com.ibm.wala.dalvik.test.callGraph.DalvikCallGraphTestBase;
import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions;
import com.ibm.wala.ipa.callgraph.CGNode;
@ -27,82 +28,78 @@ public class APKCallGraphDriver {
}
FileUtil.recurseFiles(new VoidFunction<File>() {
@Override
public void apply(File apk) {
System.gc();
System.err.println("Analyzing " + apk + "...");
try {
long time = System.currentTimeMillis();
CallGraph CG;
if (timeout == -1) {
CG = DalvikCallGraphTestBase.makeAPKCallGraph(apk.getAbsolutePath()).fst;
} else {
final long startTime = System.currentTimeMillis();
IProgressMonitor pm = new IProgressMonitor() {
private boolean cancelled = false;
@Override
public void apply(File apk) {
System.gc();
System.err.println("Analyzing " + apk + "...");
try {
long time = System.currentTimeMillis();
CallGraph CG;
final long startTime = System.currentTimeMillis();
IProgressMonitor pm = new IProgressMonitor() {
private boolean cancelled = false;
@Override
public void beginTask(String task, int totalWork) {
// TODO Auto-generated method stub
}
@Override
public void beginTask(String task, int totalWork) {
// TODO Auto-generated method stub
}
@Override
public void subTask(String subTask) {
// TODO Auto-generated method stub
}
@Override
public void subTask(String subTask) {
// TODO Auto-generated method stub
}
@Override
public void cancel() {
cancelled = true;
}
@Override
public void cancel() {
cancelled = true;
}
@Override
public boolean isCanceled() {
if (System.currentTimeMillis() - startTime > timeout) {
cancelled = true;
}
return cancelled;
}
@Override
public boolean isCanceled() {
if (System.currentTimeMillis() - startTime > timeout) {
cancelled = true;
}
return cancelled;
}
@Override
public void done() {
// TODO Auto-generated method stub
}
@Override
public void done() {
// TODO Auto-generated method stub
}
@Override
public void worked(int units) {
// TODO Auto-generated method stub
}
@Override
public void worked(int units) {
// TODO Auto-generated method stub
}
@Override
public String getCancelMessage() {
return "timeout";
}
};
CG = DalvikCallGraphTestBase.makeAPKCallGraph(apk.getAbsolutePath(), pm, ReflectionOptions.NONE).fst;
}
System.err.println("Analyzed " + apk + " in " + (System.currentTimeMillis() - time));
@Override
public String getCancelMessage() {
return "timeout";
}
};
CG = DalvikCallGraphTestBase.makeAPKCallGraph(DalvikTestBase.androidLibs(), null, apk.getAbsolutePath(), pm, ReflectionOptions.NONE).fst;
System.err.println("Analyzed " + apk + " in " + (System.currentTimeMillis() - time));
Set<IMethod> code = HashSetFactory.make();
for(CGNode n : CG) {
code.add(n.getMethod());
}
System.err.println("reachable methods for " + apk);
for(IMethod m : code) {
System.err.println("" + m.getDeclaringClass().getName() + " " + m.getName() + m.getDescriptor());
}
System.err.println("end of methods");
Set<IMethod> code = HashSetFactory.make();
for(CGNode n : CG) {
code.add(n.getMethod());
}
System.err.println("reachable methods for " + apk);
for(IMethod m : code) {
System.err.println("" + m.getDeclaringClass().getName() + " " + m.getName() + m.getDescriptor());
}
System.err.println("end of methods");
} catch (Throwable e) {
e.printStackTrace(System.err);
}
}
} catch (Throwable e) {
e.printStackTrace(System.err);
}
}
},
new Predicate<File>() {
@Override
public boolean test(File file) {
return file.getName().endsWith("apk");
}
@Override
public boolean test(File file) {
return file.getName().endsWith("apk");
}
},
apk);
}

View File

@ -1,6 +1,7 @@
package com.ibm.wala.dalvik.test;
import static com.ibm.wala.properties.WalaProperties.ANDROID_RT_JAR;
import static com.ibm.wala.properties.WalaProperties.ANDROID_RT_DEX_DIR;
import static com.ibm.wala.properties.WalaProperties.ANDROID_RT_JAVA_JAR;
import java.io.File;
import java.io.FileFilter;
@ -10,16 +11,17 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.jar.JarFile;
import com.ibm.wala.classLoader.JarFileModule;
import com.ibm.wala.classLoader.Module;
import com.ibm.wala.classLoader.NestedJarFileModule;
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
import com.ibm.wala.core.tests.shrike.DynamicCallGraphTestBase;
import com.ibm.wala.dalvik.test.callGraph.DalvikCallGraphTestBase;
import com.ibm.wala.dalvik.util.AndroidAnalysisScope;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.properties.WalaProperties;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.util.WalaException;
import com.ibm.wala.util.io.TemporaryFile;
@ -58,65 +60,67 @@ public abstract class DalvikTestBase extends DynamicCallGraphTestBase {
return f;
}
public static URI[] androidLibs() {
System.err.println(System.getProperty("java.vm.name"));
if ("Dalvik".equals(System.getProperty("java.vm.name"))) {
List<URI> libs = new ArrayList<URI>();
for(File f : new File("/system/framework/").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
String name = pathname.getName();
return
(name.startsWith("core") || name.startsWith("framework")) &&
(name.endsWith("jar") || name.endsWith("apk"));
}
}))
{
System.out.println("adding " + f);
libs.add(f.toURI());
}
return libs.toArray(new URI[ libs.size() ]);
public static File androidJavaLib() throws IOException {
if (walaProperties != null && walaProperties.getProperty(ANDROID_RT_JAVA_JAR) != null) {
return new File(walaProperties.getProperty(ANDROID_RT_JAVA_JAR));
} else {
List<URI> libs = new ArrayList<URI>();
try {
for(File lib : new File(walaProperties.getProperty(ANDROID_RT_JAR)).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith("dex") || name.endsWith("jar") || name.endsWith("apk");
}
})) {
System.out.println("adding " + lib);
libs.add(lib.toURI());
}
} catch (Exception e) {
System.out.println("unexpected " + e);
for(String l : WalaProperties.getJ2SEJarFiles()) {
libs.add(new File(l).toURI());
}
try {
File jarFile = TemporaryFile.urlToFile("android.jar", DalvikCallGraphTestBase.class.getClassLoader().getResource("android.jar"));
libs.add(jarFile.toURI());
} catch (IOException e1) {
assert false : e1;
}
}
return libs.toArray(new URI[ libs.size() ]);
File F = File.createTempFile("android", "jar");
F.deleteOnExit();
TemporaryFile.urlToFile(F, DalvikTestBase.class.getClassLoader().getResource("android.jar"));
return F;
}
}
public static URI[] androidLibs() {
List<URI> libs = new ArrayList<URI>();
if (walaProperties != null && walaProperties.getProperty(ANDROID_RT_DEX_DIR) != null) {
for(File lib : new File(walaProperties.getProperty(ANDROID_RT_DEX_DIR)).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith("dex") || name.endsWith("jar") || name.endsWith("apk");
}
})) {
libs.add(lib.toURI());
}
} else {
assert "Dalvik".equals(System.getProperty("java.vm.name"));
for(File f : new File("/system/framework/").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
String name = pathname.getName();
return
(name.startsWith("core") || name.startsWith("framework")) &&
(name.endsWith("jar") || name.endsWith("apk"));
}
}))
{
System.out.println("adding " + f);
libs.add(f.toURI());
}
}
return libs.toArray(new URI[ libs.size() ]);
}
public static AnalysisScope makeDalvikScope(boolean useAndroidLib, String dexFileName) throws IOException {
AnalysisScope scope =
useAndroidLib?
AndroidAnalysisScope.setUpAndroidAnalysisScope(
public static AnalysisScope makeDalvikScope(URI[] androidLibs, File androidAPIJar, String dexFileName) throws IOException {
if (androidLibs != null) {
return AndroidAnalysisScope.setUpAndroidAnalysisScope(
new File(dexFileName).toURI(),
CallGraphTestUtil.REGRESSION_EXCLUSIONS,
CallGraphTestUtil.class.getClassLoader(),
androidLibs()):
AndroidAnalysisScope.setUpAndroidAnalysisScope(
androidLibs);
} else {
AnalysisScope scope = AndroidAnalysisScope.setUpAndroidAnalysisScope(
new File(dexFileName).toURI(),
CallGraphTestUtil.REGRESSION_EXCLUSIONS,
CallGraphTestUtil.class.getClassLoader());
return scope;
if (androidAPIJar != null) {
scope.addToScope(ClassLoaderReference.Primordial, new JarFileModule(new JarFile(androidAPIJar)));
}
return scope;
}
}
}

View File

@ -22,10 +22,8 @@ import java.util.Set;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
import com.ibm.wala.dalvik.classLoader.DexIRFactory;
import com.ibm.wala.dalvik.test.DalvikTestBase;
import com.ibm.wala.dalvik.util.AndroidAnalysisScope;
import com.ibm.wala.dalvik.util.AndroidEntryPointLocator;
import com.ibm.wala.dalvik.util.AndroidEntryPointLocator.LocatorFlags;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
@ -53,7 +51,6 @@ import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
import com.ibm.wala.util.NullProgressMonitor;
import com.ibm.wala.util.Predicate;
import com.ibm.wala.util.collections.FilterIterator;
import com.ibm.wala.util.collections.HashSetFactory;
@ -98,29 +95,6 @@ public class DalvikCallGraphTestBase extends DalvikTestBase {
run(mainClass.substring(1).replace('/', '.'), "LibraryExclusions.txt", args);
}
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeAPKCallGraph(String apkFile) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException {
return makeAPKCallGraph(apkFile, androidLibs());
}
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeAPKCallGraph(String apkFileName, URI[] androidLibs) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
return makeAPKCallGraph(apkFileName, new NullProgressMonitor(), androidLibs);
}
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeAPKCallGraph(String apkFileName, ReflectionOptions options) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
return makeAPKCallGraph(apkFileName, new NullProgressMonitor(), options, androidLibs());
}
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeAPKCallGraph(String apkFileName, ReflectionOptions options, URI[] androidLibs) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
return makeAPKCallGraph(apkFileName, new NullProgressMonitor(), options, androidLibs);
}
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeAPKCallGraph(String apkFileName, IProgressMonitor monitor, URI[] androidLibs) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
return makeAPKCallGraph(apkFileName, monitor, ReflectionOptions.NONE, androidLibs);
}
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeAPKCallGraph(String absolutePath, IProgressMonitor pm, ReflectionOptions none) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException {
return makeAPKCallGraph(absolutePath, pm, none, androidLibs());
}
@SuppressWarnings("unused")
private static SSAContextInterpreter makeDefaultInterpreter(AnalysisOptions options, AnalysisCache cache) {
@ -148,13 +122,8 @@ public class DalvikCallGraphTestBase extends DalvikTestBase {
};
}
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeAPKCallGraph(String apkFileName, IProgressMonitor monitor, ReflectionOptions policy, URI[] androidLibs) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
AnalysisScope scope =
AndroidAnalysisScope.setUpAndroidAnalysisScope(
new File(apkFileName).toURI(),
"AndroidRegressionExclusions.txt",
CallGraphTestUtil.class.getClassLoader(),
androidLibs);
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeAPKCallGraph(URI[] androidLibs, File androidAPIJar, String apkFileName, IProgressMonitor monitor, ReflectionOptions policy) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
AnalysisScope scope = makeDalvikScope(androidLibs, androidAPIJar, apkFileName);
final IClassHierarchy cha = ClassHierarchy.make(scope);
@ -182,8 +151,8 @@ public class DalvikCallGraphTestBase extends DalvikTestBase {
return Pair.make(callGraph, ptrAnalysis);
}
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeDalvikCallGraph(boolean useAndroidLib, String mainClassName, String dexFileName) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
AnalysisScope scope = makeDalvikScope(useAndroidLib, dexFileName);
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeDalvikCallGraph(URI[] androidLibs, File androidAPIJar, String mainClassName, String dexFileName) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
AnalysisScope scope = makeDalvikScope(androidLibs, androidAPIJar, dexFileName);
final IClassHierarchy cha = ClassHierarchy.make(scope);

View File

@ -12,6 +12,7 @@ package com.ibm.wala.dalvik.test.callGraph;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Collections;
@ -36,6 +37,7 @@ import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.NullProgressMonitor;
import com.ibm.wala.util.Predicate;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.collections.HashSetFactory;
@ -101,11 +103,17 @@ public abstract class DroidBenchCGTest extends DalvikCallGraphTestBase {
return result;
}
private final URI[] androidLibs;
private final File androidJavaJar;
private final String apkFile;
private final Set<MethodReference> uncalled;
protected DroidBenchCGTest(String apkFile, Set<MethodReference> uncalled) {
protected DroidBenchCGTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
this.androidLibs = androidLibs;
this.androidJavaJar = androidJavaJar;
this.apkFile = apkFile;
this.uncalled = uncalled;
}
@ -113,7 +121,7 @@ public abstract class DroidBenchCGTest extends DalvikCallGraphTestBase {
@Test
public void test() throws IOException, ClassHierarchyException, CancelException, InvalidClassFileException, IllegalArgumentException, URISyntaxException {
System.err.println("testing " + apkFile + "...");
Pair<CallGraph,PointerAnalysis<InstanceKey>> x = makeAPKCallGraph(apkFile, ReflectionOptions.ONE_FLOW_TO_CASTS_APPLICATION_GET_METHOD);
Pair<CallGraph,PointerAnalysis<InstanceKey>> x = makeAPKCallGraph(androidLibs, androidJavaJar, apkFile, new NullProgressMonitor(), ReflectionOptions.ONE_FLOW_TO_CASTS_APPLICATION_GET_METHOD);
//System.err.println(x.fst);
Set<IMethod> bad = assertUserCodeReachable(x.fst, uncalled);
Assert.assertTrue(bad + " should be empty", bad.isEmpty());
@ -127,7 +135,7 @@ public abstract class DroidBenchCGTest extends DalvikCallGraphTestBase {
skipTests.add("Parcel1.apk");
}
public static Collection<Object[]> generateData(final String filter) {
public static Collection<Object[]> generateData(final URI[] androidLibs, final File androidJavaJar, final String filter) {
String f = walaProperties.getProperty("droidbench.root");
if (f == null || !new File(f).exists()) {
f = "/tmp/DroidBench";
@ -146,7 +154,7 @@ public abstract class DroidBenchCGTest extends DalvikCallGraphTestBase {
if (uncalled == null) {
uncalled = Collections.emptySet();
}
files.add(new Object[]{ f.getAbsolutePath(), uncalled });
files.add(new Object[]{ androidLibs, androidJavaJar, f.getAbsolutePath(), uncalled });
}
}, new Predicate<File>() {
@Override

View File

@ -13,11 +13,9 @@ package com.ibm.wala.dalvik.test.callGraph;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import org.junit.Test;
import java.net.URI;
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
import com.ibm.wala.core.tests.util.TestConstants;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
@ -32,46 +30,28 @@ import com.ibm.wala.util.Predicate;
import com.ibm.wala.util.collections.Pair;
import com.ibm.wala.util.io.TemporaryFile;
public class DynamicDalvikComparisonTest extends DalvikCallGraphTestBase {
public abstract class DynamicDalvikComparisonTest extends DalvikCallGraphTestBase {
private void test(boolean useAndroidLib, String mainClass, String javaScopeFile, String... args) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
protected void test(URI[] androidLibs, String mainClass, String javaScopeFile, String... args) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
AnalysisScope javaScope = CallGraphTestUtil.makeJ2SEAnalysisScope(javaScopeFile, CallGraphTestUtil.REGRESSION_EXCLUSIONS);
String javaJarPath = getJavaJar(javaScope);
File androidDex = convertJarToDex(javaJarPath);
Pair<CallGraph,PointerAnalysis<InstanceKey>> android = makeDalvikCallGraph(useAndroidLib, mainClass, androidDex.getAbsolutePath());
Pair<CallGraph,PointerAnalysis<InstanceKey>> android = makeDalvikCallGraph(androidLibs, null, mainClass, androidDex.getAbsolutePath());
dynamicCG(new File(javaJarPath), mainClass, args);
checkEdges(android.fst, new Predicate<MethodReference>() {
@Override
public boolean test(MethodReference t) {
return t.getDeclaringClass().getClassLoader().equals(ClassLoaderReference.Application);
}
});
checkEdges(android.fst, new Predicate<MethodReference>() {
@Override
public boolean test(MethodReference t) {
return t.getDeclaringClass().getClassLoader().equals(ClassLoaderReference.Application);
}
});
}
@Test
public void testJLexJavaLib() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
File inputFile = TemporaryFile.urlToFile("sample.lex", getClass().getClassLoader().getResource("sample.lex"));
test(false, TestConstants.JLEX_MAIN, TestConstants.JLEX, inputFile.getAbsolutePath());
}
@Test
public void testJLexDexLib() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
File inputFile = TemporaryFile.urlToFile("sample.lex", getClass().getClassLoader().getResource("sample.lex"));
test(true, TestConstants.JLEX_MAIN, TestConstants.JLEX, inputFile.getAbsolutePath());
}
@Test
public void testJavaCupJavaLib() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
File inputFile = TemporaryFile.urlToFile("troff2html.cup", getClass().getClassLoader().getResource("troff2html.cup"));
test(false, TestConstants.JAVA_CUP_MAIN, TestConstants.JAVA_CUP, inputFile.getAbsolutePath());
}
@Test
public void testJavaCupDexLib() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
File inputFile = TemporaryFile.urlToFile("troff2html.cup", getClass().getClassLoader().getResource("troff2html.cup"));
test(true, TestConstants.JAVA_CUP_MAIN, TestConstants.JAVA_CUP, inputFile.getAbsolutePath());
}
protected File testFile(String file) throws IOException {
File inputFile = TemporaryFile.urlToFile(file, getClass().getClassLoader().getResource(file));
inputFile.deleteOnExit();
return inputFile;
}
}

View File

@ -0,0 +1,34 @@
package com.ibm.wala.dalvik.test.callGraph;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import org.junit.Test;
import com.ibm.wala.core.tests.util.TestConstants;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.shrikeBT.analysis.Analyzer.FailureException;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.util.CancelException;
public class DynamicDalvikComparisonTestAndroidLibs extends DynamicDalvikComparisonTest {
protected URI[] providedAndroidLibs() {
return androidLibs();
}
@Test
public void testJLex() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
File inputFile = testFile("sample.lex");
test(providedAndroidLibs(), TestConstants.JLEX_MAIN, TestConstants.JLEX, inputFile.getAbsolutePath());
}
@Test
public void testJavaCup() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
File inputFile = testFile("troff2html.cup");
test(providedAndroidLibs(), TestConstants.JAVA_CUP_MAIN, TestConstants.JAVA_CUP, inputFile.getAbsolutePath());
}
}

View File

@ -0,0 +1,29 @@
package com.ibm.wala.dalvik.test.callGraph;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import org.junit.Test;
import com.ibm.wala.core.tests.util.TestConstants;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.shrikeBT.analysis.Analyzer.FailureException;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.util.CancelException;
public class DynamicDalvikComparisonTestJavaLibs extends DynamicDalvikComparisonTest {
@Test
public void testJLex() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
File inputFile = testFile("sample.lex");
test(null, TestConstants.JLEX_MAIN, TestConstants.JLEX, inputFile.getAbsolutePath());
}
@Test
public void testJavaCup() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidClassFileException, FailureException {
File inputFile = testFile("troff2html.cup");
test(null, TestConstants.JAVA_CUP_MAIN, TestConstants.JAVA_CUP, inputFile.getAbsolutePath());
}
}

View File

@ -35,11 +35,8 @@ import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ExceptionReturnValueKey;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.Predicate;
import com.ibm.wala.util.collections.FilterIterator;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.collections.Iterator2Collection;
import com.ibm.wala.util.collections.Pair;
@ -80,29 +77,18 @@ public class JVMLDalvikComparisonTest extends DalvikCallGraphTestBase {
return result;
}
private static void test(boolean useAndroidLib, String mainClass, String javaScopeFile) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException {
private static void test(String mainClass, String javaScopeFile) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException {
Pair<CallGraph, PointerAnalysis<InstanceKey>> java = makeJavaBuilder(javaScopeFile, mainClass);
AnalysisScope javaScope = java.fst.getClassHierarchy().getScope();
String javaJarPath = getJavaJar(javaScope);
File androidDex = convertJarToDex(javaJarPath);
Pair<CallGraph,PointerAnalysis<InstanceKey>> android = makeDalvikCallGraph(useAndroidLib, mainClass, androidDex.getAbsolutePath());
Pair<CallGraph,PointerAnalysis<InstanceKey>> android = makeDalvikCallGraph(null, null, mainClass, androidDex.getAbsolutePath());
Set<MethodReference> androidMethods = applicationMethods(android.fst);
Set<MethodReference> javaMethods = applicationMethods(java.fst);
Iterator<Pair<CGNode, CGNode>> javaExtraEdges = edgeDiff(java.fst, android.fst).iterator();
if (useAndroidLib) {
javaExtraEdges = new FilterIterator<Pair<CGNode, CGNode>>(javaExtraEdges, new Predicate<Pair<CGNode, CGNode>>() {
private boolean userCode(CGNode n) {
return n.getMethod().getDeclaringClass().getClassLoader().getReference().equals(ClassLoaderReference.Application);
}
@Override
public boolean test(Pair<CGNode, CGNode> o) {
return userCode(o.fst) && userCode(o.snd);
}
});
}
boolean fail = false;
if (javaExtraEdges.hasNext()) {
fail = true;
@ -137,16 +123,16 @@ public class JVMLDalvikComparisonTest extends DalvikCallGraphTestBase {
@Test
public void testJLex() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException {
test(false, TestConstants.JLEX_MAIN, TestConstants.JLEX);
test(TestConstants.JLEX_MAIN, TestConstants.JLEX);
}
@Test
public void testJavaCup() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException {
test(false, TestConstants.JAVA_CUP_MAIN, TestConstants.JAVA_CUP);
test(TestConstants.JAVA_CUP_MAIN, TestConstants.JAVA_CUP);
}
@Test
public void testBCEL() throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException, InterruptedException {
test(false, TestConstants.BCEL_VERIFIER_MAIN, TestConstants.BCEL);
test(TestConstants.BCEL_VERIFIER_MAIN, TestConstants.BCEL);
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class AliasingTest extends DroidBenchCGTest {
public AliasingTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public AliasingTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("Aliasing");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "Aliasing");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class AndroidSpecificTest extends DroidBenchCGTest {
public AndroidSpecificTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public AndroidSpecificTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("AndroidSpecific");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "AndroidSpecific");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class ArraysAndListsTest extends DroidBenchCGTest {
public ArraysAndListsTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public ArraysAndListsTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("ArraysAndLists");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "ArraysAndLists");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class CallbacksTest extends DroidBenchCGTest {
public CallbacksTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public CallbacksTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("Callbacks");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "Callbacks");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class EmulatorDetectionTest extends DroidBenchCGTest {
public EmulatorDetectionTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public EmulatorDetectionTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
// TODO Auto-generated constructor stub
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("EmulatorDetection");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "EmulatorDetection");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class FieldAndObjectSensitivityTest extends DroidBenchCGTest {
public FieldAndObjectSensitivityTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public FieldAndObjectSensitivityTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("FieldAndObjectSensitivity");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "FieldAndObjectSensitivity");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class GeneralJavaTest extends DroidBenchCGTest {
public GeneralJavaTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public GeneralJavaTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("GeneralJava");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "GeneralJava");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class ImplicitFlowsTest extends DroidBenchCGTest {
public ImplicitFlowsTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public ImplicitFlowsTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("ImplicitFlows");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "ImplicitFlows");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,12 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class InterAppCommunicationTest extends DroidBenchCGTest {
public InterAppCommunicationTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public InterAppCommunicationTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("InterAppCommunication");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "InterAppCommunication");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class InterComponentCommunicationTest extends DroidBenchCGTest {
public InterComponentCommunicationTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public InterComponentCommunicationTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("InterComponentCommunication");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "InterComponentCommunication");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class LifecycleTest extends DroidBenchCGTest {
public LifecycleTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public LifecycleTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("Lifecycle");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "Lifecycle");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class ReflectionTest extends DroidBenchCGTest {
public ReflectionTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public ReflectionTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("Reflection");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "Reflection");
}
}

View File

@ -1,5 +1,8 @@
package com.ibm.wala.dalvik.test.callGraph.droidbench;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Set;
@ -12,13 +15,13 @@ import com.ibm.wala.types.MethodReference;
@RunWith(Parameterized.class)
public class ThreadingTest extends DroidBenchCGTest {
public ThreadingTest(String apkFile, Set<MethodReference> uncalled) {
super(apkFile, uncalled);
public ThreadingTest(URI[] androidLibs, File androidJavaJar, String apkFile, Set<MethodReference> uncalled) {
super(androidLibs, androidJavaJar, apkFile, uncalled);
}
@Parameters
// (name="DroidBench: {0}")
public static Collection<Object[]> generateData() {
return DroidBenchCGTest.generateData("Threading");
@Parameters(name="DroidBench: {2}")
public static Collection<Object[]> generateData() throws IOException {
return DroidBenchCGTest.generateData(null, androidJavaLib(), "Threading");
}
}

View File

@ -1,19 +1,17 @@
package com.ibm.wala.dalvik.test.ir;
import static com.ibm.wala.dalvik.test.DalvikTestBase.convertJarToDex;
import static com.ibm.wala.dalvik.test.DalvikTestBase.makeDalvikScope;
import java.io.File;
import java.io.IOException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import com.ibm.wala.core.tests.ir.AnnotationTest;
import com.ibm.wala.core.tests.ir.JVMLAnnotationTest;
import com.ibm.wala.dalvik.test.DalvikTestBase;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.io.FileProvider;
import com.ibm.wala.util.io.TemporaryFile;
@ -23,19 +21,16 @@ public class DalvikAnnotationsTest extends AnnotationTest {
justThisTest(JVMLAnnotationTest.class);
}
@BeforeClass
public static void before() throws IOException, ClassHierarchyException {
private static IClassHierarchy makeCHA() throws IOException, ClassHierarchyException {
File F = File.createTempFile("walatest", ".jar");
F.deleteOnExit();
TemporaryFile.urlToFile(F, (new FileProvider()).getResource("com.ibm.wala.core.testdata_1.0.0a.jar"));
File androidDex = convertJarToDex(F.getAbsolutePath());
AnalysisScope dalvikScope = makeDalvikScope(true, androidDex.getAbsolutePath());
cha = ClassHierarchy.make(dalvikScope);
AnalysisScope dalvikScope = DalvikTestBase.makeDalvikScope(null, null, androidDex.getAbsolutePath());
return ClassHierarchy.make(dalvikScope);
}
@AfterClass
public static void after() {
cha = null;
public DalvikAnnotationsTest() throws ClassHierarchyException, IOException {
super(makeCHA());
}
}

View File

@ -0,0 +1,41 @@
//----------------------------------------------------
// The following code was generated by CUP v0.11a beta 20060608
// Sun Apr 05 20:51:34 EDT 2015
//----------------------------------------------------
/** CUP generated class containing symbol constants. */
public class sym {
/* terminals */
public static final int NH = 11;
public static final int CR = 22;
public static final int T_OPT = 27;
public static final int TE = 24;
public static final int RS = 8;
public static final int IP = 7;
public static final int LP = 10;
public static final int T_FORM = 28;
public static final int TC_ = 25;
public static final int R = 16;
public static final int UL = 20;
public static final int AU = 3;
public static final int LG = 17;
public static final int T_ROW = 29;
public static final int DS = 5;
public static final int I = 15;
public static final int RE = 9;
public static final int PP = 13;
public static final int EOF = 0;
public static final int AI = 4;
public static final int B = 14;
public static final int SM = 19;
public static final int TXT = 26;
public static final int DE = 6;
public static final int SH = 12;
public static final int error = 1;
public static final int TS = 23;
public static final int N_L = 21;
public static final int NL = 18;
public static final int TL = 2;
}

2
com.ibm.wala.dalvik/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/lib/
/dalvik.jar

View File

@ -152,6 +152,9 @@
<include>**/*TestCase.java</include>
<include>**/*Tests.java</include>
</includes>
<excludes>
<exclude>**/*AndroidLibs*.java</exclude>
</excludes>
</configuration>
</plugin>
<!-- The tycho-source-feature-plugin needs to be place before the tycho-p2-plugin, as both plugins' goals bind to the same phase -->