📄 verifier.c
字号:
/*0643./ * returns: number of words occupied by the resulting type.
/*0644./ *=======================================================================*/
/*0645*/
/*0646*/static int
/*0647*/change_Field_to_StackType(unsigned short fieldType, unsigned short* stackTypeP)
/*0648*/{
/*0649*/ switch (fieldType) {
/*0650*/ case 'I':
/*0651*/ case 'B':
/*0652*/ case 'Z':
/*0653*/ case 'C':
/*0654*/ case 'S':
/*0655*/ *stackTypeP++ = ITEM_Integer;
/*0656*/ return 1;
/*0657*/#if IMPLEMENTS_FLOAT
/*0658*/ case 'F':
/*0659*/ *stackTypeP++ = ITEM_Float;
/*0660*/ return 1;
/*0661*/ case 'D':
/*0662*/ *stackTypeP++ = ITEM_Double;
/*0663*/ *stackTypeP++ = ITEM_Double_2;
/*0664*/ return 2;
/*0665*/#endif
/*0666*/ case 'J':
/*0667*/ *stackTypeP++ = ITEM_Long;
/*0668*/ *stackTypeP++ = ITEM_Long_2;
/*0669*/ return 2;
/*0670*/ default:
/*0671*/ *stackTypeP++ = fieldType;
/*0672*/ return 1;
/*0673*/ }
/*0674*/}
/*0675*/
/*0676*//*=========================================================================
/*0677./ * FUNCTION: change_Arg_to_StackType
/*0678./ * TYPE: private operation on type keys
/*0679./ * OVERVIEW: Change an individual method argument type to a stack type
/*0680./ *
/*0681./ * INTERFACE:
/*0682./ * parameters: sigP: pointer to method signature.
/*0683./ * type: pointer for placing the corresponding stack type(s)
/*0684./ * returns: number of words occupied by the resulting type.
/*0685./ *=======================================================================*/
/*0686*/
/*0687*/static int
/*0688*/change_Arg_to_StackType(unsigned char** sigP, unsigned short* typeP)
/*0689*/{
/*0690*/ unsigned char *sig = *sigP;
/*0691*/ unsigned short hi, lo;
/*0692*/
/*0693*/ hi = *sig++;
/*0694*/
/*0695*/ if (hi == 'L') {
/*0696*/ hi = *sig++;
/*0697*/ lo = *sig++;
/*0698*/ *sigP = sig;
/*0699*/ return change_Field_to_StackType((unsigned short)((hi << 8) + lo), typeP);
/*0700*/ }
/*0701*/ if (hi < 'A' || hi > 'Z') {
/*0702*/ lo = *sig++;
/*0703*/ *sigP = sig;
/*0704*/ return change_Field_to_StackType((unsigned short)((hi << 8) + lo), typeP);
/*0705*/ }
/*0706*/ *sigP = sig;
/*0707*/ return change_Field_to_StackType(hi, typeP);
/*0708*/}
/*0709*/
/*0710*//*=========================================================================
/*0711./ * FUNCTION: getStackType
/*0712./ * TYPE: private operation on type keys
/*0713./ * OVERVIEW: Get the recorded stack map of a given target ip.
/*0714./ *
/*0715./ * INTERFACE:
/*0716./ * parameters: thisMethod: method being verified.
/*0717./ * this_ip: current ip (unused for now).
/*0718./ * target_ip: target ip (to look for a recored stack map).
/*0719./ * returns: a stack map
/*0720./ *=======================================================================*/
/*0721*/
/*0722*/static unsigned short *
/*0723*/getStackMap(METHOD thisMethod, unsigned short this_ip, unsigned short target_ip)
/*0724*/{
/*0725*/ POINTERLIST stackMaps = thisMethod->u.java.stackMaps.verifierMap;
/*0726*/ unsigned short i;
/*0727*/ if (stackMaps == NULL) {
/*0728*/ return NULL;
/*0729*/ } else {
/*0730*/ long length = stackMaps->length; /* number of entries */
/*0731*/ for (i = 0; i < length; i++) {
/*0732*/ if (target_ip == stackMaps->data[i + length].cell) {
/*0733*/ return (unsigned short*)stackMaps->data[i].cellp;
/*0734*/ }
/*0735*/ }
/*0736*/ }
/*0737*/ return NULL;
/*0738*/}
/*0739*/
/*0740*//*=========================================================================
/*0741./ * FUNCTION: matchStackMap
/*0742./ * TYPE: private operation on type keys
/*0743./ * OVERVIEW: Match two stack maps.
/*0744./ *
/*0745./ * INTERFACE:
/*0746./ * parameters: thisMethod: method being verified.
/*0747./ * this_ip: current ip (unused for now).
/*0748./ * target_ip: target ip (to look for a recored stack map).
/*0749./ * flags: bit-wise or of the SM_* flags.
/*0750./ * returns: TRUE if match, FALSE otherwise.
/*0751./ *=======================================================================*/
/*0752*/
/*0753*/static bool_t
/*0754*/matchStackMap(METHOD thisMethod, unsigned short this_ip,
/*0755*/ unsigned short target_ip, int flags)
/*0756*/{
/*0757*/ bool_t result = TRUE; /* Assume result is TRUE */
/*0758*/ unsigned short nstack;
/*0759*/ unsigned short nlocals;
/*0760*/ unsigned short i;
/*0761*/
/*0762*/ /* Following is volatile, and will disappear at first GC */
/*0763*/ unsigned short *stackMapBase = getStackMap(thisMethod, this_ip, target_ip);
/*0764*/
/*0775*/ if (stackMapBase == NULL) {
/*0781*/ return !(flags & SM_EXIST);
/*0782*/ }
/*0783*/
/*0784*/ START_TEMPORARY_ROOTS
/*0785*/ DECLARE_TEMPORARY_ROOT_FROM_BASE(unsigned short*, stackMap,
/*0786*/ stackMapBase, stackMapBase);
/*0787*/
/*0794*/ nlocals = *stackMap++;
/*0795*/ for (i = 0; i < nlocals; i++) {
/*0796*/ unsigned short ty = *stackMap++;
/*0797*/ unsigned short mergedType = ty;
/*0798*/ if ((SM_CHECK & flags) && !vIsAssignable(vLocals[i], ty, &mergedType)) {
/*0799*/ result = FALSE;
/*0800*/ goto done;
/*0801*/ }
/*0802*/ if (SM_MERGE & flags) {
/*0803*/ vLocals[i] = mergedType;
/*0804*/ }
/*0805*/ }
/*0806*/ if (SM_MERGE & flags) {
/*0807*/ for (i = nlocals; i < vFrameSize; i++) {
/*0808*/ vLocals[i] = ITEM_Bogus;
/*0809*/ }
/*0810*/ }
/*0811*/
/*0812*/ nstack = *stackMap++;
/*0813*/ if ((SM_CHECK & flags) && nstack != vSP) {
/*0814*/ result = FALSE;
/*0815*/ goto done;
/*0816*/ }
/*0817*/ if (SM_MERGE & flags) {
/*0818*/ vSP = nstack;
/*0819*/ }
/*0820*/ for (i = 0; i < nstack; i++) {
/*0821*/ unsigned short ty = *stackMap++;
/*0822*/ unsigned short mergedType = ty;
/*0823*/ if ((SM_CHECK & flags) && !vIsAssignable(vStack[i], ty, &mergedType)) {
/*0824*/ result = FALSE;
/*0825*/ goto done;
/*0826*/ }
/*0827*/ if (SM_MERGE & flags) {
/*0828*/ vStack[i] = mergedType;
/*0829*/ }
/*0830*/ }
/*0831*/ done:
/*0832*/ END_TEMPORARY_ROOTS
/*0833*/ return result;
/*0834*/}
/*0835*/
/*0836*//*=========================================================================
/*0837./ * FUNCTION: checkNewObject
/*0838./ * TYPE: private operation on type keys
/*0839./ * OVERVIEW: Check if uninitialized objects exist on backward branches.
/*0840./ *
/*0841./ * INTERFACE:
/*0842./ * parameters: this_ip: current ip
/*0843./ * target_ip: branch target ip
/*0844./ * returns: TRUE if no uninitialized objects exist, FALSE otherwise.
/*0845./ *=======================================================================*/
/*0846*/
/*0847*/static bool_t
/*0848*/checkNewObject(unsigned short this_ip, unsigned short target_ip)
/*0849*/{
/*0850*/ if (target_ip < this_ip) {
/*0851*/ int i;
/*0852*/ for (i = 0; i < vFrameSize; i++) {
/*0853*/ if (vLocals[i] & ITEM_NewObject_Flag) {
/*0854*/ return FALSE;
/*0855*/ }
/*0856*/ }
/*0857*/ for (i = 0; i < vSP; i++) {
/*0858*/ if (vStack[i] & ITEM_NewObject_Flag) {
/*0859*/ return FALSE;
/*0860*/ }
/*0861*/ }
/*0862*/ }
/*0863*/ return TRUE;
/*0864*/}
/*0865*/
/*0866*//*=========================================================================
/*0867./ * FUNCTION: verifyMethod
/*0868./ * TYPE: private operation on methods.
/*0869./ * OVERVIEW: Perform byte-code verification of a given method.
/*0870./ *
/*0871./ * INTERFACE:
/*0872./ * parameters: thisMethod: method to be verified.
/*0873./ * returns: 0 if verification succeeds, error code if verification
/*0874./ * fails.
/*0875./ *=======================================================================*/
/*0876*/
/*0877*/static int
/*0878*/verifyMethod(METHOD thisMethod)
/*0879*/{
/*0880*/ int result = 0;
/*0881*/ unsigned short ip = 0; /* virtual ip */
/*0882*/
/*0883*/ START_TEMPORARY_ROOTS
/*0884*/ unsigned short stackMapIndex = 0;
/*0885*/ /* index into the StackMap table (corresponds
/*0886./ * to jump targets).
/*0887./ */
/*0888*/
/*0889*/ unsigned char *code = thisMethod->u.java.code;
/*0890*/ unsigned short codeLength = thisMethod->u.java.codeLength;
/*0891*/ CONSTANTPOOL constPool = thisMethod->ofClass->constPool;
/*0892*/
/*0893*/ unsigned char* returnSig; /* holds the return signature */
/*0894*/ unsigned short index;
/*0895*/ unsigned short typeKey;
/*0896*/ unsigned char tag;
/*0897*/ bool_t noControlFlow; /* set to TRUE where is no direct control
/*0898./ * flow from current instruction to the next
/*0899./ * instruction in sequence.
/*0900./ */
/*0901*/
/*0902*/ /* This bitmap keeps track of all the NEW instructions that we have
/*0903./ * already seen.
/*0904./ */
/*0905*/ DECLARE_TEMPORARY_ROOT(unsigned long *, NEWInstructions, NULL);
/*0906*/
/*0907*/ /* Fix bug 4336036. Need to check for "final" methods when non-static */
/*0908*/ if ((thisMethod->accessFlags & ACC_STATIC) == 0) {
/*0909*/ if (ROMIZING || thisMethod->ofClass != JavaLangObject) {
/*0910*/ INSTANCE_CLASS thisClass = thisMethod->ofClass;
/*0911*/ INSTANCE_CLASS superClass = thisClass->superClass;
/*0912*/ METHOD superMethod =
/*0913*/ lookupMethod((CLASS)superClass, thisMethod->nameTypeKey,
/*0914*/ thisClass);
/*0915*/ if (superMethod != NULL && (superMethod->accessFlags & ACC_FINAL)) {
/*0916*/ VERIFIER_ERROR(VE_FINAL_METHOD_OVERRIDE);
/*0917*/ }
/*0918*/ }
/*0919*/ }
/*0920*/
/*0921*/ vMaxStack = thisMethod->u.java.maxStack;
/*0922*/ vFrameSize = thisMethod->frameSize;
/*0923*/ IS_TEMPORARY_ROOT(vStack,
/*0924*/ (unsigned short*)
/*0925*/ callocObject(vMaxStack * sizeof(unsigned short), GCT_NOPOINTERS));
/*0926*/ IS_TEMPORARY_ROOT(vLocals,
/*0927*/ (unsigned short*)
/*0928*/ callocObject(vFrameSize * sizeof(unsigned short), GCT_NOPOINTERS));
/*0929*/ vSP = 0; /* initial stack is empty. */
/*0930*/
/*0946*/ {
/*0947*/ /* Verify that all exception handlers have a reasonable value in
/*0948./ * the exception flag.
/*0949./ */
/*0950*/ HANDLERTABLE handlers = thisMethod->u.java.handlers;
/*0951*/ if (handlers) {
/*0952*/ unsigned short exceptionClassKey;
/*0953*/ int i;
/*0954*/ for (i = 0; i < handlers->length; i++) {
/*0955*/ index = handlers->handlers[i].exception;
/*0956*/ if (index) {
/*0957*/ CHECK_VALID_CP_INDEX(constPool, index);
/*0958*/ tag = CONSTANTPOOL_MASKED_TAG(constPool, index);
/*0959*/ if (tag != CONSTANT_Class) {
/*0960*/ VERIFIER_ERROR(VE_EXPECT_CLASS);
/*0961*/ }
/*0962*/ exceptionClassKey =GET_CLASS_CONSTANT_KEY(constPool, index);
/*0963*/ if (!vIsAssignable(exceptionClassKey, throwableClassKey,
/*0964*/ NULL)) {
/*0965*/ VERIFIER_ERROR(VE_EXPECT_THROWABLE);
/*0966*/ }
/*0967*/ }
/*0968*/ }
/*0969*/ }
/*0970*/ }
/*0971*/
/*0972*/ {
/*0973*/ /* Fill in the initial derived stack map with argument types. */
/*0974*/ unsigned char *sig = (unsigned char*)
/*0975*/ change_Key_to_Name(thisMethod->nameTypeKey.nt.typeKey, NULL);
/*0976*/ int nargs = *sig++;
/*0977*/ int i;
/*0978*/ int n;
/*0979*/
/*0980*/ n = 0;
/*0981*/ if (!(thisMethod->accessFlags & ACC_STATIC)) {
/*0982*/ /* add one extra argument for instance methods */
/*0983*/ n++;
/*0984*/ if (thisMethod->nameTypeKey.nt.nameKey == initNameAndType.nt.nameKey &&
/*0985*/ thisMethod->ofClass->clazz.key != objectClassKey) {
/*0986*/ vLocals[0] = ITEM_InitObject;
/*0987*/ } else {
/*0988*/ vLocals[0] = thisMethod->ofClass->clazz.key;
/*0989*/ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -