summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYohann Roussel <yroussel@google.com>2015-03-09 17:59:10 +0100
committerYohann Roussel <yroussel@google.com>2015-03-17 17:26:23 +0100
commit8f9fb34f2d53beb22ad9055eb071a93157b922ba (patch)
treeb2ca77f3d844ab2ea24d2d53c14f12fde5838e5d
parent366e204530e8e72abaa18fde0daa11c7a327b405 (diff)
downloadandroid_dalvik-8f9fb34f2d53beb22ad9055eb071a93157b922ba.tar.gz
android_dalvik-8f9fb34f2d53beb22ad9055eb071a93157b922ba.tar.bz2
android_dalvik-8f9fb34f2d53beb22ad9055eb071a93157b922ba.zip
Descriptor references are direct references
We have to parse descriptors and treat the types they reference as direct reference as we do for other direct type references. This is required because Dalvik verifier is checking those descriptor the same way as it does for other type references. See: https://android.googlesource.com/platform/dalvik/+/kitkat-mr2.2-release/vm/analysis/CodeVerify.cpp#637 Bug: 19626444 Change-Id: Ibdc8c3c129148994b3b28882db1c2ec38e9bbea8
-rw-r--r--dx/src/com/android/multidex/ClassReferenceListBuilder.java44
1 files changed, 30 insertions, 14 deletions
diff --git a/dx/src/com/android/multidex/ClassReferenceListBuilder.java b/dx/src/com/android/multidex/ClassReferenceListBuilder.java
index 0434cad98..8218693c9 100644
--- a/dx/src/com/android/multidex/ClassReferenceListBuilder.java
+++ b/dx/src/com/android/multidex/ClassReferenceListBuilder.java
@@ -19,7 +19,11 @@ package com.android.multidex;
import com.android.dx.cf.direct.DirectClassFile;
import com.android.dx.rop.cst.Constant;
import com.android.dx.rop.cst.ConstantPool;
+import com.android.dx.rop.cst.CstFieldRef;
+import com.android.dx.rop.cst.CstMethodRef;
import com.android.dx.rop.cst.CstType;
+import com.android.dx.rop.type.Prototype;
+import com.android.dx.rop.type.StdTypeList;
import com.android.dx.rop.type.Type;
import com.android.dx.rop.type.TypeList;
@@ -37,8 +41,8 @@ import java.util.zip.ZipFile;
public class ClassReferenceListBuilder {
private static final String CLASS_EXTENSION = ".class";
- private Path path;
- private Set<String> classNames = new HashSet<String>();
+ private final Path path;
+ private final Set<String> classNames = new HashSet<String>();
public ClassReferenceListBuilder(Path path) {
this.path = path;
@@ -96,23 +100,35 @@ public class ClassReferenceListBuilder {
private void addDependencies(ConstantPool pool) {
for (Constant constant : pool.getEntries()) {
if (constant instanceof CstType) {
- Type type = ((CstType) constant).getClassType();
- String descriptor = type.getDescriptor();
- if (descriptor.endsWith(";")) {
- int lastBrace = descriptor.lastIndexOf('[');
- if (lastBrace < 0) {
- addClassWithHierachy(descriptor.substring(1, descriptor.length()-1));
- } else {
- assert descriptor.length() > lastBrace + 3
- && descriptor.charAt(lastBrace + 1) == 'L';
- addClassWithHierachy(descriptor.substring(lastBrace + 2,
- descriptor.length() - 1));
- }
+ checkDescriptor(((CstType) constant).getClassType());
+ } else if (constant instanceof CstFieldRef) {
+ checkDescriptor(((CstFieldRef) constant).getType());
+ } else if (constant instanceof CstMethodRef) {
+ Prototype proto = ((CstMethodRef) constant).getPrototype();
+ checkDescriptor(proto.getReturnType());
+ StdTypeList args = proto.getParameterTypes();
+ for (int i = 0; i < args.size(); i++) {
+ checkDescriptor(args.get(i));
}
}
}
}
+ private void checkDescriptor(Type type) {
+ String descriptor = type.getDescriptor();
+ if (descriptor.endsWith(";")) {
+ int lastBrace = descriptor.lastIndexOf('[');
+ if (lastBrace < 0) {
+ addClassWithHierachy(descriptor.substring(1, descriptor.length()-1));
+ } else {
+ assert descriptor.length() > lastBrace + 3
+ && descriptor.charAt(lastBrace + 1) == 'L';
+ addClassWithHierachy(descriptor.substring(lastBrace + 2,
+ descriptor.length() - 1));
+ }
+ }
+ }
+
private void addClassWithHierachy(String classBinaryName) {
if (classNames.contains(classBinaryName)) {
return;