1 /*
   2  * Copyright (c) 2004, 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 <string.h>
  25 #include <stdlib.h>
  26 #include "jvmti.h"
  27 #include "agent_common.h"
  28 #include "jni_tools.h"
  29 #include "jvmti_tools.h"
  30 #include "JVMTITools.h"
  31 #include "nsk_list.h"
  32 #include "nsk_mutex.h"
  33 
  34 extern "C" {
  35 
  36 /* ============================================================================= */
  37 
  38 /* scaffold objects */
  39 static jvmtiEnv *jvmti = NULL;
  40 static jlong timeout = 0;
  41 const void *plist = NULL;
  42 
  43 #define NAME_LENGTH 50
  44 
  45 typedef struct nsk_jvmti_DCG_paramsStruct {
  46     char name[NAME_LENGTH];
  47     const void *address;
  48     jint length;
  49     int sign;
  50 } nsk_jvmti_DCG_params;
  51 
  52 static MUTEX* mutex = NULL;
  53 
  54 /* ============================================================================= */
  55 
  56 /* callbacks */
  57 void JNICALL
  58 cbDynamicCodeGenerated1(jvmtiEnv *jvmti_env, const char *name,
  59                             const void *address, jint length) {
  60     nsk_jvmti_DCG_params *rec;
  61     int b;
  62 
  63     rec = (nsk_jvmti_DCG_params *)malloc(sizeof(nsk_jvmti_DCG_params));
  64     strncpy(rec->name, name, NAME_LENGTH);
  65     rec->name[NAME_LENGTH - 1] = '\0';
  66     rec->address = address;
  67     rec->length = length;
  68     rec->sign = 0;
  69 
  70     NSK_DISPLAY3("received: 0x%p %7d %s\n", rec->address, rec->length, rec->name);
  71 
  72     MUTEX_acquire(mutex);
  73 
  74     b = NSK_VERIFY(nsk_list_add(plist, rec));
  75 
  76     MUTEX_release(mutex);
  77 
  78     if (!b) {
  79         nsk_jvmti_setFailStatus();
  80         free((void *)rec);
  81     }
  82 }
  83 
  84 void JNICALL
  85 cbDynamicCodeGenerated2(jvmtiEnv *jvmti_env, const char *name,
  86                             const void *address, jint length) {
  87 
  88     int i;
  89     nsk_jvmti_DCG_params *rec;
  90     int count = nsk_list_getCount(plist);
  91     int compLength = NAME_LENGTH - 1;
  92 
  93     for (i = 0; i < count; i ++) {
  94         rec = (nsk_jvmti_DCG_params *)nsk_list_get(plist, i);
  95         if ((rec->address == address) && (rec->length == length)) {
  96             rec->sign = 1;
  97             NSK_DISPLAY3("checked: 0x%p %7d %s\n", rec->address, rec->length,
  98                                 rec->name);
  99             if (strncmp(rec->name, name, compLength)!=0) {
 100                 NSK_DISPLAY2("\t<%s> was renamed to <%s>\n", rec->name, name);
 101             }
 102             return;
 103         }
 104 
 105     }
 106     NSK_DISPLAY3("NOT FOUND: 0x%p %7d %s\n", address, length, name);
 107 
 108 }
 109 
 110 /* ============================================================================= */
 111 
 112 static int
 113 enableEvent(jvmtiEventMode enable, jvmtiEvent event) {
 114     if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(enable, event, NULL))) {
 115         nsk_jvmti_setFailStatus();
 116         return NSK_FALSE;
 117     }
 118 
 119     return NSK_TRUE;
 120 }
 121 
 122 int setCallBacks(int stage) {
 123 
 124     jvmtiEventCallbacks eventCallbacks;
 125     memset(&eventCallbacks, 0, sizeof(eventCallbacks));
 126 
 127     eventCallbacks.DynamicCodeGenerated = (stage == 1) ?
 128                             cbDynamicCodeGenerated1 : cbDynamicCodeGenerated2;
 129 
 130     if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks))))
 131         return NSK_FALSE;
 132 
 133     return NSK_TRUE;
 134 }
 135 
 136 /* ============================================================================= */
 137 
 138 /** Agent algorithm. */
 139 static void JNICALL
 140 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
 141 
 142     NSK_DISPLAY0("Wait for debuggee to become ready\n");
 143     if (!nsk_jvmti_waitForSync(timeout))
 144         return;
 145 
 146     /* stage 2 */
 147     if (!setCallBacks(2)) {
 148         return;
 149     }
 150 
 151     if (!NSK_JVMTI_VERIFY(jvmti->GenerateEvents(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)))
 152         nsk_jvmti_setFailStatus();
 153 
 154     {
 155         int i;
 156         const nsk_jvmti_DCG_params *rec;
 157         int count = nsk_list_getCount(plist);
 158 
 159         for (i = 0; i < count; i++) {
 160             rec = (const nsk_jvmti_DCG_params *)nsk_list_get(plist, 0);
 161             if (!rec->sign) {
 162                 NSK_COMPLAIN3("missed event for\n\t0x%p %7d %s\n", rec->address, rec->length, rec->name);
 163                 nsk_jvmti_setFailStatus();
 164             }
 165             free((void *)rec);
 166             nsk_list_remove(plist, 0);
 167         }
 168 
 169     }
 170 
 171     NSK_DISPLAY0("Let debuggee to finish\n");
 172     if (!nsk_jvmti_resumeSync())
 173         return;
 174 
 175 }
 176 
 177 /* ============================================================================= */
 178 
 179 /** Agent library initialization. */
 180 #ifdef STATIC_BUILD
 181 JNIEXPORT jint JNICALL Agent_OnLoad_em04t001(JavaVM *jvm, char *options, void *reserved) {
 182     return Agent_Initialize(jvm, options, reserved);
 183 }
 184 JNIEXPORT jint JNICALL Agent_OnAttach_em04t001(JavaVM *jvm, char *options, void *reserved) {
 185     return Agent_Initialize(jvm, options, reserved);
 186 }
 187 JNIEXPORT jint JNI_OnLoad_em04t001(JavaVM *jvm, char *options, void *reserved) {
 188     return JNI_VERSION_1_8;
 189 }
 190 #endif
 191 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
 192 
 193     mutex = MUTEX_create();
 194     if (!mutex)
 195         return JNI_ERR;
 196 
 197     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
 198         return JNI_ERR;
 199 
 200     timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
 201 
 202     if (!NSK_VERIFY((jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
 203         return JNI_ERR;
 204 
 205     if (!NSK_VERIFY((plist = (const void *)nsk_list_create()) != NULL))
 206         return JNI_ERR;
 207 
 208     NSK_DISPLAY1("plist = 0x%p\n", plist);
 209 
 210     if (!setCallBacks(1)) {
 211         return JNI_ERR;
 212     }
 213 
 214     if (!enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT)
 215             || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH)
 216             || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) {
 217         return JNI_ERR;
 218     }
 219 
 220     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
 221         return JNI_ERR;
 222 
 223     return JNI_OK;
 224 }
 225 
 226 /* ============================================================================= */
 227 
 228 JNIEXPORT void JNICALL
 229 #ifdef STATIC_BUILD
 230 Agent_OnUnload_em04t001(JavaVM *jvm)
 231 #else
 232 Agent_OnUnload(JavaVM *jvm)
 233 #endif
 234 {
 235 
 236     if (!NSK_VERIFY(nsk_list_destroy(plist))) {
 237         nsk_jvmti_setFailStatus();
 238     }
 239 
 240     if (mutex) {
 241         MUTEX_destroy(mutex);
 242         mutex = NULL;
 243     }
 244 }
 245 
 246 }