⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 verifier.c

📁 This is a java virtual machine implement in c
💻 C
📖 第 1 页 / 共 5 页
字号:
/*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 + -