• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
27 static bool verifyMethod(Method* meth);
28 static 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  */
dvmVerifyClass(ClassObject * clazz)40 bool 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  */
computeWidthsAndCountOps(VerifierData * vdata)83 static 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)", 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 
124 bail:
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  */
scanTryCatchBlocks(const Method * meth,InsnFlags * insnFlags)137 static 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)",
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)",
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)",
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  */
verifyMethod(Method * meth)235 static 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");
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 
331 success:
332     result = true;
333 
334 bail:
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  */
checkArrayData(const Method * meth,u4 curOffset)346 static 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",
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",
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  */
checkNewInstance(const DvmDex * pDvmDex,u4 idx)400 static 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  */
checkNewArray(const DvmDex * pDvmDex,u4 idx)425 static 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  */
checkTypeIndex(const DvmDex * pDvmDex,u4 idx)461 static 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  */
checkFieldIndex(const DvmDex * pDvmDex,u4 idx)475 static 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  */
checkMethodIndex(const DvmDex * pDvmDex,u4 idx)489 static 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  */
checkStringIndex(const DvmDex * pDvmDex,u4 idx)502 static 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  */
checkRegisterIndex(const Method * meth,u4 idx)515 static 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  */
checkWideRegisterIndex(const Method * meth,u4 idx)528 static 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  */
checkVarargRegs(const Method * meth,const DecodedInstruction * pDecInsn)549 static 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  */
checkVarargRangeRegs(const Method * meth,const DecodedInstruction * pDecInsn)578 static 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  */
checkSwitchTargets(const Method * meth,InsnFlags * insnFlags,u4 curOffset)602 static 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",
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",
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  */
checkBranchTarget(const Method * meth,InsnFlags * insnFlags,int curOffset,bool selfOkay)717 static 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",
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  */
verifyInstructions(VerifierData * vdata)794 static 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)",
1477             codeOffset, vdata->insnsSize);
1478         return false;
1479     }
1480 
1481     return true;
1482 }
1483