aboutsummaryrefslogtreecommitdiff
path: root/dexlib2
diff options
context:
space:
mode:
authorBen Gruver <bgruv@google.com>2015-07-13 21:48:54 -0700
committerBen Gruver <bgruv@google.com>2015-09-30 20:36:12 -0700
commit64785d79a3e3179784a9ec046a4c8a5994f15dfd (patch)
tree1d8a1661e0900b60c09973862220bc477917f39a /dexlib2
parent8920228819d4cd1cb016ba577b9c65a0cd798fd4 (diff)
downloadsmali-64785d79a3e3179784a9ec046a4c8a5994f15dfd.tar.gz
Add support for using an oat file as the boot class path
Diffstat (limited to 'dexlib2')
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java57
1 files changed, 46 insertions, 11 deletions
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java
index 4185da82..2233f599 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java
@@ -34,13 +34,12 @@ package org.jf.dexlib2.analysis;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import com.google.common.collect.*;
import org.jf.dexlib2.DexFileFactory;
import org.jf.dexlib2.DexFileFactory.DexFileNotFound;
+import org.jf.dexlib2.DexFileFactory.MultipleDexFilesException;
import org.jf.dexlib2.analysis.reflection.ReflectionClassDef;
+import org.jf.dexlib2.dexbacked.OatFile.OatDexFile;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile;
import org.jf.dexlib2.immutable.ImmutableDexFile;
@@ -52,6 +51,7 @@ import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -189,21 +189,46 @@ public class ClassPath {
int api, boolean checkPackagePrivateAccess, boolean experimental) {
ArrayList<DexFile> dexFiles = Lists.newArrayList();
+ boolean isArt = false;
+
+ for (String classPathEntry: classPath) {
+ List<? extends DexFile> classPathDexFiles =
+ loadClassPathEntry(classPathDirs, classPathEntry, api, experimental);
+ if (!isArt) {
+ for (DexFile classPathDexFile: classPathDexFiles) {
+ if (classPathDexFile instanceof OatDexFile) {
+ isArt = true;
+ break;
+ }
+ }
+ }
+ dexFiles.addAll(classPathDexFiles);
+ }
+ dexFiles.add(dexFile);
+ return new ClassPath(dexFiles, checkPackagePrivateAccess);
+ }
+
+ @Nonnull
+ public static ClassPath fromClassPath(Iterable<String> classPathDirs, Iterable<String> classPath, DexFile dexFile,
+ int api, boolean checkPackagePrivateAccess, boolean experimental,
+ boolean isArt) {
+ ArrayList<DexFile> dexFiles = Lists.newArrayList();
+
for (String classPathEntry: classPath) {
try {
- dexFiles.add(loadClassPathEntry(classPathDirs, classPathEntry, api, experimental));
+ dexFiles.addAll(loadClassPathEntry(classPathDirs, classPathEntry, api, experimental));
} catch (ExceptionWithContext e){}
}
dexFiles.add(dexFile);
- return new ClassPath(dexFiles, checkPackagePrivateAccess);
+ return new ClassPath(dexFiles, checkPackagePrivateAccess, isArt);
}
private static final Pattern dalvikCacheOdexPattern = Pattern.compile("@([^@]+)@classes.dex$");
@Nonnull
- private static DexFile loadClassPathEntry(@Nonnull Iterable<String> classPathDirs,
- @Nonnull String bootClassPathEntry, int api,
- boolean experimental) {
+ private static List<? extends DexFile> loadClassPathEntry(@Nonnull Iterable<String> classPathDirs,
+ @Nonnull String bootClassPathEntry, int api,
+ boolean experimental) {
File rawEntry = new File(bootClassPathEntry);
// strip off the path - we only care about the filename
String entryName = rawEntry.getName();
@@ -229,7 +254,15 @@ public class ClassPath {
}
for (String classPathDir: classPathDirs) {
- for (String ext: new String[]{"", ".odex", ".jar", ".apk", ".zip"}) {
+ String[] extensions;
+
+ if (entryName.endsWith(".oat")) {
+ extensions = new String[] { ".oat" };
+ } else {
+ extensions = new String[] { "", ".odex", ".jar", ".apk", ".zip" };
+ }
+
+ for (String ext: extensions) {
File file = new File(classPathDir, baseEntryName + ext);
if (file.exists() && file.isFile()) {
@@ -238,9 +271,11 @@ public class ClassPath {
"warning: cannot open %s for reading. Will continue looking.", file.getPath()));
} else {
try {
- return DexFileFactory.loadDexFile(file, api, experimental);
+ return ImmutableList.of(DexFileFactory.loadDexFile(file, api, experimental));
} catch (DexFileNotFound ex) {
// ignore and continue
+ } catch (MultipleDexFilesException ex) {
+ return ex.oatFile.getDexFiles();
} catch (Exception ex) {
throw ExceptionWithContext.withContext(ex,
"Error while reading boot class path entry \"%s\"", bootClassPathEntry);