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 return (gDvm.instrWidth != NULL && gDvm.instrFormat!= NULL);
43 * Initialize some things we need for verification.
45 void dvmVerificationShutdown(void)
47 free(gDvm.instrWidth);
48 free(gDvm.instrFormat);
49 free(gDvm.instrFlags);
53 * Induce verification on all classes loaded from this DEX file as part
54 * of pre-verification and optimization. This is never called from a
55 * normally running VM.
57 * Returns "true" when all classes have been processed.
59 bool dvmVerifyAllClasses(DexFile* pDexFile)
61 u4 count = pDexFile->pHeader->classDefsSize;
64 assert(gDvm.optimizing);
66 if (gDvm.classVerifyMode == VERIFY_MODE_NONE) {
67 LOGV("+++ verification is disabled, skipping all classes\n");
70 if (gDvm.classVerifyMode == VERIFY_MODE_REMOTE &&
71 gDvm.optimizingBootstrapClass)
73 LOGV("+++ verification disabled for bootstrap classes\n");
77 for (idx = 0; idx < count; idx++) {
78 const DexClassDef* pClassDef;
79 const char* classDescriptor;
82 pClassDef = dexGetClassDef(pDexFile, idx);
83 classDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->classIdx);
85 /* all classes are loaded into the bootstrap class loader */
86 clazz = dvmLookupClass(classDescriptor, NULL, false);
88 if (clazz->pDvmDex->pDexFile != pDexFile) {
89 LOGD("DexOpt: not verifying '%s': multiple definitions\n",
92 if (dvmVerifyClass(clazz, VERIFY_DEFAULT)) {
93 assert((clazz->accessFlags & JAVA_FLAGS_MASK) ==
94 pClassDef->accessFlags);
95 ((DexClassDef*)pClassDef)->accessFlags |=
98 /* keep going even if one fails */
101 LOGV("DexOpt: +++ not verifying '%s'\n", classDescriptor);
111 * By the time we get here, the value of gDvm.classVerifyMode should already
112 * have been factored in. If you want to call into the verifier even
113 * though verification is disabled, that's your business.
115 * Returns "true" on success.
117 bool dvmVerifyClass(ClassObject* clazz, int verifyFlags)
121 if (dvmIsClassVerified(clazz)) {
122 LOGD("Ignoring duplicate verify attempt on %s\n", clazz->descriptor);
126 //LOGI("Verify1 '%s'\n", clazz->descriptor);
128 // TODO - verify class structure in DEX?
130 for (i = 0; i < clazz->directMethodCount; i++) {
131 if (!verifyMethod(&clazz->directMethods[i], verifyFlags)) {
132 LOG_VFY("Verifier rejected class %s\n", clazz->descriptor);
136 for (i = 0; i < clazz->virtualMethodCount; i++) {
137 if (!verifyMethod(&clazz->virtualMethods[i], verifyFlags)) {
138 LOG_VFY("Verifier rejected class %s\n", clazz->descriptor);
147 * Perform verification on a single method.
149 * We do this in three passes:
150 * (1) Walk through all code units, determining instruction lengths.
151 * (2) Do static checks, including branch target and operand validation.
152 * (3) Do structural checks, including data-flow analysis.
154 * Some checks may be bypassed depending on the verification mode. We can't
155 * turn this stuff off completely if we want to do "exact" GC.
157 * - operands of getfield, putfield, getstatic, putstatic must be valid
158 * - operands of method invocation instructions must be valid
160 * - code array must not be empty
161 * - (N/A) code_length must be less than 65536
162 * - opcode of first instruction begins at index 0
163 * - only documented instructions may appear
164 * - each instruction follows the last
165 * - (below) last byte of last instruction is at (code_length-1)
167 static bool verifyMethod(Method* meth, int verifyFlags)
170 UninitInstanceMap* uninitMap = NULL;
171 InsnFlags* insnFlags = NULL;
172 int i, newInstanceCount;
175 * If there aren't any instructions, make sure that's expected, then
176 * exit successfully. Note: meth->insns gets set to a native function
177 * pointer on first call.
179 if (dvmGetMethodInsnsSize(meth) == 0) {
180 if (!dvmIsNativeMethod(meth) && !dvmIsAbstractMethod(meth)) {
182 "VFY: zero-length code in concrete non-native method\n");
190 * Sanity-check the register counts. ins + locals = registers, so make
191 * sure that ins <= registers.
193 if (meth->insSize > meth->registersSize) {
194 LOG_VFY_METH(meth, "VFY: bad register counts (ins=%d regs=%d)\n",
195 meth->insSize, meth->registersSize);
200 * Allocate and populate an array to hold instruction data.
202 * TODO: Consider keeping a reusable pre-allocated array sitting
203 * around for smaller methods.
205 insnFlags = (InsnFlags*)
206 calloc(dvmGetMethodInsnsSize(meth), sizeof(InsnFlags));
207 if (insnFlags == NULL)
211 * Compute the width of each instruction and store the result in insnFlags.
212 * Count up the #of occurrences of new-instance instructions while we're
215 if (!dvmComputeCodeWidths(meth, insnFlags, &newInstanceCount))
219 * Allocate a map to hold the classes of uninitialized instances.
221 uninitMap = dvmCreateUninitInstanceMap(meth, insnFlags, newInstanceCount);
222 if (uninitMap == NULL)
226 * Set the "in try" flags for all instructions guarded by a "try" block.
228 if (!dvmSetTryFlags(meth, insnFlags))
232 * Perform static instruction verification.
234 if (!verifyInstructions(meth, insnFlags, verifyFlags))
238 * Do code-flow analysis. Do this after verifying the branch targets
239 * so we don't need to worry about it here.
241 * If there are no registers, we don't need to do much in the way of
242 * analysis, but we still need to verify that nothing actually tries
245 if (!dvmVerifyCodeFlow(meth, insnFlags, uninitMap)) {
246 //LOGD("+++ %s failed code flow\n", meth->name);
254 dvmFreeUninitInstanceMap(uninitMap);
261 * Verify an array data table. "curOffset" is the offset of the fill-array-data
264 static bool checkArrayData(const Method* meth, int curOffset)
266 const int insnCount = dvmGetMethodInsnsSize(meth);
267 const u2* insns = meth->insns + curOffset;
269 int valueCount, valueWidth, tableSize;
270 int offsetToArrayData;
272 assert(curOffset >= 0 && curOffset < insnCount);
274 /* make sure the start of the array data table is in range */
275 offsetToArrayData = insns[1] | (((s4)insns[2]) << 16);
276 if (curOffset + offsetToArrayData < 0 ||
277 curOffset + offsetToArrayData + 2 >= insnCount)
280 "VFY: invalid array data start: at %d, data offset %d, count %d\n",
281 curOffset, offsetToArrayData, insnCount);
285 /* offset to array data table is a relative branch-style offset */
286 arrayData = insns + offsetToArrayData;
288 /* make sure the table is 32-bit aligned */
289 if ((((u4) arrayData) & 0x03) != 0) {
291 "VFY: unaligned array data table: at %d, data offset %d\n",
292 curOffset, offsetToArrayData);
296 valueWidth = arrayData[1];
297 valueCount = *(u4*)(&arrayData[2]);
299 tableSize = 4 + (valueWidth * valueCount + 1) / 2;
301 /* make sure the end of the switch is in range */
302 if (curOffset + offsetToArrayData + tableSize > insnCount) {
304 "VFY: invalid array data end: at %d, data offset %d, end %d, "
306 curOffset, offsetToArrayData,
307 curOffset + offsetToArrayData + tableSize,
317 * Decode the current instruction.
319 static void decodeInstruction(const Method* meth, int insnIdx,
320 DecodedInstruction* pDecInsn)
322 dexDecodeInstruction(gDvm.instrFormat, meth->insns + insnIdx, pDecInsn);
327 * Perform static checks on a "new-instance" instruction. Specifically,
328 * make sure the class reference isn't for an array class.
330 * We don't need the actual class, just a pointer to the class name.
332 static bool checkNewInstance(const Method* meth, int insnIdx)
334 DvmDex* pDvmDex = meth->clazz->pDvmDex;
335 DecodedInstruction decInsn;
336 const char* classDescriptor;
339 decodeInstruction(meth, insnIdx, &decInsn);
340 idx = decInsn.vB; // 2nd item
341 if (idx >= pDvmDex->pHeader->typeIdsSize) {
342 LOG_VFY_METH(meth, "VFY: bad type index %d (max %d)\n",
343 idx, pDvmDex->pHeader->typeIdsSize);
347 classDescriptor = dexStringByTypeIdx(pDvmDex->pDexFile, idx);
348 if (classDescriptor[0] != 'L') {
349 LOG_VFY_METH(meth, "VFY: can't call new-instance on type '%s'\n",
358 * Perform static checks on a "new-array" instruction. Specifically, make
359 * sure they aren't creating an array of arrays that causes the number of
360 * dimensions to exceed 255.
362 static bool checkNewArray(const Method* meth, int insnIdx)
364 DvmDex* pDvmDex = meth->clazz->pDvmDex;
365 DecodedInstruction decInsn;
366 const char* classDescriptor;
369 decodeInstruction(meth, insnIdx, &decInsn);
370 idx = decInsn.vC; // 3rd item
371 if (idx >= pDvmDex->pHeader->typeIdsSize) {
372 LOG_VFY_METH(meth, "VFY: bad type index %d (max %d)\n",
373 idx, pDvmDex->pHeader->typeIdsSize);
377 classDescriptor = dexStringByTypeIdx(pDvmDex->pDexFile, idx);
379 int bracketCount = 0;
380 const char* cp = classDescriptor;
384 if (bracketCount == 0) {
385 /* The given class must be an array type. */
386 LOG_VFY_METH(meth, "VFY: can't new-array class '%s' (not an array)\n",
389 } else if (bracketCount > 255) {
390 /* It is illegal to create an array of more than 255 dimensions. */
391 LOG_VFY_METH(meth, "VFY: can't new-array class '%s' (exceeds limit)\n",
400 * Perform static checks on an instruction that takes a class constant.
401 * Ensure that the class index is in the valid range.
403 static bool checkTypeIndex(const Method* meth, int insnIdx, bool useB)
405 DvmDex* pDvmDex = meth->clazz->pDvmDex;
406 DecodedInstruction decInsn;
409 decodeInstruction(meth, insnIdx, &decInsn);
414 if (idx >= pDvmDex->pHeader->typeIdsSize) {
415 LOG_VFY_METH(meth, "VFY: bad type index %d (max %d)\n",
416 idx, pDvmDex->pHeader->typeIdsSize);
424 * Perform static checks on a field get or set instruction. All we do
425 * here is ensure that the field index is in the valid range.
427 static bool checkFieldIndex(const Method* meth, int insnIdx, bool useB)
429 DvmDex* pDvmDex = meth->clazz->pDvmDex;
430 DecodedInstruction decInsn;
433 decodeInstruction(meth, insnIdx, &decInsn);
438 if (idx >= pDvmDex->pHeader->fieldIdsSize) {
440 "VFY: bad field index %d (max %d) at offset 0x%04x\n",
441 idx, pDvmDex->pHeader->fieldIdsSize, insnIdx);
449 * Perform static checks on a method invocation instruction. All we do
450 * here is ensure that the method index is in the valid range.
452 static bool checkMethodIndex(const Method* meth, int insnIdx)
454 DvmDex* pDvmDex = meth->clazz->pDvmDex;
455 DecodedInstruction decInsn;
457 decodeInstruction(meth, insnIdx, &decInsn);
458 if (decInsn.vB >= pDvmDex->pHeader->methodIdsSize) {
459 LOG_VFY_METH(meth, "VFY: bad method index %d (max %d)\n",
460 decInsn.vB, pDvmDex->pHeader->methodIdsSize);
468 * Perform static checks on a string constant instruction. All we do
469 * here is ensure that the string index is in the valid range.
471 static bool checkStringIndex(const Method* meth, int insnIdx)
473 DvmDex* pDvmDex = meth->clazz->pDvmDex;
474 DecodedInstruction decInsn;
476 decodeInstruction(meth, insnIdx, &decInsn);
477 if (decInsn.vB >= pDvmDex->pHeader->stringIdsSize) {
478 LOG_VFY_METH(meth, "VFY: bad string index %d (max %d)\n",
479 decInsn.vB, pDvmDex->pHeader->stringIdsSize);
487 * Perform static verification on instructions.
489 * As a side effect, this sets the "branch target" flags in InsnFlags.
491 * "(CF)" items are handled during code-flow analysis.
494 * - target of each jump and branch instruction must be valid
495 * - targets of switch statements must be valid
496 * - (CF) operands referencing constant pool entries must be valid
497 * - (CF) operands of getfield, putfield, getstatic, putstatic must be valid
498 * - (new) verify operands of "quick" field ops
499 * - (CF) operands of method invocation instructions must be valid
500 * - (new) verify operands of "quick" method invoke ops
501 * - (CF) only invoke-direct can call a method starting with '<'
502 * - (CF) <clinit> must never be called explicitly
503 * - (CF) operands of instanceof, checkcast, new (and variants) must be valid
504 * - new-array[-type] limited to 255 dimensions
505 * - can't use "new" on an array class
506 * - (?) limit dimensions in multi-array creation
507 * - (CF) local variable load/store register values must be in valid range
510 * - branches must be within the bounds of the code array
511 * - targets of all control-flow instructions are the start of an instruction
512 * - (CF) register accesses fall within range of allocated registers
513 * - (N/A) access to constant pool must be of appropriate type
514 * - (CF) code does not end in the middle of an instruction
515 * - (CF) execution cannot fall off the end of the code
516 * - (earlier) for each exception handler, the "try" area must begin and
517 * end at the start of an instruction (end can be at the end of the code)
518 * - (earlier) for each exception handler, the handler must start at a valid
521 * TODO: move some of the "CF" items in here for better performance (the
522 * code-flow analysis sometimes has to process the same instruction several
525 static bool verifyInstructions(const Method* meth, InsnFlags* insnFlags,
528 const int insnCount = dvmGetMethodInsnsSize(meth);
529 const u2* insns = meth->insns;
532 /* the start of the method is a "branch target" */
533 dvmInsnSetBranchTarget(insnFlags, 0, true);
535 for (i = 0; i < insnCount; /**/) {
537 * These types of instructions can be GC points. To support precise
538 * GC, all such instructions must export the PC in the interpreter,
539 * or the GC won't be able to identify the current PC for the thread.
541 static const int gcMask = kInstrCanBranch | kInstrCanSwitch |
542 kInstrCanThrow | kInstrCanReturn;
544 int width = dvmInsnGetWidth(insnFlags, i);
545 OpCode opcode = *insns & 0xff;
546 InstructionFlags opFlags = dexGetInstrFlags(gDvm.instrFlags, opcode);
547 int offset, absOffset;
549 if ((opFlags & gcMask) != 0) {
551 * This instruction is probably a GC point. Branch instructions
552 * only qualify if they go backward, so we need to check the
557 if (dvmGetBranchTarget(meth, insnFlags, i, &offset, &unused)) {
559 dvmInsnSetGcPoint(insnFlags, i, true);
562 /* not a branch target */
563 dvmInsnSetGcPoint(insnFlags, i, true);
569 /* plain no-op or switch table data; nothing to do here */
572 case OP_CONST_STRING:
573 case OP_CONST_STRING_JUMBO:
574 if (!checkStringIndex(meth, i))
580 if (!checkTypeIndex(meth, i, true))
584 if (!checkTypeIndex(meth, i, false))
588 case OP_PACKED_SWITCH:
589 case OP_SPARSE_SWITCH:
590 /* verify the associated table */
591 if (!dvmCheckSwitchTargets(meth, insnFlags, i))
595 case OP_FILL_ARRAY_DATA:
596 /* verify the associated table */
597 if (!checkArrayData(meth, i))
615 /* check the destination */
616 if (!dvmCheckBranchTarget(meth, insnFlags, i, false))
620 /* check the destination; self-branch is okay */
621 if (!dvmCheckBranchTarget(meth, insnFlags, i, true))
625 case OP_NEW_INSTANCE:
626 if (!checkNewInstance(meth, i))
631 if (!checkNewArray(meth, i))
635 case OP_FILLED_NEW_ARRAY:
636 if (!checkTypeIndex(meth, i, true))
639 case OP_FILLED_NEW_ARRAY_RANGE:
640 if (!checkTypeIndex(meth, i, true))
647 case OP_IGET_BOOLEAN:
654 case OP_IPUT_BOOLEAN:
658 /* check the field index */
659 if (!checkFieldIndex(meth, i, false))
665 case OP_SGET_BOOLEAN:
672 case OP_SPUT_BOOLEAN:
676 /* check the field index */
677 if (!checkFieldIndex(meth, i, true))
681 case OP_INVOKE_VIRTUAL:
682 case OP_INVOKE_SUPER:
683 case OP_INVOKE_DIRECT:
684 case OP_INVOKE_STATIC:
685 case OP_INVOKE_INTERFACE:
686 case OP_INVOKE_VIRTUAL_RANGE:
687 case OP_INVOKE_SUPER_RANGE:
688 case OP_INVOKE_DIRECT_RANGE:
689 case OP_INVOKE_STATIC_RANGE:
690 case OP_INVOKE_INTERFACE_RANGE:
691 /* check the method index */
692 if (!checkMethodIndex(meth, i))
696 case OP_EXECUTE_INLINE:
697 case OP_INVOKE_DIRECT_EMPTY:
699 case OP_IGET_WIDE_QUICK:
700 case OP_IGET_OBJECT_QUICK:
702 case OP_IPUT_WIDE_QUICK:
703 case OP_IPUT_OBJECT_QUICK:
704 case OP_INVOKE_VIRTUAL_QUICK:
705 case OP_INVOKE_VIRTUAL_QUICK_RANGE:
706 case OP_INVOKE_SUPER_QUICK:
707 case OP_INVOKE_SUPER_QUICK_RANGE:
708 if ((verifyFlags & VERIFY_ALLOW_OPT_INSTRS) == 0) {
709 LOG_VFY("VFY: not expecting optimized instructions\n");
724 /* make sure the last instruction ends at the end of the insn area */
725 if (i != insnCount) {
727 "VFY: code did not end when expected (end at %d, count %d)\n",