Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetBytecodes/bytecodes003/bytecodes003.cpp
40951 views
/*1* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include <stdio.h>24#include <string.h>25#include "jvmti.h"26#include "agent_common.h"27#include "JVMTITools.h"2829extern "C" {303132#define PASSED 033#define STATUS_FAILED 23435typedef enum {36opc_iinc = 132,37opc_tableswitch = 170,38opc_lookupswitch = 171,39opc_wide = 19640} opcode_type;4142typedef struct {43const char *name;44unsigned char code;45int length;46} opcode_info;4748static jvmtiEnv *jvmti = NULL;49static jvmtiCapabilities caps;50static jvmtiEventCallbacks callbacks;51static jint result = PASSED;52static jboolean printdump = JNI_FALSE;53static int eventsCount = 0;54static opcode_info opcodes[] = {55{ "nop", 0, 1 },56{ "aconst_null", 1, 1 },57{ "iconst_m1", 2, 1 },58{ "iconst_0", 3, 1 },59{ "iconst_1", 4, 1 },60{ "iconst_2", 5, 1 },61{ "iconst_3", 6, 1 },62{ "iconst_4", 7, 1 },63{ "iconst_5", 8, 1 },64{ "lconst_0", 9, 1 },65{ "lconst_1", 10, 1 },66{ "fconst_0", 11, 1 },67{ "fconst_1", 12, 1 },68{ "fconst_2", 13, 1 },69{ "dconst_0", 14, 1 },70{ "dconst_1", 15, 1 },71{ "bipush", 16, 2 },72{ "sipush", 17, 3 },73{ "ldc", 18, 2 },74{ "ldc_w", 19, 3 },75{ "ldc2_w", 20, 3 },76{ "iload", 21, 2 },77{ "lload", 22, 2 },78{ "fload", 23, 2 },79{ "dload", 24, 2 },80{ "aload", 25, 2 },81{ "iload_0", 26, 1 },82{ "iload_1", 27, 1 },83{ "iload_2", 28, 1 },84{ "iload_3", 29, 1 },85{ "lload_0", 30, 1 },86{ "lload_1", 31, 1 },87{ "lload_2", 32, 1 },88{ "lload_3", 33, 1 },89{ "fload_0", 34, 1 },90{ "fload_1", 35, 1 },91{ "fload_2", 36, 1 },92{ "fload_3", 37, 1 },93{ "dload_0", 38, 1 },94{ "dload_1", 39, 1 },95{ "dload_2", 40, 1 },96{ "dload_3", 41, 1 },97{ "aload_0", 42, 1 },98{ "aload_1", 43, 1 },99{ "aload_2", 44, 1 },100{ "aload_3", 45, 1 },101{ "iaload", 46, 1 },102{ "laload", 47, 1 },103{ "faload", 48, 1 },104{ "daload", 49, 1 },105{ "aaload", 50, 1 },106{ "baload", 51, 1 },107{ "caload", 52, 1 },108{ "saload", 53, 1 },109{ "istore", 54, 2 },110{ "lstore", 55, 2 },111{ "fstore", 56, 2 },112{ "dstore", 57, 2 },113{ "astore", 58, 2 },114{ "istore_0", 59, 1 },115{ "istore_1", 60, 1 },116{ "istore_2", 61, 1 },117{ "istore_3", 62, 1 },118{ "lstore_0", 63, 1 },119{ "lstore_1", 64, 1 },120{ "lstore_2", 65, 1 },121{ "lstore_3", 66, 1 },122{ "fstore_0", 67, 1 },123{ "fstore_1", 68, 1 },124{ "fstore_2", 69, 1 },125{ "fstore_3", 70, 1 },126{ "dstore_0", 71, 1 },127{ "dstore_1", 72, 1 },128{ "dstore_2", 73, 1 },129{ "dstore_3", 74, 1 },130{ "astore_0", 75, 1 },131{ "astore_1", 76, 1 },132{ "astore_2", 77, 1 },133{ "astore_3", 78, 1 },134{ "iastore", 79, 1 },135{ "lastore", 80, 1 },136{ "fastore", 81, 1 },137{ "dastore", 82, 1 },138{ "aastore", 83, 1 },139{ "bastore", 84, 1 },140{ "castore", 85, 1 },141{ "sastore", 86, 1 },142{ "pop", 87, 1 },143{ "pop2", 88, 1 },144{ "dup", 89, 1 },145{ "dup_x1", 90, 1 },146{ "dup_x2", 91, 1 },147{ "dup2", 92, 1 },148{ "dup2_x1", 93, 1 },149{ "dup2_x2", 94, 1 },150{ "swap", 95, 1 },151{ "iadd", 96, 1 },152{ "ladd", 97, 1 },153{ "fadd", 98, 1 },154{ "dadd", 99, 1 },155{ "isub", 100, 1 },156{ "lsub", 101, 1 },157{ "fsub", 102, 1 },158{ "dsub", 103, 1 },159{ "imul", 104, 1 },160{ "lmul", 105, 1 },161{ "fmul", 106, 1 },162{ "dmul", 107, 1 },163{ "idiv", 108, 1 },164{ "ldiv", 109, 1 },165{ "fdiv", 110, 1 },166{ "ddiv", 111, 1 },167{ "irem", 112, 1 },168{ "lrem", 113, 1 },169{ "frem", 114, 1 },170{ "drem", 115, 1 },171{ "ineg", 116, 1 },172{ "lneg", 117, 1 },173{ "fneg", 118, 1 },174{ "dneg", 119, 1 },175{ "ishl", 120, 1 },176{ "lshl", 121, 1 },177{ "ishr", 122, 1 },178{ "lshr", 123, 1 },179{ "iushr", 124, 1 },180{ "lushr", 125, 1 },181{ "iand", 126, 1 },182{ "land", 127, 1 },183{ "ior", 128, 1 },184{ "lor", 129, 1 },185{ "ixor", 130, 1 },186{ "lxor", 131, 1 },187{ "iinc", 132, 3 },188{ "i2l", 133, 1 },189{ "i2f", 134, 1 },190{ "i2d", 135, 1 },191{ "l2i", 136, 1 },192{ "l2f", 137, 1 },193{ "l2d", 138, 1 },194{ "f2i", 139, 1 },195{ "f2l", 140, 1 },196{ "f2d", 141, 1 },197{ "d2i", 142, 1 },198{ "d2l", 143, 1 },199{ "d2f", 144, 1 },200{ "i2b", 145, 1 },201{ "i2c", 146, 1 },202{ "i2s", 147, 1 },203{ "lcmp", 148, 1 },204{ "fcmpl", 149, 1 },205{ "fcmpg", 150, 1 },206{ "dcmpl", 151, 1 },207{ "dcmpg", 152, 1 },208{ "ifeq", 153, 3 },209{ "ifne", 154, 3 },210{ "iflt", 155, 3 },211{ "ifge", 156, 3 },212{ "ifgt", 157, 3 },213{ "ifle", 158, 3 },214{ "if_icmpeq", 159, 3 },215{ "if_icmpne", 160, 3 },216{ "if_icmplt", 161, 3 },217{ "if_icmpge", 162, 3 },218{ "if_icmpgt", 163, 3 },219{ "if_icmple", 164, 3 },220{ "if_acmpeq", 165, 3 },221{ "if_acmpne", 166, 3 },222{ "goto", 167, 3 },223{ "jsr", 168, 3 },224{ "ret", 169, 2 },225{ "tableswitch", 170, 0 },226{ "lookupswitch", 171, 0 },227{ "ireturn", 172, 1 },228{ "lreturn", 173, 1 },229{ "freturn", 174, 1 },230{ "dreturn", 175, 1 },231{ "areturn", 176, 1 },232{ "return", 177, 1 },233{ "getstatic", 178, 3 },234{ "putstatic", 179, 3 },235{ "getfield", 180, 3 },236{ "putfield", 181, 3 },237{ "invokevirtual", 182, 3 },238{ "invokespecial", 183, 3 },239{ "invokestatic", 184, 3 },240{ "invokeinterface", 185, 5 },241{ "invokedynamic", 186, 5 },242{ "new", 187, 3 },243{ "newarray", 188, 2 },244{ "anewarray", 189, 3 },245{ "arraylength", 190, 1 },246{ "athrow", 191, 1 },247{ "checkcast", 192, 3 },248{ "instanceof", 193, 3 },249{ "monitorenter", 194, 1 },250{ "monitorexit", 195, 1 },251{ "wide", 196, 0 },252{ "multianewarray", 197, 4 },253{ "ifnull", 198, 3 },254{ "ifnonnull", 199, 3 },255{ "goto_w", 200, 5 },256{ "jsr_w", 201, 5 },257{ "breakpoint", 202, 1 },258{ "impdep1", 254, 1 },259{ "impdep2", 255, 1 }260};261262jint get_u4(unsigned char *p) {263return (jint)p[3] | ((jint)p[2]<<8) | ((jint)p[1]<<16) | ((jint)p[0]<<24);264}265266jboolean checkCode(jint bytecodeCount, unsigned char *buf) {267unsigned char code;268jint pc, cur_pc, length;269size_t i;270271for (pc = 0; pc >= 0 && pc < bytecodeCount; pc += length) {272code = buf[pc];273for (i = 0; i < sizeof(opcodes)/sizeof(opcode_info); i++) {274if (code == opcodes[i].code) {275switch (code) {276case opc_wide:277length = (buf[pc + 1] == opc_iinc ? 6 : 4);278break;279case opc_lookupswitch:280cur_pc = (pc + 4) & (~3);281length = cur_pc - pc + 8;282length += get_u4(buf + cur_pc + 4) * 8;283break;284case opc_tableswitch:285cur_pc = (pc + 4) & (~3);286length = cur_pc - pc + 12;287length += (get_u4(buf + cur_pc + 8) -288get_u4(buf + cur_pc + 4) + 1) * 4;289break;290default:291length = opcodes[i].length;292break;293}294if (printdump == JNI_TRUE) {295printf(">>> %4d: %s (%d)\n",296pc, opcodes[i].name, length);297}298if (length <= 0) {299printf("Invalid length: %d for opcode \"%s\" (%d)\n",300length, opcodes[i].name, code);301return JNI_FALSE;302}303break;304}305}306if (i >= sizeof(opcodes)/sizeof(opcode_info)) {307/* opcode not found */308printf("Non-standard opcode: %d (0x%x)\n", code, code);309return JNI_FALSE;310}311}312return JNI_TRUE;313}314315void JNICALL ClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *env,316jthread thr, jclass cls) {317jvmtiError err;318char *sig, *name, *msig;319jint mcount;320jmethodID *methods;321jboolean isNative;322jint bytecodeCount;323unsigned char *bytecodes;324jint i;325326sig = NULL;327err = jvmti_env->GetClassSignature(cls, &sig, NULL);328if (err != JVMTI_ERROR_NONE) {329printf("(GetClassSignature#%d) unexpected error: %s (%d)\n",330eventsCount, TranslateError(err), err);331result = STATUS_FAILED;332return;333}334err = jvmti_env->GetClassMethods(cls, &mcount, &methods);335if (err != JVMTI_ERROR_NONE) {336printf("(GetClassMethods#%d) unexpected error: %s (%d)\n",337eventsCount, TranslateError(err), err);338result = STATUS_FAILED;339return;340}341342if (printdump == JNI_TRUE) {343printf(">>> [class prepare event #%d]", eventsCount);344printf(" \"%s\"\n", sig);345printf(">>> %d methods:\n", mcount);346}347348for (i = 0; i < mcount; i++) {349if (methods[i] == NULL) {350if (printdump == JNI_TRUE) {351printf(" null");352}353} else {354name = NULL;355msig = NULL;356bytecodes = NULL;357err = jvmti_env->GetMethodName(methods[i], &name, &msig, NULL);358if (err != JVMTI_ERROR_NONE) {359printf("(GetMethodName) unexpected error: %s (%d)\n",360TranslateError(err), err);361printf(" class: \"%s\"\n", sig);362result = STATUS_FAILED;363return;364}365isNative = JNI_TRUE;366err = jvmti_env->IsMethodNative(methods[i], &isNative);367if (err != JVMTI_ERROR_NONE) {368printf("(IsMethodNative) unexpected error: %s (%d)\n",369TranslateError(err), err);370printf(" class: \"%s\"\n", sig);371printf(" method = \"%s%s\"\n", name, msig);372result = STATUS_FAILED;373return;374}375if (isNative == JNI_TRUE) {376if (printdump == JNI_TRUE) {377printf(">>> \"%s%s\", native\n", name, msig);378}379} else {380err = jvmti_env->GetBytecodes(methods[i],381&bytecodeCount, &bytecodes);382if (err != JVMTI_ERROR_NONE) {383printf("(GetBytecodes#%d:%d) unexpected error: %s (%d)\n",384eventsCount, i, TranslateError(err), err);385result = STATUS_FAILED;386return;387} else {388if (printdump == JNI_TRUE) {389printf(">>> \"%s%s\", %d bytes\n",390name, msig, bytecodeCount);391}392if (checkCode(bytecodeCount, bytecodes) == JNI_FALSE) {393printf(" class: \"%s\"\n", sig);394printf(" method = \"%s%s\"\n", name, msig);395result = STATUS_FAILED;396}397}398}399if (name != NULL) {400jvmti_env->Deallocate((unsigned char *)name);401}402if (msig != NULL) {403jvmti_env->Deallocate((unsigned char *)msig);404}405if (bytecodes != NULL) {406jvmti_env->Deallocate(bytecodes);407}408}409}410411if (methods != NULL) {412jvmti_env->Deallocate((unsigned char *)methods);413}414if (sig != NULL) {415jvmti_env->Deallocate((unsigned char *)sig);416}417eventsCount++;418}419420#ifdef STATIC_BUILD421JNIEXPORT jint JNICALL Agent_OnLoad_bytecodes003(JavaVM *jvm, char *options, void *reserved) {422return Agent_Initialize(jvm, options, reserved);423}424JNIEXPORT jint JNICALL Agent_OnAttach_bytecodes003(JavaVM *jvm, char *options, void *reserved) {425return Agent_Initialize(jvm, options, reserved);426}427JNIEXPORT jint JNI_OnLoad_bytecodes003(JavaVM *jvm, char *options, void *reserved) {428return JNI_VERSION_1_8;429}430#endif431jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {432jvmtiError err;433jint res;434435if (options != NULL && strcmp(options, "printdump") == 0) {436printdump = JNI_TRUE;437}438439res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);440if (res != JNI_OK || jvmti == NULL) {441printf("Wrong result of a valid call to GetEnv!\n");442return JNI_ERR;443}444445err = jvmti->GetCapabilities(&caps);446if (err != JVMTI_ERROR_NONE) {447printf("(GetCapabilities) unexpected error: %s (%d)\n",448TranslateError(err), err);449return JNI_ERR;450}451452err = jvmti->GetCapabilities(&caps);453if (err != JVMTI_ERROR_NONE) {454printf("(GetCapabilities) unexpected error: %s (%d)\n",455TranslateError(err), err);456return JNI_ERR;457}458459err = jvmti->GetPotentialCapabilities(&caps);460if (err != JVMTI_ERROR_NONE) {461printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",462TranslateError(err), err);463return JNI_ERR;464}465466err = jvmti->AddCapabilities(&caps);467if (err != JVMTI_ERROR_NONE) {468printf("(AddCapabilities) unexpected error: %s (%d)\n",469TranslateError(err), err);470return JNI_ERR;471}472473err = jvmti->GetCapabilities(&caps);474if (err != JVMTI_ERROR_NONE) {475printf("(GetCapabilities) unexpected error: %s (%d)\n",476TranslateError(err), err);477return JNI_ERR;478}479480if (caps.can_get_bytecodes) {481callbacks.ClassPrepare = &ClassPrepare;482err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));483if (err != JVMTI_ERROR_NONE) {484printf("(SetEventCallbacks) unexpected error: %s (%d)\n",485TranslateError(err), err);486return JNI_ERR;487}488489err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,490JVMTI_EVENT_CLASS_PREPARE, NULL);491if (err != JVMTI_ERROR_NONE) {492printf("Failed to enable ClassPrepare: %s (%d)\n",493TranslateError(err), err);494result = STATUS_FAILED;495}496} else {497printf("Warning: GetBytecodes is not implemented\n");498}499500return JNI_OK;501}502503JNIEXPORT jint JNICALL504Java_nsk_jvmti_GetBytecodes_bytecodes003_check(JNIEnv *env, jclass cls) {505jvmtiError err;506507if (jvmti == NULL) {508printf("JVMTI client was not properly loaded!\n");509return STATUS_FAILED;510}511512if (caps.can_get_bytecodes) {513err = jvmti->SetEventNotificationMode(JVMTI_DISABLE,514JVMTI_EVENT_CLASS_PREPARE, NULL);515if (err != JVMTI_ERROR_NONE) {516printf("Failed to disable JVMTI_EVENT_CLASS_PREPARE: %s (%d)\n",517TranslateError(err), err);518result = STATUS_FAILED;519}520}521522if (printdump == JNI_TRUE) {523printf("Total number of class prepare events: %d\n", eventsCount);524}525526return result;527}528529}530531532