DexVerify.cpp revision 291c84f60853d30e1c0d79dd08c5e5164f588e26
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/*
18 * Dalvik classfile verification.  This file contains the verifier entry
19 * points and the static constraint checks.
20 */
21#include "Dalvik.h"
22#include "analysis/CodeVerify.h"
23#include "libdex/DexCatch.h"
24
25
26/* fwd */
27static bool verifyMethod(Method* meth);
28static bool verifyInstructions(VerifierData* vdata);
29
30
31/*
32 * Verify a class.
33 *
34 * By the time we get here, the value of gDvm.classVerifyMode should already
35 * have been factored in.  If you want to call into the verifier even
36 * though verification is disabled, that's your business.
37 *
38 * Returns "true" on success.
39 */
40bool dvmVerifyClass(ClassObject* clazz)
41{
42    int i;
43
44    if (dvmIsClassVerified(clazz)) {
45        LOGD("Ignoring duplicate verify attempt on %s", clazz->descriptor);
46        return true;
47    }
48
49    for (i = 0; i < clazz->directMethodCount; i++) {
50        if (!verifyMethod(&clazz->directMethods[i])) {
51            LOG_VFY("Verifier rejected class %s", clazz->descriptor);
52            return false;
53        }
54    }
55    for (i = 0; i < clazz->virtualMethodCount; i++) {
56        if (!verifyMethod(&clazz->virtualMethods[i])) {
57            LOG_VFY("Verifier rejected class %s", clazz->descriptor);
58            return false;
59        }
60    }
61
62    return true;
63}
64
65
66/*
67 * Compute the width of the instruction at each address in the instruction
68 * stream, and store it in vdata->insnFlags.  Addresses that are in the
69 * middle of an instruction, or that are part of switch table data, are not
70 * touched (so the caller should probably initialize "insnFlags" to zero).
71 *
72 * The "newInstanceCount" and "monitorEnterCount" fields in vdata are
73 * also set.
74 *
75 * Performs some static checks, notably:
76 * - opcode of first instruction begins at index 0
77 * - only documented instructions may appear
78 * - each instruction follows the last
79 * - last byte of last instruction is at (code_length-1)
80 *
81 * Logs an error and returns "false" on failure.
82 */
83static bool computeWidthsAndCountOps(VerifierData* vdata)
84{
85    const Method* meth = vdata->method;
86    InsnFlags* insnFlags = vdata->insnFlags;
87    size_t insnCount = vdata->insnsSize;
88    const u2* insns = meth->insns;
89    bool result = false;
90    int newInstanceCount = 0;
91    int monitorEnterCount = 0;
92    int i;
93
94    for (i = 0; i < (int) insnCount; /**/) {
95        size_t width = dexGetWidthFromInstruction(insns);
96        if (width == 0) {
97            LOG_VFY_METH(meth, "VFY: invalid instruction (0x%04x)", *insns);
98            goto bail;
99        } else if (width > 65535) {
100            LOG_VFY_METH(meth,
101                "VFY: warning: unusually large instr width (%d)\n", width);
102        }
103
104        Opcode opcode = dexOpcodeFromCodeUnit(*insns);
105        if (opcode == OP_NEW_INSTANCE || opcode == OP_NEW_INSTANCE_JUMBO)
106            newInstanceCount++;
107        if (opcode == OP_MONITOR_ENTER)
108            monitorEnterCount++;
109
110        insnFlags[i] |= width;
111        i += width;
112        insns += width;
113    }
114    if (i != (int) vdata->insnsSize) {
115        LOG_VFY_METH(meth, "VFY: code did not end where expected (%d vs. %d)",
116            i, dvmGetMethodInsnsSize(meth));
117        goto bail;
118    }
119
120    result = true;
121    vdata->newInstanceCount = newInstanceCount;
122    vdata->monitorEnterCount = monitorEnterCount;
123
124bail:
125    return result;
126}
127
128/*
129 * Set the "in try" flags for all instructions protected by "try" statements.
130 * Also sets the "branch target" flags for exception handlers.
131 *
132 * Call this after widths have been set in "insnFlags".
133 *
134 * Returns "false" if something in the exception table looks fishy, but
135 * we're expecting the exception table to be somewhat sane.
136 */
137static bool scanTryCatchBlocks(const Method* meth, InsnFlags* insnFlags)
138{
139    u4 insnsSize = dvmGetMethodInsnsSize(meth);
140    const DexCode* pCode = dvmGetMethodCode(meth);
141    u4 triesSize = pCode->triesSize;
142    const DexTry* pTries;
143    u4 idx;
144
145    if (triesSize == 0) {
146        return true;
147    }
148
149    pTries = dexGetTries(pCode);
150
151    for (idx = 0; idx < triesSize; idx++) {
152        const DexTry* pTry = &pTries[idx];
153        u4 start = pTry->startAddr;
154        u4 end = start + pTry->insnCount;
155        u4 addr;
156
157        if ((start >= end) || (start >= insnsSize) || (end > insnsSize)) {
158            LOG_VFY_METH(meth,
159                "VFY: bad exception entry: startAddr=%d endAddr=%d (size=%d)\n",
160                start, end, insnsSize);
161            return false;
162        }
163
164        if (dvmInsnGetWidth(insnFlags, start) == 0) {
165            LOG_VFY_METH(meth,
166                "VFY: 'try' block starts inside an instruction (%d)\n",
167                start);
168            return false;
169        }
170
171        for (addr = start; addr < end;
172            addr += dvmInsnGetWidth(insnFlags, addr))
173        {
174            assert(dvmInsnGetWidth(insnFlags, addr) != 0);
175            dvmInsnSetInTry(insnFlags, addr, true);
176        }
177    }
178
179    /* Iterate over each of the handlers to verify target addresses. */
180    u4 handlersSize = dexGetHandlersSize(pCode);
181    u4 offset = dexGetFirstHandlerOffset(pCode);
182    for (idx = 0; idx < handlersSize; idx++) {
183        DexCatchIterator iterator;
184        dexCatchIteratorInit(&iterator, pCode, offset);
185
186        for (;;) {
187            DexCatchHandler* handler = dexCatchIteratorNext(&iterator);
188            u4 addr;
189
190            if (handler == NULL) {
191                break;
192            }
193
194            addr = handler->address;
195            if (dvmInsnGetWidth(insnFlags, addr) == 0) {
196                LOG_VFY_METH(meth,
197                    "VFY: exception handler starts at bad address (%d)\n",
198                    addr);
199                return false;
200            }
201
202            dvmInsnSetBranchTarget(insnFlags, addr, true);
203        }
204
205        offset = dexCatchIteratorGetEndOffset(&iterator, pCode);
206    }
207
208    return true;
209}
210
211/*
212 * Perform verification on a single method.
213 *
214 * We do this in three passes:
215 *  (1) Walk through all code units, determining instruction locations,
216 *      widths, and other characteristics.
217 *  (2) Walk through all code units, performing static checks on
218 *      operands.
219 *  (3) Iterate through the method, checking type safety and looking
220 *      for code flow problems.
221 *
222 * Some checks may be bypassed depending on the verification mode.  We can't
223 * turn this stuff off completely if we want to do "exact" GC.
224 *
225 * TODO: cite source?
226 * Confirmed here:
227 * - code array must not be empty
228 * - (N/A) code_length must be less than 65536
229 * Confirmed by computeWidthsAndCountOps():
230 * - opcode of first instruction begins at index 0
231 * - only documented instructions may appear
232 * - each instruction follows the last
233 * - last byte of last instruction is at (code_length-1)
234 */
235static bool verifyMethod(Method* meth)
236{
237    bool result = false;
238
239    /*
240     * Verifier state blob.  Various values will be cached here so we
241     * can avoid expensive lookups and pass fewer arguments around.
242     */
243    VerifierData vdata;
244#if 1   // ndef NDEBUG
245    memset(&vdata, 0x99, sizeof(vdata));
246#endif
247
248    vdata.method = meth;
249    vdata.insnsSize = dvmGetMethodInsnsSize(meth);
250    vdata.insnRegCount = meth->registersSize;
251    vdata.insnFlags = NULL;
252    vdata.uninitMap = NULL;
253    vdata.basicBlocks = NULL;
254
255    /*
256     * If there aren't any instructions, make sure that's expected, then
257     * exit successfully.  Note: for native methods, meth->insns gets set
258     * to a native function pointer on first call, so don't use that as
259     * an indicator.
260     */
261    if (vdata.insnsSize == 0) {
262        if (!dvmIsNativeMethod(meth) && !dvmIsAbstractMethod(meth)) {
263            LOG_VFY_METH(meth,
264                "VFY: zero-length code in concrete non-native method\n");
265            goto bail;
266        }
267
268        goto success;
269    }
270
271    /*
272     * Sanity-check the register counts.  ins + locals = registers, so make
273     * sure that ins <= registers.
274     */
275    if (meth->insSize > meth->registersSize) {
276        LOG_VFY_METH(meth, "VFY: bad register counts (ins=%d regs=%d)",
277            meth->insSize, meth->registersSize);
278        goto bail;
279    }
280
281    /*
282     * Allocate and populate an array to hold instruction data.
283     *
284     * TODO: Consider keeping a reusable pre-allocated array sitting
285     * around for smaller methods.
286     */
287    vdata.insnFlags = (InsnFlags*) calloc(vdata.insnsSize, sizeof(InsnFlags));
288    if (vdata.insnFlags == NULL)
289        goto bail;
290
291    /*
292     * Compute the width of each instruction and store the result in insnFlags.
293     * Count up the #of occurrences of certain opcodes while we're at it.
294     */
295    if (!computeWidthsAndCountOps(&vdata))
296        goto bail;
297
298    /*
299     * Allocate a map to hold the classes of uninitialized instances.
300     */
301    vdata.uninitMap = dvmCreateUninitInstanceMap(meth, vdata.insnFlags,
302        vdata.newInstanceCount);
303    if (vdata.uninitMap == NULL)
304        goto bail;
305
306    /*
307     * Set the "in try" flags for all instructions guarded by a "try" block.
308     * Also sets the "branch target" flag on exception handlers.
309     */
310    if (!scanTryCatchBlocks(meth, vdata.insnFlags))
311        goto bail;
312
313    /*
314     * Perform static instruction verification.  Also sets the "branch
315     * target" flags.
316     */
317    if (!verifyInstructions(&vdata))
318        goto bail;
319
320    /*
321     * Do code-flow analysis.
322     *
323     * We could probably skip this for a method with no registers, but
324     * that's so rare that there's little point in checking.
325     */
326    if (!dvmVerifyCodeFlow(&vdata)) {
327        //LOGD("+++ %s failed code flow", meth->name);
328        goto bail;
329    }
330
331success:
332    result = true;
333
334bail:
335    dvmFreeVfyBasicBlocks(&vdata);
336    dvmFreeUninitInstanceMap(vdata.uninitMap);
337    free(vdata.insnFlags);
338    return result;
339}
340
341
342/*
343 * Verify an array data table.  "curOffset" is the offset of the
344 * fill-array-data instruction.
345 */
346static bool checkArrayData(const Method* meth, u4 curOffset)
347{
348    const u4 insnCount = dvmGetMethodInsnsSize(meth);
349    const u2* insns = meth->insns + curOffset;
350    const u2* arrayData;
351    u4 valueCount, valueWidth, tableSize;
352    s4 offsetToArrayData;
353
354    assert(curOffset < insnCount);
355
356    /* make sure the start of the array data table is in range */
357    offsetToArrayData = insns[1] | (((s4)insns[2]) << 16);
358    if ((s4)curOffset + offsetToArrayData < 0 ||
359        curOffset + offsetToArrayData + 2 >= insnCount)
360    {
361        LOG_VFY("VFY: invalid array data start: at %d, data offset %d, "
362                "count %d\n",
363            curOffset, offsetToArrayData, insnCount);
364        return false;
365    }
366
367    /* offset to array data table is a relative branch-style offset */
368    arrayData = insns + offsetToArrayData;
369
370    /* make sure the table is 32-bit aligned */
371    if ((((u4) arrayData) & 0x03) != 0) {
372        LOG_VFY("VFY: unaligned array data table: at %d, data offset %d",
373            curOffset, offsetToArrayData);
374        return false;
375    }
376
377    valueWidth = arrayData[1];
378    valueCount = *(u4*)(&arrayData[2]);
379
380    tableSize = 4 + (valueWidth * valueCount + 1) / 2;
381
382    /* make sure the end of the switch is in range */
383    if (curOffset + offsetToArrayData + tableSize > insnCount) {
384        LOG_VFY("VFY: invalid array data end: at %d, data offset %d, end %d, "
385                "count %d\n",
386            curOffset, offsetToArrayData,
387            curOffset + offsetToArrayData + tableSize, insnCount);
388        return false;
389    }
390
391    return true;
392}
393
394/*
395 * Perform static checks on a "new-instance" instruction.  Specifically,
396 * make sure the class reference isn't for an array class.
397 *
398 * We don't need the actual class, just a pointer to the class name.
399 */
400static bool checkNewInstance(const DvmDex* pDvmDex, u4 idx)
401{
402    const char* classDescriptor;
403
404    if (idx >= pDvmDex->pHeader->typeIdsSize) {
405        LOG_VFY("VFY: bad type index %d (max %d)",
406            idx, pDvmDex->pHeader->typeIdsSize);
407        return false;
408    }
409
410    classDescriptor = dexStringByTypeIdx(pDvmDex->pDexFile, idx);
411    if (classDescriptor[0] != 'L') {
412        LOG_VFY("VFY: can't call new-instance on type '%s'",
413            classDescriptor);
414        return false;
415    }
416
417    return true;
418}
419
420/*
421 * Perform static checks on a "new-array" instruction.  Specifically, make
422 * sure they aren't creating an array of arrays that causes the number of
423 * dimensions to exceed 255.
424 */
425static bool checkNewArray(const DvmDex* pDvmDex, u4 idx)
426{
427    const char* classDescriptor;
428
429    if (idx >= pDvmDex->pHeader->typeIdsSize) {
430        LOG_VFY("VFY: bad type index %d (max %d)",
431            idx, pDvmDex->pHeader->typeIdsSize);
432        return false;
433    }
434
435    classDescriptor = dexStringByTypeIdx(pDvmDex->pDexFile, idx);
436
437    int bracketCount = 0;
438    const char* cp = classDescriptor;
439    while (*cp++ == '[')
440        bracketCount++;
441
442    if (bracketCount == 0) {
443        /* The given class must be an array type. */
444        LOG_VFY("VFY: can't new-array class '%s' (not an array)",
445            classDescriptor);
446        return false;
447    } else if (bracketCount > 255) {
448        /* It is illegal to create an array of more than 255 dimensions. */
449        LOG_VFY("VFY: can't new-array class '%s' (exceeds limit)",
450            classDescriptor);
451        return false;
452    }
453
454    return true;
455}
456
457/*
458 * Perform static checks on an instruction that takes a class constant.
459 * Ensure that the class index is in the valid range.
460 */
461static bool checkTypeIndex(const DvmDex* pDvmDex, u4 idx)
462{
463    if (idx >= pDvmDex->pHeader->typeIdsSize) {
464        LOG_VFY("VFY: bad type index %d (max %d)",
465            idx, pDvmDex->pHeader->typeIdsSize);
466        return false;
467    }
468    return true;
469}
470
471/*
472 * Perform static checks on a field get or set instruction.  All we do
473 * here is ensure that the field index is in the valid range.
474 */
475static bool checkFieldIndex(const DvmDex* pDvmDex, u4 idx)
476{
477    if (idx >= pDvmDex->pHeader->fieldIdsSize) {
478        LOG_VFY("VFY: bad field index %d (max %d)",
479            idx, pDvmDex->pHeader->fieldIdsSize);
480        return false;
481    }
482    return true;
483}
484
485/*
486 * Perform static checks on a method invocation instruction.  All we do
487 * here is ensure that the method index is in the valid range.
488 */
489static bool checkMethodIndex(const DvmDex* pDvmDex, u4 idx)
490{
491    if (idx >= pDvmDex->pHeader->methodIdsSize) {
492        LOG_VFY("VFY: bad method index %d (max %d)",
493            idx, pDvmDex->pHeader->methodIdsSize);
494        return false;
495    }
496    return true;
497}
498
499/*
500 * Ensure that the string index is in the valid range.
501 */
502static bool checkStringIndex(const DvmDex* pDvmDex, u4 idx)
503{
504    if (idx >= pDvmDex->pHeader->stringIdsSize) {
505        LOG_VFY("VFY: bad string index %d (max %d)",
506            idx, pDvmDex->pHeader->stringIdsSize);
507        return false;
508    }
509    return true;
510}
511
512/*
513 * Ensure that the register index is valid for this method.
514 */
515static bool checkRegisterIndex(const Method* meth, u4 idx)
516{
517    if (idx >= meth->registersSize) {
518        LOG_VFY("VFY: register index out of range (%d >= %d)",
519            idx, meth->registersSize);
520        return false;
521    }
522    return true;
523}
524
525/*
526 * Ensure that the wide register index is valid for this method.
527 */
528static bool checkWideRegisterIndex(const Method* meth, u4 idx)
529{
530    if (idx+1 >= meth->registersSize) {
531        LOG_VFY("VFY: wide register index out of range (%d+1 >= %d)",
532            idx, meth->registersSize);
533        return false;
534    }
535    return true;
536}
537
538/*
539 * Check the register indices used in a "vararg" instruction, such as
540 * invoke-virtual or filled-new-array.
541 *
542 * vA holds word count (0-5), args[] have values.
543 *
544 * There are some tests we don't do here, e.g. we don't try to verify
545 * that invoking a method that takes a double is done with consecutive
546 * registers.  This requires parsing the target method signature, which
547 * we will be doing later on during the code flow analysis.
548 */
549static bool checkVarargRegs(const Method* meth,
550    const DecodedInstruction* pDecInsn)
551{
552    u2 registersSize = meth->registersSize;
553    unsigned int idx;
554
555    if (pDecInsn->vA > 5) {
556        LOG_VFY("VFY: invalid arg count (%d) in non-range invoke)",
557            pDecInsn->vA);
558        return false;
559    }
560
561    for (idx = 0; idx < pDecInsn->vA; idx++) {
562        if (pDecInsn->arg[idx] > registersSize) {
563            LOG_VFY("VFY: invalid reg index (%d) in non-range invoke (> %d)",
564                pDecInsn->arg[idx], registersSize);
565            return false;
566        }
567    }
568
569    return true;
570}
571
572/*
573 * Check the register indices used in a "vararg/range" instruction, such as
574 * invoke-virtual/range or filled-new-array/range.
575 *
576 * vA holds word count, vC holds index of first reg.
577 */
578static bool checkVarargRangeRegs(const Method* meth,
579    const DecodedInstruction* pDecInsn)
580{
581    u2 registersSize = meth->registersSize;
582
583    /*
584     * vA/vC are unsigned 8-bit/16-bit quantities for /range instructions,
585     * so there's no risk of integer overflow when adding them here.
586     */
587    if (pDecInsn->vA + pDecInsn->vC > registersSize) {
588        LOG_VFY("VFY: invalid reg index %d+%d in range invoke (> %d)",
589            pDecInsn->vA, pDecInsn->vC, registersSize);
590        return false;
591    }
592
593    return true;
594}
595
596/*
597 * Verify a switch table.  "curOffset" is the offset of the switch
598 * instruction.
599 *
600 * Updates "insnFlags", setting the "branch target" flag.
601 */
602static bool checkSwitchTargets(const Method* meth, InsnFlags* insnFlags,
603    u4 curOffset)
604{
605    const u4 insnCount = dvmGetMethodInsnsSize(meth);
606    const u2* insns = meth->insns + curOffset;
607    const u2* switchInsns;
608    u2 expectedSignature;
609    u4 switchCount, tableSize;
610    s4 offsetToSwitch, offsetToKeys, offsetToTargets;
611    s4 offset, absOffset;
612    u4 targ;
613
614    assert(curOffset < insnCount);
615
616    /* make sure the start of the switch is in range */
617    offsetToSwitch = insns[1] | ((s4) insns[2]) << 16;
618    if ((s4) curOffset + offsetToSwitch < 0 ||
619        curOffset + offsetToSwitch + 2 >= insnCount)
620    {
621        LOG_VFY("VFY: invalid switch start: at %d, switch offset %d, "
622                "count %d\n",
623            curOffset, offsetToSwitch, insnCount);
624        return false;
625    }
626
627    /* offset to switch table is a relative branch-style offset */
628    switchInsns = insns + offsetToSwitch;
629
630    /* make sure the table is 32-bit aligned */
631    if ((((u4) switchInsns) & 0x03) != 0) {
632        LOG_VFY("VFY: unaligned switch table: at %d, switch offset %d",
633            curOffset, offsetToSwitch);
634        return false;
635    }
636
637    switchCount = switchInsns[1];
638
639    if ((*insns & 0xff) == OP_PACKED_SWITCH) {
640        /* 0=sig, 1=count, 2/3=firstKey */
641        offsetToTargets = 4;
642        offsetToKeys = -1;
643        expectedSignature = kPackedSwitchSignature;
644    } else {
645        /* 0=sig, 1=count, 2..count*2 = keys */
646        offsetToKeys = 2;
647        offsetToTargets = 2 + 2*switchCount;
648        expectedSignature = kSparseSwitchSignature;
649    }
650    tableSize = offsetToTargets + switchCount*2;
651
652    if (switchInsns[0] != expectedSignature) {
653        LOG_VFY("VFY: wrong signature for switch table (0x%04x, wanted 0x%04x)",
654            switchInsns[0], expectedSignature);
655        return false;
656    }
657
658    /* make sure the end of the switch is in range */
659    if (curOffset + offsetToSwitch + tableSize > (u4) insnCount) {
660        LOG_VFY("VFY: invalid switch end: at %d, switch offset %d, end %d, "
661                "count %d\n",
662            curOffset, offsetToSwitch, curOffset + offsetToSwitch + tableSize,
663            insnCount);
664        return false;
665    }
666
667    /* for a sparse switch, verify the keys are in ascending order */
668    if (offsetToKeys > 0 && switchCount > 1) {
669        s4 lastKey;
670
671        lastKey = switchInsns[offsetToKeys] |
672                  (switchInsns[offsetToKeys+1] << 16);
673        for (targ = 1; targ < switchCount; targ++) {
674            s4 key = (s4) switchInsns[offsetToKeys + targ*2] |
675                    (s4) (switchInsns[offsetToKeys + targ*2 +1] << 16);
676            if (key <= lastKey) {
677                LOG_VFY("VFY: invalid packed switch: last key=%d, this=%d",
678                    lastKey, key);
679                return false;
680            }
681
682            lastKey = key;
683        }
684    }
685
686    /* verify each switch target */
687    for (targ = 0; targ < switchCount; targ++) {
688        offset = (s4) switchInsns[offsetToTargets + targ*2] |
689                (s4) (switchInsns[offsetToTargets + targ*2 +1] << 16);
690        absOffset = curOffset + offset;
691
692        if (absOffset < 0 || absOffset >= (s4)insnCount ||
693            !dvmInsnIsOpcode(insnFlags, absOffset))
694        {
695            LOG_VFY("VFY: invalid switch target %d (-> %#x) at %#x[%d]",
696                offset, absOffset, curOffset, targ);
697            return false;
698        }
699        dvmInsnSetBranchTarget(insnFlags, absOffset, true);
700    }
701
702    return true;
703}
704
705/*
706 * Verify that the target of a branch instruction is valid.
707 *
708 * We don't expect code to jump directly into an exception handler, but
709 * it's valid to do so as long as the target isn't a "move-exception"
710 * instruction.  We verify that in a later stage.
711 *
712 * The VM spec doesn't forbid an instruction from branching to itself,
713 * but the Dalvik spec declares that only certain instructions can do so.
714 *
715 * Updates "insnFlags", setting the "branch target" flag.
716 */
717static bool checkBranchTarget(const Method* meth, InsnFlags* insnFlags,
718    int curOffset, bool selfOkay)
719{
720    const int insnCount = dvmGetMethodInsnsSize(meth);
721    s4 offset, absOffset;
722    bool isConditional;
723
724    if (!dvmGetBranchOffset(meth, insnFlags, curOffset, &offset,
725            &isConditional))
726        return false;
727
728    if (!selfOkay && offset == 0) {
729        LOG_VFY_METH(meth, "VFY: branch offset of zero not allowed at %#x",
730            curOffset);
731        return false;
732    }
733
734    /*
735     * Check for 32-bit overflow.  This isn't strictly necessary if we can
736     * depend on the VM to have identical "wrap-around" behavior, but
737     * it's unwise to depend on that.
738     */
739    if (((s8) curOffset + (s8) offset) != (s8)(curOffset + offset)) {
740        LOG_VFY_METH(meth, "VFY: branch target overflow %#x +%d",
741            curOffset, offset);
742        return false;
743    }
744    absOffset = curOffset + offset;
745    if (absOffset < 0 || absOffset >= insnCount ||
746        !dvmInsnIsOpcode(insnFlags, absOffset))
747    {
748        LOG_VFY_METH(meth,
749            "VFY: invalid branch target %d (-> %#x) at %#x\n",
750            offset, absOffset, curOffset);
751        return false;
752    }
753    dvmInsnSetBranchTarget(insnFlags, absOffset, true);
754
755    return true;
756}
757
758
759/*
760 * Perform static verification on instructions.
761 *
762 * As a side effect, this sets the "branch target" flags in InsnFlags.
763 *
764 * "(CF)" items are handled during code-flow analysis.
765 *
766 * v3 4.10.1
767 * - target of each jump and branch instruction must be valid
768 * - targets of switch statements must be valid
769 * - operands referencing constant pool entries must be valid
770 * - (CF) operands of getfield, putfield, getstatic, putstatic must be valid
771 * - (new) verify operands of "quick" field ops
772 * - (CF) operands of method invocation instructions must be valid
773 * - (new) verify operands of "quick" method invoke ops
774 * - (CF) only invoke-direct can call a method starting with '<'
775 * - (CF) <clinit> must never be called explicitly
776 * - operands of instanceof, checkcast, new (and variants) must be valid
777 * - new-array[-type] limited to 255 dimensions
778 * - can't use "new" on an array class
779 * - (?) limit dimensions in multi-array creation
780 * - local variable load/store register values must be in valid range
781 *
782 * v3 4.11.1.2
783 * - branches must be within the bounds of the code array
784 * - targets of all control-flow instructions are the start of an instruction
785 * - register accesses fall within range of allocated registers
786 * - (N/A) access to constant pool must be of appropriate type
787 * - code does not end in the middle of an instruction
788 * - execution cannot fall off the end of the code
789 * - (earlier) for each exception handler, the "try" area must begin and
790 *   end at the start of an instruction (end can be at the end of the code)
791 * - (earlier) for each exception handler, the handler must start at a valid
792 *   instruction
793 */
794static bool verifyInstructions(VerifierData* vdata)
795{
796    const Method* meth = vdata->method;
797    const DvmDex* pDvmDex = meth->clazz->pDvmDex;
798    InsnFlags* insnFlags = vdata->insnFlags;
799    const u2* insns = meth->insns;
800    unsigned int codeOffset;
801
802    /* the start of the method is a "branch target" */
803    dvmInsnSetBranchTarget(insnFlags, 0, true);
804
805    for (codeOffset = 0; codeOffset < vdata->insnsSize; /**/) {
806        /*
807         * Pull the instruction apart.
808         */
809        int width = dvmInsnGetWidth(insnFlags, codeOffset);
810        DecodedInstruction decInsn;
811        bool okay = true;
812
813        dexDecodeInstruction(meth->insns + codeOffset, &decInsn);
814
815        /*
816         * Check register, type, class, field, method, and string indices
817         * for out-of-range values.  Do additional checks on branch targets
818         * and some special cases like new-instance and new-array.
819         */
820        switch (decInsn.opcode) {
821        case OP_NOP:
822        case OP_RETURN_VOID:
823            /* nothing to check */
824            break;
825        case OP_MOVE_RESULT:
826        case OP_MOVE_RESULT_OBJECT:
827        case OP_MOVE_EXCEPTION:
828        case OP_RETURN:
829        case OP_RETURN_OBJECT:
830        case OP_CONST_4:
831        case OP_CONST_16:
832        case OP_CONST:
833        case OP_CONST_HIGH16:
834        case OP_MONITOR_ENTER:
835        case OP_MONITOR_EXIT:
836        case OP_THROW:
837            okay &= checkRegisterIndex(meth, decInsn.vA);
838            break;
839        case OP_MOVE_RESULT_WIDE:
840        case OP_RETURN_WIDE:
841        case OP_CONST_WIDE_16:
842        case OP_CONST_WIDE_32:
843        case OP_CONST_WIDE:
844        case OP_CONST_WIDE_HIGH16:
845            okay &= checkWideRegisterIndex(meth, decInsn.vA);
846            break;
847        case OP_GOTO:
848        case OP_GOTO_16:
849            okay &= checkBranchTarget(meth, insnFlags, codeOffset, false);
850            break;
851        case OP_GOTO_32:
852            okay &= checkBranchTarget(meth, insnFlags, codeOffset, true);
853            break;
854        case OP_MOVE:
855        case OP_MOVE_FROM16:
856        case OP_MOVE_16:
857        case OP_MOVE_OBJECT:
858        case OP_MOVE_OBJECT_FROM16:
859        case OP_MOVE_OBJECT_16:
860        case OP_ARRAY_LENGTH:
861        case OP_NEG_INT:
862        case OP_NOT_INT:
863        case OP_NEG_FLOAT:
864        case OP_INT_TO_FLOAT:
865        case OP_FLOAT_TO_INT:
866        case OP_INT_TO_BYTE:
867        case OP_INT_TO_CHAR:
868        case OP_INT_TO_SHORT:
869        case OP_ADD_INT_2ADDR:
870        case OP_SUB_INT_2ADDR:
871        case OP_MUL_INT_2ADDR:
872        case OP_DIV_INT_2ADDR:
873        case OP_REM_INT_2ADDR:
874        case OP_AND_INT_2ADDR:
875        case OP_OR_INT_2ADDR:
876        case OP_XOR_INT_2ADDR:
877        case OP_SHL_INT_2ADDR:
878        case OP_SHR_INT_2ADDR:
879        case OP_USHR_INT_2ADDR:
880        case OP_ADD_FLOAT_2ADDR:
881        case OP_SUB_FLOAT_2ADDR:
882        case OP_MUL_FLOAT_2ADDR:
883        case OP_DIV_FLOAT_2ADDR:
884        case OP_REM_FLOAT_2ADDR:
885        case OP_ADD_INT_LIT16:
886        case OP_RSUB_INT:
887        case OP_MUL_INT_LIT16:
888        case OP_DIV_INT_LIT16:
889        case OP_REM_INT_LIT16:
890        case OP_AND_INT_LIT16:
891        case OP_OR_INT_LIT16:
892        case OP_XOR_INT_LIT16:
893        case OP_ADD_INT_LIT8:
894        case OP_RSUB_INT_LIT8:
895        case OP_MUL_INT_LIT8:
896        case OP_DIV_INT_LIT8:
897        case OP_REM_INT_LIT8:
898        case OP_AND_INT_LIT8:
899        case OP_OR_INT_LIT8:
900        case OP_XOR_INT_LIT8:
901        case OP_SHL_INT_LIT8:
902        case OP_SHR_INT_LIT8:
903        case OP_USHR_INT_LIT8:
904            okay &= checkRegisterIndex(meth, decInsn.vA);
905            okay &= checkRegisterIndex(meth, decInsn.vB);
906            break;
907        case OP_INT_TO_LONG:
908        case OP_INT_TO_DOUBLE:
909        case OP_FLOAT_TO_LONG:
910        case OP_FLOAT_TO_DOUBLE:
911        case OP_SHL_LONG_2ADDR:
912        case OP_SHR_LONG_2ADDR:
913        case OP_USHR_LONG_2ADDR:
914            okay &= checkWideRegisterIndex(meth, decInsn.vA);
915            okay &= checkRegisterIndex(meth, decInsn.vB);
916            break;
917        case OP_LONG_TO_INT:
918        case OP_LONG_TO_FLOAT:
919        case OP_DOUBLE_TO_INT:
920        case OP_DOUBLE_TO_FLOAT:
921            okay &= checkRegisterIndex(meth, decInsn.vA);
922            okay &= checkWideRegisterIndex(meth, decInsn.vB);
923            break;
924        case OP_MOVE_WIDE:
925        case OP_MOVE_WIDE_FROM16:
926        case OP_MOVE_WIDE_16:
927        case OP_DOUBLE_TO_LONG:
928        case OP_LONG_TO_DOUBLE:
929        case OP_NEG_DOUBLE:
930        case OP_NEG_LONG:
931        case OP_NOT_LONG:
932        case OP_ADD_LONG_2ADDR:
933        case OP_SUB_LONG_2ADDR:
934        case OP_MUL_LONG_2ADDR:
935        case OP_DIV_LONG_2ADDR:
936        case OP_REM_LONG_2ADDR:
937        case OP_AND_LONG_2ADDR:
938        case OP_OR_LONG_2ADDR:
939        case OP_XOR_LONG_2ADDR:
940        case OP_ADD_DOUBLE_2ADDR:
941        case OP_SUB_DOUBLE_2ADDR:
942        case OP_MUL_DOUBLE_2ADDR:
943        case OP_DIV_DOUBLE_2ADDR:
944        case OP_REM_DOUBLE_2ADDR:
945            okay &= checkWideRegisterIndex(meth, decInsn.vA);
946            okay &= checkWideRegisterIndex(meth, decInsn.vB);
947            break;
948        case OP_CONST_STRING:
949        case OP_CONST_STRING_JUMBO:
950            okay &= checkRegisterIndex(meth, decInsn.vA);
951            okay &= checkStringIndex(pDvmDex, decInsn.vB);
952            break;
953        case OP_CONST_CLASS:
954        case OP_CONST_CLASS_JUMBO:
955        case OP_CHECK_CAST:
956        case OP_CHECK_CAST_JUMBO:
957            okay &= checkRegisterIndex(meth, decInsn.vA);
958            okay &= checkTypeIndex(pDvmDex, decInsn.vB);
959            break;
960        case OP_INSTANCE_OF:
961        case OP_INSTANCE_OF_JUMBO:
962            okay &= checkRegisterIndex(meth, decInsn.vA);
963            okay &= checkRegisterIndex(meth, decInsn.vB);
964            okay &= checkTypeIndex(pDvmDex, decInsn.vC);
965            break;
966        case OP_NEW_INSTANCE:
967        case OP_NEW_INSTANCE_JUMBO:
968            okay &= checkRegisterIndex(meth, decInsn.vA);
969            okay &= checkNewInstance(pDvmDex, decInsn.vB);
970            break;
971        case OP_NEW_ARRAY:
972        case OP_NEW_ARRAY_JUMBO:
973            okay &= checkRegisterIndex(meth, decInsn.vA);
974            okay &= checkRegisterIndex(meth, decInsn.vB);
975            okay &= checkNewArray(pDvmDex, decInsn.vC);
976            break;
977        case OP_FILL_ARRAY_DATA:
978            okay &= checkRegisterIndex(meth, decInsn.vA);
979            okay &= checkArrayData(meth, codeOffset);
980            break;
981        case OP_PACKED_SWITCH:
982            okay &= checkRegisterIndex(meth, decInsn.vA);
983            okay &= checkSwitchTargets(meth, insnFlags, codeOffset);
984            break;
985        case OP_SPARSE_SWITCH:
986            okay &= checkRegisterIndex(meth, decInsn.vA);
987            okay &= checkSwitchTargets(meth, insnFlags, codeOffset);
988            break;
989        case OP_CMPL_FLOAT:
990        case OP_CMPG_FLOAT:
991        case OP_AGET:
992        case OP_AGET_OBJECT:
993        case OP_AGET_BOOLEAN:
994        case OP_AGET_BYTE:
995        case OP_AGET_CHAR:
996        case OP_AGET_SHORT:
997        case OP_APUT:
998        case OP_APUT_OBJECT:
999        case OP_APUT_BOOLEAN:
1000        case OP_APUT_BYTE:
1001        case OP_APUT_CHAR:
1002        case OP_APUT_SHORT:
1003        case OP_ADD_INT:
1004        case OP_SUB_INT:
1005        case OP_MUL_INT:
1006        case OP_DIV_INT:
1007        case OP_REM_INT:
1008        case OP_AND_INT:
1009        case OP_OR_INT:
1010        case OP_XOR_INT:
1011        case OP_SHL_INT:
1012        case OP_SHR_INT:
1013        case OP_USHR_INT:
1014        case OP_ADD_FLOAT:
1015        case OP_SUB_FLOAT:
1016        case OP_MUL_FLOAT:
1017        case OP_DIV_FLOAT:
1018        case OP_REM_FLOAT:
1019            okay &= checkRegisterIndex(meth, decInsn.vA);
1020            okay &= checkRegisterIndex(meth, decInsn.vB);
1021            okay &= checkRegisterIndex(meth, decInsn.vC);
1022            break;
1023        case OP_AGET_WIDE:
1024        case OP_APUT_WIDE:
1025            okay &= checkWideRegisterIndex(meth, decInsn.vA);
1026            okay &= checkRegisterIndex(meth, decInsn.vB);
1027            okay &= checkRegisterIndex(meth, decInsn.vC);
1028            break;
1029        case OP_CMPL_DOUBLE:
1030        case OP_CMPG_DOUBLE:
1031        case OP_CMP_LONG:
1032            okay &= checkRegisterIndex(meth, decInsn.vA);
1033            okay &= checkWideRegisterIndex(meth, decInsn.vB);
1034            okay &= checkWideRegisterIndex(meth, decInsn.vC);
1035            break;
1036        case OP_ADD_DOUBLE:
1037        case OP_SUB_DOUBLE:
1038        case OP_MUL_DOUBLE:
1039        case OP_DIV_DOUBLE:
1040        case OP_REM_DOUBLE:
1041        case OP_ADD_LONG:
1042        case OP_SUB_LONG:
1043        case OP_MUL_LONG:
1044        case OP_DIV_LONG:
1045        case OP_REM_LONG:
1046        case OP_AND_LONG:
1047        case OP_OR_LONG:
1048        case OP_XOR_LONG:
1049            okay &= checkWideRegisterIndex(meth, decInsn.vA);
1050            okay &= checkWideRegisterIndex(meth, decInsn.vB);
1051            okay &= checkWideRegisterIndex(meth, decInsn.vC);
1052            break;
1053        case OP_SHL_LONG:
1054        case OP_SHR_LONG:
1055        case OP_USHR_LONG:
1056            okay &= checkWideRegisterIndex(meth, decInsn.vA);
1057            okay &= checkWideRegisterIndex(meth, decInsn.vB);
1058            okay &= checkRegisterIndex(meth, decInsn.vC);
1059            break;
1060        case OP_IF_EQ:
1061        case OP_IF_NE:
1062        case OP_IF_LT:
1063        case OP_IF_GE:
1064        case OP_IF_GT:
1065        case OP_IF_LE:
1066            okay &= checkRegisterIndex(meth, decInsn.vA);
1067            okay &= checkRegisterIndex(meth, decInsn.vB);
1068            okay &= checkBranchTarget(meth, insnFlags, codeOffset, false);
1069            break;
1070        case OP_IF_EQZ:
1071        case OP_IF_NEZ:
1072        case OP_IF_LTZ:
1073        case OP_IF_GEZ:
1074        case OP_IF_GTZ:
1075        case OP_IF_LEZ:
1076            okay &= checkRegisterIndex(meth, decInsn.vA);
1077            okay &= checkBranchTarget(meth, insnFlags, codeOffset, false);
1078            break;
1079        case OP_IGET:
1080        case OP_IGET_JUMBO:
1081        case OP_IGET_OBJECT:
1082        case OP_IGET_OBJECT_JUMBO:
1083        case OP_IGET_BOOLEAN:
1084        case OP_IGET_BOOLEAN_JUMBO:
1085        case OP_IGET_BYTE:
1086        case OP_IGET_BYTE_JUMBO:
1087        case OP_IGET_CHAR:
1088        case OP_IGET_CHAR_JUMBO:
1089        case OP_IGET_SHORT:
1090        case OP_IGET_SHORT_JUMBO:
1091        case OP_IPUT:
1092        case OP_IPUT_JUMBO:
1093        case OP_IPUT_OBJECT:
1094        case OP_IPUT_OBJECT_JUMBO:
1095        case OP_IPUT_BOOLEAN:
1096        case OP_IPUT_BOOLEAN_JUMBO:
1097        case OP_IPUT_BYTE:
1098        case OP_IPUT_BYTE_JUMBO:
1099        case OP_IPUT_CHAR:
1100        case OP_IPUT_CHAR_JUMBO:
1101        case OP_IPUT_SHORT:
1102        case OP_IPUT_SHORT_JUMBO:
1103            okay &= checkRegisterIndex(meth, decInsn.vA);
1104            okay &= checkRegisterIndex(meth, decInsn.vB);
1105            okay &= checkFieldIndex(pDvmDex, decInsn.vC);
1106            break;
1107        case OP_IGET_WIDE:
1108        case OP_IGET_WIDE_JUMBO:
1109        case OP_IPUT_WIDE:
1110        case OP_IPUT_WIDE_JUMBO:
1111            okay &= checkWideRegisterIndex(meth, decInsn.vA);
1112            okay &= checkRegisterIndex(meth, decInsn.vB);
1113            okay &= checkFieldIndex(pDvmDex, decInsn.vC);
1114            break;
1115        case OP_SGET:
1116        case OP_SGET_JUMBO:
1117        case OP_SGET_OBJECT:
1118        case OP_SGET_OBJECT_JUMBO:
1119        case OP_SGET_BOOLEAN:
1120        case OP_SGET_BOOLEAN_JUMBO:
1121        case OP_SGET_BYTE:
1122        case OP_SGET_BYTE_JUMBO:
1123        case OP_SGET_CHAR:
1124        case OP_SGET_CHAR_JUMBO:
1125        case OP_SGET_SHORT:
1126        case OP_SGET_SHORT_JUMBO:
1127        case OP_SPUT:
1128        case OP_SPUT_JUMBO:
1129        case OP_SPUT_OBJECT:
1130        case OP_SPUT_OBJECT_JUMBO:
1131        case OP_SPUT_BOOLEAN:
1132        case OP_SPUT_BOOLEAN_JUMBO:
1133        case OP_SPUT_BYTE:
1134        case OP_SPUT_BYTE_JUMBO:
1135        case OP_SPUT_CHAR:
1136        case OP_SPUT_CHAR_JUMBO:
1137        case OP_SPUT_SHORT:
1138        case OP_SPUT_SHORT_JUMBO:
1139            okay &= checkRegisterIndex(meth, decInsn.vA);
1140            okay &= checkFieldIndex(pDvmDex, decInsn.vB);
1141            break;
1142        case OP_SGET_WIDE:
1143        case OP_SGET_WIDE_JUMBO:
1144        case OP_SPUT_WIDE:
1145        case OP_SPUT_WIDE_JUMBO:
1146            okay &= checkWideRegisterIndex(meth, decInsn.vA);
1147            okay &= checkFieldIndex(pDvmDex, decInsn.vB);
1148            break;
1149        case OP_FILLED_NEW_ARRAY:
1150            /* decoder uses B, not C, for type ref */
1151            okay &= checkTypeIndex(pDvmDex, decInsn.vB);
1152            okay &= checkVarargRegs(meth, &decInsn);
1153            break;
1154        case OP_FILLED_NEW_ARRAY_RANGE:
1155        case OP_FILLED_NEW_ARRAY_JUMBO:
1156            okay &= checkTypeIndex(pDvmDex, decInsn.vB);
1157            okay &= checkVarargRangeRegs(meth, &decInsn);
1158            break;
1159        case OP_INVOKE_VIRTUAL:
1160        case OP_INVOKE_SUPER:
1161        case OP_INVOKE_DIRECT:
1162        case OP_INVOKE_STATIC:
1163        case OP_INVOKE_INTERFACE:
1164            /* decoder uses B, not C, for type ref */
1165            okay &= checkMethodIndex(pDvmDex, decInsn.vB);
1166            okay &= checkVarargRegs(meth, &decInsn);
1167            break;
1168        case OP_INVOKE_VIRTUAL_RANGE:
1169        case OP_INVOKE_VIRTUAL_JUMBO:
1170        case OP_INVOKE_SUPER_RANGE:
1171        case OP_INVOKE_SUPER_JUMBO:
1172        case OP_INVOKE_DIRECT_RANGE:
1173        case OP_INVOKE_DIRECT_JUMBO:
1174        case OP_INVOKE_STATIC_RANGE:
1175        case OP_INVOKE_STATIC_JUMBO:
1176        case OP_INVOKE_INTERFACE_RANGE:
1177        case OP_INVOKE_INTERFACE_JUMBO:
1178            okay &= checkMethodIndex(pDvmDex, decInsn.vB);
1179            okay &= checkVarargRangeRegs(meth, &decInsn);
1180            break;
1181
1182        /* verifier/optimizer output; we should never see these */
1183        case OP_IGET_VOLATILE:
1184        case OP_IPUT_VOLATILE:
1185        case OP_SGET_VOLATILE:
1186        case OP_SPUT_VOLATILE:
1187        case OP_IGET_OBJECT_VOLATILE:
1188        case OP_IPUT_OBJECT_VOLATILE:
1189        case OP_SGET_OBJECT_VOLATILE:
1190        case OP_SPUT_OBJECT_VOLATILE:
1191        case OP_IGET_WIDE_VOLATILE:
1192        case OP_IPUT_WIDE_VOLATILE:
1193        case OP_SGET_WIDE_VOLATILE:
1194        case OP_SPUT_WIDE_VOLATILE:
1195        case OP_IGET_VOLATILE_JUMBO:
1196        case OP_IPUT_VOLATILE_JUMBO:
1197        case OP_SGET_VOLATILE_JUMBO:
1198        case OP_SPUT_VOLATILE_JUMBO:
1199        case OP_IGET_OBJECT_VOLATILE_JUMBO:
1200        case OP_IPUT_OBJECT_VOLATILE_JUMBO:
1201        case OP_SGET_OBJECT_VOLATILE_JUMBO:
1202        case OP_SPUT_OBJECT_VOLATILE_JUMBO:
1203        case OP_IGET_WIDE_VOLATILE_JUMBO:
1204        case OP_IPUT_WIDE_VOLATILE_JUMBO:
1205        case OP_SGET_WIDE_VOLATILE_JUMBO:
1206        case OP_SPUT_WIDE_VOLATILE_JUMBO:
1207        case OP_BREAKPOINT:
1208        case OP_THROW_VERIFICATION_ERROR:
1209        case OP_THROW_VERIFICATION_ERROR_JUMBO:
1210        case OP_EXECUTE_INLINE:
1211        case OP_EXECUTE_INLINE_RANGE:
1212        case OP_INVOKE_OBJECT_INIT_RANGE:
1213        case OP_INVOKE_OBJECT_INIT_JUMBO:
1214        case OP_RETURN_VOID_BARRIER:
1215        case OP_IGET_QUICK:
1216        case OP_IGET_WIDE_QUICK:
1217        case OP_IGET_OBJECT_QUICK:
1218        case OP_IPUT_QUICK:
1219        case OP_IPUT_WIDE_QUICK:
1220        case OP_IPUT_OBJECT_QUICK:
1221        case OP_INVOKE_VIRTUAL_QUICK:
1222        case OP_INVOKE_VIRTUAL_QUICK_RANGE:
1223        case OP_INVOKE_SUPER_QUICK:
1224        case OP_INVOKE_SUPER_QUICK_RANGE:
1225        case OP_UNUSED_3E:
1226        case OP_UNUSED_3F:
1227        case OP_UNUSED_40:
1228        case OP_UNUSED_41:
1229        case OP_UNUSED_42:
1230        case OP_UNUSED_43:
1231        case OP_UNUSED_73:
1232        case OP_UNUSED_79:
1233        case OP_UNUSED_7A:
1234        case OP_DISPATCH_FF:
1235        case OP_UNUSED_27FF:
1236        case OP_UNUSED_28FF:
1237        case OP_UNUSED_29FF:
1238        case OP_UNUSED_2AFF:
1239        case OP_UNUSED_2BFF:
1240        case OP_UNUSED_2CFF:
1241        case OP_UNUSED_2DFF:
1242        case OP_UNUSED_2EFF:
1243        case OP_UNUSED_2FFF:
1244        case OP_UNUSED_30FF:
1245        case OP_UNUSED_31FF:
1246        case OP_UNUSED_32FF:
1247        case OP_UNUSED_33FF:
1248        case OP_UNUSED_34FF:
1249        case OP_UNUSED_35FF:
1250        case OP_UNUSED_36FF:
1251        case OP_UNUSED_37FF:
1252        case OP_UNUSED_38FF:
1253        case OP_UNUSED_39FF:
1254        case OP_UNUSED_3AFF:
1255        case OP_UNUSED_3BFF:
1256        case OP_UNUSED_3CFF:
1257        case OP_UNUSED_3DFF:
1258        case OP_UNUSED_3EFF:
1259        case OP_UNUSED_3FFF:
1260        case OP_UNUSED_40FF:
1261        case OP_UNUSED_41FF:
1262        case OP_UNUSED_42FF:
1263        case OP_UNUSED_43FF:
1264        case OP_UNUSED_44FF:
1265        case OP_UNUSED_45FF:
1266        case OP_UNUSED_46FF:
1267        case OP_UNUSED_47FF:
1268        case OP_UNUSED_48FF:
1269        case OP_UNUSED_49FF:
1270        case OP_UNUSED_4AFF:
1271        case OP_UNUSED_4BFF:
1272        case OP_UNUSED_4CFF:
1273        case OP_UNUSED_4DFF:
1274        case OP_UNUSED_4EFF:
1275        case OP_UNUSED_4FFF:
1276        case OP_UNUSED_50FF:
1277        case OP_UNUSED_51FF:
1278        case OP_UNUSED_52FF:
1279        case OP_UNUSED_53FF:
1280        case OP_UNUSED_54FF:
1281        case OP_UNUSED_55FF:
1282        case OP_UNUSED_56FF:
1283        case OP_UNUSED_57FF:
1284        case OP_UNUSED_58FF:
1285        case OP_UNUSED_59FF:
1286        case OP_UNUSED_5AFF:
1287        case OP_UNUSED_5BFF:
1288        case OP_UNUSED_5CFF:
1289        case OP_UNUSED_5DFF:
1290        case OP_UNUSED_5EFF:
1291        case OP_UNUSED_5FFF:
1292        case OP_UNUSED_60FF:
1293        case OP_UNUSED_61FF:
1294        case OP_UNUSED_62FF:
1295        case OP_UNUSED_63FF:
1296        case OP_UNUSED_64FF:
1297        case OP_UNUSED_65FF:
1298        case OP_UNUSED_66FF:
1299        case OP_UNUSED_67FF:
1300        case OP_UNUSED_68FF:
1301        case OP_UNUSED_69FF:
1302        case OP_UNUSED_6AFF:
1303        case OP_UNUSED_6BFF:
1304        case OP_UNUSED_6CFF:
1305        case OP_UNUSED_6DFF:
1306        case OP_UNUSED_6EFF:
1307        case OP_UNUSED_6FFF:
1308        case OP_UNUSED_70FF:
1309        case OP_UNUSED_71FF:
1310        case OP_UNUSED_72FF:
1311        case OP_UNUSED_73FF:
1312        case OP_UNUSED_74FF:
1313        case OP_UNUSED_75FF:
1314        case OP_UNUSED_76FF:
1315        case OP_UNUSED_77FF:
1316        case OP_UNUSED_78FF:
1317        case OP_UNUSED_79FF:
1318        case OP_UNUSED_7AFF:
1319        case OP_UNUSED_7BFF:
1320        case OP_UNUSED_7CFF:
1321        case OP_UNUSED_7DFF:
1322        case OP_UNUSED_7EFF:
1323        case OP_UNUSED_7FFF:
1324        case OP_UNUSED_80FF:
1325        case OP_UNUSED_81FF:
1326        case OP_UNUSED_82FF:
1327        case OP_UNUSED_83FF:
1328        case OP_UNUSED_84FF:
1329        case OP_UNUSED_85FF:
1330        case OP_UNUSED_86FF:
1331        case OP_UNUSED_87FF:
1332        case OP_UNUSED_88FF:
1333        case OP_UNUSED_89FF:
1334        case OP_UNUSED_8AFF:
1335        case OP_UNUSED_8BFF:
1336        case OP_UNUSED_8CFF:
1337        case OP_UNUSED_8DFF:
1338        case OP_UNUSED_8EFF:
1339        case OP_UNUSED_8FFF:
1340        case OP_UNUSED_90FF:
1341        case OP_UNUSED_91FF:
1342        case OP_UNUSED_92FF:
1343        case OP_UNUSED_93FF:
1344        case OP_UNUSED_94FF:
1345        case OP_UNUSED_95FF:
1346        case OP_UNUSED_96FF:
1347        case OP_UNUSED_97FF:
1348        case OP_UNUSED_98FF:
1349        case OP_UNUSED_99FF:
1350        case OP_UNUSED_9AFF:
1351        case OP_UNUSED_9BFF:
1352        case OP_UNUSED_9CFF:
1353        case OP_UNUSED_9DFF:
1354        case OP_UNUSED_9EFF:
1355        case OP_UNUSED_9FFF:
1356        case OP_UNUSED_A0FF:
1357        case OP_UNUSED_A1FF:
1358        case OP_UNUSED_A2FF:
1359        case OP_UNUSED_A3FF:
1360        case OP_UNUSED_A4FF:
1361        case OP_UNUSED_A5FF:
1362        case OP_UNUSED_A6FF:
1363        case OP_UNUSED_A7FF:
1364        case OP_UNUSED_A8FF:
1365        case OP_UNUSED_A9FF:
1366        case OP_UNUSED_AAFF:
1367        case OP_UNUSED_ABFF:
1368        case OP_UNUSED_ACFF:
1369        case OP_UNUSED_ADFF:
1370        case OP_UNUSED_AEFF:
1371        case OP_UNUSED_AFFF:
1372        case OP_UNUSED_B0FF:
1373        case OP_UNUSED_B1FF:
1374        case OP_UNUSED_B2FF:
1375        case OP_UNUSED_B3FF:
1376        case OP_UNUSED_B4FF:
1377        case OP_UNUSED_B5FF:
1378        case OP_UNUSED_B6FF:
1379        case OP_UNUSED_B7FF:
1380        case OP_UNUSED_B8FF:
1381        case OP_UNUSED_B9FF:
1382        case OP_UNUSED_BAFF:
1383        case OP_UNUSED_BBFF:
1384        case OP_UNUSED_BCFF:
1385        case OP_UNUSED_BDFF:
1386        case OP_UNUSED_BEFF:
1387        case OP_UNUSED_BFFF:
1388        case OP_UNUSED_C0FF:
1389        case OP_UNUSED_C1FF:
1390        case OP_UNUSED_C2FF:
1391        case OP_UNUSED_C3FF:
1392        case OP_UNUSED_C4FF:
1393        case OP_UNUSED_C5FF:
1394        case OP_UNUSED_C6FF:
1395        case OP_UNUSED_C7FF:
1396        case OP_UNUSED_C8FF:
1397        case OP_UNUSED_C9FF:
1398        case OP_UNUSED_CAFF:
1399        case OP_UNUSED_CBFF:
1400        case OP_UNUSED_CCFF:
1401        case OP_UNUSED_CDFF:
1402        case OP_UNUSED_CEFF:
1403        case OP_UNUSED_CFFF:
1404        case OP_UNUSED_D0FF:
1405        case OP_UNUSED_D1FF:
1406        case OP_UNUSED_D2FF:
1407        case OP_UNUSED_D3FF:
1408        case OP_UNUSED_D4FF:
1409        case OP_UNUSED_D5FF:
1410        case OP_UNUSED_D6FF:
1411        case OP_UNUSED_D7FF:
1412        case OP_UNUSED_D8FF:
1413        case OP_UNUSED_D9FF:
1414        case OP_UNUSED_DAFF:
1415        case OP_UNUSED_DBFF:
1416        case OP_UNUSED_DCFF:
1417        case OP_UNUSED_DDFF:
1418        case OP_UNUSED_DEFF:
1419        case OP_UNUSED_DFFF:
1420        case OP_UNUSED_E0FF:
1421        case OP_UNUSED_E1FF:
1422        case OP_UNUSED_E2FF:
1423        case OP_UNUSED_E3FF:
1424        case OP_UNUSED_E4FF:
1425        case OP_UNUSED_E5FF:
1426        case OP_UNUSED_E6FF:
1427        case OP_UNUSED_E7FF:
1428        case OP_UNUSED_E8FF:
1429        case OP_UNUSED_E9FF:
1430        case OP_UNUSED_EAFF:
1431        case OP_UNUSED_EBFF:
1432        case OP_UNUSED_ECFF:
1433        case OP_UNUSED_EDFF:
1434        case OP_UNUSED_EEFF:
1435        case OP_UNUSED_EFFF:
1436        case OP_UNUSED_F0FF:
1437        case OP_UNUSED_F1FF:
1438            LOGE("VFY: unexpected opcode %04x", decInsn.opcode);
1439            okay = false;
1440            break;
1441
1442        /*
1443         * DO NOT add a "default" clause here.  Without it the compiler will
1444         * complain if an instruction is missing (which is desirable).
1445         */
1446        }
1447
1448        if (!okay) {
1449            LOG_VFY_METH(meth, "VFY:  rejecting opcode 0x%02x at 0x%04x",
1450                decInsn.opcode, codeOffset);
1451            return false;
1452        }
1453
1454        OpcodeFlags opFlags = dexGetFlagsFromOpcode(decInsn.opcode);
1455        if ((opFlags & VERIFY_GC_INST_MASK) != 0) {
1456            /*
1457             * This instruction is a GC point.  If space is a concern,
1458             * the set of GC points could be reduced by eliminating
1459             * foward branches.
1460             *
1461             * TODO: we could also scan the targets of a "switch" statement,
1462             * and if none of them branch backward we could ignore that
1463             * instruction as well.
1464             */
1465            dvmInsnSetGcPoint(insnFlags, codeOffset, true);
1466        }
1467
1468        assert(width > 0);
1469        codeOffset += width;
1470        insns += width;
1471    }
1472
1473    /* make sure the last instruction ends at the end of the insn area */
1474    if (codeOffset != vdata->insnsSize) {
1475        LOG_VFY_METH(meth,
1476            "VFY: code did not end when expected (end at %d, count %d)\n",
1477            codeOffset, vdata->insnsSize);
1478        return false;
1479    }
1480
1481    return true;
1482}
1483