2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Dalvik classfile verification. This file contains the verifier entry
19 * points and the static constraint checks.
22 #include "analysis/CodeVerify.h"
26 static bool verifyMethod(Method* meth, int verifyFlags);
27 static bool verifyInstructions(const Method* meth, InsnFlags* insnFlags,
32 * Initialize some things we need for verification.
34 bool dvmVerificationStartup(void)
36 gDvm.instrWidth = dexCreateInstrWidthTable();
37 gDvm.instrFormat = dexCreateInstrFormatTable();
38 gDvm.instrFlags = dexCreateInstrFlagsTable();
39 if (gDvm.instrWidth == NULL || gDvm.instrFormat == NULL ||
40 gDvm.instrFlags == NULL)
42 LOGE("Unable to create instruction tables\n");
50 * Free up some things we needed for verification.
52 void dvmVerificationShutdown(void)
54 free(gDvm.instrWidth);
55 free(gDvm.instrFormat);
56 free(gDvm.instrFlags);
60 * Induce verification on all classes loaded from this DEX file as part
61 * of pre-verification and optimization. This is never called from a
62 * normally running VM.
64 * Returns "true" when all classes have been processed.
66 bool dvmVerifyAllClasses(DexFile* pDexFile)
68 u4 count = pDexFile->pHeader->classDefsSize;
71 assert(gDvm.optimizing);
73 if (gDvm.classVerifyMode == VERIFY_MODE_NONE) {
74 LOGV("+++ verification is disabled, skipping all classes\n");
77 if (gDvm.classVerifyMode == VERIFY_MODE_REMOTE &&
78 gDvm.optimizingBootstrapClass)
80 LOGV("+++ verification disabled for bootstrap classes\n");
84 for (idx = 0; idx < count; idx++) {
85 const DexClassDef* pClassDef;
86 const char* classDescriptor;
89 pClassDef = dexGetClassDef(pDexFile, idx);
90 classDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->classIdx);
92 /* all classes are loaded into the bootstrap class loader */
93 clazz = dvmLookupClass(classDescriptor, NULL, false);
95 if (clazz->pDvmDex->pDexFile != pDexFile) {
96 LOGD("DexOpt: not verifying '%s': multiple definitions\n",
99 if (dvmVerifyClass(clazz, VERIFY_DEFAULT)) {
100 assert((clazz->accessFlags & JAVA_FLAGS_MASK) ==
101 pClassDef->accessFlags);
102 ((DexClassDef*)pClassDef)->accessFlags |=
105 /* keep going even if one fails */
108 LOGV("DexOpt: +++ not verifying '%s'\n", classDescriptor);
118 * By the time we get here, the value of gDvm.classVerifyMode should already
119 * have been factored in. If you want to call into the verifier even
120 * though verification is disabled, that's your business.
122 * Returns "true" on success.
124 bool dvmVerifyClass(ClassObject* clazz, int verifyFlags)
128 if (dvmIsClassVerified(clazz)) {
129 LOGD("Ignoring duplicate verify attempt on %s\n", clazz->descriptor);
133 //LOGI("Verify1 '%s'\n", clazz->descriptor);
135 // TODO - verify class structure in DEX?
137 for (i = 0; i < clazz->directMethodCount; i++) {
138 if (!verifyMethod(&clazz->directMethods[i], verifyFlags)) {
139 LOG_VFY("Verifier rejected class %s\n", clazz->descriptor);
143 for (i = 0; i < clazz->virtualMethodCount; i++) {
144 if (!verifyMethod(&clazz->virtualMethods[i], verifyFlags)) {
145 LOG_VFY("Verifier rejected class %s\n", clazz->descriptor);
154 * Temporarily "undo" any breakpoints found in this method. There is no risk
155 * of confusing the interpreter, because unverified code cannot be executed.
157 * Breakpoints can be set after a class is loaded but before it has been
160 * The "breakpoint" opcode can replace any other opcode, leaving no
161 * indication of the original instruction's width or purpose in the
162 * instruction stream. We either have to quietly undo the breakpoints
163 * before verification, or look up the original opcode whenever we need it.
164 * The latter is more efficient since we only slow down on code that
165 * actually has breakpoints, but it requires explicit handling in every
166 * function that examines the instruction stream.
168 * We need to ensure that the debugger doesn't insert any additional
169 * breakpoints while we work. This either requires holding a lock on the
170 * breakpoint set throughout the verification of this method, or adding a
171 * "do not touch anything on these pages" list to the set. Either way,
172 * the caller of this method must ensure that it calls "redo" to release
175 * A debugger could connect while we work, so we return without doing
176 * anything if a debugger doesn't happen to be connected now. We can only
177 * avoid doing work if the debugger thread isn't running (dexopt, zygote,
178 * or debugging not configured).
180 * Returns "false" if we did nothing, "true" if we did stuff (and, hence,
181 * need to call "redo" at some point).
183 static bool undoBreakpoints(Method* meth)
186 if (gDvm.optimizing || gDvm.zygote || !gDvm.jdwpConfigured)
188 dvmUndoBreakpoints(meth);
196 * Restore any breakpoints we undid previously. Also has to update the
197 * stored "original opcode" value for any instruction that we replaced
198 * with a throw-verification-error op.
200 static void redoBreakpoints(Method* meth)
203 if (gDvm.optimizing || gDvm.zygote || !gDvm.jdwpConfigured) {
204 /* should not be here */
208 dvmRedoBreakpoints(meth);
215 * Perform verification on a single method.
217 * We do this in three passes:
218 * (1) Walk through all code units, determining instruction lengths.
219 * (2) Do static checks, including branch target and operand validation.
220 * (3) Do structural checks, including data-flow analysis.
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.
225 * - operands of getfield, putfield, getstatic, putstatic must be valid
226 * - operands of method invocation instructions must be valid
228 * - code array must not be empty
229 * - (N/A) code_length must be less than 65536
230 * - opcode of first instruction begins at index 0
231 * - only documented instructions may appear
232 * - each instruction follows the last
233 * - (below) last byte of last instruction is at (code_length-1)
235 static bool verifyMethod(Method* meth, int verifyFlags)
238 UninitInstanceMap* uninitMap = NULL;
239 InsnFlags* insnFlags = NULL;
240 int i, newInstanceCount;
241 bool undidBreakpoints;
243 undidBreakpoints = undoBreakpoints(meth);
246 * If there aren't any instructions, make sure that's expected, then
247 * exit successfully. Note: meth->insns gets set to a native function
248 * pointer on first call.
250 if (dvmGetMethodInsnsSize(meth) == 0) {
251 if (!dvmIsNativeMethod(meth) && !dvmIsAbstractMethod(meth)) {
253 "VFY: zero-length code in concrete non-native method\n");
261 * Sanity-check the register counts. ins + locals = registers, so make
262 * sure that ins <= registers.
264 if (meth->insSize > meth->registersSize) {
265 LOG_VFY_METH(meth, "VFY: bad register counts (ins=%d regs=%d)\n",
266 meth->insSize, meth->registersSize);
271 * Allocate and populate an array to hold instruction data.
273 * TODO: Consider keeping a reusable pre-allocated array sitting
274 * around for smaller methods.
276 insnFlags = (InsnFlags*)
277 calloc(dvmGetMethodInsnsSize(meth), sizeof(InsnFlags));
278 if (insnFlags == NULL)
282 * Compute the width of each instruction and store the result in insnFlags.
283 * Count up the #of occurrences of new-instance instructions while we're
286 if (!dvmComputeCodeWidths(meth, insnFlags, &newInstanceCount))
290 * Allocate a map to hold the classes of uninitialized instances.
292 uninitMap = dvmCreateUninitInstanceMap(meth, insnFlags, newInstanceCount);
293 if (uninitMap == NULL)
297 * Set the "in try" flags for all instructions guarded by a "try" block.
299 if (!dvmSetTryFlags(meth, insnFlags))
303 * Perform static instruction verification.
305 if (!verifyInstructions(meth, insnFlags, verifyFlags))
309 * Do code-flow analysis. Do this after verifying the branch targets
310 * so we don't need to worry about it here.
312 * If there are no registers, we don't need to do much in the way of
313 * analysis, but we still need to verify that nothing actually tries
316 if (!dvmVerifyCodeFlow(meth, insnFlags, uninitMap)) {
317 //LOGD("+++ %s failed code flow\n", meth->name);
325 if (undidBreakpoints)
326 redoBreakpoints(meth);
327 dvmFreeUninitInstanceMap(uninitMap);
334 * Verify an array data table. "curOffset" is the offset of the fill-array-data
337 static bool checkArrayData(const Method* meth, int curOffset)
339 const int insnCount = dvmGetMethodInsnsSize(meth);
340 const u2* insns = meth->insns + curOffset;
342 int valueCount, valueWidth, tableSize;
343 int offsetToArrayData;
345 assert(curOffset >= 0 && curOffset < insnCount);
347 /* make sure the start of the array data table is in range */
348 offsetToArrayData = insns[1] | (((s4)insns[2]) << 16);
349 if (curOffset + offsetToArrayData < 0 ||
350 curOffset + offsetToArrayData + 2 >= insnCount)
353 "VFY: invalid array data start: at %d, data offset %d, count %d\n",
354 curOffset, offsetToArrayData, insnCount);
358 /* offset to array data table is a relative branch-style offset */
359 arrayData = insns + offsetToArrayData;
361 /* make sure the table is 32-bit aligned */
362 if ((((u4) arrayData) & 0x03) != 0) {
364 "VFY: unaligned array data table: at %d, data offset %d\n",
365 curOffset, offsetToArrayData);
369 valueWidth = arrayData[1];
370 valueCount = *(u4*)(&arrayData[2]);
372 tableSize = 4 + (valueWidth * valueCount + 1) / 2;
374 /* make sure the end of the switch is in range */
375 if (curOffset + offsetToArrayData + tableSize > insnCount) {
377 "VFY: invalid array data end: at %d, data offset %d, end %d, "
379 curOffset, offsetToArrayData,
380 curOffset + offsetToArrayData + tableSize,
390 * Decode the current instruction.
392 static void decodeInstruction(const Method* meth, int insnIdx,
393 DecodedInstruction* pDecInsn)
395 dexDecodeInstruction(gDvm.instrFormat, meth->insns + insnIdx, pDecInsn);
400 * Perform static checks on a "new-instance" instruction. Specifically,
401 * make sure the class reference isn't for an array class.
403 * We don't need the actual class, just a pointer to the class name.
405 static bool checkNewInstance(const Method* meth, int insnIdx)
407 DvmDex* pDvmDex = meth->clazz->pDvmDex;
408 DecodedInstruction decInsn;
409 const char* classDescriptor;
412 decodeInstruction(meth, insnIdx, &decInsn);
413 idx = decInsn.vB; // 2nd item
414 if (idx >= pDvmDex->pHeader->typeIdsSize) {
415 LOG_VFY_METH(meth, "VFY: bad type index %d (max %d)\n",
416 idx, pDvmDex->pHeader->typeIdsSize);
420 classDescriptor = dexStringByTypeIdx(pDvmDex->pDexFile, idx);
421 if (classDescriptor[0] != 'L') {
422 LOG_VFY_METH(meth, "VFY: can't call new-instance on type '%s'\n",
431 * Perform static checks on a "new-array" instruction. Specifically, make
432 * sure they aren't creating an array of arrays that causes the number of
433 * dimensions to exceed 255.
435 static bool checkNewArray(const Method* meth, int insnIdx)
437 DvmDex* pDvmDex = meth->clazz->pDvmDex;
438 DecodedInstruction decInsn;
439 const char* classDescriptor;
442 decodeInstruction(meth, insnIdx, &decInsn);
443 idx = decInsn.vC; // 3rd item
444 if (idx >= pDvmDex->pHeader->typeIdsSize) {
445 LOG_VFY_METH(meth, "VFY: bad type index %d (max %d)\n",
446 idx, pDvmDex->pHeader->typeIdsSize);
450 classDescriptor = dexStringByTypeIdx(pDvmDex->pDexFile, idx);
452 int bracketCount = 0;
453 const char* cp = classDescriptor;
457 if (bracketCount == 0) {
458 /* The given class must be an array type. */
459 LOG_VFY_METH(meth, "VFY: can't new-array class '%s' (not an array)\n",
462 } else if (bracketCount > 255) {
463 /* It is illegal to create an array of more than 255 dimensions. */
464 LOG_VFY_METH(meth, "VFY: can't new-array class '%s' (exceeds limit)\n",
473 * Perform static checks on an instruction that takes a class constant.
474 * Ensure that the class index is in the valid range.
476 static bool checkTypeIndex(const Method* meth, int insnIdx, bool useB)
478 DvmDex* pDvmDex = meth->clazz->pDvmDex;
479 DecodedInstruction decInsn;
482 decodeInstruction(meth, insnIdx, &decInsn);
487 if (idx >= pDvmDex->pHeader->typeIdsSize) {
488 LOG_VFY_METH(meth, "VFY: bad type index %d (max %d)\n",
489 idx, pDvmDex->pHeader->typeIdsSize);
497 * Perform static checks on a field get or set instruction. All we do
498 * here is ensure that the field index is in the valid range.
500 static bool checkFieldIndex(const Method* meth, int insnIdx, bool useB)
502 DvmDex* pDvmDex = meth->clazz->pDvmDex;
503 DecodedInstruction decInsn;
506 decodeInstruction(meth, insnIdx, &decInsn);
511 if (idx >= pDvmDex->pHeader->fieldIdsSize) {
513 "VFY: bad field index %d (max %d) at offset 0x%04x\n",
514 idx, pDvmDex->pHeader->fieldIdsSize, insnIdx);
522 * Perform static checks on a method invocation instruction. All we do
523 * here is ensure that the method index is in the valid range.
525 static bool checkMethodIndex(const Method* meth, int insnIdx)
527 DvmDex* pDvmDex = meth->clazz->pDvmDex;
528 DecodedInstruction decInsn;
530 decodeInstruction(meth, insnIdx, &decInsn);
531 if (decInsn.vB >= pDvmDex->pHeader->methodIdsSize) {
532 LOG_VFY_METH(meth, "VFY: bad method index %d (max %d)\n",
533 decInsn.vB, pDvmDex->pHeader->methodIdsSize);
541 * Perform static checks on a string constant instruction. All we do
542 * here is ensure that the string index is in the valid range.
544 static bool checkStringIndex(const Method* meth, int insnIdx)
546 DvmDex* pDvmDex = meth->clazz->pDvmDex;
547 DecodedInstruction decInsn;
549 decodeInstruction(meth, insnIdx, &decInsn);
550 if (decInsn.vB >= pDvmDex->pHeader->stringIdsSize) {
551 LOG_VFY_METH(meth, "VFY: bad string index %d (max %d)\n",
552 decInsn.vB, pDvmDex->pHeader->stringIdsSize);
560 * Perform static verification on instructions.
562 * As a side effect, this sets the "branch target" flags in InsnFlags.
564 * "(CF)" items are handled during code-flow analysis.
567 * - target of each jump and branch instruction must be valid
568 * - targets of switch statements must be valid
569 * - (CF) operands referencing constant pool entries must be valid
570 * - (CF) operands of getfield, putfield, getstatic, putstatic must be valid
571 * - (new) verify operands of "quick" field ops
572 * - (CF) operands of method invocation instructions must be valid
573 * - (new) verify operands of "quick" method invoke ops
574 * - (CF) only invoke-direct can call a method starting with '<'
575 * - (CF) <clinit> must never be called explicitly
576 * - (CF) operands of instanceof, checkcast, new (and variants) must be valid
577 * - new-array[-type] limited to 255 dimensions
578 * - can't use "new" on an array class
579 * - (?) limit dimensions in multi-array creation
580 * - (CF) local variable load/store register values must be in valid range
583 * - branches must be within the bounds of the code array
584 * - targets of all control-flow instructions are the start of an instruction
585 * - (CF) register accesses fall within range of allocated registers
586 * - (N/A) access to constant pool must be of appropriate type
587 * - (CF) code does not end in the middle of an instruction
588 * - (CF) execution cannot fall off the end of the code
589 * - (earlier) for each exception handler, the "try" area must begin and
590 * end at the start of an instruction (end can be at the end of the code)
591 * - (earlier) for each exception handler, the handler must start at a valid
594 * TODO: move some of the "CF" items in here for better performance (the
595 * code-flow analysis sometimes has to process the same instruction several
598 static bool verifyInstructions(const Method* meth, InsnFlags* insnFlags,
601 const int insnCount = dvmGetMethodInsnsSize(meth);
602 const u2* insns = meth->insns;
605 /* the start of the method is a "branch target" */
606 dvmInsnSetBranchTarget(insnFlags, 0, true);
608 for (i = 0; i < insnCount; /**/) {
610 * These types of instructions can be GC points. To support precise
611 * GC, all such instructions must export the PC in the interpreter,
612 * or the GC won't be able to identify the current PC for the thread.
614 static const int gcMask = kInstrCanBranch | kInstrCanSwitch |
615 kInstrCanThrow | kInstrCanReturn;
617 int width = dvmInsnGetWidth(insnFlags, i);
618 OpCode opcode = *insns & 0xff;
619 InstructionFlags opFlags = dexGetInstrFlags(gDvm.instrFlags, opcode);
620 int offset, absOffset;
622 if ((opFlags & gcMask) != 0) {
624 * This instruction is probably a GC point. Branch instructions
625 * only qualify if they go backward, so we need to check the
630 if (dvmGetBranchTarget(meth, insnFlags, i, &offset, &unused)) {
632 dvmInsnSetGcPoint(insnFlags, i, true);
635 /* not a branch target */
636 dvmInsnSetGcPoint(insnFlags, i, true);
642 /* plain no-op or switch table data; nothing to do here */
645 case OP_CONST_STRING:
646 case OP_CONST_STRING_JUMBO:
647 if (!checkStringIndex(meth, i))
653 if (!checkTypeIndex(meth, i, true))
657 if (!checkTypeIndex(meth, i, false))
661 case OP_PACKED_SWITCH:
662 case OP_SPARSE_SWITCH:
663 /* verify the associated table */
664 if (!dvmCheckSwitchTargets(meth, insnFlags, i))
668 case OP_FILL_ARRAY_DATA:
669 /* verify the associated table */
670 if (!checkArrayData(meth, i))
688 /* check the destination */
689 if (!dvmCheckBranchTarget(meth, insnFlags, i, false))
693 /* check the destination; self-branch is okay */
694 if (!dvmCheckBranchTarget(meth, insnFlags, i, true))
698 case OP_NEW_INSTANCE:
699 if (!checkNewInstance(meth, i))
704 if (!checkNewArray(meth, i))
708 case OP_FILLED_NEW_ARRAY:
709 if (!checkTypeIndex(meth, i, true))
712 case OP_FILLED_NEW_ARRAY_RANGE:
713 if (!checkTypeIndex(meth, i, true))
720 case OP_IGET_BOOLEAN:
727 case OP_IPUT_BOOLEAN:
731 /* check the field index */
732 if (!checkFieldIndex(meth, i, false))
738 case OP_SGET_BOOLEAN:
745 case OP_SPUT_BOOLEAN:
749 /* check the field index */
750 if (!checkFieldIndex(meth, i, true))
754 case OP_INVOKE_VIRTUAL:
755 case OP_INVOKE_SUPER:
756 case OP_INVOKE_DIRECT:
757 case OP_INVOKE_STATIC:
758 case OP_INVOKE_INTERFACE:
759 case OP_INVOKE_VIRTUAL_RANGE:
760 case OP_INVOKE_SUPER_RANGE:
761 case OP_INVOKE_DIRECT_RANGE:
762 case OP_INVOKE_STATIC_RANGE:
763 case OP_INVOKE_INTERFACE_RANGE:
764 /* check the method index */
765 if (!checkMethodIndex(meth, i))
769 case OP_EXECUTE_INLINE:
770 case OP_INVOKE_DIRECT_EMPTY:
772 case OP_IGET_WIDE_QUICK:
773 case OP_IGET_OBJECT_QUICK:
775 case OP_IPUT_WIDE_QUICK:
776 case OP_IPUT_OBJECT_QUICK:
777 case OP_INVOKE_VIRTUAL_QUICK:
778 case OP_INVOKE_VIRTUAL_QUICK_RANGE:
779 case OP_INVOKE_SUPER_QUICK:
780 case OP_INVOKE_SUPER_QUICK_RANGE:
781 if ((verifyFlags & VERIFY_ALLOW_OPT_INSTRS) == 0) {
782 LOG_VFY("VFY: not expecting optimized instructions\n");
797 /* make sure the last instruction ends at the end of the insn area */
798 if (i != insnCount) {
800 "VFY: code did not end when expected (end at %d, count %d)\n",