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