1 /*
   2  * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 #include <stdio.h>
  25 #include <string.h>
  26 #include "jvmti.h"
  27 #include "agent_common.h"
  28 #include "JVMTITools.h"
  29 
  30 extern "C" {
  31 
  32 
  33 #define PASSED 0
  34 #define STATUS_FAILED 2
  35 
  36 static jvmtiCapabilities caps;
  37 static jvmtiEventCallbacks callbacks;
  38 
  39 #define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return
  40 
  41 static jint      errCode       = PASSED;
  42 static jvmtiEnv *jvmti         = NULL;
  43 static jmethodID midCheckPoint = NULL;
  44 
  45 
  46 JNIEXPORT void JNICALL
  47 Java_nsk_jvmti_unit_GetConstantPool_getcpool001_getCP(
  48     JNIEnv *env, jclass c, jint id, jclass cls) {
  49     jvmtiError    err;
  50     int           idx          = 0;
  51     int           rep          = 0;
  52     jint          cp_cnt       = 0;
  53     jint          cp_bytes_cnt = 0;
  54     unsigned char *cp_bytes    = NULL;
  55 
  56     err = jvmti->GetConstantPool(cls, &cp_cnt, &cp_bytes_cnt, &cp_bytes);
  57     if (err != JVMTI_ERROR_NONE) {
  58         printf("(GetConstantPool) unexpected error: %s (%d)\n",
  59                TranslateError(err), err);
  60         RETURN_FAILED;
  61     }
  62 
  63     /* Print Constant Pool attrs*/
  64     printf("getCP: id = %d, cnt = %03d, bytes_cnt = %04d\n",
  65             id, cp_cnt, cp_bytes_cnt);
  66     fflush(0);
  67 }
  68 
  69 void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env,
  70         jthread thread, jmethodID method, jlocation location) {
  71     jvmtiError     err;
  72 
  73     if (midCheckPoint != method) {
  74         printf("bp: don't know where we get called from");
  75         RETURN_FAILED;
  76     }
  77 
  78     printf(">>> breakpoint in checkPoint\n");
  79 
  80     err = jvmti_env->ClearBreakpoint(midCheckPoint, 0);
  81     if (err != JVMTI_ERROR_NONE) {
  82         printf("(ClearBreakpoint) unexpected error: %s (%d)\n",
  83                TranslateError(err), err);
  84         RETURN_FAILED;
  85     }
  86     fflush(0);
  87 }
  88 
  89 #ifdef STATIC_BUILD
  90 JNIEXPORT jint JNICALL Agent_OnLoad_getcpool001(JavaVM *jvm, char *options, void *reserved) {
  91     return Agent_Initialize(jvm, options, reserved);
  92 }
  93 JNIEXPORT jint JNICALL Agent_OnAttach_getcpool001(JavaVM *jvm, char *options, void *reserved) {
  94     return Agent_Initialize(jvm, options, reserved);
  95 }
  96 JNIEXPORT jint JNI_OnLoad_getcpool001(JavaVM *jvm, char *options, void *reserved) {
  97     return JNI_VERSION_1_8;
  98 }
  99 #endif
 100 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
 101     jvmtiError err;
 102     jint res;
 103 
 104     res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
 105     if (res != JNI_OK || jvmti == NULL) {
 106         printf("Wrong result of a valid call to GetEnv!\n");
 107         return JNI_ERR;
 108     }
 109 
 110     err = jvmti->GetPotentialCapabilities(&caps);
 111     if (err != JVMTI_ERROR_NONE) {
 112         printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",
 113                TranslateError(err), err);
 114         return JNI_ERR;
 115     }
 116 
 117     err = jvmti->AddCapabilities(&caps);
 118     if (err != JVMTI_ERROR_NONE) {
 119         printf("(AddCapabilities) unexpected error: %s (%d)\n",
 120                TranslateError(err), err);
 121         return JNI_ERR;
 122     }
 123 
 124     err = jvmti->GetCapabilities(&caps);
 125     if (err != JVMTI_ERROR_NONE) {
 126         printf("(GetCapabilities) unexpected error: %s (%d)\n",
 127                TranslateError(err), err);
 128         return JNI_ERR;
 129     }
 130 
 131     if (!caps.can_force_early_return) {
 132         printf("Warning: GetConstantPool is not implemented\n");
 133     }
 134 
 135     if (caps.can_generate_breakpoint_events &&
 136             caps.can_generate_single_step_events) {
 137         callbacks.Breakpoint = &Breakpoint;
 138         err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
 139         if (err != JVMTI_ERROR_NONE) {
 140             printf("(SetEventCallbacks) unexpected error: %s (%d)\n",
 141                    TranslateError(err), err);
 142             return JNI_ERR;
 143         }
 144     }
 145 
 146     return JNI_OK;
 147 }
 148 
 149 JNIEXPORT void JNICALL
 150 Java_nsk_jvmti_unit_GetConstantPool_getcpool001_getReady(
 151     JNIEnv *env, jclass c, jclass cls) {
 152     jvmtiError err;
 153 
 154     if (jvmti == NULL) {
 155         printf("JVMTI client was not properly loaded!\n");
 156         RETURN_FAILED;
 157     }
 158 
 159     if (!caps.can_force_early_return ||
 160         !caps.can_generate_breakpoint_events ||
 161         !caps.can_generate_single_step_events) {
 162         return;
 163     }
 164 
 165     midCheckPoint = env->GetMethodID(cls, "checkPoint", "()V");
 166     if (midCheckPoint == NULL) {
 167         printf("Cannot find Method ID for method checkPoint\n");
 168         RETURN_FAILED;
 169     }
 170 
 171     err = jvmti->SetBreakpoint(midCheckPoint, 0);
 172     if (err != JVMTI_ERROR_NONE) {
 173         printf("(SetBreakpoint) unexpected error: %s (%d)\n",
 174                TranslateError(err), err);
 175         RETURN_FAILED;
 176     }
 177 
 178     err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL);
 179     if (err != JVMTI_ERROR_NONE) {
 180         printf("Failed to enable BREAKPOINT event: %s (%d)\n",
 181                TranslateError(err), err);
 182         RETURN_FAILED;
 183     }
 184 
 185 }
 186 
 187 JNIEXPORT jint JNICALL
 188 Java_nsk_jvmti_unit_GetConstantPool_getcpool001_check(JNIEnv *env, jclass cls) {
 189     return errCode;
 190 }
 191 
 192 }