Path: blob/master/runtime/bcverify/rtverify.c
12499 views
/*******************************************************************************1* Copyright (c) 1991, 2022 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include "bcvcfr.h"23#include "j9bcvnls.h"24#include "cfrerrnls.h"2526#include "cfreader.h"27#include "bcnames.h"28#include "pcstack.h"29#include "j9protos.h"30#include "j9consts.h"31#include "omrthread.h"32#include "jvminit.h"33#include "vrfyconvert.h"34#include "bcverify.h"35#include "bcverify_internal.h"36#include "vrfytbl.h"37#include "j9cp.h"3839#include "ut_j9bcverify.h"404142static IDATA verifyBytecodes (J9BytecodeVerificationData * verifyData);43static IDATA matchStack (J9BytecodeVerificationData * verifyData, J9BranchTargetStack *liveStack, J9BranchTargetStack * targetStack, UDATA inlineMatch);44static IDATA findAndMatchStack (J9BytecodeVerificationData *verifyData, IDATA targetPC, IDATA currentPC);45static IDATA verifyExceptions (J9BytecodeVerificationData *verifyData);46static J9BranchTargetStack * nextStack (J9BytecodeVerificationData *verifyData, UDATA *nextMapIndex, IDATA *nextStackPC);47static IDATA nextExceptionStart (J9BytecodeVerificationData *verifyData, J9ROMMethod *romMethod, IDATA lastPC);48static void storeArgumentErrorData (J9BytecodeVerificationData * verifyData, U_32 errorCurrentFramePosition, U_16 errorArgumentIndex);49static void storeMethodInfo (J9BytecodeVerificationData * verifyData, J9UTF8* errorClassString, J9UTF8* errorMethodString, J9UTF8* errorSignatureString, IDATA currentPC);5051/*52* returns J9Class * on success53* returns NULL on error54* set reasonCode to BCV_ERR_INSUFFICIENT_MEMORY on OOM55*/56J9Class *57j9rtv_verifierGetRAMClass( J9BytecodeVerificationData *verifyData, J9ClassLoader* classLoader, U_8 *className, UDATA nameLength, IDATA *reasonCode)58{59J9Class *found = NULL;60JavaVM* jniVM = (JavaVM*)verifyData->javaVM;61J9ThreadEnv* threadEnv = NULL;62J9JavaVM *vm = verifyData->vmStruct->javaVM;63(*jniVM)->GetEnv(jniVM, (void**)&threadEnv, J9THREAD_VERSION_1_1);6465#ifdef J9VM_THR_PREEMPTIVE66threadEnv->monitor_enter(vm->classTableMutex);67#endif6869/* Sniff the class table to see if already loaded */70Trc_RTV_j9rtv_verifierGetRAMClass_Entry(verifyData->vmStruct, classLoader, nameLength, className);71found = vm->internalVMFunctions->hashClassTableAt (classLoader, className, nameLength);7273#ifdef J9VM_THR_PREEMPTIVE74threadEnv->monitor_exit(vm->classTableMutex);75#endif7677if (!found) {78/* Set reasonCode to BCV_ERR_CLASS_RELATIONSHIP_RECORD_REQUIRED if -XX:+ClassRelationshipVerifier is used, the class is not already loaded and if the classfile major version is at least 51 (Java 7) */79if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_ENABLE_CLASS_RELATIONSHIP_VERIFIER) && (verifyData->romClass->majorVersion >= 51)) {80*reasonCode = BCV_ERR_CLASS_RELATIONSHIP_RECORD_REQUIRED;81return NULL;82} else {83J9BytecodeVerificationData savedVerifyData;84UDATA *currentAlloc;85UDATA *internalBufferStart;86UDATA *internalBufferEnd;87J9VMThread *tmpVMC = verifyData->vmStruct;8889Trc_RTV_j9rtv_verifierGetRAMClass_notFound(verifyData->vmStruct);9091/* Nest class loading */92memcpy(&savedVerifyData, verifyData, sizeof(savedVerifyData));93verifyData->vmStruct = NULL;9495if (BCV_ERR_INSUFFICIENT_MEMORY == allocateVerifyBuffers (tmpVMC->javaVM->portLibrary, verifyData)) {96/* returning BCV_ERR_INSUFFICIENT_MEMORY for OOM condition */97Trc_RTV_j9rtv_verifierGetRAMClass_OutOfMemoryException(verifyData->vmStruct, classLoader, nameLength, className);98*reasonCode = BCV_ERR_INSUFFICIENT_MEMORY;99return NULL;100}101102#ifdef J9VM_THR_PREEMPTIVE103threadEnv->monitor_exit(verifyData->verifierMutex);104#endif105106/* Find the requested class, fully loading it, but not initializing it. */107108found = tmpVMC->javaVM->internalVMFunctions->internalFindClassUTF8(109tmpVMC,110className,111nameLength,112classLoader,113J9_FINDCLASS_FLAG_THROW_ON_FAIL);114115if (NULL == found) {116*reasonCode = BCV_ERR_INACCESSIBLE_CLASS;117}118119#ifdef J9VM_THR_PREEMPTIVE120/*121* Note: if locking both verifierMutex and classTableMutex, they must be entered in that order (CMVC 186043).122*/123124threadEnv->monitor_enter(verifyData->verifierMutex);125#endif126127freeVerifyBuffers (tmpVMC->javaVM->portLibrary, verifyData);128129/* The currentAlloc, internalBufferStart, internalBufferEnd fields are NOT nested */130/* used in bcvalloc/bcvfree - avoid hammering it */131/* This should probably be moved out of the struct, but where? - split the struct by scope */132currentAlloc = verifyData->currentAlloc;133internalBufferStart = verifyData->internalBufferStart;134internalBufferEnd = verifyData->internalBufferEnd;135136memcpy(verifyData, &savedVerifyData, sizeof(savedVerifyData));137138verifyData->currentAlloc = currentAlloc;139verifyData->internalBufferStart = internalBufferStart;140verifyData->internalBufferEnd = internalBufferEnd;141}142} else {143Trc_RTV_j9rtv_verifierGetRAMClass_found(verifyData->vmStruct);144}145146Trc_RTV_j9rtv_verifierGetRAMClass_Exit(verifyData->vmStruct);147148return found;149}150151152/*153* returns BCV_SUCCESS on success154* returns BCV_ERR_INSUFFICIENT_MEMORY on OOM155* returns BCV_ERR_INTERNAL_ERROR on error156*/157IDATA158j9rtv_verifyBytecodes (J9BytecodeVerificationData *verifyData)159{160J9ROMClass *romClass = verifyData->romClass;161J9ROMMethod *romMethod = verifyData->romMethod;162163UDATA oldState = verifyData->vmStruct->omrVMThread->vmState;164IDATA result = BCV_SUCCESS;165166verifyData->vmStruct->omrVMThread->vmState = J9VMSTATE_RTVERIFY;167168Trc_RTV_j9rtv_verifyBytecodes_Entry(verifyData->vmStruct,169(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass)),170J9UTF8_DATA(J9ROMCLASS_CLASSNAME(romClass)));171172if (romMethod->modifiers & CFR_ACC_HAS_EXCEPTION_INFO) {173result = verifyExceptions (verifyData);174}175176/* Go walk the bytecodes */177if (BCV_SUCCESS == result) {178result = verifyBytecodes (verifyData);179}180181if (BCV_SUCCESS != result) {182if (BCV_ERR_INSUFFICIENT_MEMORY == result) {183Trc_RTV_j9rtv_verifyBytecodes_OutOfMemoryException(verifyData->vmStruct,184(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass)),185J9UTF8_DATA(J9ROMCLASS_CLASSNAME(romClass)));186187verifyData->errorModule = J9NLS_BCV_ERR_VERIFY_OUT_OF_MEMORY__MODULE;188verifyData->errorCode = J9NLS_BCV_ERR_VERIFY_OUT_OF_MEMORY__ID;189} else {190verifyData->errorModule = J9NLS_BCV_ERR_NOT_THROWABLE__MODULE;191verifyData->errorCode = J9NLS_BCV_ERR_NOT_THROWABLE__ID;192}193Trc_RTV_j9rtv_verifyBytecodes_VerifyError(verifyData->vmStruct, verifyData->errorCode, verifyData->errorPC);194}195196verifyData->vmStruct->omrVMThread->vmState = oldState;197Trc_RTV_j9rtv_verifyBytecodes_Exit(verifyData->vmStruct);198199return result;200}201202203/*204REMOVED: ( Check for backwards branching and if found, look for uninitialized objects. )205Find the target stack and then match.206This is only called to match out-of-line stacks - branches and switches.207return BCV_SUCCESS on finding matching stack208return BCV_FAIL on stack mismatch209return BCV_ERR_INSUFFICIENT_MEMORY on OOM210*/211212static IDATA213findAndMatchStack (J9BytecodeVerificationData *verifyData, IDATA targetPC, IDATA currentPC)214{215U_32 *bytecodeMap = verifyData->bytecodeMap;216J9BranchTargetStack *liveStack = (J9BranchTargetStack *) verifyData->liveStack;217J9BranchTargetStack *targetStack;218UDATA stackIndex;219IDATA rc = BCV_SUCCESS;220221Trc_RTV_findAndMatchStack_Entry(verifyData->vmStruct, currentPC, targetPC);222223if (bytecodeMap[targetPC] & BRANCH_TARGET) {224stackIndex = bytecodeMap[targetPC] >> BRANCH_INDEX_SHIFT;225targetStack = BCV_INDEX_STACK (stackIndex);226227/* backwards branch? */228if (targetPC < currentPC) {229/* Ensure we never backwards branch to code that has an initialized this when this code doesn't.230* Remember: the verifier does a *linear* walk of the bytecodes.231*/232if (TRUE == liveStack->uninitializedThis) {233if (TRUE != targetStack->uninitializedThis) {234rc = BCV_FAIL;235goto exit;236}237}238}239240/* Never considered an inline match if we perform a find */241rc = matchStack (verifyData, liveStack, targetStack, FALSE);242} else {243/* failed to find map */244Trc_RTV_findAndMatchStack_StackNotFound(verifyData->vmStruct,245(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),246J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),247(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),248J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),249(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),250J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),251targetPC);252rc = BCV_FAIL;253verifyData->errorDetailCode = BCV_ERR_EXPECT_STACKMAP_FRAME;254/* Set the branch target PC value to show up in the error message framework */255verifyData->errorTempData = targetPC;256}257exit:258/* Jazz 82615: errorDetailCode has been initialized with 0 (SUCCESS).259* liveStack->pc should be updated to the current pc value when any260* verification error is detected above.261*/262if (verifyData->errorDetailCode < 0) {263liveStack->pc = (UDATA)currentPC;264}265Trc_RTV_findAndMatchStack_Exit(verifyData->vmStruct, rc);266return rc;267}268269270/*271Returns272BCV_SUCCESS on success,273BCV_FAIL on stack mismatch.274BCV_ERR_INSUFFICIENT_MEMORY on OOM.275*/276static IDATA277matchStack(J9BytecodeVerificationData * verifyData, J9BranchTargetStack *liveStack, J9BranchTargetStack * targetStack, UDATA inlineMatch)278{279UDATA *livePtr = liveStack->stackElements;280UDATA *liveTop = RELOAD_STACKTOP(liveStack);281UDATA *targetPtr = targetStack->stackElements;282UDATA *targetTop = RELOAD_STACKTOP(targetStack);283UDATA size = liveStack->stackTopIndex;284IDATA rc = BCV_SUCCESS;285IDATA reasonCode = 0;286287Trc_RTV_matchStack_Entry(verifyData->vmStruct, inlineMatch);288289if (size != (UDATA) targetStack->stackTopIndex) {290Trc_RTV_matchStack_DepthMismatchException(verifyData->vmStruct,291(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),292J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),293(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),294J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),295(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),296J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),297size, targetStack->stackTopIndex);298rc = BCV_FAIL; /* fail - stack depth mismatch */299verifyData->errorDetailCode = BCV_ERR_STACK_SIZE_MISMATCH;300/* There are two situations for setting the location of data type on 'stack':301* 1) size == 0: it means (U_32)(liveTop - liveStack->stackElements) == 0302* and only show up the 1st data type on 'stack'.303* 2) size > 0: given the stackTop pointer always points to the next slot304* after pushing data type onto 'stack', it needs to step back305* by 1 slot to the latest valid data type.306*/307livePtr = (size > 0) ? (liveTop - 1) : liveTop;308goto _errorLocation;309}310311/* Note: Target stack frame flag needs to be subset of ours. See JVM sepc 4.10.1.4 */312if (liveStack->uninitializedThis && !targetStack->uninitializedThis) {313rc = BCV_FAIL;314goto _finished;315}316317while (livePtr != liveTop) {318319if (*livePtr != *targetPtr) {320if ((*targetPtr & BCV_BASE_OR_SPECIAL) == 0) {321rc = isClassCompatible (verifyData, *livePtr, *targetPtr, &reasonCode);322323if (FALSE == rc) {324if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {325Trc_RTV_matchStack_OutOfMemoryException(verifyData->vmStruct,326(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),327J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),328(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),329J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),330(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),331J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)));332rc = BCV_ERR_INSUFFICIENT_MEMORY;333goto _finished;334} else {335Trc_RTV_matchStack_IncompatibleClassException(verifyData->vmStruct,336(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),337J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),338(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),339J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),340(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),341J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),342(livePtr - liveStack->stackElements), *livePtr, *targetPtr);343rc = BCV_FAIL; /* fail - object type mismatch*/344goto _incompatibleType;345}346}347} else if (*targetPtr != BCV_BASE_TYPE_TOP) {348if ((*targetPtr & BCV_SPECIAL_INIT) && verifyData->createdStackMap) {349/* Generated stackmaps can skip the check on the target slot with BCV_SPECIAL_INIT350* as this slot is set up based on the bytecode itself rather than decompressed stackmaps.351*/352} else {353Trc_RTV_matchStack_PrimitiveOrSpecialMismatchException(verifyData->vmStruct,354(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),355J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),356(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),357J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),358(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),359J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),360(livePtr - liveStack->stackElements), *livePtr, *targetPtr);361rc = BCV_FAIL; /* fail - primitive or special mismatch */362goto _incompatibleType;363}364}365}366livePtr++;367targetPtr++;368}369370if (inlineMatch) {371/* hammer the live stack to be the target stack */372Trc_RTV_matchStack_InlineMatchEvent(verifyData->vmStruct);373livePtr = liveStack->stackElements;374targetPtr = targetStack->stackElements;375memcpy (livePtr, targetPtr, size * sizeof(UDATA));376377/* Propagate the uninitialized_this flag to targetStack if liveStack is uninitialized */378if (((UDATA)TRUE == liveStack->uninitializedThis) || ((UDATA)TRUE == targetStack->uninitializedThis)) {379liveStack->uninitializedThis = targetStack->uninitializedThis = TRUE;380}381}382383rc = BCV_SUCCESS;384385_finished:386Trc_RTV_matchStack_Exit(verifyData->vmStruct, rc);387return rc;388389_incompatibleType:390/* errorDetailCode has been initialized with 0 (SUCCESS).391* Verification error data for incompatible data type should be saved here when any verification error occurs is detected above.392*/393verifyData->errorDetailCode = BCV_ERR_FRAMES_INCOMPATIBLE_TYPE;394verifyData->errorTargetType = *targetPtr;395_errorLocation:396verifyData->errorCurrentFramePosition = (U_32)(livePtr - liveStack->stackElements);397verifyData->errorTargetFrameIndex = (U_32)BCV_STACK_INDEX(targetStack);398goto _finished;399}400401402/*403Walk the bytecodes linearly and verify that the recorded stack maps match.404405returns BCV_SUCCESS on success406returns BCV_ERR_INTERNAL_ERROR on verification error407returns BCV_ERR_INSUFFICIENT_MEMORY on OOM408*/409410static IDATA411verifyBytecodes (J9BytecodeVerificationData * verifyData)412{413#define CHECK_END \414if (pc > length) { \415errorType = J9NLS_BCV_ERR_UNEXPECTED_EOF__ID; \416verboseErrorCode = BCV_ERR_UNEXPECTED_EOF; \417index = (UDATA)-1; \418goto _miscError; \419}420421J9ROMClass * romClass = verifyData->romClass;422J9ROMMethod * romMethod = verifyData->romMethod;423J9BranchTargetStack *liveStack;424J9BranchTargetStack *currentMapData = NULL;425UDATA nextMapIndex = 0;426IDATA start = 0;427UDATA pc, length, index;428J9ROMConstantPoolItem *constantPool;429J9ROMConstantPoolItem *info;430J9ROMStringRef *classRef;431J9UTF8 *utf8string;432U_8 *code, *temp, *bcIndex;433UDATA returnChar;434UDATA bc = 0;435UDATA i;436UDATA inconsistentStack = FALSE;437UDATA inconsistentStack2 = FALSE;438UDATA type, type1, type2, arrayType, temp1, temp2, temp3, popCount, receiver, cpIndex;439UDATA action = RTV_NOP;440UDATA *stackBase, *stackTop, *temps;441UDATA *ptr;442IDATA target;443IDATA i1, i2;444U_8 *className;445UDATA classIndex, maxStack;446UDATA wideIndex = FALSE;447IDATA nextStackPC;448IDATA nextExceptionStartPC;449IDATA rc = 0;450U_8 returnBytecode;451UDATA errorModule = J9NLS_BCV_ERR_BYTECODES_INVALID__MODULE; /* defaults to BCV NLS catalog */452U_16 errorType;453I_16 offset16;454I_32 offset32;455UDATA argCount;456UDATA checkIfInsideException = romMethod->modifiers & J9AccMethodHasExceptionInfo;457UDATA tempStoreChange;458J9ExceptionInfo *exceptionInfo = J9_EXCEPTION_DATA_FROM_ROM_METHOD(romMethod);459J9ExceptionHandler *handler;460J9UTF8 *catchName;461UDATA catchClass;462J9SRP *callSiteData = (J9SRP *) J9ROMCLASS_CALLSITEDATA(romClass);463UDATA* originalStackTop;464UDATA originalStackZeroEntry;465BOOLEAN isInitMethod;466IDATA verboseErrorCode = 0;467/* Jazz 82615: Initialized by default if unused */468UDATA errorTargetType = (UDATA)-1;469UDATA errorStackIndex = (UDATA)-1;470UDATA errorTempData = (UDATA)-1;471BOOLEAN isNextStack = FALSE;472473Trc_RTV_verifyBytecodes_Entry(verifyData->vmStruct,474(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(romMethod)),475J9UTF8_DATA(J9ROMMETHOD_NAME(romMethod)),476(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(romMethod)),477J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(romMethod)));478479pc = 0;480481liveStack = (J9BranchTargetStack *) verifyData->liveStack;482stackTop = &(liveStack->stackElements[0]);483484/* Determine the initial stack map from the method signature */485isInitMethod = liveStack->uninitializedThis = buildStackFromMethodSignature (verifyData, &stackTop, &argCount);486487code = J9_BYTECODE_START_FROM_ROM_METHOD(romMethod);488length = (UDATA) J9_BYTECODE_SIZE_FROM_ROM_METHOD(romMethod);489maxStack = J9_MAX_STACK_FROM_ROM_METHOD(romMethod);490491if (argCount != romMethod->argCount) {492errorType = J9NLS_BCV_ERR_ARGUMENTS_INCOMPATIBLE__ID; /* correct error code ??? */493/* Jazz 82615: Set the error code and the mismatched argument calculated from the method's signature */494verboseErrorCode = BCV_ERR_ARGUMENTS_MISMATCH;495errorTempData = argCount;496goto _miscError;497}498499/* Set the base just past the temps - only args and temps are on the stack after building the signature */500/* args and temps are accessed relative to liveStack->stackElements */501SAVE_STACKTOP(liveStack, stackTop);502liveStack->stackBaseIndex = liveStack->stackTopIndex;503504/* Jazz 105041: Initialize the 1st data slot on 'stack' with 'top' (placeholdler)505* to avoid storing garbage data type in the error message buffer506* when stack underflow occurs.507*/508liveStack->stackElements[liveStack->stackBaseIndex] = BCV_BASE_TYPE_TOP;509510RELOAD_LIVESTACK;511512/* result in temp1 is ignored */513returnBytecode = getReturnBytecode (romClass, romMethod, &temp1);514515bcIndex = code;516517constantPool = J9_ROM_CP_FROM_ROM_CLASS(romClass);518519currentMapData = nextStack (verifyData, &nextMapIndex, &nextStackPC);520521/* Determine where the first region of bytecodes covered by an exception handler is */522nextExceptionStartPC = nextExceptionStart (verifyData, romMethod, -1);523524/* walk the bytecodes linearly */525while (pc < length) {526if (inconsistentStack) {527_inconsistentStack:528/* Jazz 82615: Only used for cases when errorType has not yet been set up for the verification error */529errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;530_inconsistentStack2:531/* Jazz 82615: Store all verification error data here when the incompatible type issue is detected.532* Note: errorTempData is set to -1 by default if unused when verification error occurs.533*/534storeVerifyErrorData(verifyData, BCV_ERR_INCOMPATIBLE_TYPE, (U_32)errorStackIndex, errorTargetType, errorTempData, start);535goto _verifyError;536}537538if ((UDATA) (stackTop - stackBase) > maxStack) {539errorType = J9NLS_BCV_ERR_STACK_OVERFLOW__ID;540/* Jazz 82615: Set the error code and the location of wrong data type on stack (only keep the maximum size for stack) */541verboseErrorCode = BCV_ERR_STACK_OVERFLOW;542errorStackIndex = stackBase - liveStack->stackElements;543if (maxStack > 0) {544errorStackIndex += maxStack - 1;545}546goto _miscError;547}548549/* If we are at the point of the next stack map, ensure that the current stack matches the mapped stack */550if (pc == (UDATA) nextStackPC) {551SAVE_STACKTOP(liveStack, stackTop);552rc = matchStack (verifyData, liveStack, currentMapData, TRUE);553if (BCV_SUCCESS != rc) {554if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {555goto _outOfMemoryError;556}557/* Jazz 82615: Set liveStack->pc to the next pc value rather than the current pc value (start)558* in the case of the matched stack frame in the current frame (liveStack)559* of the detailed error message560*/561liveStack->pc = pc;562goto _mapError;563}564565/* Matched the expected next stack, find a new next stack */566currentMapData = nextStack (verifyData, &nextMapIndex, &nextStackPC);567}568569/* Check the stack against the exception handler stack */570if (pc == (UDATA) nextExceptionStartPC) {571handler = J9EXCEPTIONINFO_HANDLERS(exceptionInfo);572SAVE_STACKTOP(liveStack, stackTop);573574/* Save the current liveStack element zero */575/* Reset the stack pointer and push the exception on the empty stack */576originalStackTop = stackTop;577originalStackZeroEntry = liveStack->stackElements[liveStack->stackBaseIndex];578579/* Find all exception handlers from here */580for (i = exceptionInfo->catchCount; i; i--, handler++) {581if (handler->startPC == pc) {582/* Check the maps at the handler PC */583/* Modify the liveStack temporarily to contain the handler exception */584if (handler->exceptionClassIndex) {585catchName = J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *)(&constantPool [handler->exceptionClassIndex]));586catchClass = convertClassNameToStackMapType(verifyData, J9UTF8_DATA(catchName), J9UTF8_LENGTH(catchName), 0, 0);587} else {588catchClass = BCV_JAVA_LANG_THROWABLE_INDEX;589catchClass <<= BCV_CLASS_INDEX_SHIFT;590}591592/* Empty the stack */593stackTop = &(liveStack->stackElements[liveStack->stackBaseIndex]);594PUSH(catchClass);595SAVE_STACKTOP(liveStack, stackTop);596597rc = findAndMatchStack (verifyData, handler->handlerPC, start);598if (BCV_SUCCESS != rc) {599if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {600goto _outOfMemoryError;601}602goto _mapError;603}604}605}606607/* Restore liveStack */608liveStack->stackElements[liveStack->stackBaseIndex] = originalStackZeroEntry;609stackTop = originalStackTop;610611/* Get next exception start PC of interest */612nextExceptionStartPC = nextExceptionStart (verifyData, romMethod, nextExceptionStartPC);613}614615bcIndex = code + pc;616617bc = *bcIndex;618619start = pc;620pc += (J9JavaInstructionSizeAndBranchActionTable[bc] & 7);621CHECK_END;622623if ((stackTop - (JavaStackActionTable[bc] & 7)) < stackBase) {624errorType = J9NLS_BCV_ERR_STACK_UNDERFLOW__ID;625/* Jazz 82615: Set the error code and the location of data type involved626* when the verification error related to stack underflow occurs.627*/628verboseErrorCode = BCV_ERR_STACK_UNDERFLOW;629/* Given that the actual data type involved has not yet been located630* through pop operation when stack underflow occurs,631* it needs to step back by 1 slot to the actual data type to be manipulated by the opcode.632*/633errorStackIndex = (stackTop - liveStack->stackElements) - 1;634/* Always set to the location of the 1st data type on 'stack' to show up if stackTop <= stackBase635* Note: this setup is disabled to avoid decoding the garbage data in the error messages636* if the current stack frame is loaded from the next stack (without data on the stack)637* of the stackmaps.638*/639if ((stackTop <= stackBase) && !isNextStack) {640errorStackIndex = stackBase - liveStack->stackElements;641}642goto _miscError;643}644/* Reset as the flag is only used for the current bytecode */645isNextStack = FALSE;646647/* Format: 8bits action, 4bits type Y, 4bits type X */648type1 = (UDATA) J9JavaBytecodeVerificationTable[bc];649action = type1 >> 8;650type2 = (type1 >> 4) & 0xF;651type1 = (UDATA) decodeTable[type1 & 0xF];652type2 = (UDATA) decodeTable[type2];653654/* Many bytecodes are isomorphic - ie have the same actions on the stack. Walk655* based on the action type, rather than the individual bytecode.656*/657switch (action) {658case RTV_NOP:659break;660661case RTV_WIDE_LOAD_TEMP_PUSH:662wideIndex = TRUE; /* Fall through case !!! */663664case RTV_LOAD_TEMP_PUSH:665index = type2 & 0x7;666if (type2 == 0) {667index = PARAM_8(bcIndex, 1);668if (wideIndex) {669index = PARAM_16(bcIndex, 1);670wideIndex = FALSE;671}672}673if (temps[index] != type1) {674if ((type1 != BCV_GENERIC_OBJECT) || (temps[index] & BCV_TAG_BASE_TYPE_OR_TOP)) {675inconsistentStack = TRUE;676/* Jazz 82615: Set the expected data type and the location of wrong data type677* on stack (already in index) when the verification error occurs.678*/679errorTargetType = type1;680errorStackIndex = index;681goto _inconsistentStack;682}683}684if (type1 == BCV_GENERIC_OBJECT) {685PUSH(temps[index]);686break;687}688if (type1 & BCV_WIDE_TYPE_MASK) {689CHECK_TEMP((index + 1), BCV_BASE_TYPE_TOP);690if (inconsistentStack) {691/* Jazz 82615: Set the expected long/double type (already in type1)692* and the location of wrong data type on stack when the verification error occurs.693*/694errorTargetType = BCV_BASE_TYPE_TOP;695/* Save the long/double type to errorTempData (verifyData->errorTempData)696* so as to ensure the wrong data type is the 2nd slot of long/double type697* in the error message framework rather than a 'top' type.698*/699errorTempData = type1;700errorStackIndex = index + 1;701goto _inconsistentStack;702}703} /* Fall through case !!! */704705case RTV_PUSH_CONSTANT:706707_pushConstant:708PUSH(type1);709if (type1 & BCV_WIDE_TYPE_MASK) {710PUSH(BCV_BASE_TYPE_TOP);711}712break;713714case RTV_PUSH_CONSTANT_POOL_ITEM:715switch (bc) {716case JBldc:717case JBldcw:718if (bc == JBldc) {719index = PARAM_8(bcIndex, 1);720} else {721index = PARAM_16(bcIndex, 1);722}723stackTop = pushLdcType(verifyData, romClass, index, stackTop);724break;725726/* Change lookup table to generate constant of correct type */727case JBldc2lw:728PUSH_LONG_CONSTANT;729break;730731case JBldc2dw:732PUSH_DOUBLE_CONSTANT;733break;734}735break;736737case RTV_ARRAY_FETCH_PUSH:738POP_TOS_INTEGER;739if (inconsistentStack) {740/* Jazz 82615: Set the expected data type and the location of wrong data type741* on stack when the verification error occurs.742*/743errorTargetType = BCV_BASE_TYPE_INT;744errorStackIndex = stackTop - liveStack->stackElements;745goto _inconsistentStack;746}747arrayType = POP;748if (arrayType != BCV_BASE_TYPE_NULL) {749if (bc == JBaaload) {750inconsistentStack |= arrayType & BCV_BASE_OR_SPECIAL;751inconsistentStack |= (arrayType & BCV_ARITY_MASK) == 0;752if (inconsistentStack) {753/* Jazz 82615: Set the expected data type (presumably object array with 1 dimension)754* and the location of wrong data type on stack when the verification error occurs.755*/756errorTargetType = (UDATA)(BCV_GENERIC_OBJECT | (1 << BCV_ARITY_SHIFT));757errorStackIndex = stackTop - liveStack->stackElements;758goto _inconsistentStack;759}760type1 = arrayType - 0x01000000; /* reduce types arity by one */761PUSH(type1);762break;763} else {764type = (UDATA) J9JavaBytecodeArrayTypeTable[bc - JBiaload];765/* The operand checking for baload needs to cover the case of boolean arrays */766CHECK_BOOL_ARRAY(JBbaload, bc, type);767if (inconsistentStack) {768/* Jazz 82615: Set the expected data type (already in type) and the location of wrong data type769* on stack when the verification error occurs.770*/771errorTargetType = type;772errorStackIndex = stackTop - liveStack->stackElements;773goto _inconsistentStack;774}775}776}777goto _pushConstant;778break;779780case RTV_WIDE_POP_STORE_TEMP:781wideIndex = TRUE; /* Fall through case !!! */782783case RTV_POP_STORE_TEMP:784index = type2 & 0x7;785if (type2 == 0) {786index = PARAM_8(bcIndex, 1);787if (wideIndex) {788index = PARAM_16(bcIndex, 1);789wideIndex = FALSE;790}791}792POP_TOS_TYPE( type, type1 );793if (inconsistentStack) {794/* Jazz 82615: Set the 2nd slot of long/double type (already in type1) and795* the location of wrong data type on stack when the verification error occurs.796*/797errorTargetType = BCV_BASE_TYPE_TOP;798/* Save the long/double type to errorTempData (verifyData->errorTempData)799* so as to ensure the wrong data type is the 2nd slot of long/double type800* in the error message framework rather than a 'top' type.801*/802errorTempData = type1;803/* The location of wrong data type needs to adjusted back to the right place804* because it pops twice from the stack for the wide type.805*/806errorStackIndex = (stackTop - liveStack->stackElements) + 1;807goto _inconsistentStack;808}809810tempStoreChange = FALSE;811812if (type != type1) {813if ((type1 != BCV_GENERIC_OBJECT) || (type & BCV_TAG_BASE_TYPE_OR_TOP)) {814inconsistentStack = TRUE;815/* Jazz 82615: Set the expected data type and the location of wrong data type816* on stack when the verification error occurs.817*/818errorTargetType = type1;819errorStackIndex = stackTop - liveStack->stackElements;820goto _inconsistentStack;821}822}823824/* because of pre-index local clearing - the order here matters */825if (type1 & BCV_WIDE_TYPE_MASK) {826tempStoreChange = (temps[index + 1] != BCV_BASE_TYPE_TOP);827STORE_TEMP((index + 1), BCV_BASE_TYPE_TOP);828}829tempStoreChange |= (type != temps[index]);830STORE_TEMP(index, type);831832if (checkIfInsideException && tempStoreChange) {833/* If we've stored a value into an arg/local, and it's of a different type than was834* originally there, we need to ensure that we are still compatible with all our835* exception handlers.836*837* For all exception handlers covering this instruction838*/839handler = J9EXCEPTIONINFO_HANDLERS(exceptionInfo);840SAVE_STACKTOP(liveStack, stackTop);841842/* Save the current liveStack element zero */843/* Reset the stack pointer to push the exception on the empty stack */844originalStackTop = stackTop;845originalStackZeroEntry = liveStack->stackElements[liveStack->stackBaseIndex];846847/* Find all exception handlers from here */848for (i = exceptionInfo->catchCount; i; i--, handler++) {849if (((UDATA) start >= handler->startPC) && ((UDATA) start < handler->endPC)) {850#ifdef DEBUG_BCV851printf("exception map change check at startPC: %d\n", handler->startPC);852#endif853/* Check the maps at the handler PC */854/* Modify the liveStack temporarily to contain the handler exception */855if (handler->exceptionClassIndex) {856catchName = J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *)(&constantPool [handler->exceptionClassIndex]));857catchClass = convertClassNameToStackMapType(verifyData, J9UTF8_DATA(catchName), J9UTF8_LENGTH(catchName), 0, 0);858} else {859catchClass = BCV_JAVA_LANG_THROWABLE_INDEX;860catchClass <<= BCV_CLASS_INDEX_SHIFT;861}862863stackTop = &(liveStack->stackElements[liveStack->stackBaseIndex]);864PUSH(catchClass);865SAVE_STACKTOP(liveStack, stackTop);866867rc = findAndMatchStack (verifyData, handler->handlerPC, start);868if (BCV_SUCCESS != rc) {869if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {870goto _outOfMemoryError;871}872goto _mapError;873}874}875}876877/* Restore liveStack */878liveStack->stackElements[liveStack->stackBaseIndex] = originalStackZeroEntry;879stackTop = originalStackTop;880}881break;882883case RTV_ARRAY_STORE:884POP_TOS_TYPE( type, type1 );885if (inconsistentStack) {886/* Jazz 82615: Set the 2nd slot of long/double type (already in type1) and887* the location of wrong data type on stack when the verification error occurs.888*/889errorTargetType = BCV_BASE_TYPE_TOP;890/* Save the long/double type to errorTempData (verifyData->errorTempData)891* so as to ensure the wrong data type is the 2nd slot of long/double type892* in the error message framework rather than a 'top' type.893*/894errorTempData = type1;895/* The location of wrong data type needs to adjusted back to the right place896* because it pops twice from the stack for the wide type.897*/898errorStackIndex = (stackTop - liveStack->stackElements) + 1;899goto _inconsistentStack;900}901POP_TOS_INTEGER;902if (inconsistentStack) {903/* Jazz 82615: Set the expected data type and the location of wrong data type904* on stack when the verification error occurs.905*/906errorTargetType = BCV_BASE_TYPE_INT;907errorStackIndex = stackTop - liveStack->stackElements;908goto _inconsistentStack;909}910arrayType = POP;911if (arrayType != BCV_BASE_TYPE_NULL) {912if (bc == JBaastore) {913inconsistentStack |= (arrayType | type) & BCV_BASE_OR_SPECIAL;914if (inconsistentStack) {915/* Jazz 82615: Set the expected data type and the location of wrong data type on stack when the verification error occurs.916* Note: Given that the current location on stack is for arrayType, it needs to move forward by two slots917* to skip over the arrayType plus the index of array so as to reach the location of wrong type (value stored in the array).918*/919errorTargetType = type1;920errorStackIndex = (stackTop - liveStack->stackElements) + 2;921goto _inconsistentStack;922}923inconsistentStack |= (arrayType & BCV_ARITY_MASK) == 0;924if (inconsistentStack) {925/* Jazz 82615: Set the expected data type (array of object reference)926* and the location of wrong data type on stack when the verification error occurs.927*/928errorTargetType = type1 | (1 << BCV_ARITY_SHIFT);929errorStackIndex = stackTop - liveStack->stackElements;930goto _inconsistentStack;931}932} else {933inconsistentStack |= (type != type1);934if (inconsistentStack) {935/* Jazz 82615: Set the expected data type and the location of wrong data type on stack when the verification error occurs.936* Note: Given that the current location on stack is for arrayType, it needs to move forward by two slots937* to skip over the index of array and get to the location of wrong type (value stored in the array).938*/939errorTargetType = type1;940errorStackIndex = (stackTop - liveStack->stackElements) + 2;941goto _inconsistentStack;942}943944type2 = (UDATA) J9JavaBytecodeArrayTypeTable[bc - JBiastore];945/* The operand checking for bastore needs to cover the case of boolean arrays */946CHECK_BOOL_ARRAY(JBbastore, bc, type2);947if (inconsistentStack) {948/* Jazz 82615: Set the expected data type and the location of wrong data type949* on stack when the verification error occurs.950*/951errorTargetType = type2;952errorStackIndex = stackTop - liveStack->stackElements;953goto _inconsistentStack;954}955}956}957break;958959case RTV_INCREMENT:960index = PARAM_8(bcIndex, 1);961if (bc == JBiincw) {962index = PARAM_16(bcIndex, 1);963}964CHECK_TEMP_INTEGER(index);965if (inconsistentStack) {966/* Jazz 82615: Set the expected data type and the location of wrong data type on stack967* (already in index) when the verification error occurs.968*/969errorTargetType = BCV_BASE_TYPE_INT;970errorStackIndex = index;971goto _inconsistentStack;972}973break;974975case RTV_POP_2_PUSH:976POP_TOS_TYPE_EQUAL( type, type1 );977if (inconsistentStack) {978/* Jazz 82615: Set the 2nd slot of long/double type (already in type1) and979* the location of wrong data type on stack when the verification error occurs.980*/981errorTargetType = BCV_BASE_TYPE_TOP;982/* Save the long/double type to errorTempData (verifyData->errorTempData)983* so as to ensure the wrong data type is the 2nd slot of long/double type984* in the error message framework rather than a 'top' type.985*/986errorTempData = type1;987/* The location of wrong data type needs to adjusted back to the right place988* because it pops twice from the stack for the wide type.989*/990errorStackIndex = (stackTop - liveStack->stackElements) + 1;991goto _inconsistentStack;992/* Jazz 82615: the second inconsistent stack case in POP_TOS_TYPE_EQUAL should be addressed here */993} else if (inconsistentStack2) {994errorTargetType = type1;995errorStackIndex = stackTop - liveStack->stackElements;996goto _inconsistentStack;997}998POP_TOS_TYPE_EQUAL( type, type1 );999if (inconsistentStack) {1000/* Jazz 82615: Set the 2nd slot of long/double type (already in type1) and1001* the location of wrong data type on stack when the verification error occurs.1002*/1003errorTargetType = BCV_BASE_TYPE_TOP;1004/* Save the long/double type to errorTempData (verifyData->errorTempData)1005* so as to ensure the wrong data type is the 2nd slot of long/double type1006* in the error message framework rather than a 'top' type.1007*/1008errorTempData = type1;1009/* The location of wrong data type needs to adjusted back to the right place1010* because it pops twice from the stack for the wide type.1011*/1012errorStackIndex = (stackTop - liveStack->stackElements) + 1;1013goto _inconsistentStack;1014/* Jazz 82615: the second inconsistent stack case in POP_TOS_TYPE_EQUAL should be addressed here */1015} else if (inconsistentStack2) {1016errorTargetType = type1;1017errorStackIndex = stackTop - liveStack->stackElements;1018goto _inconsistentStack;1019}1020goto _pushConstant;1021break;10221023case RTV_POP_X_PUSH_X:1024/* Shifts only have non-zero type2 */1025if (type2) {1026POP_TOS_INTEGER;1027if (inconsistentStack) {1028/* Jazz 82615: Set the expected data type and the location of wrong data type1029* on stack when the verification error occurs.1030*/1031errorTargetType = BCV_BASE_TYPE_INT;1032errorStackIndex = stackTop - liveStack->stackElements;1033goto _inconsistentStack;1034}1035}1036POP_TOS_TYPE_EQUAL( type, type1 );1037if (inconsistentStack) {1038/* Jazz 82615: Set the 2nd slot of long/double type (already in type1) and1039* the location of wrong data type on stack when the verification error occurs.1040*/1041errorTargetType = BCV_BASE_TYPE_TOP;1042/* Save the long/double type to errorTempData (verifyData->errorTempData)1043* so as to ensure the wrong data type is the 2nd slot of long/double type1044* in the error message framework rather than a 'top' type.1045*/1046errorTempData = type1;1047/* The location of wrong data type needs to adjusted back to the right place1048* because it pops twice from the stack for the wide type.1049*/1050errorStackIndex = (stackTop - liveStack->stackElements) + 1;1051goto _inconsistentStack;1052/* Jazz 82615: the second inconsistent stack case in POP_TOS_TYPE_EQUAL should be addressed here */1053} else if (inconsistentStack2) {1054errorTargetType = type1;1055errorStackIndex = stackTop - liveStack->stackElements;1056goto _inconsistentStack;1057}1058goto _pushConstant;1059break;10601061case RTV_POP_X_PUSH_Y:1062POP_TOS_TYPE_EQUAL( type, type1 );1063if (inconsistentStack) {1064/* Jazz 82615: Set the 2nd slot of long/double type (already in type1) and1065* the location of wrong data type on stack when the verification error occurs.1066*/1067errorTargetType = BCV_BASE_TYPE_TOP;1068/* Save the long/double type to errorTempData (verifyData->errorTempData)1069* so as to ensure the wrong data type is the 2nd slot of long/double type1070* in the error message framework rather than a 'top' type.1071*/1072errorTempData = type1;1073/* The location of wrong data type needs to adjusted back to the right place1074* because it pops twice from the stack for the wide type.1075*/1076errorStackIndex = (stackTop - liveStack->stackElements) + 1;1077goto _inconsistentStack;1078/* Jazz 82615: the second inconsistent stack case in POP_TOS_TYPE_EQUAL should be addressed here */1079} else if (inconsistentStack2) {1080errorTargetType = type1;1081errorStackIndex = stackTop - liveStack->stackElements;1082goto _inconsistentStack;1083}1084type1 = type2;1085goto _pushConstant;1086break;10871088case RTV_BRANCH:1089popCount = type2 - 8;1090for (i = 0; i < popCount; i++) {1091if (type1 == BCV_GENERIC_OBJECT) {1092type = POP;1093/* Jazz 89060: According to the explanation of the Verification type hierarchy/rules1094* at section 4.10.1.2 Verification Type System (The JVM Specification Java SE 8 Edition):1095* isAssignable(uninitialized, X) :- isAssignable(reference, X).1096* isAssignable(uninitializedThis, X) :- isAssignable(uninitialized, X).1097* isAssignable(uninitialized(_), X) :- isAssignable(uninitialized, X).1098*1099* It means that 'uninitializedThis' is a subtype of 'reference',1100* and then 'uninitializedThis' is compatible with BCV_GENERIC_OBJECT ( 'reference' type )1101*/1102if (J9_ARE_NO_BITS_SET(type, BCV_SPECIAL)) {1103IDATA reasonCode = 0;1104rc = isClassCompatible (verifyData, type, BCV_GENERIC_OBJECT, &reasonCode);1105if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1106goto _outOfMemoryError;1107}11081109inconsistentStack |= (FALSE == rc);1110if (inconsistentStack) {1111/* Jazz 82615: Set the expected data type and the location of wrong data type1112* on stack when the verification error occurs.1113*/1114errorTargetType = BCV_GENERIC_OBJECT;1115errorStackIndex = stackTop - liveStack->stackElements;1116goto _inconsistentStack;1117}1118}1119} else {1120POP_TOS_INTEGER;1121if (inconsistentStack) {1122/* Jazz 82615: Set the expected data type and the location of wrong data type1123* on stack when the verification error occurs.1124*/1125errorTargetType = BCV_BASE_TYPE_INT;1126errorStackIndex = stackTop - liveStack->stackElements;1127goto _inconsistentStack;1128}1129}1130}11311132if (bc == JBgotow) {1133offset32 = (I_32) PARAM_32(bcIndex, 1);1134target = start + offset32;1135} else {1136offset16 = (I_16) PARAM_16(bcIndex, 1);1137target = start + offset16;1138}11391140SAVE_STACKTOP(liveStack, stackTop);1141/* Merge our stack to the target */1142rc = findAndMatchStack (verifyData, target, start);1143if (BCV_SUCCESS != rc) {1144if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {1145goto _outOfMemoryError;1146}1147goto _mapError;1148}11491150/* Unconditional branch */1151if (popCount == 0) {1152goto _newStack;1153}1154break;11551156case RTV_RETURN:1157utf8string = J9ROMMETHOD_SIGNATURE(romMethod);1158temp = &J9UTF8_DATA(utf8string)[J9UTF8_LENGTH(utf8string) - 2];1159returnChar = (UDATA) temp[1];1160if (temp[0] != ')') {1161returnChar = 0;1162className = J9UTF8_DATA(utf8string);1163while (*className++ != ')');1164temp1 = parseObjectOrArrayName(verifyData, className);1165}11661167switch (bc) {11681169case JBreturn0:1170case JBsyncReturn0:1171case JBreturnFromConstructor:1172inconsistentStack |= (returnChar != 'V');1173if (inconsistentStack) {1174_illegalPrimitiveReturn:1175/* Jazz 82615: Set the error code in the case of verification error on return. */1176errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;1177verboseErrorCode = BCV_ERR_WRONG_RETURN_TYPE;1178goto _miscError;1179}1180break;11811182case JBreturn1:1183case JBreturnB:1184case JBreturnC:1185case JBreturnS:1186case JBreturnZ:1187case JBsyncReturn1:1188/* Note: for synchronized return{B,C,S,Z}, JBgenericReturn is used */1189if (returnChar) {1190U_32 returnType = 0;1191/* single character return description */1192if ((returnChar < 'A') || (returnChar > 'Z')) {1193inconsistentStack = TRUE;1194goto _illegalPrimitiveReturn;1195}1196type = (UDATA) oneArgTypeCharConversion[returnChar - 'A'];1197POP_TOS(type);11981199/* check methods that return char, byte, short, or bool use the right opcode */1200if (BCV_BASE_TYPE_INT == type){1201switch(bc) {1202case JBreturnB:1203returnType = BCV_BASE_TYPE_BYTE_BIT;1204break;12051206case JBreturnC:1207returnType = BCV_BASE_TYPE_CHAR_BIT;1208break;12091210case JBreturnS:1211returnType = BCV_BASE_TYPE_SHORT_BIT;1212break;12131214case JBreturnZ:1215returnType = BCV_BASE_TYPE_BOOL_BIT;1216break;1217/* Note: synchronized return of b,c,s,z are handled as a JBgenericReturn */1218case JBreturn1:1219case JBsyncReturn1:1220returnType = BCV_BASE_TYPE_INT_BIT;1221break;1222default:1223Trc_RTV_j9rtv_verifyBytecodes_Unreachable(verifyData->vmStruct,1224(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),1225J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),1226(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),1227J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),1228(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),1229J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),1230__LINE__);1231break;1232}1233inconsistentStack |= returnType != baseTypeCharConversion[returnChar - 'A'];1234}1235if (inconsistentStack) {1236/* Jazz 82615: Set the expected data type (already in type) and1237* the location of wrong data type on stack when the verification error occurs.1238*/1239errorTargetType = type;1240errorStackIndex = stackTop - liveStack->stackElements;1241goto _inconsistentStack;1242}12431244} else {1245IDATA reasonCode = 0;12461247/* Object */1248POP_TOS_OBJECT(type);1249if (inconsistentStack) {1250/* Jazz 82615: Set the expected data type and the location of wrong data type on stack when the verification error occurs. */1251errorTargetType = BCV_GENERIC_OBJECT;1252errorStackIndex = stackTop - liveStack->stackElements;1253goto _inconsistentStack;1254}12551256rc = isClassCompatible(verifyData, type, temp1, &reasonCode);1257if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1258goto _outOfMemoryError;1259}1260inconsistentStack |= (FALSE == rc);1261if (inconsistentStack) {1262/* Jazz 82615: Set the expected data type and the location of wrong data type1263* on stack when the verification error occurs.1264*/1265errorTargetType = temp1;1266errorStackIndex = stackTop - liveStack->stackElements;1267goto _inconsistentStack;1268}1269}1270break;12711272case JBreturn2:1273case JBsyncReturn2:1274/* single character return description */1275if ((returnChar < 'A') || (returnChar > 'Z')) {1276inconsistentStack = TRUE;1277goto _illegalPrimitiveReturn;1278}1279type = (UDATA) argTypeCharConversion[returnChar - 'A'];1280POP_TOS_2(type);1281if (inconsistentStack) {1282/* Jazz 82615: Set the expected data type (already in type)1283* and the location of wrong data type on stack when the verification error occurs.1284*/1285errorTargetType = type;1286errorStackIndex = stackTop - liveStack->stackElements;1287goto _inconsistentStack;1288}1289break;12901291case JBgenericReturn:1292/* Decide based on the signature of this method what the return is supposed to be */1293if (returnChar) {1294/* single character return description */1295if ((returnChar < 'A') || (returnChar > 'Z')) {1296inconsistentStack = TRUE;1297goto _illegalPrimitiveReturn;1298}1299if (returnChar != 'V') {1300type = (UDATA) argTypeCharConversion[returnChar - 'A'];1301if ((returnChar == 'J') || (returnChar == 'D')) {1302POP_TOS(BCV_BASE_TYPE_TOP);1303if (inconsistentStack) {1304/* Jazz 82615: Set the expected long/double type and the location of wrong data type on stack when the verification error occurs. */1305errorTempData = ('J' == returnChar) ? BCV_BASE_TYPE_LONG : BCV_BASE_TYPE_DOUBLE;1306errorTargetType = BCV_BASE_TYPE_TOP;1307errorStackIndex = stackTop - liveStack->stackElements;1308goto _inconsistentStack;1309}1310}1311POP_TOS(type);1312if (inconsistentStack) {1313/* Jazz 82615: Set the expected data type (already in type) and1314* the location of wrong data type on stack when the verification error occurs.1315*/1316errorTargetType = type;1317errorStackIndex = stackTop - liveStack->stackElements;1318goto _inconsistentStack;1319}1320}1321} else {1322IDATA reasonCode = 0;13231324/* Object */1325POP_TOS_OBJECT(type);1326if (inconsistentStack) {1327/* Jazz 82615: Set the expected data type and the location of wrong data type1328* on stack when the verification error occurs.1329*/1330errorTargetType = BCV_GENERIC_OBJECT;1331errorStackIndex = stackTop - liveStack->stackElements;1332goto _inconsistentStack;1333}13341335rc = isClassCompatible(verifyData, type, temp1, &reasonCode);1336if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1337goto _outOfMemoryError;1338}1339inconsistentStack |= (FALSE == rc);1340if (inconsistentStack) {1341/* Jazz 82615: Set the expected data type and the location of wrong data type1342* on stack when the verification error occurs.1343*/1344errorTargetType = temp1;1345errorStackIndex = stackTop - liveStack->stackElements;1346goto _inconsistentStack;1347}1348}13491350/* Don't rewrite the return bytecode for j.l.Object.<init>()V or if the romClass is in the shared classes cache*/1351if ((stackTop == stackBase)1352&& ((argCount != 1) || (returnBytecode != JBreturnFromConstructor) || (J9ROMCLASS_SUPERCLASSNAME(romClass) != NULL))1353&& (FALSE == verifyData->romClassInSharedClasses)1354) {1355/* Rewrite clean return if empty stack - needed for StackMap/StackMapTable attribute methods */1356*bcIndex = returnBytecode;1357}13581359break;1360}13611362/* If this is <init>, need to ensure that the uninitialized_this1363* has been initialized. Can be determined from the stack map's1364* flag1365*/1366if (isInitMethod) {1367if (liveStack->uninitializedThis == (UDATA)TRUE){1368errorType = J9NLS_BCV_ERR_INIT_NOT_CALL_INIT__ID;1369/* Jazz 82615: Set the error code and the location of data type on stack in the case of the verification error unrelated to incompatible type.*/1370verboseErrorCode = BCV_ERR_INIT_NOT_CALL_INIT;1371/* Given that there is no real wrong data type on stack in such case, the stackTop pointer needs to step back by one slot1372* to point to the current data type on stack so as to print all data types correctly in the error message framework.1373*/1374errorStackIndex = (stackTop - liveStack->stackElements) - 1;1375/* Always set to the location of the 1st data type on 'stack' to show up if stackTop <= stackBase */1376if (stackTop <= stackBase) {1377errorStackIndex = stackBase - liveStack->stackElements;1378}1379goto _miscError;1380}1381}13821383goto _newStack;1384break;13851386case RTV_STATIC_FIELD_ACCESS:1387{1388IDATA reasonCode = 0;1389/* Jazz 82615: Save the location of wrong data type (receiver) */1390UDATA *receiverPtr = NULL;13911392index = PARAM_16(bcIndex, 1);1393info = &constantPool[index];1394utf8string = ((J9UTF8 *) (J9ROMNAMEANDSIGNATURE_SIGNATURE(J9ROMFIELDREF_NAMEANDSIGNATURE((J9ROMFieldRef *) info))));13951396receiver = BCV_BASE_TYPE_NULL; /* makes class compare work with statics */13971398if ((bc & 1)1399#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)1400|| (bc == JBwithfield)1401#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */1402) {1403/* case for JBwithfield and odd bc's which are JBputfield/JBpustatic */1404type = POP;1405if ((*J9UTF8_DATA(utf8string) == 'D') || (*J9UTF8_DATA(utf8string) == 'J')) {1406inconsistentStack |= (type != BCV_BASE_TYPE_TOP);1407if (inconsistentStack) {1408/* Jazz 82615: Set the expected long/double type and the location of wrong data type1409* on stack when the verification error occurs.1410*/1411errorTempData = ('J' == *J9UTF8_DATA(utf8string)) ? BCV_BASE_TYPE_LONG : BCV_BASE_TYPE_DOUBLE;1412errorTargetType = BCV_BASE_TYPE_TOP;1413errorStackIndex = stackTop - liveStack->stackElements;1414goto _inconsistentStack;1415}1416type = POP;1417}1418/* HACK: Pushes the return type without moving the stack pointer */1419pushFieldType(verifyData, utf8string, stackTop);1420if (*stackTop & BCV_TAG_BASE_TYPE_OR_TOP) {1421inconsistentStack |= (*stackTop != type);1422} else {1423rc = isClassCompatible(verifyData, type, *stackTop, &reasonCode);1424if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1425goto _outOfMemoryError;1426}14271428inconsistentStack |= (FALSE == rc);1429}1430if (inconsistentStack) {1431/* Jazz 82615: Set the expected data type and the location of wrong data type on stack when the verification error occurs. */1432errorTargetType = *stackTop;1433errorStackIndex = stackTop - liveStack->stackElements;14341435/* Jazz 82615: This is an exception when storing the verification error data, which was originally caused by the hack (pushFieldType) above.1436* The stackTop pointer doesn't get updated after calling pushFieldType() to store the return type, so *stackTop stores1437* the expected data type rather than the wrong data type which has already been popped up from stack.1438*1439* According to the output format of error message framework, only the wrong data type is expected to occur at *stackTop on stack1440* rather than the expected data type. Thus, the wrong data type must be pushed back to *stackTop after saving the expected data type1441* somewhere else.1442*/1443PUSH(type);1444goto _inconsistentStack;1445}14461447if (bc == JBputfield) {1448receiver = POP;1449/* Jazz 82615: Save the location of receiver */1450receiverPtr = stackTop;1451}1452} else {1453/* JBgetfield/JBgetstatic - even bc's */1454if (bc == JBgetfield) {1455receiver = POP;1456/* Jazz 82615: Save the location of receiver */1457receiverPtr = stackTop;1458}1459stackTop = pushFieldType(verifyData, utf8string, stackTop);1460}14611462rc = isFieldAccessCompatible (verifyData, (J9ROMFieldRef *) info, bc, receiver, &reasonCode);1463if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1464goto _outOfMemoryError;1465}1466inconsistentStack |= (FALSE == rc);1467if (inconsistentStack) {1468constantPool = (J9ROMConstantPoolItem *) (romClass + 1);1469utf8string = J9ROMCLASSREF_NAME((J9ROMClassRef *) &constantPool[((J9ROMFieldRef *) info)->classRefCPIndex]);14701471/* Jazz 82615: Store the expected data type for later retrieval in classNameList. */1472errorTargetType = convertClassNameToStackMapType(verifyData, J9UTF8_DATA(utf8string), J9UTF8_LENGTH(utf8string), 0, 0);14731474/* If the error occurs in isFieldAccessCompatible(), the stackTop pointer needs1475* to be restored to point to the previous location of receiver (wrong data type) and1476* restore the value of receiver if overridden by other data.1477*/1478if (NULL != receiverPtr) {1479stackTop = receiverPtr;1480}1481*stackTop = receiver;1482errorStackIndex = stackTop - liveStack->stackElements;1483goto _inconsistentStack;1484}14851486if (receiver != BCV_BASE_TYPE_NULL) {1487utf8string = J9ROMCLASSREF_NAME((J9ROMClassRef *) &constantPool[((J9ROMFieldRef *) info)->classRefCPIndex]);14881489rc = isProtectedAccessPermitted (verifyData, utf8string, receiver, (void *) info, TRUE, &reasonCode);1490if (FALSE == rc) {1491if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1492goto _outOfMemoryError;1493}1494errorType = J9NLS_BCV_ERR_BAD_ACCESS_PROTECTED__ID;1495/* Jazz 82615: Set the error code when error occurs in checking the protected member access. */1496verboseErrorCode = BCV_ERR_BAD_ACCESS_PROTECTED;1497goto _miscError;1498}1499}1500break;1501}15021503case RTV_SEND:1504if ((bc == JBinvokehandle) || (bc == JBinvokehandlegeneric)) {1505IDATA reasonCode = 0;15061507index = PARAM_16(bcIndex, 1);1508info = &constantPool[index];1509utf8string = ((J9UTF8 *) (J9ROMNAMEANDSIGNATURE_SIGNATURE(J9ROMMETHODREF_NAMEANDSIGNATURE((J9ROMMethodRef *) info))));1510/* Removes the args from the stack and verify the stack shape is consistent */1511rc = j9rtv_verifyArguments(verifyData, utf8string, &stackTop);1512CHECK_STACK_UNDERFLOW;1513if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {1514goto _outOfMemoryError;1515}1516inconsistentStack |= (BCV_SUCCESS != rc);1517if (inconsistentStack) {1518/* errorDetailCode has been initialized with 0 (SUCCESS) before any verification error is detected1519* For the return code from j9rtv_verifyArguments(), there is no need to print out error message framework1520* in the case of BCV_FAIL for bad signature (should never happen - caught by cfreader.c in checkMethodSignature)1521* and BCV_ERR_INSUFFICIENT_MEMORY for OOM as there is nothing meaningful to show up.1522*/1523if (verifyData->errorDetailCode < 0) {1524J9UTF8 * utf8ClassString = J9ROMCLASSREF_NAME((J9ROMClassRef *) &constantPool[((J9ROMMethodRef *) info)->classRefCPIndex]);1525J9UTF8 * utf8MethodString = ((J9UTF8 *) (J9ROMNAMEANDSIGNATURE_NAME(J9ROMMETHODREF_NAMEANDSIGNATURE((J9ROMMethodRef *) info))));1526storeMethodInfo(verifyData, utf8ClassString, utf8MethodString, utf8string, start);1527}1528errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;1529goto _verifyError;1530}15311532/* Don't need to do protected access check here - both of these are special1533* cases of invokevirtual which only invoke public methods of a public class.1534*/15351536/* Remove the receiver from the stack. */1537type = POP;1538/* Receiver compatible with MethodHandle? */1539rc = isClassCompatibleByName(verifyData, type, (U_8 *)"java/lang/invoke/MethodHandle", sizeof("java/lang/invoke/MethodHandle") - 1, &reasonCode);1540#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)1541if ((JBinvokehandle == bc) && (FALSE == rc)) {1542if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1543goto _outOfMemoryError;1544}1545/* Receiver compatible with VarHandle? */1546rc = isClassCompatibleByName(verifyData, type, (U_8 *)"java/lang/invoke/VarHandle", sizeof("java/lang/invoke/VarHandle") - 1, &reasonCode);1547}1548#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */1549if (FALSE == rc) {1550if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1551goto _outOfMemoryError;1552}1553errorType = J9NLS_BCV_ERR_RECEIVER_NOT_COMPATIBLE__ID;1554/* Jazz 82615: Store the index of the expected data type 'java/lang/invoke/MethodHandle'1555* or 'java/lang/invoke/VarHandle' for later retrieval in classNameList. */1556errorTargetType = (UDATA)(BCV_JAVA_LANG_INVOKE_METHODHANDLE_INDEX << BCV_CLASS_INDEX_SHIFT);1557errorStackIndex = stackTop - liveStack->stackElements;1558goto _inconsistentStack2;1559}1560stackTop = pushReturnType(verifyData, utf8string, stackTop);15611562break;1563}15641565if (bc == JBinvokedynamic) {1566index = PARAM_16(bcIndex, 1); /* TODO 3 byte index */1567utf8string = ((J9UTF8 *) (J9ROMNAMEANDSIGNATURE_SIGNATURE(SRP_PTR_GET(callSiteData + index, J9ROMNameAndSignature*))));1568/* Removes the args from the stack and verify the stack shape is consistent */1569rc = j9rtv_verifyArguments(verifyData, utf8string, &stackTop);1570CHECK_STACK_UNDERFLOW;1571if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {1572goto _outOfMemoryError;1573}1574inconsistentStack |= (BCV_SUCCESS != rc);1575if (inconsistentStack) {1576/* errorDetailCode has been initialized with 0 (SUCCESS) before any verification error is detected1577* For the return code from j9rtv_verifyArguments(), there is no need to print out error message framework1578* in the case of BCV_FAIL for bad signature (should never happen - caught by cfreader.c in checkMethodSignature)1579* and BCV_ERR_INSUFFICIENT_MEMORY for OOM as there is nothing meaningful to show up.1580*/1581if (verifyData->errorDetailCode < 0) {1582J9UTF8 * utf8ClassString = J9ROMCLASS_CLASSNAME(romClass);1583J9UTF8 * utf8MethodString = ((J9UTF8 *) (J9ROMNAMEANDSIGNATURE_NAME(SRP_PTR_GET(callSiteData + index, J9ROMNameAndSignature*))));1584storeMethodInfo(verifyData, utf8ClassString, utf8MethodString, utf8string, start);1585}1586errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;1587goto _verifyError;1588}1589stackTop = pushReturnType(verifyData, utf8string, stackTop);1590break;1591}15921593if (bc == JBinvokeinterface2) {1594bcIndex += 2;1595bc = JBinvokeinterface;1596}1597index = PARAM_16(bcIndex, 1);1598if (JBinvokestaticsplit == bc) {1599index = *(U_16 *)(J9ROMCLASS_STATICSPLITMETHODREFINDEXES(romClass) + index);1600} else if (JBinvokespecialsplit == bc) {1601index = *(U_16 *)(J9ROMCLASS_SPECIALSPLITMETHODREFINDEXES(romClass) + index);1602}1603info = &constantPool[index];1604utf8string = ((J9UTF8 *) (J9ROMNAMEANDSIGNATURE_SIGNATURE(J9ROMMETHODREF_NAMEANDSIGNATURE((J9ROMMethodRef *) info))));1605cpIndex = ((J9ROMMethodRef *) info)->classRefCPIndex;1606classRef = (J9ROMStringRef *) &constantPool[cpIndex];1607rc = j9rtv_verifyArguments(verifyData, utf8string, &stackTop); /* Removes the args from the stack */1608CHECK_STACK_UNDERFLOW;1609if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {1610goto _outOfMemoryError;1611}1612inconsistentStack |= (BCV_SUCCESS != rc);1613if (inconsistentStack) {1614/* errorDetailCode has been initialized with 0 (SUCCESS) before any verification error is detected1615* For the return code from j9rtv_verifyArguments(), there is no need to print out error message framework1616* in the case of BCV_FAIL for bad signature (should never happen - caught by cfreader.c in checkMethodSignature)1617* and BCV_ERR_INSUFFICIENT_MEMORY for OOM as there is nothing meaningful to show up.1618*/1619if (verifyData->errorDetailCode < 0) {1620J9UTF8 * utf8ClassString = J9ROMSTRINGREF_UTF8DATA(classRef);1621J9UTF8 * utf8MethodString = ((J9UTF8 *) (J9ROMNAMEANDSIGNATURE_NAME(J9ROMMETHODREF_NAMEANDSIGNATURE((J9ROMMethodRef *) info))));1622storeMethodInfo(verifyData, utf8ClassString, utf8MethodString, utf8string, start);1623}1624errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;1625goto _verifyError;1626}16271628if ((JBinvokestatic != bc)1629&& (JBinvokestaticsplit != bc)1630) {1631IDATA reasonCode = 0;16321633type = POP; /* Remove the receiver from the stack */1634switch (bc) {1635case JBinvokespecial:1636case JBinvokespecialsplit:1637CHECK_STACK_UNDERFLOW;1638/* cannot use isInitMethod here b/c invokespecial may be invoking a different <init> method then the one we are in */1639if (J9UTF8_DATA(J9ROMNAMEANDSIGNATURE_NAME(J9ROMMETHODREF_NAMEANDSIGNATURE((J9ROMMethodRef *) info)))[0] == '<') {16401641/* This is <init>, verify that this is a NEW or INIT object */1642if ((type & BCV_SPECIAL) == 0) {1643/* Fail - not an init object */1644errorType = J9NLS_BCV_ERR_BAD_INIT__ID;1645/* Jazz 82615: Set the expected data type and the location of wrong data type1646* on stack when the verification error occurs.1647*/1648errorTargetType = BCV_SPECIAL_INIT;1649errorStackIndex = stackTop - liveStack->stackElements;1650goto _inconsistentStack2;1651} else {1652temp1 = getSpecialType(verifyData, type, code);1653if (temp1 & BCV_SPECIAL_INIT) {1654/* fail if getSpecialType didn't decode to a non-special type */1655errorType = J9NLS_BCV_ERR_ARGUMENTS_INCOMPATIBLE__ID;1656/* Jazz 82615: Set the error code, decoded data type (already in temp1) and1657* update the stackTopIndex to include the wrong type on stack (already popped out of stack).1658*/1659verboseErrorCode = BCV_ERR_BAD_INIT_OBJECT;1660errorTempData = temp1;1661errorStackIndex = stackTop - liveStack->stackElements;1662goto _miscError;1663}16641665/* For uninitialized(x), ensure that class @ 'new X' and class of <init> are identical */1666if (type & BCV_SPECIAL_NEW) {1667utf8string = J9ROMSTRINGREF_UTF8DATA(classRef);1668classIndex = convertClassNameToStackMapType(verifyData, J9UTF8_DATA(utf8string), J9UTF8_LENGTH(utf8string), 0, 0);1669if (classIndex != temp1) {1670errorType = J9NLS_BCV_ERR_WRONG_INIT_METHOD__ID;1671/* Jazz 82615: Set the expected data type, the wrong type on stack and1672* the location of wrong data type on stack when the verification error occurs.1673*/1674errorTargetType = temp1;1675*stackTop = classIndex;1676errorStackIndex = stackTop - liveStack->stackElements;1677goto _inconsistentStack2;1678}1679}16801681/* Ensure the <init> method is either for this class or its direct super class */1682if (type & BCV_SPECIAL_INIT) {1683UDATA superClassIndex = 0;16841685utf8string = J9ROMSTRINGREF_UTF8DATA(classRef);1686classIndex = convertClassNameToStackMapType(verifyData, J9UTF8_DATA(utf8string), J9UTF8_LENGTH(utf8string), 0, 0);16871688utf8string = J9ROMCLASS_SUPERCLASSNAME(romClass);1689superClassIndex = convertClassNameToStackMapType(verifyData, J9UTF8_DATA(utf8string), J9UTF8_LENGTH(utf8string), 0, 0);1690if ((classIndex != temp1) && (classIndex != superClassIndex)) {1691errorType = J9NLS_BCV_ERR_WRONG_INIT_METHOD__ID;1692/* Jazz 82615: Set the expected data type, the wrong type on stack and1693* the location of wrong data type on stack when the verification error occurs.1694*/1695errorTargetType = temp1;1696*stackTop = classIndex;1697errorStackIndex = stackTop - liveStack->stackElements;1698goto _inconsistentStack2;1699}1700}17011702/* This invoke special will make all copies of this "type" on the stack a real1703object, find all copies of this object and initialize them */1704ptr = temps; /* assumption that stack follows temps */1705/* we don't strictly need to walk temps here, the pending stack would be enough */1706while (ptr != stackTop) {1707if (*ptr == type) {1708*ptr = temp1;1709}1710ptr++;1711}1712/* Flag the initialization occurred only if its uninitialized_this */1713if (type & BCV_SPECIAL_INIT) {1714liveStack->uninitializedThis = FALSE;1715}1716type = temp1;1717}17181719} else { /* non <init> */1720/* The JVM converts invokevirtual of final methods in Object to invokespecial.1721* For verification purposes, treat these as invokevirtual by falling through.1722*/1723J9ROMNameAndSignature *nas = J9ROMMETHODREF_NAMEANDSIGNATURE((J9ROMMethodRef *) info);1724J9UTF8 *name = J9ROMNAMEANDSIGNATURE_NAME(nas);1725J9UTF8 *sig = J9ROMNAMEANDSIGNATURE_SIGNATURE(nas);1726if (!methodIsFinalInObject(J9UTF8_LENGTH(name), J9UTF8_DATA(name), J9UTF8_LENGTH(sig), J9UTF8_DATA(sig))) {1727utf8string = J9ROMCLASS_CLASSNAME(romClass);1728classIndex = convertClassNameToStackMapType(verifyData, J9UTF8_DATA(utf8string), J9UTF8_LENGTH(utf8string), 0, 0);1729utf8string = J9ROMSTRINGREF_UTF8DATA(classRef);17301731/* the lazy evaluation would guarantee reasonCode reflects the first failure.1732* In all three functions, returned boolean value would indicate an error occurred and the reasonCode is set to BCV_ERR_INSUFFICIENT_MEMORY in OOM cases.1733* Hence, if any of the 3 conditions should fail, if it is not on OOM as reasonCode would indicate, it must be a verification error.1734*/1735if ((FALSE == isClassCompatibleByName(verifyData, classIndex, J9UTF8_DATA(utf8string), J9UTF8_LENGTH(utf8string), &reasonCode))1736|| (FALSE == isClassCompatible(verifyData, type, classIndex, &reasonCode))1737) {1738if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1739goto _outOfMemoryError;1740}1741errorType = J9NLS_BCV_ERR_BAD_INVOKESPECIAL__ID;1742/* Jazz 82615: Set the error code when error occurs in checking the final method. */1743verboseErrorCode = BCV_ERR_BAD_INVOKESPECIAL;1744goto _miscError;1745}1746}1747} /* fall through */17481749case JBinvokevirtual:1750rc = isProtectedAccessPermitted (verifyData, J9ROMSTRINGREF_UTF8DATA(classRef), type,1751J9ROMMETHODREF_NAMEANDSIGNATURE((J9ROMMethodRef *) info), FALSE, &reasonCode);17521753if (FALSE == rc) {1754if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1755goto _outOfMemoryError;1756}1757errorType = J9NLS_BCV_ERR_BAD_ACCESS_PROTECTED__ID;1758/* Jazz 82615: Set the error code when error occurs in checking the protected member access. */1759verboseErrorCode = BCV_ERR_BAD_ACCESS_PROTECTED;1760goto _miscError;1761}1762break;1763}17641765if (bc != JBinvokeinterface) {1766utf8string = J9ROMSTRINGREF_UTF8DATA(classRef);17671768rc = isClassCompatibleByName (verifyData, type, J9UTF8_DATA(utf8string), J9UTF8_LENGTH(utf8string), &reasonCode);1769if (FALSE == rc) {1770if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1771goto _outOfMemoryError;1772}1773errorType = J9NLS_BCV_ERR_RECEIVER_NOT_COMPATIBLE__ID;1774/* Jazz 82615: Store the index of the expected data type for later retrieval in classNameList */1775errorTargetType = convertClassNameToStackMapType(verifyData, J9UTF8_DATA(utf8string), J9UTF8_LENGTH(utf8string), 0, 0);1776errorStackIndex = stackTop - liveStack->stackElements;1777goto _inconsistentStack2;1778}1779} else {1780/* Need to ensure that there is at least an Object reference on the stack for the1781* invokeinterface receiver. If the top of stack is a base type or TOP, then1782* throw a verify error. The check for the receiver to be an interface occurs in1783* the invokeinterface bytecode.1784* Note: we need to check whether the Object reference on the stack is initialized1785* so as to stop an uninitialized object from being addressed here by invokeinterface.1786*/1787if ((BCV_TAG_BASE_TYPE_OR_TOP == (type & BCV_TAG_MASK))1788|| J9_ARE_ANY_BITS_SET(type, BCV_SPECIAL)1789) {1790errorType = J9NLS_BCV_ERR_RECEIVER_NOT_COMPATIBLE__ID;1791/* Jazz 82615: Set the expected data type and the location of wrong data type1792* on stack when the verification error occurs.1793*/1794errorTargetType = BCV_GENERIC_OBJECT;1795errorStackIndex = stackTop - liveStack->stackElements;1796goto _inconsistentStack2;1797}1798}1799}18001801utf8string = ((J9UTF8 *) (J9ROMNAMEANDSIGNATURE_SIGNATURE(J9ROMMETHODREF_NAMEANDSIGNATURE((J9ROMMethodRef *) info))));1802stackTop = pushReturnType(verifyData, utf8string, stackTop);1803break;18041805case RTV_PUSH_NEW:1806switch (bc) {1807#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)1808case JBaconst_init:1809index = PARAM_16(bcIndex, 1);1810info = &constantPool[index];1811utf8string = J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info);1812stackTop = pushClassType(verifyData, utf8string, stackTop);1813break;1814#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */18151816case JBnew:1817case JBnewdup:1818index = PARAM_16(bcIndex, 1);1819info = &constantPool[index];1820utf8string = J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info);1821stackTop = pushClassType(verifyData, utf8string, stackTop);1822type = POP;1823if (J9_ARE_ANY_BITS_SET(type, BCV_ARITY_MASK)) {1824errorType = J9NLS_BCV_ERR_BC_NEW_ARRAY__ID;1825verboseErrorCode = BCV_ERR_NEW_OJBECT_MISMATCH;1826errorTempData = ((type & BCV_ARITY_MASK) >> BCV_ARITY_SHIFT);1827goto _miscError;1828}1829/* put a uninitialized object of the correct type on the stack */1830PUSH(BCV_SPECIAL_NEW | (start << BCV_CLASS_INDEX_SHIFT));1831break;18321833case JBnewarray:1834POP_TOS_INTEGER; /* pop the size of the array */1835if (inconsistentStack) {1836/* Jazz 82615: Set the expected data type and the location of wrong data type1837* on stack when the verification error occurs.1838*/1839errorTargetType = BCV_BASE_TYPE_INT;1840errorStackIndex = stackTop - liveStack->stackElements;1841goto _inconsistentStack;1842}18431844index = PARAM_8(bcIndex, 1);1845type = (UDATA) newArrayParamConversion[index];1846PUSH(type); /* arity of one implicit */1847break;18481849case JBanewarray:1850POP_TOS_INTEGER; /* pop the size of the array */1851if (inconsistentStack) {1852/* Jazz 82615: Set the expected data type and the location of wrong data type1853* on stack when the verification error occurs.1854*/1855errorTargetType = BCV_BASE_TYPE_INT;1856errorStackIndex = stackTop - liveStack->stackElements;1857goto _inconsistentStack;1858}18591860index = PARAM_16(bcIndex, 1);1861info = &constantPool[index];1862utf8string = J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info);18631864stackTop = pushClassType(verifyData, utf8string, stackTop);1865/* arity is one greater than signature */1866type = POP;1867/* Check for arity overflow */1868if ((type & BCV_ARITY_MASK) == BCV_ARITY_MASK) {1869errorType = J9NLS_BCV_ERR_ARRAY_TYPE_MISMATCH__ID;1870/* Jazz 82615: Set the error code and the arity in the case of arity overflow. */1871verboseErrorCode = BCV_ERR_ARRAY_ARITY_OVERFLOW;1872errorTempData = (type & BCV_ARITY_MASK);1873goto _miscError;1874}1875PUSH(( (UDATA)1 << BCV_ARITY_SHIFT) + type);1876break;18771878case JBmultianewarray:1879/* points to cp entry for class of object to create */1880index = PARAM_16(bcIndex, 1);1881i1 = PARAM_8(bcIndex, 3);18821883if (i1 == 0) {1884errorType = J9NLS_BCV_ERR_ARRAY_DIMENSION_MISMATCH__ID;1885/* Jazz 82615: Set the error code and the dimension of array if incorrect. */1886verboseErrorCode = BCV_ERR_ARRAY_DIMENSION_MISMATCH;1887errorTempData = i1;1888goto _miscError;1889}18901891if ((stackTop - i1) < stackBase) {1892errorType = J9NLS_BCV_ERR_STACK_UNDERFLOW__ID;1893/* Jazz 82615: Set the error code when the verification error related to stack underflow occurs */1894verboseErrorCode = BCV_ERR_STACK_UNDERFLOW;1895/* Given that the actual data type involved has not yet been located through pop operation when stack underflow occurs,1896* step back by one slot to the actual data type to be manipulated by the opcode.1897*/1898errorStackIndex = (stackTop - liveStack->stackElements) - 1;1899/* Always set to the location of the 1st data type on 'stack' to show up if stackTop <= stackBase */1900if (stackTop <= stackBase) {1901errorStackIndex = stackBase - liveStack->stackElements;1902}1903goto _miscError;1904}19051906for (i2 = 0; i2 < i1; i2++) {1907POP_TOS_INTEGER;1908if (inconsistentStack) {1909/* Jazz 82615: Set the expected data type and the location of wrong data type1910* on stack when the verification error occurs.1911*/1912errorTargetType = BCV_BASE_TYPE_INT;1913errorStackIndex = stackTop - liveStack->stackElements;1914goto _inconsistentStack;1915}1916}19171918info = &constantPool[index];1919utf8string = J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info);19201921stackTop = pushClassType(verifyData, utf8string, stackTop);1922/* Silly test? */1923type = POP;1924if (type & BCV_TAG_BASE_ARRAY_OR_NULL) {1925i1--;1926}1927if ((type >> BCV_ARITY_SHIFT) < (UDATA) i1) {1928errorType = J9NLS_BCV_ERR_ARRAY_DIMENSION_MISMATCH__ID;1929/* Jazz 82615: Set the error code when the dimension of array is incorrect. */1930verboseErrorCode = BCV_ERR_ARRAY_DIMENSION_MISMATCH;1931errorTempData = (type >> BCV_ARITY_SHIFT);1932goto _miscError;1933}1934PUSH(type);1935break;1936}1937break;19381939case RTV_MISC:1940{1941IDATA reasonCode = 0;1942switch (bc) {1943case JBathrow:1944POP_TOS_OBJECT(type);1945rc = isClassCompatible(verifyData, type, (UDATA) (BCV_JAVA_LANG_THROWABLE_INDEX << BCV_CLASS_INDEX_SHIFT), &reasonCode);1946if (FALSE == rc) {1947if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {1948goto _outOfMemoryError;1949}1950errorType = J9NLS_BCV_ERR_NOT_THROWABLE__ID;1951/* Jazz 82615: Store the index of the expected data type 'java/lang/invoke/MethodHandle' for later retrieval in classNameList */1952errorTargetType = (UDATA)(BCV_JAVA_LANG_THROWABLE_INDEX << BCV_CLASS_INDEX_SHIFT);1953errorStackIndex = stackTop - liveStack->stackElements;19541955/* Jazz 82615: errorType may change in the case of _compatibleError */1956if (BCV_ERR_INTERNAL_ERROR == rc) {1957goto _compatibleError;1958} else {1959goto _inconsistentStack2;1960}1961}1962goto _newStack;1963break;19641965case JBarraylength:1966POP_TOS_ARRAY(type);1967if (inconsistentStack) {1968/* Jazz 82615: Given that there is no way to know the information of the expected array type1969* (e.g. base/object type, arity, etc), so set the error code (invalid array reference) and1970* the location of wrong data type on stack when the verification error occurs.1971*/1972errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;1973verboseErrorCode = BCV_ERR_INVALID_ARRAY_REFERENCE;1974errorTempData = type;1975errorStackIndex = stackTop - liveStack->stackElements;1976goto _miscError;1977}1978PUSH_INTEGER_CONSTANT;1979break;19801981case JBtableswitch:1982case JBlookupswitch:1983POP_TOS_INTEGER;1984if (inconsistentStack) {1985/* Jazz 82615: Set the expected data type and the location of wrong data type1986* on stack when the verification error occurs.1987*/1988errorTargetType = BCV_BASE_TYPE_INT;1989errorStackIndex = stackTop - liveStack->stackElements;1990goto _inconsistentStack;1991}1992index = (UDATA) ((4 - (pc & 3)) & 3); /* consume padding */1993pc += index;1994bcIndex += index;1995pc += 8;1996CHECK_END;1997offset32 = (I_32) PARAM_32(bcIndex, 1);1998bcIndex += 4;1999target = offset32 + start;2000SAVE_STACKTOP(liveStack, stackTop);2001rc = findAndMatchStack (verifyData, target, start);2002if (BCV_SUCCESS != rc) {2003if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {2004goto _outOfMemoryError;2005}2006goto _mapError;2007}20082009if (bc == JBtableswitch) {2010i1 = (I_32) PARAM_32(bcIndex, 1);2011bcIndex += 4;2012pc += 4;2013i2 = (I_32) PARAM_32(bcIndex, 1);2014bcIndex += 4;20152016pc += ((I_32)i2 - (I_32)i1 + 1) * 4;2017CHECK_END;20182019/* Add the table switch destinations in reverse order to more closely mimic the order that people2020(ie: the TCKs) expect you to load classes */2021bcIndex += (((I_32)i2 - (I_32)i1) * 4); /* point at the last table switch entry */20222023/* Count the entries */2024i2 = (I_32)i2 - (I_32)i1 + 1;2025for (i1 = 0; (I_32)i1 < (I_32)i2; i1++) {2026offset32 = (I_32) PARAM_32(bcIndex, 1);2027bcIndex -= 4; /* back up to point at the previous table switch entry */2028target = offset32 + start;2029rc = findAndMatchStack (verifyData, target, start);2030if (BCV_SUCCESS != rc) {2031if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {2032goto _outOfMemoryError;2033}2034goto _mapError;2035}2036}2037} else {2038BOOLEAN firstKey = TRUE;2039I_32 currentKey = 0;2040I_32 nextKey = 0;2041i2 = (I_32) PARAM_32(bcIndex, 1);2042bcIndex += 4;20432044pc += (I_32)i2 * 8;2045CHECK_END;2046for (i1 = 0; (I_32)i1 < (I_32)i2; i1++) {2047nextKey = (I_32) PARAM_32(bcIndex, 1);2048bcIndex += 4;2049if (!firstKey) {2050if (nextKey <= currentKey) {2051verboseErrorCode = BCV_ERR_BYTECODE_ERROR;2052storeVerifyErrorData(verifyData, (I_16)verboseErrorCode, (U_32)errorStackIndex, (UDATA)-1, (UDATA)-1, start);2053errorType = J9NLS_CFR_ERR_BC_SWITCH_NOT_SORTED__ID;2054errorModule = J9NLS_CFR_ERR_BC_SWITCH_NOT_SORTED__MODULE;2055goto _verifyError;2056}2057} else {2058firstKey = FALSE;2059}2060currentKey = nextKey;20612062offset32 = (I_32) PARAM_32(bcIndex, 1);2063bcIndex += 4;2064target = offset32 + start;2065rc = findAndMatchStack (verifyData, target, start);2066if (BCV_SUCCESS != rc) {2067if (BCV_ERR_INSUFFICIENT_MEMORY == rc) {2068goto _outOfMemoryError;2069}2070goto _mapError;2071}2072}2073}2074goto _newStack;2075break;20762077case JBmonitorenter:2078case JBmonitorexit:2079/* Monitor instructions are allowed to accept an uninitialized object */2080POP_TOS_OBJECT_IN_MONITOR(type);2081if (inconsistentStack) {2082/* Jazz 82615: Set the expected data type and the location of wrong data type2083* on stack when the verification error occurs.2084*/2085errorTargetType = BCV_GENERIC_OBJECT;2086errorStackIndex = stackTop - liveStack->stackElements;2087goto _inconsistentStack;2088}2089break;20902091case JBcheckcast:2092index = PARAM_16(bcIndex, 1);2093POP_TOS_OBJECT(type);2094if (inconsistentStack) {2095/* Jazz 82615: Set the expected data type and the location of wrong data type2096* on stack when the verification error occurs.2097*/2098errorTargetType = BCV_GENERIC_OBJECT;2099errorStackIndex = stackTop - liveStack->stackElements;2100goto _inconsistentStack;2101}2102info = &constantPool[index];2103utf8string = J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info);2104stackTop = pushClassType(verifyData, utf8string, stackTop);2105break;21062107case JBinstanceof:2108POP_TOS_OBJECT(type);2109if (inconsistentStack) {2110/* Jazz 82615: Set the expected data type and the location of wrong data type2111* on stack when the verification error occurs.2112*/2113errorTargetType = BCV_GENERIC_OBJECT;2114errorStackIndex = stackTop - liveStack->stackElements;2115goto _inconsistentStack;2116}2117PUSH_INTEGER_CONSTANT;2118break;2119}2120break;2121}2122case RTV_POP_2_PUSH_INT:2123POP_TOS_TYPE_EQUAL( type, type1 );2124if (inconsistentStack) {2125/* Jazz 82615: Set the 2nd slot of long/double type (already in type1) and2126* the location of wrong data type on stack when the verification error occurs.2127*/2128errorTargetType = BCV_BASE_TYPE_TOP;2129/* Save the long/double type to errorTempData (verifyData->errorTempData)2130* so as to ensure the wrong data type is the 2nd slot of long/double type2131* in the error message framework rather than a 'top' type.2132*/2133errorTempData = type1;2134/* The location of wrong data type needs to adjusted back to the right place2135* because it pops twice from the stack for the wide type.2136*/2137errorStackIndex = (stackTop - liveStack->stackElements) + 1;2138goto _inconsistentStack;2139/* Jazz 82615: the second inconsistent stack case in POP_TOS_TYPE_EQUAL should be addressed here */2140} else if (inconsistentStack2) {2141errorTargetType = type1;2142errorStackIndex = stackTop - liveStack->stackElements;2143goto _inconsistentStack;2144}2145POP_TOS_TYPE_EQUAL( type, type1 );2146if (inconsistentStack) {2147/* Jazz 82615: Set the 2nd slot of long/double type (already in type1) and2148* the location of wrong data type on stack when the verification error occurs.2149*/2150errorTargetType = BCV_BASE_TYPE_TOP;2151/* Save the long/double type to errorTempData (verifyData->errorTempData)2152* so as to ensure the wrong data type is the 2nd slot of long/double type2153* in the error message framework rather than a 'top' type.2154*/2155errorTempData = type1;2156/* The location of wrong data type needs to adjusted back to the right place2157* because it pops twice from the stack for the wide type.2158*/2159errorStackIndex = (stackTop - liveStack->stackElements) + 1;2160goto _inconsistentStack;2161/* Jazz 82615: the second inconsistent stack case in POP_TOS_TYPE_EQUAL should be addressed here */2162} else if (inconsistentStack2) {2163errorTargetType = type1;2164errorStackIndex = stackTop - liveStack->stackElements;2165goto _inconsistentStack;2166}2167PUSH_INTEGER_CONSTANT;2168break;21692170case RTV_BYTECODE_POP:2171POP_TOS_SINGLE(type);2172if (inconsistentStack) {2173/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2174errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2175verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2176errorStackIndex = stackTop - liveStack->stackElements;2177goto _miscError;2178}2179break;21802181case RTV_BYTECODE_POP2:2182POP_TOS_PAIR(temp1, temp2);2183if (inconsistentStack) {2184/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2185errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2186verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2187/* The pair of data types should be printed out once detected as invalid */2188errorStackIndex = stackTop - liveStack->stackElements + 1;2189goto _miscError;2190}2191break;21922193case RTV_BYTECODE_DUP:2194POP_TOS_SINGLE(type);2195if (inconsistentStack) {2196/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2197errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2198verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2199errorStackIndex = stackTop - liveStack->stackElements;2200goto _miscError;2201}2202PUSH(type);2203PUSH(type);2204break;22052206case RTV_BYTECODE_DUPX1:2207POP_TOS_SINGLE(type);2208if (inconsistentStack) {2209/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2210errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2211verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2212errorStackIndex = stackTop - liveStack->stackElements;2213goto _miscError;2214}2215POP_TOS_SINGLE(temp1);2216if (inconsistentStack) {2217/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2218errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2219verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2220errorStackIndex = stackTop - liveStack->stackElements;2221goto _miscError;2222}2223PUSH(type);2224PUSH(temp1);2225PUSH(type);2226break;22272228case RTV_BYTECODE_DUPX2:2229POP_TOS_SINGLE(type);2230if (inconsistentStack) {2231/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2232errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2233verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2234errorStackIndex = stackTop - liveStack->stackElements;2235goto _miscError;2236}2237POP_TOS_PAIR(temp1, temp2); /* use nverifyPop2 ?? */2238if (inconsistentStack) {2239/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2240errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2241verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2242/* The pair of data types should be printed out once detected as invalid */2243errorStackIndex = stackTop - liveStack->stackElements + 1;2244goto _miscError;2245}2246PUSH(type);2247PUSH(temp2);2248PUSH(temp1);2249PUSH(type);2250break;22512252case RTV_BYTECODE_DUP2:2253POP_TOS_PAIR(temp1, temp2);2254if (inconsistentStack) {2255/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2256errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2257verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2258/* The pair of data types should be printed out once detected as invalid */2259errorStackIndex = stackTop - liveStack->stackElements + 1;2260goto _miscError;2261}2262PUSH(temp2);2263PUSH(temp1);2264PUSH(temp2);2265PUSH(temp1);2266break;22672268case RTV_BYTECODE_DUP2X1:2269POP_TOS_PAIR(type, temp1);2270if (inconsistentStack) {2271/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2272errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2273verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2274/* The pair of data types should be printed out once detected as invalid */2275errorStackIndex = stackTop - liveStack->stackElements + 1;2276goto _miscError;2277}2278POP_TOS_SINGLE(temp2);2279if (inconsistentStack) {2280/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2281errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2282verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2283errorStackIndex = stackTop - liveStack->stackElements;2284goto _miscError;2285}2286PUSH(temp1);2287PUSH(type);2288PUSH(temp2);2289PUSH(temp1);2290PUSH(type);2291break;22922293case RTV_BYTECODE_DUP2X2:2294POP_TOS_PAIR(type, temp1);2295if (inconsistentStack) {2296/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2297errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2298verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2299/* The pair of data types should be printed out once detected as invalid */2300errorStackIndex = stackTop - liveStack->stackElements + 1;2301goto _miscError;2302}2303POP_TOS_PAIR(temp2, temp3);2304if (inconsistentStack) {2305/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2306errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2307verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2308/* The pair of data types should be printed out once detected as invalid */2309errorStackIndex = stackTop - liveStack->stackElements + 1;2310goto _miscError;2311}2312/* should probably do more checking to avoid bogus dup's of long/double pairs */2313PUSH(temp1);2314PUSH(type);2315PUSH(temp3);2316PUSH(temp2);2317PUSH(temp1);2318PUSH(type);2319break;23202321case RTV_BYTECODE_SWAP:2322POP_TOS_SINGLE(type);2323if (inconsistentStack) {2324/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2325errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2326verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2327errorStackIndex = stackTop - liveStack->stackElements;2328goto _miscError;2329}2330POP_TOS_SINGLE(temp1);2331if (inconsistentStack) {2332/* Jazz 82615: Set the error code (a non-top type is expected on stack). */2333errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2334verboseErrorCode = BCV_ERR_WRONG_TOP_TYPE;2335errorStackIndex = stackTop - liveStack->stackElements;2336goto _miscError;2337}2338PUSH(type);2339PUSH(temp1);2340break;23412342default:2343errorType = J9NLS_BCV_ERR_BC_UNKNOWN__ID;2344/* Jazz 82615: Set the error code in the case of unrecognized opcode. */2345verboseErrorCode = BCV_ERR_BAD_BYTECODE;2346goto _miscError;2347}2348continue;23492350_newStack:23512352/* Do I need a new stack? */2353if (pc < length) {23542355/* Do I have more stacks */2356if ((UDATA) nextStackPC < length) {23572358/* Is the next stack for the next bytecode */2359if (pc != (UDATA) nextStackPC) {2360if (J9ROMCLASS_HAS_VERIFY_DATA(romClass) && (!verifyData->ignoreStackMaps)) {2361/* the nextStack is not the wanted stack */2362/* Flow verification allows dead code without a map */2363/* Jazz 82615: Set the error code, the next pc value, and the pc value of unexpected stackmap frame. */2364errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2365verboseErrorCode = BCV_ERR_WRONG_STACKMAP_FRAME;2366errorTempData = nextStackPC;2367start = pc;2368goto _miscError;2369} else {2370/* skip dead code to nextStackPC */2371pc = nextStackPC;2372}2373}23742375/* Load the next stack into the live stack */2376SAVE_STACKTOP(liveStack, stackTop);2377memcpy((UDATA *) liveStack, (UDATA *) currentMapData, verifyData->stackSize);2378isNextStack = TRUE;2379RELOAD_LIVESTACK;23802381/* Start with uninitialized_this flag for the current map data */2382liveStack->uninitializedThis = currentMapData->uninitializedThis;23832384/* New next stack */2385currentMapData = nextStack (verifyData, &nextMapIndex, &nextStackPC);2386} else {2387/* no map available */2388if (J9ROMCLASS_HAS_VERIFY_DATA(romClass) && (!verifyData->ignoreStackMaps)) {2389/* Flow verification allows dead code without a map */2390/* Jazz 82615: Set the error code when nextStackPC goes beyond the stackmap table. */2391errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2392verboseErrorCode = BCV_ERR_NO_STACKMAP_FRAME;2393errorTempData = (UDATA)nextStackPC;2394goto _miscError;2395} else {2396if ((action != RTV_RETURN)2397&& (bc !=JBathrow)2398&& (bc !=JBtableswitch)2399&& (bc !=JBlookupswitch)2400&& (bc !=JBgoto)2401&& (bc !=JBgotow)2402) {2403/* Jazz 82615: Set the error code when it reaches unterminated dead code. */2404errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2405verboseErrorCode = BCV_ERR_DEAD_CODE;2406goto _miscError;2407}2408/* no more maps, skip remaining code as dead */2409pc = length;2410}2411}2412}2413}24142415/* StackMap/StackMapTable attribute treat all code as live */2416/* Flow verification allows unterminated dead code */2417if ((action != RTV_RETURN)2418&& (bc !=JBathrow)2419&& (bc !=JBtableswitch)2420&& (bc !=JBlookupswitch)2421&& (bc !=JBgoto)2422&& (bc !=JBgotow)2423) {2424/* Jazz 82615: Set the error code when it reaches unterminated dead code. */2425errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2426verboseErrorCode = BCV_ERR_DEAD_CODE;2427goto _miscError;2428}24292430Trc_RTV_verifyBytecodes_Exit(verifyData->vmStruct);24312432return BCV_SUCCESS;2433#undef CHECK_END24342435errorType = J9NLS_BCV_ERR_UNEXPECTED_EOF__ID; /* should never reach here */2436goto _verifyError;24372438_mapError:2439/* TODO: add tracepoint that indicates a map error occured:2440* class, method, pc2441*/24422443errorType = J9NLS_BCV_ERR_INCONSISTENT_STACK__ID;2444_compatibleError:2445if (rc == BCV_ERR_INTERNAL_ERROR) {2446errorType = J9NLS_BCV_ERR_CLASS_LOAD_FAILED__ID;2447}24482449_verifyError:2450/* Jazz 82615: Store the error code in the case of CHECK_STACK_UNDERFLOW */2451if ((stackTop < stackBase) && (J9NLS_BCV_ERR_STACK_UNDERFLOW__ID == errorType)) {2452/* Reset to the location of the 1st data type on 'stack' in the case of stack underflow to show up */2453errorStackIndex = stackBase - liveStack->stackElements;2454storeVerifyErrorData(verifyData, BCV_ERR_STACK_UNDERFLOW, (U_32)errorStackIndex, (UDATA)-1, (UDATA)-1, start);2455}24562457Trc_RTV_verifyBytecodes_VerifyError(verifyData->vmStruct,2458errorType,2459(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(romMethod)),2460J9UTF8_DATA(J9ROMMETHOD_NAME(romMethod)),2461(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(romMethod)),2462J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(romMethod)),2463start);24642465Trc_RTV_verifyBytecodes_VerifyErrorBytecode(verifyData->vmStruct,2466(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2467J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2468(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(romMethod)),2469J9UTF8_DATA(J9ROMMETHOD_NAME(romMethod)),2470(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(romMethod)),2471J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(romMethod)),2472errorType, start, start, *(code + start));2473BUILD_VERIFY_ERROR(errorModule, errorType);24742475return BCV_ERR_INTERNAL_ERROR;24762477_miscError:2478/* Jazz 82615: Store the error code and the location of wrong data type on stack in the case of the verification error unrelated to incompatible type */2479storeVerifyErrorData(verifyData, (I_16)verboseErrorCode, (U_32)errorStackIndex, (UDATA)-1, errorTempData, start);2480goto _verifyError;24812482_outOfMemoryError:2483errorType = J9NLS_BCV_ERR_VERIFY_OUT_OF_MEMORY__ID;2484Trc_RTV_verifyBytecodes_OutOfMemoryException(verifyData->vmStruct,2485errorType,2486(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(romMethod)),2487J9UTF8_DATA(J9ROMMETHOD_NAME(romMethod)),2488(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(romMethod)),2489J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(romMethod)),2490start);2491BUILD_VERIFY_ERROR(errorModule, errorType);2492return BCV_ERR_INSUFFICIENT_MEMORY;2493}249424952496/*2497* returns BCV_SUCCESS on success2498* returns BCV_FAIL on error2499* returns BCV_ERR_INSUFFICIENT_MEMORY on OOM2500*/2501static IDATA2502verifyExceptions (J9BytecodeVerificationData *verifyData)2503{2504J9ROMMethod *romMethod = verifyData->romMethod;2505J9ROMClass *romClass = verifyData->romClass;2506J9ExceptionInfo *exceptionInfo;2507J9ExceptionHandler *handler;2508J9ROMConstantPoolItem *romConstantPool;2509J9UTF8 *catchName;2510UDATA i, catchClass;2511IDATA rc = BCV_SUCCESS;2512IDATA reasonCode = 0;25132514Trc_RTV_verifyExceptions_Entry(verifyData->vmStruct,2515(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(romMethod)),2516J9UTF8_DATA(J9ROMMETHOD_NAME(romMethod)),2517(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(romMethod)),2518J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(romMethod)));25192520/* Verify catch types are throwable */2521exceptionInfo = J9_EXCEPTION_DATA_FROM_ROM_METHOD(romMethod);2522handler = J9EXCEPTIONINFO_HANDLERS(exceptionInfo);2523romConstantPool = J9_ROM_CP_FROM_ROM_CLASS(verifyData->romClass);25242525for (i = 0; i < exceptionInfo->catchCount; i++, handler++) {2526if (handler->exceptionClassIndex) {2527IDATA tempRC = 0;25282529catchName = J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *)(&romConstantPool [handler->exceptionClassIndex]));2530catchClass = convertClassNameToStackMapType(verifyData, J9UTF8_DATA(catchName), J9UTF8_LENGTH(catchName), 0, 0);2531tempRC = isClassCompatible (verifyData, catchClass, (UDATA) (BCV_JAVA_LANG_THROWABLE_INDEX << BCV_CLASS_INDEX_SHIFT), &reasonCode);2532if (FALSE == tempRC) {2533if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {2534Trc_RTV_verifyExceptions_OutOfMemoryException(verifyData->vmStruct,2535(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2536J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2537(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(romMethod)),2538J9UTF8_DATA(J9ROMMETHOD_NAME(romMethod)),2539(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(romMethod)),2540J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(romMethod)));2541rc = BCV_ERR_INSUFFICIENT_MEMORY;2542break;2543} else {2544Trc_RTV_verifyExceptions_VerifyError(verifyData->vmStruct,2545(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2546J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2547(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(romMethod)),2548J9UTF8_DATA(J9ROMMETHOD_NAME(romMethod)),2549(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(romMethod)),2550J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(romMethod)),2551i, J9UTF8_LENGTH(catchName), J9UTF8_DATA(catchName));2552rc = BCV_FAIL;2553break;2554}2555}2556}2557}25582559Trc_RTV_verifyExceptions_Exit(verifyData->vmStruct);25602561return rc;2562}2563256425652566/*2567* returns BCV_SUCCESS on success2568* returns BCV_FAIL on errors2569* returns BCV_ERR_INSUFFICIENT_MEMORY on OOM2570* TODO: get rid of all the "this should never happen, checked by cfreader.c checks" */2571IDATA2572j9rtv_verifyArguments (J9BytecodeVerificationData *verifyData, J9UTF8 * utf8string, UDATA ** pStackTop)2573{2574IDATA argCount, index;2575UDATA arity, objectType, baseType;2576UDATA *stackTop;2577U_8 *signature;2578U_16 length;2579U_8 *string;2580IDATA rc;2581IDATA mrc = BCV_SUCCESS;2582BOOLEAN boolType = FALSE;2583J9BranchTargetStack *liveStack = (J9BranchTargetStack *) verifyData->liveStack;25842585Trc_RTV_j9rtv_verifyArguments_Entry(verifyData->vmStruct, J9UTF8_LENGTH(utf8string), J9UTF8_DATA(utf8string));25862587stackTop = *pStackTop;25882589/* Arguments are in reverse order on the stack, we must pre-pop the stack */2590argCount = (IDATA) getSendSlotsFromSignature(J9UTF8_DATA(utf8string));25912592/*2593* Jazz 82615: When the number of arguments is greater than the whole stack size,2594* Set stackTop with the address at liveStack->stackElements to avoid compare against garbage that doesn't exist on stack.2595*/2596if ((IDATA)(stackTop - liveStack->stackElements) < argCount) {2597stackTop = liveStack->stackElements;2598} else {2599stackTop = stackTop - argCount;2600}26012602signature = J9UTF8_DATA(utf8string) + 1; /* skip open bracket */26032604/* Walk the arguments and verify the stack */2605for (index = 0; index < argCount; index++) {26062607arity = 0;2608objectType = 0;2609boolType = FALSE;26102611/* Look for an array */2612if (*signature == '[') {26132614while (*signature == '[') {2615signature++;2616arity++;2617}26182619}26202621/* Object or array */2622if (IS_REF_OR_VAL_SIGNATURE(*signature) || arity) {2623IDATA reasonCode = 0;26242625/* Object array */2626if (IS_REF_OR_VAL_SIGNATURE(*signature)) {2627signature++;2628string = signature; /* remember the start of the string */2629while (*signature++ != ';');2630length = (U_16) (signature - string - 1);2631objectType = convertClassNameToStackMapType(verifyData, string, length, 0, arity);26322633/* Base type array */2634} else {26352636if ((*signature < 'A') || (*signature > 'Z')) {2637/* Should never happen - bad sig. caught by cfreader.c checkMethodSignature */2638Trc_RTV_j9rtv_verifyArguments_Unreachable(verifyData->vmStruct,2639(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2640J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2641(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2642J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2643(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2644J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2645__LINE__);2646mrc = BCV_FAIL;2647break;2648}26492650objectType = (UDATA) baseTypeCharConversion[*signature - 'A'];2651signature++;26522653if (!objectType) {2654/* Should never happen - bad sig. caught by cfreader.c checkMethodSignature */2655Trc_RTV_j9rtv_verifyArguments_Unreachable(verifyData->vmStruct,2656(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2657J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2658(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2659J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2660(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2661J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2662__LINE__);2663mrc = BCV_FAIL;2664break;2665}26662667arity--;2668objectType |= BCV_TAG_BASE_ARRAY_OR_NULL;2669}26702671/* Check the object */2672objectType |= (arity << BCV_ARITY_SHIFT);2673rc = isClassCompatible (verifyData, stackTop[index], objectType, &reasonCode);26742675if (FALSE == rc) {2676if (BCV_ERR_INSUFFICIENT_MEMORY == reasonCode) {2677Trc_RTV_j9rtv_verifyArguments_OutOfMemoryException(verifyData->vmStruct,2678(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2679J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2680(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2681J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2682(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2683J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)));2684mrc = BCV_ERR_INSUFFICIENT_MEMORY;2685break;2686} else if (BCV_ERR_INACCESSIBLE_CLASS == reasonCode) {2687Trc_RTV_j9rtv_verifyArguments_InaccessibleClass(verifyData->vmStruct,2688(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2689J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2690(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2691J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2692(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2693J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)));2694mrc = BCV_ERR_INACCESSIBLE_CLASS;2695break;2696} else {2697Trc_RTV_j9rtv_verifyArguments_ObjectMismatch(verifyData->vmStruct,2698(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2699J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2700(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2701J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2702(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2703J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2704index, J9UTF8_LENGTH(utf8string), J9UTF8_DATA(utf8string), stackTop[index]);2705mrc = BCV_FAIL;2706verifyData->errorDetailCode = BCV_ERR_INCOMPATIBLE_TYPE; /* failure - object type mismatch */2707verifyData->errorTargetType = objectType;2708break;2709}2710}27112712/* Base type */2713} else {27142715if ((*signature < 'A') || (*signature > 'Z')) {2716/* Should never happen - bad sig. caught by cfreader.c checkMethodSignature */2717Trc_RTV_j9rtv_verifyArguments_Unreachable(verifyData->vmStruct,2718(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2719J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2720(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2721J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2722(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2723J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2724__LINE__);2725mrc = BCV_FAIL;2726break;2727}27282729baseType = (UDATA) argTypeCharConversion[*signature - 'A'];2730/* Jazz 82615: Tagged as 'bool' when argTypeCharConversion returns BCV_BASE_TYPE_INT for type 'Z'2731* Note: for base type, type B (byte) and type Z (boolean) correspond to the verification type int.2732* In such case, there is no way to determine whether the original type is byte or boolean after the2733* conversion of argument type. To ensure type Z is correctly generated to the error messages, we need2734* to filter it out here by checking the type in signature.2735*/2736if ('Z' == *signature) {2737boolType = TRUE;2738}2739signature++;27402741if (!baseType) {2742/* Should never happen - bad sig. caught by cfreader.c checkMethodSignature */2743Trc_RTV_j9rtv_verifyArguments_Unreachable(verifyData->vmStruct,2744(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2745J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2746(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2747J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2748(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2749J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2750__LINE__);2751mrc = BCV_FAIL;2752break;2753}27542755if (stackTop[index] != baseType) {2756Trc_RTV_j9rtv_verifyArguments_PrimitiveMismatch(verifyData->vmStruct,2757(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2758J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2759(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2760J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2761(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2762J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2763index, J9UTF8_LENGTH(utf8string), J9UTF8_DATA(utf8string), stackTop[index]);2764mrc = BCV_FAIL;2765verifyData->errorDetailCode = BCV_ERR_INCOMPATIBLE_TYPE; /* failure - primitive mismatch */2766verifyData->errorTargetType = (TRUE == boolType) ? BCV_BASE_TYPE_BOOL : baseType;2767break;2768}27692770if (baseType & BCV_WIDE_TYPE_MASK) {2771index++;2772if (stackTop[index] != BCV_BASE_TYPE_TOP) {2773Trc_RTV_j9rtv_verifyArguments_WidePrimitiveMismatch(verifyData->vmStruct,2774(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2775J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2776(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2777J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2778(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2779J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2780index, J9UTF8_LENGTH(utf8string), J9UTF8_DATA(utf8string));2781mrc = BCV_FAIL;2782verifyData->errorDetailCode = BCV_ERR_INCOMPATIBLE_TYPE; /* failure - wide primitive mismatch */2783verifyData->errorTargetType = (TRUE == boolType) ? BCV_BASE_TYPE_BOOL : baseType;2784break;2785}2786}2787}2788}27892790/* errorDetailCode has been initialized with 0 (SUCCESS).2791* Verification error data related to argument mismatch should be saved here when any verification error is detected above.2792*/2793if (verifyData->errorDetailCode < 0) {2794storeArgumentErrorData(verifyData, (U_32)(&stackTop[index] - liveStack->stackElements), (U_16)index);2795}27962797*pStackTop = stackTop;27982799Trc_RTV_j9rtv_verifyArguments_Exit(verifyData->vmStruct, mrc);28002801return mrc;2802}28032804/* Return a pointer to the next stack, update the nextMapIndex and the nextStackPC */28052806static J9BranchTargetStack *2807nextStack (J9BytecodeVerificationData *verifyData, UDATA *nextMapIndex, IDATA *nextStackPC)2808{2809J9BranchTargetStack * returnStack = NULL;2810/* Default nextStackPC is the end of the method */2811*nextStackPC = J9_BYTECODE_SIZE_FROM_ROM_METHOD(verifyData->romMethod);28122813while (*nextMapIndex < (UDATA) verifyData->stackMapsCount) {2814returnStack = BCV_INDEX_STACK (*nextMapIndex);2815(*nextMapIndex)++;28162817/* skip unused stack maps */2818/* simulateStack can have unused stack map targets - they result from being in dead code */2819if (returnStack->stackBaseIndex != -1) {2820*nextStackPC = returnStack->pc;2821break;2822}2823}2824Trc_RTV_nextStack_Result(verifyData->vmStruct,2825(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2826J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2827(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2828J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2829(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2830J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2831verifyData->stackMapsCount, *nextMapIndex, *nextStackPC,2832J9_BYTECODE_SIZE_FROM_ROM_METHOD(verifyData->romMethod));2833return returnStack;2834}28352836/* Return the next pc in the method that is an exception handler start address */28372838static IDATA2839nextExceptionStart (J9BytecodeVerificationData *verifyData, J9ROMMethod *romMethod, IDATA lastPC)2840{2841/* Method size */2842IDATA nextPC = J9_BYTECODE_SIZE_FROM_ROM_METHOD(romMethod);28432844if (romMethod->modifiers & CFR_ACC_HAS_EXCEPTION_INFO) {2845J9ExceptionInfo *exceptionInfo = J9_EXCEPTION_DATA_FROM_ROM_METHOD(romMethod);2846J9ExceptionHandler *handler = J9EXCEPTIONINFO_HANDLERS(exceptionInfo);2847UDATA i;28482849for (i = exceptionInfo->catchCount; i; i--, handler++) {2850if (((IDATA) handler->startPC) > lastPC) {2851if (handler->startPC < (UDATA) nextPC) {2852nextPC = handler->startPC;2853}2854}2855}2856Trc_RTV_nextExceptionStart_Result(verifyData->vmStruct,2857(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2858J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),2859(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_NAME(verifyData->romMethod)),2860J9UTF8_DATA(J9ROMMETHOD_NAME(verifyData->romMethod)),2861(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2862J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(verifyData->romMethod)),2863exceptionInfo->catchCount, lastPC, nextPC,2864J9_BYTECODE_SIZE_FROM_ROM_METHOD(romMethod));2865}2866return nextPC;2867}286828692870/**2871* Store the failure info regarding mismatched argument in method signature to the2872* J9BytecodeVerificationData structure for outputting detailed error message2873* @param verifyData - pointer to J9BytecodeVerificationData2874* @param errorCurrentFramePosition - the location of type data in the current frame when error occurs2875* @param errorArgumentIndex - index to the argument of method signature when error occurs2876*/2877static void2878storeArgumentErrorData (J9BytecodeVerificationData * verifyData, U_32 errorCurrentFramePosition, U_16 errorArgumentIndex)2879{2880verifyData->errorCurrentFramePosition = errorCurrentFramePosition;2881verifyData->errorArgumentIndex = errorArgumentIndex;2882}28832884/**2885* Postpone storing the method info to the checking of return code after the mismatched argument in method signature is detected2886* J9BytecodeVerificationData structure for outputting detailed error message2887* @param verifyData - pointer to J9BytecodeVerificationData2888* @param errorClassString - pointer to class name2889* @param errorMethodString - pointer to method name2890* @param errorSignatureString - pointer to signature string2891* @param currentPC - current pc value2892*/2893static void2894storeMethodInfo (J9BytecodeVerificationData * verifyData, J9UTF8* errorClassString, J9UTF8* errorMethodString, J9UTF8* errorSignatureString, IDATA currentPC)2895{2896J9BranchTargetStack *liveStack = (J9BranchTargetStack *) verifyData->liveStack;2897verifyData->errorClassString = errorClassString;2898verifyData->errorMethodString = errorMethodString;2899verifyData->errorSignatureString = errorSignatureString;29002901/* Jazz 82615: Set liveStack->pc to the current pc value in the current frame (liveStack)2902* info of the detailed error message.2903*/2904liveStack->pc = (UDATA)currentPC;2905}290629072908