Annotation.cpp revision 364f9d924cbd9d392744a66f80cc084c3d80caf0
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Annotations. 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're not expecting to make much use of runtime annotations, so speed vs. 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * space choices are weighted heavily toward small size. 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * It would have been nice to treat "system" annotations in the same way 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we do "real" annotations, but that doesn't work. The chief difficulty 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is that some of them have member types that are not legal in annotations, 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * such as Method and Annotation. Another source of pain comes from the 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * AnnotationDefault annotation, which by virtue of being an annotation 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * could itself have default values, requiring some additional checks to 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * prevent recursion. 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * It's simpler, and more efficient, to handle the system annotations 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entirely inside the VM. There are empty classes defined for the system 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * annotation types, but their only purpose is to allow the system 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * annotations to share name space with standard annotations. 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// fwd 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* processEncodedAnnotation(const ClassObject* clazz,\ 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1** pPtr); 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool skipEncodedAnnotation(const ClassObject* clazz, const u1** pPtr); 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * System annotation descriptors. 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* kDescrAnnotationDefault 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = "Ldalvik/annotation/AnnotationDefault;"; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* kDescrEnclosingClass 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = "Ldalvik/annotation/EnclosingClass;"; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* kDescrEnclosingMethod 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = "Ldalvik/annotation/EnclosingMethod;"; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* kDescrInnerClass = "Ldalvik/annotation/InnerClass;"; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* kDescrMemberClasses 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = "Ldalvik/annotation/MemberClasses;"; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* kDescrSignature = "Ldalvik/annotation/Signature;"; 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* kDescrThrows = "Ldalvik/annotation/Throws;"; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Perform Annotation setup. 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmReflectAnnotationStartup(void) 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* meth; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find some standard Annotation classes. 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangAnnotationAnnotationArray = 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindArrayClass("[Ljava/lang/annotation/Annotation;", NULL); 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangAnnotationAnnotationArrayArray = 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindArrayClass("[[Ljava/lang/annotation/Annotation;", NULL); 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.classJavaLangAnnotationAnnotationArray == NULL || 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangAnnotationAnnotationArrayArray == NULL) 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Could not find Annotation-array classes\n"); 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * VM-specific annotation classes. 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory = 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Lorg/apache/harmony/lang/annotation/AnnotationFactory;"); 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember = 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindSystemClassNoInit("Lorg/apache/harmony/lang/annotation/AnnotationMember;"); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray = 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindArrayClass("[Lorg/apache/harmony/lang/annotation/AnnotationMember;", NULL); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory == NULL || 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember == NULL || 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray == NULL) 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Could not find android.lang annotation classes\n"); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth = dvmFindDirectMethodByDescriptor(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory, 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "createAnnotation", 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "(Ljava/lang/Class;[Lorg/apache/harmony/lang/annotation/AnnotationMember;)Ljava/lang/annotation/Annotation;"); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (meth == NULL) { 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Unable to find createAnnotation() in android AnnotationFactory\n"); 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation = meth; 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project meth = dvmFindDirectMethodByDescriptor(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember, 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<init>", 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V"); 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (meth == NULL) { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Unable to find 4-arg constructor in android AnnotationMember\n"); 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init = meth; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read an unsigned LEB128 value from a buffer. Advances "pBuf". 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic u4 readUleb128(const u1** pBuf) 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 123de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro u4 result = 0; 124de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro int shift = 0; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* buf = *pBuf; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 val; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Worst-case on bad data is we read too much data and return a bogus 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result. Safe to assume that we will encounter a byte with its 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * high bit clear before the end of the mapped file. 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(shift < 32); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = *buf++; 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result |= (val & 0x7f) << shift; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shift += 7; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while ((val & 0x80) != 0); 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pBuf = buf; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the annotations directory item. 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const DexAnnotationsDirectoryItem* getAnnoDirectory(DexFile* pDexFile, 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassObject* clazz) 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexClassDef* pClassDef; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the class def in the DEX file. For better performance we should 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stash this in the ClassObject. 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClassDef = dexFindClass(pDexFile, clazz->descriptor); 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pClassDef != NULL); 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dexGetAnnotationsDirectoryItem(pDexFile, pClassDef); 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a zero-length array of Annotation objects. 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: this currently allocates a new array each time, but I think we 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can get away with returning a canonical copy. 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ArrayObject* emptyAnnoArray(void) 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dvmAllocArrayByClass( 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangAnnotationAnnotationArray, 0, ALLOC_DEFAULT); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 177de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * Return an array of empty arrays of Annotation objects. 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ArrayObject* emptyAnnoArrayArray(int numElements) 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* arr; 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 186de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arr = dvmAllocArrayByClass(gDvm.classJavaLangAnnotationAnnotationArrayArray, 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numElements, ALLOC_DEFAULT); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arr != NULL) { 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject** elems = (ArrayObject**) arr->contents; 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < numElements; i++) { 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elems[i] = emptyAnnoArray(); 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc((Object*)elems[i], self); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return arr; 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read a signed integer. "zwidth" is the zero-based byte count. 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic s4 readSignedInt(const u1* ptr, int zwidth) 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project s4 val = 0; 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = zwidth; i >= 0; --i) 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = ((u4)val >> 8) | (((s4)*ptr++) << 24); 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val >>= (3 - zwidth) * 8; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read an unsigned integer. "zwidth" is the zero-based byte count, 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "fillOnRight" indicates which side we want to zero-fill from. 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic u4 readUnsignedInt(const u1* ptr, int zwidth, bool fillOnRight) 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 val = 0; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!fillOnRight) { 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = zwidth; i >= 0; --i) 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = (val >> 8) | (((u4)*ptr++) << 24); 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val >>= (3 - zwidth) * 8; 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = zwidth; i >= 0; --i) 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = (val >> 8) | (((u4)*ptr++) << 24); 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read a signed long. "zwidth" is the zero-based byte count. 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic s8 readSignedLong(const u1* ptr, int zwidth) 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project s8 val = 0; 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = zwidth; i >= 0; --i) 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = ((u8)val >> 8) | (((s8)*ptr++) << 56); 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val >>= (7 - zwidth) * 8; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read an unsigned long. "zwidth" is the zero-based byte count, 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "fillOnRight" indicates which side we want to zero-fill from. 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic u8 readUnsignedLong(const u1* ptr, int zwidth, bool fillOnRight) 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u8 val = 0; 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!fillOnRight) { 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = zwidth; i >= 0; --i) 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = (val >> 8) | (((u8)*ptr++) << 56); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val >>= (7 - zwidth) * 8; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = zwidth; i >= 0; --i) 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = (val >> 8) | (((u8)*ptr++) << 56); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Element extraction 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An annotation in "clazz" refers to a method by index. This just gives 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * us the name of the class and the name and signature of the method. We 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * need to find the method's class, and then find the method within that 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class. If the method has been resolved before, we can just use the 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * results of the previous lookup. 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Normally we do this as part of method invocation in the interpreter, which 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * provides us with a bit of context: is it virtual or direct, do we need 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to initialize the class because it's a static method, etc. We don't have 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that information here, so we have to do a bit of searching. 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if the method was not found (exception may be pending). 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Method* resolveAmbiguousMethod(const ClassObject* referrer, u4 methodIdx) 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* resClass; 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* resMethod; 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexMethodId* pMethodId; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* name; 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* if we've already resolved this method, return it */ 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod = dvmDexGetResolvedMethod(referrer->pDvmDex, methodIdx); 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resMethod != NULL) 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return resMethod; 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexFile = referrer->pDvmDex->pDexFile; 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMethodId = dexGetMethodId(pDexFile, methodIdx); 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resClass = dvmResolveClass(referrer, pMethodId->classIdx, true); 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resClass == NULL) { 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* note exception will be pending */ 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("resolveAmbiguousMethod: unable to find class %d\n", methodIdx); 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsInterfaceClass(resClass)) { 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* method is part of an interface -- not expecting that */ 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("resolveAmbiguousMethod: method in interface?\n"); 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO - consider a method access flag that indicates direct vs. virtual 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name = dexStringById(pDexFile, pMethodId->nameIdx); 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexProto proto; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexProtoSetFromMethodId(&proto, pDexFile, pMethodId); 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name[0] == '<') { 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructor or class initializer. Only need to examine the 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "direct" list, and don't need to look up the class hierarchy. 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resMethod = dvmFindDirectMethod(resClass, name, &proto); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 3321d9206d47ee3f7ae1f75de3d1cb02a8e9a72a0bbAndy McFadden * Do a hierarchical scan for direct and virtual methods. 3331d9206d47ee3f7ae1f75de3d1cb02a8e9a72a0bbAndy McFadden * 3341d9206d47ee3f7ae1f75de3d1cb02a8e9a72a0bbAndy McFadden * This uses the search order from the VM spec (v2 5.4.3.3), which 3351d9206d47ee3f7ae1f75de3d1cb02a8e9a72a0bbAndy McFadden * seems appropriate here. 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3371d9206d47ee3f7ae1f75de3d1cb02a8e9a72a0bbAndy McFadden resMethod = dvmFindMethodHier(resClass, name, &proto); 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return resMethod; 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * constants for processAnnotationValue indicating what style of 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result is wanted 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum { 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kAllObjects, /* return everything as an object */ 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kAllRaw, /* return everything as a raw value or index */ 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kPrimitivesOrObjects /* return primitives as-is but the rest as objects */ 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} AnnotationResultStyle; 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Recursively process an annotation value. 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "clazz" is the class on which the annotations are defined. It may be 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NULL when "resultStyle" is "kAllRaw". 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "resultStyle" is "kAllObjects", the result will always be an Object of an 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appropriate type (in pValue->value.l). For primitive types, the usual 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * wrapper objects will be created. 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "resultStyle" is "kAllRaw", numeric constants are stored directly into 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "pValue", and indexed values like String and Method are returned as 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * indexes. Complex values like annotations and arrays are not handled. 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "resultStyle" is "kPrimitivesOrObjects", numeric constants are stored 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * directly into "pValue", and everything else is constructed as an Object 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of appropriate type (in pValue->value.l). 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The caller must call dvmReleaseTrackedAlloc on returned objects, when 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * using "kAllObjects" or "kPrimitivesOrObjects". 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" on success, "false" if the value could not be processed 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or an object could not be allocated. On allocation failure an exception 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will be raised. 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool processAnnotationValue(const ClassObject* clazz, 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1** pPtr, AnnotationValue* pValue, 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationResultStyle resultStyle) 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* elemObj = NULL; 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool setObject = false; 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr = *pPtr; 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 valueType, valueArg; 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width; 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx; 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType = *ptr++; 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueArg = valueType >> kDexAnnotationValueArgShift; 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = valueArg + 1; /* assume, correct later */ 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("----- type is 0x%02x %d, ptr=%p [0x%06x]\n", 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType & kDexAnnotationValueTypeMask, valueArg, ptr-1, 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (ptr-1) - (u1*)clazz->pDvmDex->pDexFile->baseAddr); 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->type = valueType & kDexAnnotationValueTypeMask; 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (valueType & kDexAnnotationValueTypeMask) { 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationByte: 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = (s1) readSignedInt(ptr, valueArg); 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllObjects) { 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmWrapPrimitive(pValue->value, 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindPrimitiveClass('B')); 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationShort: 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = (s2) readSignedInt(ptr, valueArg); 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllObjects) { 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmWrapPrimitive(pValue->value, 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindPrimitiveClass('S')); 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationChar: 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = (u2) readUnsignedInt(ptr, valueArg, false); 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllObjects) { 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmWrapPrimitive(pValue->value, 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindPrimitiveClass('C')); 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationInt: 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = readSignedInt(ptr, valueArg); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllObjects) { 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmWrapPrimitive(pValue->value, 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindPrimitiveClass('I')); 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationLong: 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.j = readSignedLong(ptr, valueArg); 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllObjects) { 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmWrapPrimitive(pValue->value, 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindPrimitiveClass('J')); 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationFloat: 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = readUnsignedInt(ptr, valueArg, true); 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllObjects) { 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmWrapPrimitive(pValue->value, 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindPrimitiveClass('F')); 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationDouble: 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.j = readUnsignedLong(ptr, valueArg, true); 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllObjects) { 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmWrapPrimitive(pValue->value, 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindPrimitiveClass('D')); 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationBoolean: 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = (valueArg != 0); 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllObjects) { 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmWrapPrimitive(pValue->value, 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmFindPrimitiveClass('Z')); 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = 0; 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationString: 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project idx = readUnsignedInt(ptr, valueArg, false); 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllRaw) { 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = idx; 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmResolveString(clazz, idx); 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elemObj == NULL) 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddTrackedAlloc(elemObj, self); // balance the Release 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationType: 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project idx = readUnsignedInt(ptr, valueArg, false); 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllRaw) { 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = idx; 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) dvmResolveClass(clazz, idx, true); 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elemObj == NULL) { 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* we're expected to throw a TypeNotPresentException here */ 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = clazz->pDvmDex->pDexFile; 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* desc = dexStringByTypeIdx(pDexFile, idx); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearException(self); 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowExceptionWithClassMessage( 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Ljava/lang/TypeNotPresentException;", desc); 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddTrackedAlloc(elemObj, self); // balance the Release 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationMethod: 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project idx = readUnsignedInt(ptr, valueArg, false); 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllRaw) { 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = idx; 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* meth = resolveAmbiguousMethod(clazz, idx); 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (meth == NULL) 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = dvmCreateReflectObjForMethod(clazz, meth); 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elemObj == NULL) 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationField: 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project idx = readUnsignedInt(ptr, valueArg, false); 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); // TODO 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationEnum: 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* enum values are the contents of a static field */ 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project idx = readUnsignedInt(ptr, valueArg, false); 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllRaw) { 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = idx; 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StaticField* sfield; 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sfield = dvmResolveStaticField(clazz, idx); 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sfield == NULL) { 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(sfield->field.clazz->descriptor[0] == 'L'); 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = sfield->value.l; 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddTrackedAlloc(elemObj, self); // balance the Release 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationArray: 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * encoded_array format, which is a size followed by a stream 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of annotation_value. 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We create an array of Object, populate it, and return it. 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllRaw) { 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* newArray; 547364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes u4 size, count; 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = readUleb128(&ptr); 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("--- annotation array, size is %u at %p\n", size, ptr); 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newArray = dvmAllocArrayByClass(gDvm.classJavaLangObjectArray, 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size, ALLOC_DEFAULT); 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newArray == NULL) { 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("annotation element array alloc failed (%d)\n", size); 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationValue avalue; 559364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes for (count = 0; count < size; count++) { 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!processAnnotationValue(clazz, &ptr, &avalue, 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kAllObjects)) { 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc((Object*)newArray, self); 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj = avalue.value.l; 566364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmSetObjectArrayElement(newArray, count, obj); 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(obj, self); 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = (Object*) newArray; 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = 0; 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationAnnotation: 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* encoded_annotation format */ 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllRaw) 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemObj = processEncodedAnnotation(clazz, &ptr); 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elemObj == NULL) 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddTrackedAlloc(elemObj, self); // balance the Release 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = 0; 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationNull: 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultStyle == kAllRaw) { 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.i = 0; 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(elemObj == NULL); 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setObject = true; 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = 0; 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Bad annotation element value byte 0x%02x (0x%02x)\n", 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType, valueType & kDexAnnotationValueTypeMask); 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr += width; 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pPtr = ptr; 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (setObject) 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pValue->value.l = elemObj; 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For most object types, we have nothing to do here, and we just return 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "valueObj". 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For an array annotation, the type of the extracted object will always 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be java.lang.Object[], but we want it to match the type that the 6174bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden * annotation member is expected to return. In some cases this may 6184bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden * involve un-boxing primitive values. 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We allocate a second array with the correct type, then copy the data 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * over. This releases the tracked allocation on "valueObj" and returns 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a new, tracked object. 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * On failure, this releases the tracking on "valueObj" and returns NULL 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (allowing the call to say "foo = convertReturnType(foo, ..)"). 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* convertReturnType(Object* valueObj, ClassObject* methodReturn) 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueObj == NULL || 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmIsArray((ArrayObject*)valueObj) || !dvmIsArrayClass(methodReturn)) 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return valueObj; 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* srcElemClass; 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* dstElemClass; 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 6404bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden * We always extract kDexAnnotationArray into Object[], so we expect to 6414bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden * find that here. This means we can skip the FindClass on 6424bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden * (valueObj->clazz->descriptor+1, valueObj->clazz->classLoader). 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 6444bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden if (strcmp(valueObj->clazz->descriptor, "[Ljava/lang/Object;") != 0) { 6454bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden LOGE("Unexpected src type class (%s)\n", valueObj->clazz->descriptor); 6464bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden return NULL; 6474bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden } 6484bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden srcElemClass = gDvm.classJavaLangObject; 6494bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden 6504bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden /* 6514bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden * Skip past the '[' to get element class name. Note this is not always 6524bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden * the same as methodReturn->elementClass. 6534bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden */ 6544bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden char firstChar = methodReturn->descriptor[1]; 6554bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden if (firstChar == 'L' || firstChar == '[') { 6564bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden dstElemClass = dvmFindClass(methodReturn->descriptor+1, 6574bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden methodReturn->classLoader); 6584bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden } else { 6594bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden dstElemClass = dvmFindPrimitiveClass(firstChar); 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("HEY: converting valueObj from [%s to [%s\n", 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project srcElemClass->descriptor, dstElemClass->descriptor); 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* srcArray = (ArrayObject*) valueObj; 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 length = srcArray->length; 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* newArray; 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newArray = dvmAllocArrayByClass(methodReturn, length, ALLOC_DEFAULT); 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newArray == NULL) { 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Failed creating duplicate annotation class (%s %d)\n", 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodReturn->descriptor, length); 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6754bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden bool success; 6764bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden if (dstElemClass->primitiveType == PRIM_NOT) { 6774bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden success = dvmCopyObjectArray(newArray, srcArray, dstElemClass); 6784bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden } else { 6794bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden success = dvmUnboxObjectArray(newArray, srcArray, dstElemClass); 6804bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden } 6814bc10cc26f856f2447bb23316e6729bcd20c2bf4Andy McFadden if (!success) { 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Annotation array copy failed\n"); 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc((Object*)newArray, self); 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newArray = NULL; 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* replace old, return new */ 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(valueObj, self); 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (Object*) newArray; 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new AnnotationMember. 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "clazz" is the class on which the annotations are defined. "pPtr" 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * points to a pointer into the annotation data. "annoClass" is the 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * annotation's class. 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We extract the annotation's value, create a new AnnotationMember object, 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and construct it. 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL on failure; an exception may or may not be raised. 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* createAnnotationMember(const ClassObject* clazz, 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassObject* annoClass, const u1** pPtr) 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFile* pDexFile = clazz->pDvmDex->pDexFile; 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringObject* nameObj = NULL; 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* valueObj = NULL; 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* newMember = NULL; 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* methodObj = NULL; 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* methodReturn = NULL; 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 elementNameIdx; 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* name; 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationValue avalue; 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue result; 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool failed = true; 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementNameIdx = readUleb128(pPtr); 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!processAnnotationValue(clazz, pPtr, &avalue, kAllObjects)) { 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Failed processing annotation value\n"); 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueObj = avalue.value.l; 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* new member to hold the element */ 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newMember = 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAllocObject(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember, 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ALLOC_DEFAULT); 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name = dexStringById(pDexFile, elementNameIdx); 73581f3ebe03cd33c9003641084bece0604ee68bf88Barry Hayes nameObj = dvmCreateStringFromCstr(name); 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the method in the annotation class, given only the name */ 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name != NULL) { 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* annoMeth = dvmFindVirtualMethodByName(annoClass, name); 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annoMeth == NULL) { 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("WARNING: could not find annotation member %s in %s\n", 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project name, annoClass->descriptor); 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodObj = dvmCreateReflectMethodObject(annoMeth); 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodReturn = dvmGetBoxedReturnType(annoMeth); 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newMember == NULL || nameObj == NULL || methodObj == NULL || 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodReturn == NULL) 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Failed creating annotation element (m=%p n=%p a=%p r=%p)\n", 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newMember, nameObj, methodObj, methodReturn); 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* convert the return type, if necessary */ 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueObj = convertReturnType(valueObj, methodReturn); 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (valueObj == NULL) 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* call 4-argument constructor */ 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmCallMethod(self, gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init, 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newMember, &result, nameObj, valueObj, methodReturn, methodObj); 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmCheckException(self)) { 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("Failed constructing annotation element\n"); 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project failed = false; 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* release tracked allocations */ 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(newMember, self); 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc((Object*)nameObj, self); 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(valueObj, self); 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(methodObj, self); 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (failed) 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newMember; 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new Annotation object from what we find in the annotation item. 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "clazz" is the class on which the annotations are defined. "pPtr" 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * points to a pointer into the annotation data. 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We use the AnnotationFactory class to create the annotation for us. The 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method we call is: 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * public static Annotation createAnnotation( 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Class<? extends Annotation> annotationType, 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * AnnotationMember[] elements) 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a new Annotation, which will NOT be in the local ref table and 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not referenced elsewhere, so store it away soon. On failure, returns NULL 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with an exception raised. 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* processEncodedAnnotation(const ClassObject* clazz, 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1** pPtr) 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* newAnno = NULL; 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* elementArray = NULL; 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassObject* annoClass; 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr; 808364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes u4 typeIdx, size, count; 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = *pPtr; 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeIdx = readUleb128(&ptr); 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = readUleb128(&ptr); 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("----- processEnc ptr=%p type=%d size=%d\n", ptr, typeIdx, size); 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoClass = dvmDexGetResolvedClass(clazz->pDvmDex, typeIdx); 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annoClass == NULL) { 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoClass = dvmResolveClass(clazz, typeIdx, true); 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annoClass == NULL) { 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Unable to resolve %s annotation class %d\n", 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz->descriptor, typeIdx); 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmCheckException(self)); 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("----- processEnc ptr=%p [0x%06x] typeIdx=%d size=%d class=%s\n", 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pPtr, *pPtr - (u1*) clazz->pDvmDex->pDexFile->baseAddr, 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeIdx, size, annoClass->descriptor); 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Elements are parsed out and stored in an array. The Harmony 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * constructor wants an array with just the declared elements -- 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * default values get merged in later. 835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JValue result; 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size > 0) { 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementArray = dvmAllocArrayByClass( 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray, 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size, ALLOC_DEFAULT); 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elementArray == NULL) { 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("failed to allocate annotation member array (%d elements)\n", 844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size); 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "ptr" points to a byte stream with "size" occurrences of 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * annotation_element. 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 853364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes for (count = 0; count < size; count++) { 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* newMember = createAnnotationMember(clazz, annoClass, &ptr); 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newMember == NULL) 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* add it to the array */ 859364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmSetObjectArrayElement(elementArray, count, newMember); 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmCallMethod(self, 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation, 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, &result, annoClass, elementArray); 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmCheckException(self)) { 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("Failed creating an annotation\n"); 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dvmLogExceptionStackTrace(); 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newAnno = result.l; 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc((Object*) elementArray, NULL); 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pPtr = ptr; 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newAnno == NULL && !dvmCheckException(self)) { 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure an exception is raised */ 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/RuntimeException;", 879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "failure in processEncodedAnnotation"); 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newAnno; 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run through an annotation set and convert each entry into an Annotation 886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * object. 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an array of Annotation objects, or NULL with an exception raised 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on alloc failure. 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ArrayObject* processAnnotationSet(const ClassObject* clazz, 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet, int visibility) 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = clazz->pDvmDex->pDexFile; 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* annoArray; 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, count; 898364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes u4 dstIndex; 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* we need these later; make sure they're initialized */ 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory)) 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory); 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember)) 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember); 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* count up the number of visible elements */ 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = count = 0; i < (int) pAnnoSet->size; i++) { 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i); 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem->visibility == visibility) 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count++; 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 913364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes annoArray = 914364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmAllocArrayByClass(gDvm.classJavaLangAnnotationAnnotationArray, 915364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes count, ALLOC_DEFAULT); 916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annoArray == NULL) 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate Annotation objects. We must put them into the array 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * immediately (or add them to the tracked ref table). 922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 923364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dstIndex = 0; 924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < (int) pAnnoSet->size; i++) { 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i); 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem->visibility != visibility) 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr = pAnnoItem->annotation; 929364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes Object *anno = processEncodedAnnotation(clazz, &ptr); 930364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes if (anno == NULL) { 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc((Object*) annoArray, NULL); 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 934364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmSetObjectArrayElement(annoArray, dstIndex, anno); 935364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes ++dstIndex; 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return annoArray; 939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Skipping and scanning 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Skip past an annotation value. 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "clazz" is the class on which the annotations are defined. 952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" on success, "false" on parsing failure. 954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool skipAnnotationValue(const ClassObject* clazz, const u1** pPtr) 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr = *pPtr; 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 valueType, valueArg; 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width; 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType = *ptr++; 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueArg = valueType >> kDexAnnotationValueArgShift; 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = valueArg + 1; /* assume */ 964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("----- type is 0x%02x %d, ptr=%p [0x%06x]\n", 966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project valueType & kDexAnnotationValueTypeMask, valueArg, ptr-1, 967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (ptr-1) - (u1*)clazz->pDvmDex->pDexFile->baseAddr); 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (valueType & kDexAnnotationValueTypeMask) { 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationByte: break; 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationShort: break; 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationChar: break; 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationInt: break; 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationLong: break; 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationFloat: break; 976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationDouble: break; 977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationString: break; 978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationType: break; 979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationMethod: break; 980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationField: break; 981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationEnum: break; 982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationArray: 984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* encoded_array format */ 985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 size = readUleb128(&ptr); 987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (size--) { 988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!skipAnnotationValue(clazz, &ptr)) 989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = 0; 993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationAnnotation: 995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* encoded_annotation format */ 996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!skipEncodedAnnotation(clazz, &ptr)) 997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = 0; 999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationBoolean: 1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kDexAnnotationNull: 1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = 0; 1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Bad annotation element value byte 0x%02x\n", valueType); 1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr += width; 1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pPtr = ptr; 1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Skip past an encoded annotation. Mainly useful for annotations embedded 1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in other annotations. 1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool skipEncodedAnnotation(const ClassObject* clazz, const u1** pPtr) 1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr; 1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 size; 1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = *pPtr; 1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (void) readUleb128(&ptr); 1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = readUleb128(&ptr); 1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "ptr" points to a byte stream with "size" occurrences of 1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * annotation_element. 1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (size--) { 1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (void) readUleb128(&ptr); 1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!skipAnnotationValue(clazz, &ptr)) 1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pPtr = ptr; 1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compare the name of the class in the DEX file to the supplied descriptor. 1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return value is equivalent to strcmp. 1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int compareClassDescriptor(DexFile* pDexFile, u4 typeIdx, 1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor) 1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* str = dexStringByTypeIdx(pDexFile, typeIdx); 1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strcmp(str, descriptor); 1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Search through the annotation set for an annotation with a matching 1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * descriptor. 1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Comparing the string descriptor is slower than comparing an integer class 1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * index. If annotation lists are expected to be long, we could look up 1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the class' index by name from the DEX file, rather than doing a class 1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * lookup and string compare on each entry. (Note the index will be 1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * different for each DEX file, so we can't cache annotation class indices 1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * globally.) 1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const DexAnnotationItem* searchAnnotationSet(const ClassObject* clazz, 1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet, const char* descriptor, 1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int visibility) 1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = clazz->pDvmDex->pDexFile; 1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* result = NULL; 1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 typeIdx; 1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("##### searchAnnotationSet %s %d\n", descriptor, visibility); 1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < (int) pAnnoSet->size; i++) { 1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i); 1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem->visibility != visibility) 1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr = pAnnoItem->annotation; 1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeIdx = readUleb128(&ptr); 1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (compareClassDescriptor(pDexFile, typeIdx, descriptor) == 0) { 1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("##### match on %x/%p at %d\n", typeIdx, pDexFile, i); 1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = pAnnoItem; 1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find an annotation value in the annotation_item whose name matches "name". 1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A pointer to the annotation_value is returned, or NULL if it's not found. 1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const u1* searchEncodedAnnotation(const ClassObject* clazz, 1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr, const char* name) 1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = clazz->pDvmDex->pDexFile; 1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 typeIdx, size; 1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeIdx = readUleb128(&ptr); 1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = readUleb128(&ptr); 1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("##### searching ptr=%p type=%u size=%u\n", ptr, typeIdx, size); 1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (size--) { 1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 elementNameIdx; 1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* elemName; 1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elementNameIdx = readUleb128(&ptr); 1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elemName = dexStringById(pDexFile, elementNameIdx); 1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(name, elemName) == 0) { 1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("##### item match on %s\n", name); 1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ptr; /* points to start of value */ 1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project skipAnnotationValue(clazz, &ptr); 1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("##### no item match on %s\n", name); 1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GAV_FAILED ((Object*) 0x10000001) 1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract an encoded annotation value from the field specified by "annoName". 1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "expectedType" is an annotation value type, e.g. kDexAnnotationString. 1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "debugAnnoName" is only used in debug messages. 1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns GAV_FAILED on failure. If an allocation failed, an exception 1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * will be raised. 1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* getAnnotationValue(const ClassObject* clazz, 1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem, const char* annoName, 1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int expectedType, const char* debugAnnoName) 1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr; 1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationValue avalue; 1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the annotation */ 1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, annoName); 1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ptr == NULL) { 1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("%s annotation lacks '%s' member\n", debugAnnoName, annoName); 1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return GAV_FAILED; 1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!processAnnotationValue(clazz, &ptr, &avalue, kAllObjects)) 1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return GAV_FAILED; 1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure it has the expected format */ 1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (avalue.type != expectedType) { 1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("%s %s has wrong type (0x%02x, expected 0x%02x)\n", 1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugAnnoName, annoName, avalue.type, expectedType); 1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return GAV_FAILED; 1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return avalue.value.l; 1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the Signature attribute and extract its value. (Signatures can 1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be found in annotations on classes, constructors, methods, and fields.) 1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if not found. On memory alloc failure, returns NULL with an 1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception raised. 1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ArrayObject* getSignatureValue(const ClassObject* clazz, 1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet) 1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj; 1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrSignature, 1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilitySystem); 1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem == NULL) 1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The Signature annotation has one member, "String value". 1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationArray, 1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Signature"); 1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == GAV_FAILED) 1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(obj->clazz == gDvm.classJavaLangObjectArray); 1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ArrayObject*)obj; 1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Class 1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the DexAnnotationSetItem for this class. 1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const DexAnnotationSetItem* findAnnotationSetForClass( 1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassObject* clazz) 1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile; 1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationsDirectoryItem* pAnnoDir; 1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz->pDvmDex == NULL) /* generated class (Proxy, array) */ 1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexFile = clazz->pDvmDex->pDexFile; 1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoDir = getAnnoDirectory(pDexFile, clazz); 1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoDir != NULL) 1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dexGetClassAnnotationSet(pDexFile, pAnnoDir); 1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return an array of Annotation objects for the class. Returns an empty 1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * array if there are no annotations. 1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * On allocation failure, this returns NULL with an exception raised. 1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectArrayObject* dvmGetClassAnnotations(const ClassObject* clazz) 1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* annoArray; 1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet = NULL; 1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForClass(clazz); 1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) { 1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no annotations for anything in class, or no class annotations */ 1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArray = emptyAnnoArray(); 1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArray = processAnnotationSet(clazz, pAnnoSet, 1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilityRuntime); 1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return annoArray; 1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Retrieve the Signature annotation, if any. Returns NULL if no signature 1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exists. 1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectArrayObject* dvmGetClassSignatureAnnotation(const ClassObject* clazz) 1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* signature = NULL; 1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForClass(clazz); 1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet != NULL) 1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = getSignatureValue(clazz, pAnnoSet); 1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signature; 1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the EnclosingMethod attribute from an annotation. Returns a Method 1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * object, or NULL. 1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObject* dvmGetEnclosingMethod(const ClassObject* clazz) 1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj; 1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForClass(clazz); 1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) 1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingMethod, 1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilitySystem); 1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem == NULL) 1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The EnclosingMethod annotation has one member, "Method value". 1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationMethod, 1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "EnclosingMethod"); 1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == GAV_FAILED) 1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(obj->clazz == gDvm.classJavaLangReflectConstructor || 1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj->clazz == gDvm.classJavaLangReflectMethod); 1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return obj; 1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find a class' enclosing class. We return what we find in the 1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * EnclosingClass attribute. 1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a Class object, or NULL. 1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectClassObject* dvmGetDeclaringClass(const ClassObject* clazz) 1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj; 1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForClass(clazz); 1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) 1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingClass, 1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilitySystem); 1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem == NULL) 1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The EnclosingClass annotation has one member, "Class value". 1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationType, 1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "EnclosingClass"); 1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == GAV_FAILED) 1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(obj->clazz == gDvm.classJavaLangClass); 1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ClassObject*)obj; 1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find a class' enclosing class. We first search for an EnclosingClass 1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * attribute, and if that's not found we look for an EnclosingMethod. 1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a Class object, or NULL. 1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectClassObject* dvmGetEnclosingClass(const ClassObject* clazz) 1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj; 1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForClass(clazz); 1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) 1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingClass, 1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilitySystem); 1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem != NULL) { 1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The EnclosingClass annotation has one member, "Class value". 1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationType, 1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "EnclosingClass"); 1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj != GAV_FAILED) { 1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(obj->clazz == gDvm.classJavaLangClass); 1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ClassObject*)obj; 1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * That didn't work. Look for an EnclosingMethod. 1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We could create a java.lang.reflect.Method object and extract the 1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * declaringClass from it, but that's more work than we want to do. 1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Instead, we find the "value" item and parse the index out ourselves. 1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingMethod, 1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilitySystem); 1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem == NULL) 1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the value member */ 1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr; 1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "value"); 1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ptr == NULL) { 1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("EnclosingMethod annotation lacks 'value' member\n"); 1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* parse it, verify the type */ 1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationValue avalue; 1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!processAnnotationValue(clazz, &ptr, &avalue, kAllRaw)) { 1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("EnclosingMethod parse failed\n"); 1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (avalue.type != kDexAnnotationMethod) { 1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("EnclosingMethod value has wrong type (0x%02x, expected 0x%02x)\n", 1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project avalue.type, kDexAnnotationMethod); 1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* pull out the method index and resolve the method */ 1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* meth = resolveAmbiguousMethod(clazz, avalue.value.i); 1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (meth == NULL) 1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* methClazz = meth->clazz; 1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddTrackedAlloc((Object*) methClazz, NULL); // balance the Release 1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return methClazz; 1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the EnclosingClass attribute from an annotation. If found, returns 1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "true". A String with the original name of the class and the original 1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * access flags are returned through the arguments. (The name will be NULL 1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for an anonymous inner class.) 1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmGetInnerClass(const ClassObject* clazz, StringObject** pName, 1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int* pAccessFlags) 1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForClass(clazz); 1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) 1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrInnerClass, 1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilitySystem); 1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem == NULL) 1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The InnerClass annotation has two members, "String name" and 1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "int accessFlags". We don't want to get the access flags as an 1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Integer, so we process that as a simple value. 1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr; 1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "name"); 1444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ptr == NULL) { 1445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("InnerClass annotation lacks 'name' member\n"); 1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* parse it into an Object */ 1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationValue avalue; 1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!processAnnotationValue(clazz, &ptr, &avalue, kAllObjects)) { 1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("processAnnotationValue failed on InnerClass member 'name'\n"); 1453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure it has the expected format */ 1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (avalue.type != kDexAnnotationNull && 1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project avalue.type != kDexAnnotationString) 1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("InnerClass name has bad type (0x%02x, expected STRING or NULL)\n", 1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project avalue.type); 1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pName = (StringObject*) avalue.value.l; 1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(*pName == NULL || (*pName)->obj.clazz == gDvm.classJavaLangString); 1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "accessFlags"); 1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ptr == NULL) { 1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("InnerClass annotation lacks 'accessFlags' member\n"); 1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* parse it, verify the type */ 1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!processAnnotationValue(clazz, &ptr, &avalue, kAllRaw)) { 1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("InnerClass accessFlags parse failed\n"); 1477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (avalue.type != kDexAnnotationInt) { 1480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("InnerClass value has wrong type (0x%02x, expected 0x%02x)\n", 1481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project avalue.type, kDexAnnotationInt); 1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *pAccessFlags = avalue.value.i; 1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract an array of Class objects from the MemberClasses annotation 1492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for this class. 1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if we don't find any member classes. 1497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectArrayObject* dvmGetDeclaredClasses(const ClassObject* clazz) 1499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 1502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj; 1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForClass(clazz); 1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) 1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrMemberClasses, 1509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilitySystem); 1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem == NULL) 1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The MemberClasses annotation has one member, "Class[] value". 1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = getAnnotationValue(clazz, pAnnoItem, "value", 1517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexAnnotationArray, "MemberClasses"); 1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == GAV_FAILED) 1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsArray((ArrayObject*)obj)); 1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = convertReturnType(obj, gDvm.classJavaLangClassArray); 1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ArrayObject*)obj; 1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Method (and Constructor) 1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compare the attributes (class name, method name, method signature) of 1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the specified method to "method". 1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int compareMethodStr(DexFile* pDexFile, u4 methodIdx, 1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* method) 1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexMethodId* pMethodId = dexGetMethodId(pDexFile, methodIdx); 1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* str = dexStringByTypeIdx(pDexFile, pMethodId->classIdx); 1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = strcmp(str, method->clazz->descriptor); 1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project str = dexStringById(pDexFile, pMethodId->nameIdx); 1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(str, method->name); 1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexProto proto; 1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexProtoSetFromMethodId(&proto, pDexFile, pMethodId); 1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = dexProtoCompare(&proto, &method->prototype); 1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Given a method, determine the method's index. 1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We could simply store this in the Method*, but that would cost 4 bytes 1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * per method. Instead we plow through the DEX data. 1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We have two choices: look through the class method data, or look through 1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the global method_ids table. The former is awkward because the method 1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * could have been defined in a superclass or interface. The latter works 1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * out reasonably well because it's in sorted order, though we're still left 1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * doing a fair number of string comparisons. 1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic u4 getMethodIdx(const Method* method) 1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = method->clazz->pDvmDex->pDexFile; 1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 hi = pDexFile->pHeader->methodIdsSize -1; 1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 lo = 0; 1573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 cur; 1574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (hi >= lo) { 1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cmp; 1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cur = (lo + hi) / 2; 1578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmp = compareMethodStr(pDexFile, cur, method); 1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cmp < 0) { 1581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lo = cur + 1; 1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (cmp > 0) { 1583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hi = cur - 1; 1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (hi < lo) { 1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* this should be impossible -- the method came out of this DEX */ 1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc = dexProtoCopyMethodDescriptor(&method->prototype); 1592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Unable to find method %s.%s %s in DEX file!\n", 1593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->clazz->descriptor, method->name, desc); 1594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); 1595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 1596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return cur; 1599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the DexAnnotationSetItem for this method. 1603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if none found. 1605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const DexAnnotationSetItem* findAnnotationSetForMethod( 1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* method) 1608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = method->clazz; 1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile; 1611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationsDirectoryItem* pAnnoDir; 1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexMethodAnnotationsItem* pMethodList; 1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet = NULL; 1614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz->pDvmDex == NULL) /* generated class (Proxy, array) */ 1616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexFile = clazz->pDvmDex->pDexFile; 1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoDir = getAnnoDirectory(pDexFile, clazz); 1620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoDir != NULL) { 1621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMethodList = dexGetMethodAnnotations(pDexFile, pAnnoDir); 1622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethodList != NULL) { 1623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run through the list and find a matching method. We compare the 1625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method ref indices in the annotation list with the method's DEX 1626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method_idx value. 1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: use a binary search for long lists 1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Alternate approach: for each entry in the annotations list, 1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * find the method definition in the DEX file and perform string 1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * comparisons on class name, method name, and signature. 1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 methodIdx = getMethodIdx(method); 1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 count = dexGetMethodAnnotationsSize(pDexFile, pAnnoDir); 1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx; 1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (idx = 0; idx < count; idx++) { 1639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethodList[idx].methodIdx == methodIdx) { 1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* found! */ 1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = dexGetMethodAnnotationSetItem(pDexFile, 1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &pMethodList[idx]); 1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pAnnoSet; 1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return an array of Annotation objects for the method. Returns an empty 1654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * array if there are no annotations. 1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * On allocation failure, this returns NULL with an exception raised. 1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectArrayObject* dvmGetMethodAnnotations(const Method* method) 1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = method->clazz; 1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* annoArray = NULL; 1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForMethod(method); 1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) { 1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no matching annotations found */ 1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArray = emptyAnnoArray(); 1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArray = processAnnotationSet(clazz, pAnnoSet,kDexVisibilityRuntime); 1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return annoArray; 1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Retrieve the Signature annotation, if any. Returns NULL if no signature 1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exists. 1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectArrayObject* dvmGetMethodSignatureAnnotation(const Method* method) 1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = method->clazz; 1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* signature = NULL; 1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForMethod(method); 1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet != NULL) 1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = getSignatureValue(clazz, pAnnoSet); 1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signature; 1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract an array of exception classes from the "system" annotation list 1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for this method. 1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if we don't find any exceptions for this method. 1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectArrayObject* dvmGetMethodThrows(const Method* method) 1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = method->clazz; 1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the set for this method */ 1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForMethod(method); 1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) 1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; /* nothing for this method */ 1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the "Throws" annotation, if any */ 1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrThrows, 1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilitySystem); 1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem == NULL) 1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; /* no Throws */ 1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The Throws annotation has one member, "Class[] value". 1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj = getAnnotationValue(clazz, pAnnoItem, "value", 1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexAnnotationArray, "Throws"); 1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == GAV_FAILED) 1727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsArray((ArrayObject*)obj)); 1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = convertReturnType(obj, gDvm.classJavaLangClassArray); 1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (ArrayObject*)obj; 1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Given an Annotation's method, find the default value, if any. 1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If this is a CLASS annotation, and we can't find a match for the 1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * default class value, we need to throw a TypeNotPresentException. 1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObject* dvmGetAnnotationDefaultValue(const Method* method) 1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassObject* clazz = method->clazz; 1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = clazz->pDvmDex->pDexFile; 1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationsDirectoryItem* pAnnoDir; 1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet = NULL; 1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The method's declaring class (the annotation) will have an 1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * AnnotationDefault "system" annotation associated with it if any 1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of its methods have default values. Start by finding the 1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * DexAnnotationItem associated with the class. 1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoDir = getAnnoDirectory(pDexFile, clazz); 1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoDir != NULL) 1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = dexGetClassAnnotationSet(pDexFile, pAnnoDir); 1757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) { 1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no annotations for anything in class, or no class annotations */ 1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the "AnnotationDefault" annotation, if any */ 1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationItem* pAnnoItem; 1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrAnnotationDefault, 1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilitySystem); 1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoItem == NULL) { 1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no default values for any member in this annotation */ 1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("##### no default annotations for %s.%s\n", 1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // method->clazz->descriptor, method->name); 1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The AnnotationDefault annotation has one member, "Annotation value". 1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need to pull that out. 1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u1* ptr; 1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "value"); 1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ptr == NULL) { 1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("AnnotationDefault annotation lacks 'value'\n"); 1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((*ptr & kDexAnnotationValueTypeMask) != kDexAnnotationAnnotation) { 1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("AnnotationDefault value has wrong type (0x%02x)\n", 1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ptr & kDexAnnotationValueTypeMask); 1786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The value_type byte for VALUE_ANNOTATION is followed by 1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * encoded_annotation data. We want to scan through it to find an 1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entry whose name matches our method name. 1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr++; 1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = searchEncodedAnnotation(clazz, ptr, method->name); 1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ptr == NULL) 1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; /* no default annotation for this method */ 1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* got it, pull it out */ 1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationValue avalue; 1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!processAnnotationValue(clazz, &ptr, &avalue, kAllObjects)) { 1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("processAnnotationValue failed on default for '%s'\n", 1803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->name); 1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* convert the return type, if necessary */ 1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* methodReturn = dvmGetBoxedReturnType(method); 1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* obj = avalue.value.l; 1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = convertReturnType(obj, methodReturn); 1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return obj; 1813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Field 1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compare the attributes (class name, field name, field signature) of 1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the specified field to "field". 1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int compareFieldStr(DexFile* pDexFile, u4 idx, const Field* field) 1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFieldId* pFieldId = dexGetFieldId(pDexFile, idx); 1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* str = dexStringByTypeIdx(pDexFile, pFieldId->classIdx); 1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = strcmp(str, field->clazz->descriptor); 1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project str = dexStringById(pDexFile, pFieldId->nameIdx); 1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(str, field->name); 1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project str = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx); 1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(str, field->signature); 1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Given a field, determine the field's index. 1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This has the same tradeoffs as getMethodIdx. 1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic u4 getFieldIdx(const Field* field) 1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = field->clazz->pDvmDex->pDexFile; 1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 hi = pDexFile->pHeader->fieldIdsSize -1; 1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 lo = 0; 1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 cur; 1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (hi >= lo) { 1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cmp; 1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cur = (lo + hi) / 2; 1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmp = compareFieldStr(pDexFile, cur, field); 1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cmp < 0) { 1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lo = cur + 1; 1863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (cmp > 0) { 1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hi = cur - 1; 1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (hi < lo) { 1871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* this should be impossible -- the field came out of this DEX */ 1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Unable to find field %s.%s %s in DEX file!\n", 1873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project field->clazz->descriptor, field->name, field->signature); 1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return cur; 1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the DexAnnotationSetItem for this field. 1882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if none found. 1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const DexAnnotationSetItem* findAnnotationSetForField(const Field* field) 1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = field->clazz; 1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = clazz->pDvmDex->pDexFile; 1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationsDirectoryItem* pAnnoDir; 1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFieldAnnotationsItem* pFieldList; 1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoDir = getAnnoDirectory(pDexFile, clazz); 1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoDir == NULL) 1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pFieldList = dexGetFieldAnnotations(pDexFile, pAnnoDir); 1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pFieldList == NULL) 1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run through the list and find a matching field. We compare the 1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * field ref indices in the annotation list with the field's DEX 1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * field_idx value. 1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: use a binary search for long lists 1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Alternate approach: for each entry in the annotations list, 1908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * find the field definition in the DEX file and perform string 1909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * comparisons on class name, field name, and signature. 1910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 fieldIdx = getFieldIdx(field); 1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 count = dexGetFieldAnnotationsSize(pDexFile, pAnnoDir); 1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx; 1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (idx = 0; idx < count; idx++) { 1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pFieldList[idx].fieldIdx == fieldIdx) { 1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* found! */ 1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dexGetFieldAnnotationSetItem(pDexFile, &pFieldList[idx]); 1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return an array of Annotation objects for the field. Returns an empty 1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * array if there are no annotations. 1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * On allocation failure, this returns NULL with an exception raised. 1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectArrayObject* dvmGetFieldAnnotations(const Field* field) 1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = field->clazz; 1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* annoArray = NULL; 1937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet = NULL; 1938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForField(field); 1940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet == NULL) { 1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no matching annotations found */ 1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArray = emptyAnnoArray(); 1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArray = processAnnotationSet(clazz, pAnnoSet, 1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kDexVisibilityRuntime); 1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return annoArray; 1949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Retrieve the Signature annotation, if any. Returns NULL if no signature 1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exists. 1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectArrayObject* dvmGetFieldSignatureAnnotation(const Field* field) 1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = field->clazz; 1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 1961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* signature = NULL; 1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = findAnnotationSetForField(field); 1964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoSet != NULL) 1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = getSignatureValue(clazz, pAnnoSet); 1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signature; 1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parameter 1974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 1975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We have an annotation_set_ref_list, which is essentially a list of 1979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entries that we pass to processAnnotationSet(). 1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The returned object must be released with dvmReleaseTrackedAlloc. 1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ArrayObject* processAnnotationSetRefList(const ClassObject* clazz, 1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetRefList* pAnnoSetList, u4 count) 1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = clazz->pDvmDex->pDexFile; 1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* annoArrayArray = NULL; 1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx; 1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* allocate an array of Annotation arrays to hold results */ 1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArrayArray = dvmAllocArrayByClass( 1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.classJavaLangAnnotationAnnotationArrayArray, count, ALLOC_DEFAULT); 1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (annoArrayArray == NULL) { 1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("annotation set ref array alloc failed\n"); 1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (idx = 0; idx < count; idx++) { 1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread* self = dvmThreadSelf(); 2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetRefItem* pItem; 2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetItem* pAnnoSet; 2002364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes Object *annoSet; 2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pItem = dexGetParameterAnnotationSetRef(pAnnoSetList, idx); 2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSet = dexGetSetRefItemItem(pDexFile, pItem); 2006364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes annoSet = (Object *)processAnnotationSet(clazz, 2007364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes pAnnoSet, 2008364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes kDexVisibilityRuntime); 2009364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes if (annoSet == NULL) { 2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("processAnnotationSet failed\n"); 2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArrayArray = NULL; 2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2014364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmSetObjectArrayElement(annoArrayArray, idx, annoSet); 2015364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmReleaseTrackedAlloc((Object*) annoSet, self); 2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return annoArrayArray; 2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the DexAnnotationSetItem for this parameter. 2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if none found. 2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const DexParameterAnnotationsItem* findAnnotationsItemForMethod( 2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* method) 2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = method->clazz; 2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile; 2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationsDirectoryItem* pAnnoDir; 2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexParameterAnnotationsItem* pParameterList; 2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz->pDvmDex == NULL) /* generated class (Proxy, array) */ 2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pDexFile = clazz->pDvmDex->pDexFile; 2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoDir = getAnnoDirectory(pDexFile, clazz); 2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pAnnoDir == NULL) 2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pParameterList = dexGetParameterAnnotations(pDexFile, pAnnoDir); 2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pParameterList == NULL) 2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run through the list and find a matching method. We compare the 2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method ref indices in the annotation list with the method's DEX 2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method_idx value. 2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: use a binary search for long lists 2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Alternate approach: for each entry in the annotations list, 2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * find the method definition in the DEX file and perform string 2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * comparisons on class name, method name, and signature. 2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 methodIdx = getMethodIdx(method); 2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 count = dexGetParameterAnnotationsSize(pDexFile, pAnnoDir); 2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx; 2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (idx = 0; idx < count; idx++) { 2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pParameterList[idx].methodIdx == methodIdx) { 2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* found! */ 2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return &pParameterList[idx]; 2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count up the number of arguments the method takes. The "this" pointer 2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * doesn't count. 2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int countMethodArguments(const Method* method) 2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* method->shorty[0] is the return type */ 2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strlen(method->shorty + 1); 2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return an array of arrays of Annotation objects. The outer array has 2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one entry per method parameter, the inner array has the list of annotations 2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * associated with that parameter. 2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the method has no parameters, we return an array of length zero. If 2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the method has one or more parameters, we return an array whose length 2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is equal to the number of parameters; if a given parameter does not have 2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an annotation, the corresponding entry will be null. 2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Caller must call dvmReleaseTrackedAlloc(). 2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectArrayObject* dvmGetParameterAnnotations(const Method* method) 2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* clazz = method->clazz; 2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexParameterAnnotationsItem* pItem; 2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayObject* annoArrayArray = NULL; 2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pItem = findAnnotationsItemForMethod(method); 2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pItem != NULL) { 2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexAnnotationSetRefList* pAnnoSetList; 2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 size; 2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = dexGetParameterAnnotationSetRefSize(pDexFile, pItem); 2108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pAnnoSetList = dexGetParameterAnnotationSetRefList(pDexFile, pItem); 2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArrayArray = processAnnotationSetRefList(clazz, pAnnoSetList, size); 2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* no matching annotations found */ 2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project annoArrayArray = emptyAnnoArrayArray(countMethodArguments(method)); 2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return annoArrayArray; 2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * DexEncodedArray interpretation 2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initializes an encoded array iterator. 2127de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param iterator iterator to initialize 2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param encodedArray encoded array to iterate over 2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param clazz class to use when resolving strings and types 2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmEncodedArrayIteratorInitialize(EncodedArrayIterator* iterator, 2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexEncodedArray* encodedArray, const ClassObject* clazz) { 2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iterator->encodedArray = encodedArray; 2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iterator->cursor = encodedArray->array; 2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iterator->size = readUleb128(&iterator->cursor); 2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iterator->elementsLeft = iterator->size; 2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iterator->clazz = clazz; 2139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns whether there are more elements to be read. 2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmEncodedArrayIteratorHasNext(const EncodedArrayIterator* iterator) { 2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (iterator->elementsLeft != 0); 2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the next decoded value from the iterator, advancing its 2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * cursor. This returns primitive values in their corresponding union 2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * slots, and returns everything else (including nulls) as object 2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * references in the "l" union slot. 2153de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The caller must call dvmReleaseTrackedAlloc() on any returned reference. 2155de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 2156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value pointer to store decoded value into 2157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @returns true if a value was decoded and the cursor advanced; false if 2158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the last value had already been decoded or if there was a problem decoding 2159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmEncodedArrayIteratorGetNext(EncodedArrayIterator* iterator, 2161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationValue* value) { 2162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool processed; 2163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (iterator->elementsLeft == 0) { 2165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project processed = processAnnotationValue(iterator->clazz, &iterator->cursor, 2169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project value, kPrimitivesOrObjects); 2170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! processed) { 2172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Failed to process array element %d from %p", 2173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iterator->size - iterator->elementsLeft, 2174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iterator->encodedArray); 2175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iterator->elementsLeft = 0; 2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 2177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iterator->elementsLeft--; 2180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2182