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

📄 verifierutil.c

📁 Nucleus_2_kvm_Hello 是kvm移植到Nucleus系统的源代码。。。好东西啊
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 1998-2001 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information").  You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * * Use is subject to license terms. *//*========================================================================= * SYSTEM:    KVM * SUBSYSTEM: Class file verifier (runtime part) * FILE:      verifierUtil.c * OVERVIEW:  Implementation-specific parts of the KVM verifier. * AUTHORS:   Sheng Liang, Frank Yellin, restructured by Nik Shaylor *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include "stddef.h"#include "verifierUtil.h"/*========================================================================= * Global variables and definitions *=======================================================================*//* * This is always the method being verified. (The verifier cannot be called * recursively) */METHOD methodBeingVerified;/* * Pointer to the bytecodes */unsigned char *bytecodesBeingVerified;/* * Holds the return signature */static unsigned char *returnSig;/* * Global variables used by the verifier. */VERIFIERTYPE *vStack;VERIFIERTYPE *vLocals;unsigned long *NEWInstructions;bool_t vNeedInitialization; /* must call a this.<init> or super. */unsigned short  vMaxStack;unsigned short  vFrameSize;unsigned short  vSP;#if INCLUDEDEBUGCODEstatic int vErrorIp;#endif/*========================================================================= * Old verifier functions (inherited from KVM 1.0.3) *=======================================================================*//*========================================================================= * FUNCTION:      initializeVerifier * TYPE:          public global operation * OVERVIEW:      Initialize the bytecode verifier * * INTERFACE: *   parameters:  <nothing> *   returns:     <nothing> *=======================================================================*/void InitializeVerifier(void) {}/*========================================================================= * FUNCTION:      vIsAssignable * TYPE:          private operation on type keys * OVERVIEW:      Check if a value of one type key can be converted to a *                value of another type key. * * INTERFACE: *   parameters:  fromKey: from type *                toKey: to type *                mergedKeyP: pointer to merged type *   returns:     TRUE: can convert. *                FALSE: cannot convert. *=======================================================================*/bool_t vIsAssignable(VERIFIERTYPE fromKey, VERIFIERTYPE toKey, VERIFIERTYPE *mergedKeyP) {    if (mergedKeyP) {        /* Most of the time merged type is toKey */        *mergedKeyP = toKey;    }    if (fromKey == toKey)     /* trivial case */        return TRUE;    if (toKey == ITEM_Bogus)        return TRUE;    if (toKey == ITEM_Reference) {        return fromKey == ITEM_Null ||            fromKey > 255 ||            fromKey == ITEM_InitObject ||            (fromKey & ITEM_NewObject_Flag);    }    if ((toKey & ITEM_NewObject_Flag) || (fromKey & ITEM_NewObject_Flag)) {        return FALSE;    }    if (fromKey == ITEM_Null && toKey > 255) {        return TRUE;    }    if (fromKey > 255 && toKey > 255) {        CLASS fromClass = change_Key_to_CLASS(Vfy_toClassKey(fromKey));        CLASS toClass   = change_Key_to_CLASS(Vfy_toClassKey(toKey));        bool_t res = isAssignableTo(fromClass, toClass);        /* Interfaces are treated like java.lang.Object in the verifier. */        if (toClass->accessFlags & ACC_INTERFACE) {            /* Set mergedKey to fromKey for interfaces */            if (mergedKeyP) {                *mergedKeyP = Vfy_getObjectVerifierType();            }            return TRUE;        }        return res;    }    return FALSE;}/*========================================================================= * FUNCTION:      vIsProtectedAccess * TYPE:          private operation on type keys * OVERVIEW:      Check if the access to a method or field is to *                a protected field/method of a superclass. * * INTERFACE: *   parameters:  thisClass:   The class in question *                index:       Constant pool entry of field or method *                isMethod:    true for method, false for field. *=======================================================================*/bool_t vIsProtectedAccess(INSTANCE_CLASS thisClass, POOLINDEX index, bool_t isMethod) {    CONSTANTPOOL constPool = thisClass->constPool;    unsigned short memberClassIndex =        constPool->entries[index].method.classIndex;    INSTANCE_CLASS memberClass =        (INSTANCE_CLASS)constPool->entries[memberClassIndex].clazz;    INSTANCE_CLASS tClass;    unsigned short nameTypeIndex;    unsigned long nameTypeKey;    /* if memberClass isn't a superclass of this class, then we don't worry     * about this case */    for (tClass = thisClass; ; tClass = tClass->superClass) {        if (tClass == NULL) {            return FALSE;        } else if (tClass == memberClass) {            break;        }    }    nameTypeIndex = constPool->entries[index].method.nameTypeIndex;    nameTypeKey = constPool->entries[nameTypeIndex].nameTypeKey.i;    while (memberClass != NULL) {        if (isMethod) {            FOR_EACH_METHOD(method, memberClass->methodTable)                if (method->nameTypeKey.i == nameTypeKey) {                    return (((method->accessFlags & ACC_PROTECTED) != 0)                          && (memberClass->clazz.packageName !=                                  thisClass->clazz.packageName));                }            END_FOR_EACH_METHOD        } else {            FOR_EACH_FIELD(field, memberClass->fieldTable)                if (field->nameTypeKey.i == nameTypeKey) {                    return (((field->accessFlags & ACC_PROTECTED) != 0)                          && (memberClass->clazz.packageName !=                                  thisClass->clazz.packageName));                }            END_FOR_EACH_FIELD        }        memberClass = memberClass->superClass;    }    return FALSE;}/*========================================================================= * FUNCTION:      Vfy_getReferenceArrayElementType * TYPE:          private operation on type keys * OVERVIEW:      Obtain the element type key of a given object reference type. * * INTERFACE: *   parameters:  typeKey: object array type key. *   returns:     element type key. * * DANGER: *   Before calling this function, make sure that typeKey in fact is an *   object array. *=======================================================================*/VERIFIERTYPE Vfy_getReferenceArrayElementType(VERIFIERTYPE arrayType) {    CLASSKEY arrayTypeKey = Vfy_toClassKey(arrayType);    int n = (arrayTypeKey >> FIELD_KEY_ARRAY_SHIFT);    if (arrayTypeKey == ITEM_Null) {        return ITEM_Null;    } else if (n < MAX_FIELD_KEY_ARRAY_DEPTH) {        return ((n - 1) << FIELD_KEY_ARRAY_SHIFT) + (arrayTypeKey & 0x1FFF);    } else {        CLASS arrayClass           = change_Key_to_CLASS(Vfy_toClassKey(arrayTypeKey));        const char* baseNameString = arrayClass->baseName->string;        UString baseName           = getUStringX(&baseNameString, 1, arrayClass->baseName->length - 1);        UString packageName        = arrayClass->packageName;        CLASS elemClass            = change_Name_to_CLASS(packageName, baseName);        return Vfy_toVerifierType(elemClass->key);    }}/*========================================================================= * FUNCTION:      Vfy_getClassArrayVerifierType * TYPE:          private operation on type keys * OVERVIEW:      Obtain the object array type key whose element type is the *                given element type key. * * INTERFACE: *   parameters:  typeKey: element type key. *   returns:     object array type key. * * DANGER: *   Before calling this function, make sure that typeKey in fact is an *   object type. *=======================================================================*/VERIFIERTYPE Vfy_getClassArrayVerifierType(CLASSKEY typeKey) {    CLASSKEY res;    int n = (typeKey >> FIELD_KEY_ARRAY_SHIFT);    if (n < MAX_FIELD_KEY_ARRAY_DEPTH - 1) {        res = (1 << FIELD_KEY_ARRAY_SHIFT) + typeKey;    } else {        CLASS elemClass = change_Key_to_CLASS(typeKey);        ARRAY_CLASS arrayClass = getObjectArrayClass(elemClass);        res = arrayClass->clazz.key;    }    return Vfy_toVerifierType(res);}/*========================================================================= * FUNCTION:      Vfy_isArrayClassKey * TYPE:          private operation on type keys * OVERVIEW:      Check if the given type key denotes an array type of the *                given dimension. * * INTERFACE: *   parameters:  typeKey: a type key. *                dim: dimension. *   returns:     TRUE if the type key is an array of dim dimension, FALSE *                otherwise. *=======================================================================*/bool_t Vfy_isArrayClassKey(CLASSKEY typeKey, int dim) {    if (typeKey == ITEM_Null) {        return TRUE;    } else {        int n = (typeKey >> FIELD_KEY_ARRAY_SHIFT);        /* n is the dimension of the class.  It has the value         * 0..MAX_FIELD_KEY_ARRAY_DEPTH, in which the last value means         * MAX_FIELD_KEY_ARRAY_DEPTH or more. . .         */        if (dim <= MAX_FIELD_KEY_ARRAY_DEPTH) {            return n >= dim;        } if (n < MAX_FIELD_KEY_ARRAY_DEPTH) {            /* We are looking for at more than MAX_FIELD_KEY_ARRAY_DEPTH,             * dimensions, so n needs to be that value. */            return FALSE;        } else {            CLASS arrayClass = change_Key_to_CLASS(typeKey);            char *baseName = arrayClass->baseName->string;            /* The first dim characters of baseName must be [ */            for ( ; dim > 0; --dim) {                if (*baseName++ != '[') {                    return FALSE;                }            }            return TRUE;        }    }}/*========================================================================= * FUNCTION:      change_Field_to_StackType * TYPE:          private operation on type keys * OVERVIEW:      Change an individual field type to a stack type * * INTERFACE: *   parameters:  fieldType: field type *                stackTypeP: pointer for placing the corresponding stack type(s) *   returns:     number of words occupied by the resulting type. *=======================================================================*/int change_Field_to_StackType(CLASSKEY fieldType, VERIFIERTYPE* stackTypeP) {    switch (fieldType) {        case 'I':        case 'B':        case 'Z':        case 'C':        case 'S':            *stackTypeP++ = ITEM_Integer;            return 1;#if IMPLEMENTS_FLOAT        case 'F':            *stackTypeP++ = ITEM_Float;            return 1;        case 'D':            *stackTypeP++ = ITEM_Double;            *stackTypeP++ = ITEM_Double_2;            return 2;#endif        case 'J':            *stackTypeP++ = ITEM_Long;            *stackTypeP++ = ITEM_Long_2;            return 2;        default:            *stackTypeP++ = fieldType;            return 1;    }}/*========================================================================= * FUNCTION:      change_Arg_to_StackType * TYPE:          private operation on type keys * OVERVIEW:      Change an individual method argument type to a stack type * * INTERFACE: *   parameters:  sigP: pointer to method signature. *                type: pointer for placing the corresponding stack type(s) *   returns:     number of words occupied by the resulting type. *=======================================================================*/int change_Arg_to_StackType(unsigned char** sigP, VERIFIERTYPE* typeP) {    unsigned char *sig = *sigP;    unsigned short hi, lo;    hi = *sig++;    if (hi == 'L') {        hi = *sig++;        lo = *sig++;        *sigP = sig;        return change_Field_to_StackType((unsigned short)((hi << 8) + lo), typeP);    }    if (hi < 'A' || hi > 'Z') {        lo = *sig++;        *sigP = sig;        return change_Field_to_StackType((unsigned short)((hi << 8) + lo), typeP);    }    *sigP = sig;    return change_Field_to_StackType(hi, typeP);}/*========================================================================= * FUNCTION:      getStackType * TYPE:          private operation on type keys * OVERVIEW:      Get the recorded stack map of a given target ip. * * INTERFACE: *   parameters:  thisMethod: method being verified. *                this_ip: current ip (unused for now). *                target_ip: target ip (to look for a recored stack map). *   returns:     a stack map *=======================================================================*/static unsigned short *getStackMap(METHOD thisMethod, IPINDEX target_ip) {    POINTERLIST stackMaps = thisMethod->u.java.stackMaps.verifierMap;    unsigned short i;    if (stackMaps == NULL) {        return NULL;    } else {        long length = stackMaps->length; /* number of entries */        for (i = 0; i < length; i++) {            if (target_ip == stackMaps->data[i + length].cell) {                return (unsigned short*)stackMaps->data[i].cellp;            }        }    }    return NULL;}/*========================================================================= * FUNCTION:      matchStackMap * TYPE:          private operation on type keys * OVERVIEW:      Match two stack maps. * * INTERFACE: *   parameters:  thisMethod: method being verified. *                target_ip: target ip (to look for a recored stack map). *                flags: bit-wise or of the SM_* flags. *   returns:     TRUE if match, FALSE otherwise. *=======================================================================*/bool_t matchStackMap(METHOD thisMethod, IPINDEX target_ip, int flags) {    bool_t result = TRUE;  /* Assume result is TRUE */    bool_t target_needs_initialization;    unsigned short nstack;    unsigned short nlocals;    unsigned short i;    /* Following is volatile, and will disappear at first GC */    unsigned short *stackMapBase = getStackMap(thisMethod, target_ip);#if INCLUDEDEBUGCODE    if (traceverifier) {        fprintf(stdout, "Match stack maps (this=%ld, target=%ld)%s%s%s\n",                (long)vErrorIp, (long)target_ip,            (flags & SM_CHECK) ? " CHECK" : "",            (flags & SM_MERGE) ? " MERGE" : "",            (flags & SM_EXIST) ? " EXIST" : "");    }#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -