diff options
author | Yohann Roussel <yroussel@google.com> | 2015-03-09 17:59:10 +0100 |
---|---|---|
committer | Yohann Roussel <yroussel@google.com> | 2015-03-17 17:26:23 +0100 |
commit | 8f9fb34f2d53beb22ad9055eb071a93157b922ba (patch) | |
tree | b2ca77f3d844ab2ea24d2d53c14f12fde5838e5d | |
parent | 366e204530e8e72abaa18fde0daa11c7a327b405 (diff) | |
download | android_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.java | 44 |
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; |