📄 verifierutil.c
字号:
if (stackMapBase == NULL) {#if INCLUDEDEBUGCODE if (traceverifier) { fprintf(stdout, "No recorded stack map at %ld\n", (long)target_ip); }#endif return !(flags & SM_EXIST); } START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT_FROM_BASE(unsigned short*, stackMap, stackMapBase, stackMapBase);#if INCLUDEDEBUGCODE if (traceverifier) { static void printStackMap(METHOD thisMethod, IPINDEX ip); printStackMap(thisMethod, target_ip); }#endif nlocals = *stackMap++; /* We implicitly need to still perform initialization if * one local or stack variable contains ITEM_InitObject */ target_needs_initialization = FALSE; for (i = 0; i < nlocals; i++) { unsigned short ty = *stackMap++; unsigned short mergedType = ty; if (ty == ITEM_InitObject) { target_needs_initialization = TRUE; } if ((SM_CHECK & flags) && !vIsAssignable(vLocals[i], ty, &mergedType)) { result = FALSE; goto done; } if (SM_MERGE & flags) { vLocals[i] = mergedType; } } if (SM_MERGE & flags) { for (i = nlocals; i < vFrameSize; i++) { vLocals[i] = ITEM_Bogus; } } nstack = *stackMap++; if ((SM_CHECK & flags) && nstack != vSP) { result = FALSE; goto done; } if (SM_MERGE & flags) { vSP = nstack; } for (i = 0; i < nstack; i++) { unsigned short ty = *stackMap++; unsigned short mergedType = ty; if (ty == ITEM_InitObject) { target_needs_initialization = TRUE; } if ((SM_CHECK & flags) && !vIsAssignable(vStack[i], ty, &mergedType)) { result = FALSE; goto done; } if (SM_MERGE & flags) { vStack[i] = mergedType; } } if (methodBeingVerified->nameTypeKey.nt.nameKey == initNameAndType.nt.nameKey) { if (vNeedInitialization && !target_needs_initialization) { /* We still need to perform initialization, but we are * merging into a location that doesn't. */ result = FALSE; goto done; } if (SM_MERGE & flags) { vNeedInitialization = target_needs_initialization; } } done: END_TEMPORARY_ROOTS return result;}/*========================================================================= * FUNCTION: checkNewObject * TYPE: private operation on type keys * OVERVIEW: Check if uninitialized objects exist on backward branches. * * INTERFACE: * parameters: this_ip: current ip * target_ip: branch target ip * returns: TRUE if no uninitialized objects exist, FALSE otherwise. *=======================================================================*/bool_t checkNewObject(IPINDEX this_ip, IPINDEX target_ip) { if (target_ip < this_ip) { int i; for (i = 0; i < vFrameSize; i++) { if (vLocals[i] & ITEM_NewObject_Flag) { return FALSE; } } for (i = 0; i < vSP; i++) { if (vStack[i] & ITEM_NewObject_Flag) { return FALSE; } } } return TRUE;}/*========================================================================= * FUNCTION: verifyClass * TYPE: public operation on classes. * OVERVIEW: Perform byte-code verification of a given class. Iterate * through all methods. * * INTERFACE: * parameters: thisClass: class to be verified. * returns: 0 if verification succeeds, error code if verification * fails. *=======================================================================*/int verifyClass(INSTANCE_CLASS thisClass) { static int Vfy_verifyMethod(METHOD vMethod); int i; int result = 0;#if USESTATIC CONSTANTPOOL cp = thisClass->constPool;#endif if (thisClass->methodTable) { if (!checkVerifiedClassList(thisClass)) { /* Verify all methods */ for (i = 0; i < thisClass->methodTable->length; i++) { METHOD thisMethod = &thisClass->methodTable->methods[i]; /* Skip special synthesized methods. */ if (thisMethod == RunCustomCodeMethod) { continue; } /* Skip abstract and native methods. */ if (thisMethod->accessFlags & (ACC_NATIVE | ACC_ABSTRACT)) { continue; } /* * Call the core routine */ result = Vfy_verifyMethod(thisMethod); if (result != 0) { break; } } if (result == 0) { /* Add this newly verified class to verified class list. */ appendVerifiedClassList(thisClass); } } /* Rewrite the stack maps */ for (i = 0; i < thisClass->methodTable->length; i++) { METHOD thisMethod = &thisClass->methodTable->methods[i]; if (thisMethod->u.java.stackMaps.verifierMap != NULL) { STACKMAP newStackMap = (result == 0) ? rewriteVerifierStackMapsAsPointerMaps(thisMethod) : NULL;#if !USESTATIC thisMethod->u.java.stackMaps.pointerMap = newStackMap;#else int offset = (char *)&thisMethod->u.java.stackMaps.pointerMap - (char *)cp; modifyStaticMemory(cp, offset, &newStackMap, sizeof(STACKMAP));#endif } } } if (result == 0) { thisClass->status = CLASS_VERIFIED; } return result;}/*========================================================================= * Debugging and printing operations *=======================================================================*//*========================================================================= * FUNCTION: printStackType, printStackMap * TYPE: debugging operations * OVERVIEW: Print verifier-related information * * INTERFACE: * parameters: pretty obvious * returns: *=======================================================================*/#if INCLUDEDEBUGCODE/* Print a string, and add padding. */static voidprint_str(char *str){ int i; fprintf(stdout, "%s", str); i = 30 - strlen(str); while (i > 0) { fprintf(stdout, " "); i--; }}/* Print a type key */static voidprintStackType(METHOD thisMethod, unsigned short key){ char buf[128]; switch (key) { case 0xFFF: print_str("-"); return; case ITEM_Bogus: print_str("*"); return; case ITEM_Integer: print_str("I"); return;#if IMPLEMENTS_FLOAT case ITEM_Float: print_str("F"); return; case ITEM_Double: print_str("D"); return;#endif case ITEM_Long: print_str("J"); return; case ITEM_Null: print_str("null"); return; case ITEM_InitObject: print_str("this"); return; case ITEM_Long_2: print_str("J2"); return;#if IMPLEMENTS_FLOAT case ITEM_Double_2: print_str("D2"); return;#endif default: /* ITEM_Object and ITEM_NewObject */ if (key & ITEM_NewObject_Flag) { sprintf(buf, "new %ld", (long)DECODE_NEWOBJECT(key)); print_str(buf); } else { print_str(change_Key_to_FieldSignature(key)); } return; }}#define MAX(a,b) ((a) > (b) ? (a) : (b))/* Print the derived stackmap and recorded stackmap (if it exists) at * a given ip. */static voidprintStackMap(METHOD thisMethod, unsigned short ip){ START_TEMPORARY_ROOTS unsigned short* stackMapX = getStackMap(thisMethod, ip); DECLARE_TEMPORARY_ROOT_FROM_BASE(unsigned short*, stackMap, stackMapX, stackMapX); int nlocals, nstack, i; int lTop; for (lTop = vFrameSize; lTop > 0; lTop--) { if (vLocals[lTop - 1] != ITEM_Bogus) { break; } } fprintf(stdout, "__SLOT__DERIVED_______________________"); if (stackMap) { fprintf(stdout, "RECORDED______________________\n"); } else { fprintf(stdout, "\n"); } nlocals = stackMap ? (*stackMap++) : 0; for (i = 0; i < MAX(lTop, nlocals); i++) { unsigned short ty; if (i < 100) { fprintf(stdout, " "); if (i < 10) { fprintf(stdout, " "); } } fprintf(stdout, "L[%ld] ", (long)i); if (i < lTop) { ty = vLocals[i]; } else { ty = 0xFFF; } printStackType(thisMethod, ty); if (stackMap) { if (i < nlocals) { ty = *stackMap++; } else { ty = 0xFFF; } printStackType(thisMethod, ty); } fprintf(stdout, "\n"); } nstack = stackMap ? (*stackMap++) : 0; for (i = 0; i < MAX(vSP, nstack); i++) { unsigned short ty; if (i < 100) { fprintf(stdout, " "); if (i < 10) { fprintf(stdout, " "); } } fprintf(stdout, "S[%ld] ", (long)i); if (i < vSP) { ty = vStack[i]; } else { ty = 0xFFF; } printStackType(thisMethod, ty); if (stackMap) { if (i < nstack) { ty = *stackMap++; } else { ty = 0xFFF; } printStackType(thisMethod, ty); } fprintf(stdout, "\n"); } END_TEMPORARY_ROOTS}#endif /* INCLUDEDEBUGCODE *//*========================================================================= * New verifier functions *=======================================================================*//* ------------------------------------------------------------------------ *\ * Initialization *\* ------------------------------------------------------------------------ *//*========================================================================= * FUNCTION: Vfy_initializeLocals * TYPE: private operation * OVERVIEW: Initialize the local variable types from the method * signature * * INTERFACE: * parameters: None * returns: Nothing *=======================================================================*/void Vfy_initializeLocals() { /* Fill in the initial derived stack map with argument types. */ unsigned char *sig = (unsigned char*) change_Key_to_Name(methodBeingVerified->nameTypeKey.nt.typeKey, NULL); int nargs = *sig++; int i; int n; n = 0; vNeedInitialization = FALSE; if (!Mth_isStatic(methodBeingVerified)) { /* add one extra argument for instance methods */ n++; if (methodBeingVerified->nameTypeKey.nt.nameKey == initNameAndType.nt.nameKey && methodBeingVerified->ofClass->clazz.key != Vfy_getObjectVerifierType()) { vLocals[0] = ITEM_InitObject; vNeedInitialization = TRUE; } else { vLocals[0] = methodBeingVerified->ofClass->clazz.key; } } for (i = 0; i < nargs; i++) { n += change_Arg_to_StackType(&sig, &vLocals[n]); } returnSig = sig;}/* ------------------------------------------------------------------------ *\ * General functions *\* ------------------------------------------------------------------------ *//*========================================================================= * FUNCTION: Vfy_getOpcode * TYPE: private operation * OVERVIEW: Get an opcode from the bytecode array. * If it is a BREAKPOINT then get * the real instruction from the debugger * * INTERFACE: * parameters: IPINDEX of the bytecode * returns: The opcode *=======================================================================*/int Vfy_getOpcode(IPINDEX ip) { int opcode = Vfy_getUByte(ip);#if ENABLE_JAVA_DEBUGGER if (opcode == BREAKPOINT) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -