📄 verifier.c
字号:
/*0001*//*
/*0002./ * Copyright (c) 1998-2001 Sun Microsystems, Inc. All Rights Reserved.
/*0003./ *
/*0004./ * This software is the confidential and proprietary information of Sun
/*0005./ * Microsystems, Inc. ("Confidential Information"). You shall not
/*0006./ * disclose such Confidential Information and shall use it only in
/*0007./ * accordance with the terms of the license agreement you entered into
/*0008./ * with Sun.
/*0009./ *
/*0010./ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
/*0011./ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
/*0012./ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/*0013./ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
/*0014./ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
/*0015./ * THIS SOFTWARE OR ITS DERIVATIVES.
/*0016./ *
/*0017./ */
/*0018*/
/*0019*//*
/*0020./ * NOTICE:
/*0021./ * This file is considered "Shared Part" under the CLDC SCSL
/*0022./ * and commercial licensing terms, and is therefore not to
/*0023./ * be modified by licensees. For definition of the term
/*0024./ * "Shared Part", please refer to the CLDC SCSL license
/*0025./ * attachment E, Section 2.1 (Definitions) paragraph "e",
/*0026./ * or your commercial licensing terms as applicable.
/*0027./ */
/*0028*/
/*0029*//*=========================================================================
/*0030./ * SYSTEM: KVM
/*0031./ * SUBSYSTEM: Class file verifier (runtime part)
/*0032./ * FILE: verifier.c
/*0033./ * OVERVIEW: KVM has a two-phase class file verifier. In order to
/*0034./ * run in KVM, class files must first be processed with
/*0035./ * a special "pre-verifier" tool. This phase is typically
/*0036./ * done on the development workstation. During execution,
/*0037./ * the runtime verifier (defined in this file) of the KVM
/*0038./ * performs the actual class file verification based on
/*0039./ * both runtime information and pre-verification information.
/*0040./ * AUTHOR: Sheng Liang, Frank Yellin
/*0041./ *=======================================================================*/
/*0042*/
/*0043*//*=========================================================================
/*0044./ * Include files
/*0045./ *=======================================================================*/
/*0046*/
/*0047*/#include <global.h>
/*0048*/#include <stddef.h>
/*0049*/
/*0050*//*=========================================================================
/*0051./ * Global variables and definitions
/*0052./ *=======================================================================*/
/*0053*/
/*0054*/#define IS_NTH_BIT(var, bit) (var[(bit) >> 5] & (1 << ((bit) & 0x1F)))
/*0055*/#define SET_NTH_BIT(var, bit) (var[(bit) >> 5] |= (1 << ((bit) & 0x1F)))
/*0056*/#define callocNewBitmap(size) \
/*0057*/ ((unsigned long *) callocObject((size + 31) >> 5, GCT_NOPOINTERS))
/*0058*/
/*0059*/
/*0070*//* Used to encode the type of 2-byte entities: long and double */
/*0071*/struct DoubleWordItem {
/*0072*/ unsigned short fst;
/*0073*/ unsigned short snd;
/*0074*/};
/*0075*/
/*0076*//* Global variables holding the type key of well-known classes */
/*0077*/unsigned short booleanArrayClassKey;
/*0078*/unsigned short byteArrayClassKey;
/*0079*/unsigned short charArrayClassKey;
/*0080*/unsigned short shortArrayClassKey;
/*0081*/unsigned short intArrayClassKey;
/*0082*/unsigned short longArrayClassKey;
/*0083*/
/*0084*/#if IMPLEMENTS_FLOAT
/*0085*/unsigned short floatArrayClassKey;
/*0086*/unsigned short doubleArrayClassKey;
/*0087*/#endif
/*0088*/
/*0089*/unsigned short objectClassKey;
/*0090*/unsigned short stringClassKey;
/*0091*/unsigned short throwableClassKey;
/*0092*/unsigned short objectArrayClassKey;
/*0093*/
/*0094*//* Global variables used by the verifier. Obviously the verifier is
/*0095./ * not re-entrant.
/*0096./ */
/*0097*/unsigned short* vStack;
/*0098*/unsigned short* vLocals;
/*0099*/unsigned short vMaxStack;
/*0100*/unsigned short vFrameSize;
/*0101*/unsigned short vSP;
/*0102*/unsigned short lastStackPop;
/*0103*/struct DoubleWordItem lastStackPop2;
/*0104*/unsigned short lastLocalGet;
/*0105*/
/*0106*//* Flags used to control how to match two stack maps.
/*0107./ * One of the stack maps is derived as part of the type checking process.
/*0108./ * The other stack map is recorded in the class file.
/*0109./ */
/*0110*/#define SM_CHECK 1 /* Check if derived types match recorded types. */
/*0111*/#define SM_MERGE 2 /* Merge recorded types into derived types. */
/*0112*/#define SM_EXIST 4 /* A recorded type attribute must exist. */
/*0113*/
/*0114*//* Error codes
/*0115./ * We use error code instead of text messages to reduce memory usage.
/*0116./ */
/*0117*/#define VE_STACK_OVERFLOW 1
/*0118*/#define VE_STACK_UNDERFLOW 2
/*0119*/#define VE_STACK_EXPECT_CAT1 3
/*0120*/#define VE_STACK_BAD_TYPE 4
/*0121*/#define VE_LOCALS_OVERFLOW 5
/*0122*/#define VE_LOCALS_BAD_TYPE 6
/*0123*/#define VE_LOCALS_UNDERFLOW 7
/*0124*/#define VE_TARGET_BAD_TYPE 8
/*0125*/#define VE_BACK_BRANCH_UNINIT 9
/*0126*/#define VE_SEQ_BAD_TYPE 10
/*0127*/#define VE_EXPECT_CLASS 11
/*0128*/#define VE_EXPECT_THROWABLE 12
/*0129*/#define VE_BAD_LOOKUPSWITCH 13
/*0130*/#define VE_BAD_LDC 14
/*0131*/#define VE_BALOAD_BAD_TYPE 15
/*0132*/#define VE_AALOAD_BAD_TYPE 16
/*0133*/#define VE_BASTORE_BAD_TYPE 17
/*0134*/#define VE_AASTORE_BAD_TYPE 18
/*0135*/#define VE_FIELD_BAD_TYPE 19
/*0136*/#define VE_EXPECT_METHODREF 20
/*0137*/#define VE_ARGS_NOT_ENOUGH 21
/*0138*/#define VE_ARGS_BAD_TYPE 22
/*0139*/#define VE_EXPECT_INVOKESPECIAL 23
/*0140*/#define VE_EXPECT_NEW 24
/*0141*/#define VE_EXPECT_UNINIT 25
/*0142*/#define VE_BAD_INSTR 26
/*0143*/#define VE_EXPECT_ARRAY 27
/*0144*/#define VE_MULTIANEWARRAY 28
/*0145*/#define VE_EXPECT_NO_RETVAL 29
/*0146*/#define VE_RETVAL_BAD_TYPE 30
/*0147*/#define VE_EXPECT_RETVAL 31
/*0148*/#define VE_RETURN_UNINIT_THIS 32
/*0149*/#define VE_BAD_STACKMAP 33
/*0150*/#define VE_FALL_THROUGH 34
/*0151*/#define VE_EXPECT_ZERO 35
/*0152*/#define VE_NARGS_MISMATCH 36
/*0153*/#define VE_INVOKESPECIAL 37
/*0154*/#define VE_BAD_INIT_CALL 38
/*0155*/#define VE_EXPECT_FIELDREF 39
/*0156*/#define VE_FINAL_METHOD_OVERRIDE 40
/*0157*/#define VE_MIDDLE_OF_BYTE_CODE 41
/*0158*/#define VE_BAD_NEW_OFFSET 42
/*0159*/
/*0160*//* If you add new errors to this list, be sure to also add
/*0161./ * an explanation to KVM_MSG_VERIFIER_STATUS_INFO_INITIALIZER in
/*0162./ * messages.h.
/*0163./ */
/*0164*/
/*0165*/
/*0166*/
/*0167*/#define CONSTANTPOOL_MASKED_TAG(cp, index) \
/*0168*/ (CONSTANTPOOL_TAG(cp, index) & CP_CACHEMASK)
/*0169*/
/*0170*/#define GET_CLASS_CONSTANT_KEY(cp, index) (cp->entries[index].clazz->key)
/*0171*/
/*0172*//* Used to check stackmaps for exception handlers. */
/*0173*/#define CHECK_TARGET(this_ip, target_ip) \
/*0174*/ if (!matchStackMap(thisMethod, (this_ip), (unsigned short)(target_ip), SM_CHECK | SM_EXIST)) { \
/*0175*/ VERIFIER_ERROR(VE_TARGET_BAD_TYPE); \
/*0176*/ } else
/*0177*/
/*0178*//* Used to check stackmaps for jump instructions. Make sure that there are
/*0179./ * no uninitialized instances on backward branch.
/*0180./ */
/*0190*/#define CHECK_JUMP_TARGET(this_ip, target_ip) \
/*0191*/ CHECK_TARGET(this_ip, target_ip); \
/*0192*/ if (!checkNewObject(this_ip, (unsigned short)(target_ip))) { \
/*0193*/ VERIFIER_ERROR(VE_BACK_BRANCH_UNINIT); \
/*0194*/ } else
/*0196*/
/*0197*/
/*0198*//* Use goto statement to handle error to eliminate code duplication. */
/*0199*/#define BAIL_OUT() { goto err;}
/*0200*/
/*0201*//* Set result code and bail out. */
/*0202*/#define VERIFIER_ERROR(n) \
/*0203*/ result = n; \
/*0204*/ BAIL_OUT();
/*0205*/
/*0206*//* The following macros call a function and then check error code. We factor out
/*0207./ * code in to functions to minimize code size.
/*0208./ */
/*0209*/#define PUSH_STACK(t) \
/*0210*/ result = vPushStack(t); \
/*0211*/ if (result) BAIL_OUT();
/*0212*/
/*0213*/#define POP_STACK(t) \
/*0214*/ result = vPopStack(t); \
/*0215*/ if (result) BAIL_OUT();
/*0216*/
/*0217*/#define GET_LOCAL(i, v) \
/*0218*/ result = vGetLocal(i, v); \
/*0219*/ if (result) BAIL_OUT();
/*0220*/
/*0221*/#define SET_LOCAL(i, v) \
/*0222*/ result = vSetLocal(i, v); \
/*0223*/ if (result) BAIL_OUT();
/*0224*/
/*0225*/#define CHECK_VALID_CP_INDEX(cp, i) \
/*0226*/ if (i >= CONSTANTPOOL_LENGTH(cp)) { \
/*0227*/ result = 120; \
/*0228*/ BAIL_OUT(); \
/*0229*/ } else
/*0230*/
/*0231*//*=========================================================================
/*0232./ * FUNCTION: initializeVerifier
/*0233./ * TYPE: public global operation
/*0234./ * OVERVIEW: Initialize the bytecode verifier
/*0235./ *
/*0236./ * INTERFACE:
/*0237./ * parameters: <nothing>
/*0238./ * returns: <nothing>
/*0239./ *=======================================================================*/
/*0240*/
/*0241*/void
/*0242*/InitializeVerifier(void)
/*0243*/{
/*0244*/ booleanArrayClassKey = (1 << FIELD_KEY_ARRAY_SHIFT) + 'Z';
/*0245*/ byteArrayClassKey = (1 << FIELD_KEY_ARRAY_SHIFT) + 'B';
/*0246*/ charArrayClassKey = (1 << FIELD_KEY_ARRAY_SHIFT) + 'C';
/*0247*/ shortArrayClassKey = (1 << FIELD_KEY_ARRAY_SHIFT) + 'S';
/*0248*/ intArrayClassKey = (1 << FIELD_KEY_ARRAY_SHIFT) + 'I';
/*0249*/ longArrayClassKey = (1 << FIELD_KEY_ARRAY_SHIFT) + 'J';
/*0250*/
/*0251*/#if IMPLEMENTS_FLOAT
/*0252*/ floatArrayClassKey = (1 << FIELD_KEY_ARRAY_SHIFT) + 'F';
/*0253*/ doubleArrayClassKey = (1 << FIELD_KEY_ARRAY_SHIFT) + 'D';
/*0254*/#endif
/*0255*/
/*0256*/ /* Note that java.lang.Object and java.lang.String classes have been
/*0257./ * created, but Throwable and Object[] classes have not.
/*0258./ */
/*0259*/ objectClassKey = JavaLangObject->clazz.key;
/*0260*/ stringClassKey = JavaLangString->clazz.key;
/*0261*/ /* java.lang.Throwable class is loaded lazily. */
/*0262*/ throwableClassKey = JavaLangThrowable->clazz.key;
/*0263*/ /* Object[] class is not yet loaded. */
/*0264*/ objectArrayClassKey = objectClassKey + (1 << FIELD_KEY_ARRAY_SHIFT);
/*0265*/}
/*0266*/
/*0267*//*=========================================================================
/*0268./ * FUNCTION: vIsAssignable
/*0269./ * TYPE: private operation on type keys
/*0270./ * OVERVIEW: Check if a value of one type key can be converted to a value of
/*0271./ * another type key.
/*0272./ *
/*0273./ * INTERFACE:
/*0274./ * parameters: fromKey: from type
/*0275./ * toKey: to type
/*0276./ * mergedKeyP: pointer to merged type
/*0277./ * returns: TRUE: can convert.
/*0278./ * FALSE: cannot convert.
/*0279./ *=======================================================================*/
/*0280*/
/*0281*/static bool_t
/*0282*/vIsAssignable(unsigned short fromKey, unsigned short toKey, unsigned short *mergedKeyP)
/*0283*/{
/*0284*/ if (mergedKeyP) {
/*0285*/ /* Most of the time merged type is toKey */
/*0286*/ *mergedKeyP = toKey;
/*0287*/ }
/*0288*/ if (fromKey == toKey) /* trivial case */
/*0289*/ return TRUE;
/*0290*/ if (toKey == ITEM_Bogus)
/*0291*/ return TRUE;
/*0292*/ if (toKey == ITEM_Reference) {
/*0293*/ return fromKey == ITEM_Null ||
/*0294*/ fromKey > 255 ||
/*0295*/ fromKey == ITEM_InitObject ||
/*0296*/ (fromKey & ITEM_NewObject_Flag);
/*0297*/ }
/*0298*/ if ((toKey & ITEM_NewObject_Flag) || (fromKey & ITEM_NewObject_Flag)) {
/*0299*/ return FALSE;
/*0300*/ }
/*0301*/ if (fromKey == ITEM_Null && toKey > 255) {
/*0302*/ return TRUE;
/*0303*/ }
/*0304*/ if (fromKey > 255 && toKey > 255) {
/*0305*/ CLASS fromClass = change_Key_to_CLASS(fromKey);
/*0306*/ CLASS toClass = change_Key_to_CLASS(toKey);
/*0307*/ bool_t res = isAssignableTo(fromClass, toClass);
/*0308*/ /* Interfaces are treated like java.lang.Object in the verifier. */
/*0309*/ if (toClass->accessFlags & ACC_INTERFACE) {
/*0310*/ /* Set mergedKey to fromKey for interfaces */
/*0311*/ if (mergedKeyP) {
/*0312*/ *mergedKeyP = objectClassKey;
/*0313*/ }
/*0314*/ return TRUE;
/*0315*/ }
/*0316*/ return res;
/*0317*/ }
/*0318*/ return FALSE;
/*0319*/}
/*0320*/
/*0321*//*=========================================================================
/*0322./ * FUNCTION: vIsProtectedAccess
/*0323./ * TYPE: private operation on type keys
/*0324./ * OVERVIEW: Check if the access to a method or field is to
/*0325./ * a protected field/method of a superclass.
/*0326./ *
/*0327./ * INTERFACE:
/*0328./ * parameters: thisMethod: Method being verified.
/*0329./ * index: Constant pool entry of field or method
/*0330./ * isMethod: true for method, false for field.
/*0331./ *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -