1 /*
   2  * Copyright (c) 2003, 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 "jvmti.h"
  26 #include "agent_common.h"
  27 #include "jni_tools.h"
  28 #include "jvmti_tools.h"
  29 
  30 extern "C" {
  31 
  32 /* ============================================================================= */
  33 
  34 /* scaffold objects */
  35 static jlong timeout = 0;
  36 
  37 /* constant names */
  38 #define DEBUGEE_CLASS_NAME    "nsk/jvmti/SetTag/settag001"
  39 #define OBJECT_CLASS_NAME     "nsk/jvmti/SetTag/settag001TestedClass"
  40 #define OBJECT_CLASS_SIG      "L" OBJECT_CLASS_NAME ";"
  41 #define OBJECT_FIELD_NAME     "testedObject"
  42 
  43 /* ============================================================================= */
  44 
  45 /** Agent algorithm. */
  46 static void JNICALL
  47 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
  48     NSK_DISPLAY0("Wait for object created\n");
  49     if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
  50         return;
  51 
  52     /* perform testing */
  53     {
  54         jobject testedObject = NULL;
  55         jlong objectTag = 111;
  56 
  57         NSK_DISPLAY0(">>> Obtain tested object from a static field of debugee class\n");
  58         {
  59             jclass debugeeClass = NULL;
  60             jfieldID objectField = NULL;
  61 
  62             NSK_DISPLAY1("Find debugee class: %s\n", DEBUGEE_CLASS_NAME);
  63             if (!NSK_JNI_VERIFY(jni, (debugeeClass =
  64                     jni->FindClass(DEBUGEE_CLASS_NAME)) != NULL)) {
  65                 nsk_jvmti_setFailStatus();
  66                 return;
  67             }
  68             NSK_DISPLAY1("  ... found class: 0x%p\n", (void*)debugeeClass);
  69 
  70             NSK_DISPLAY1("Find static field: %s\n", OBJECT_FIELD_NAME);
  71             if (!NSK_JNI_VERIFY(jni, (objectField =
  72                     jni->GetStaticFieldID(debugeeClass, OBJECT_FIELD_NAME, OBJECT_CLASS_SIG)) != NULL)) {
  73                 nsk_jvmti_setFailStatus();
  74                 return;
  75             }
  76             NSK_DISPLAY1("  ... got fieldID: 0x%p\n", (void*)objectField);
  77 
  78             NSK_DISPLAY1("Get object from static field: %s\n", OBJECT_FIELD_NAME);
  79             if (!NSK_JNI_VERIFY(jni, (testedObject =
  80                     jni->GetStaticObjectField(debugeeClass, objectField)) != NULL)) {
  81                 nsk_jvmti_setFailStatus();
  82                 return;
  83             }
  84             NSK_DISPLAY1("  ... got object: 0x%p\n", (void*)testedObject);
  85 
  86             NSK_DISPLAY1("Create global reference for object: 0x%p\n", (void*)testedObject);
  87             if (!NSK_JNI_VERIFY(jni, (testedObject = jni->NewGlobalRef(testedObject)) != NULL)) {
  88                 nsk_jvmti_setFailStatus();
  89                 return;
  90             }
  91             NSK_DISPLAY1("  ... got reference: 0x%p\n", (void*)testedObject);
  92         }
  93 
  94         NSK_DISPLAY0(">>> Testcase #1: set tag for the tested object\n");
  95         {
  96             NSK_DISPLAY1("Set tag for object: 0x%p\n", (void*)testedObject);
  97             if (!NSK_JVMTI_VERIFY(jvmti->SetTag(testedObject, objectTag))) {
  98                 nsk_jvmti_setFailStatus();
  99                 return;
 100             }
 101             NSK_DISPLAY1("  ... tag set: %ld\n", (long)objectTag);
 102         }
 103 
 104         NSK_DISPLAY0(">>> Testcase #2: get tag of not changed object and compare with initial\n");
 105         {
 106             jlong tag = 222;
 107 
 108             NSK_DISPLAY1("Get tag for object: 0x%p\n", (void*)testedObject);
 109             if (!NSK_JVMTI_VERIFY(jvmti->GetTag(testedObject, &tag))) {
 110                 nsk_jvmti_setFailStatus();
 111                 return;
 112             }
 113             NSK_DISPLAY1("  ... got tag: %ld\n", (long)tag);
 114 
 115             if (tag != objectTag) {
 116                 NSK_COMPLAIN2("GetTag() returns different tag for not changed object:\n"
 117                               "#   got tag:  %ld\n"
 118                               "#   expected: %ld\n",
 119                               (long)tag, (long)objectTag);
 120                 nsk_jvmti_setFailStatus();
 121             } else {
 122                 NSK_DISPLAY2("SUCCESS: Got tag is equal to initial: %ld = %ld\n",
 123                               (long)tag, (long)objectTag);
 124             }
 125         }
 126 
 127         NSK_DISPLAY0(">>> Testcase #3: get tag of changed object and compare with initial\n");
 128         {
 129             jlong tag = 333;
 130 
 131             NSK_DISPLAY0("Let debugee to change object data\n");
 132             if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
 133                 return;
 134             if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
 135                 return;
 136 
 137             NSK_DISPLAY1("Get tag for object: 0x%p\n", (void*)testedObject);
 138             if (!NSK_JVMTI_VERIFY(jvmti->GetTag(testedObject, &tag))) {
 139                 nsk_jvmti_setFailStatus();
 140                 return;
 141             }
 142             NSK_DISPLAY1("  ... got tag: %ld\n", (long)tag);
 143 
 144             if (tag != objectTag) {
 145                 NSK_COMPLAIN2("GetTag() returns different tag for changed object:\n"
 146                               "#   got tag:  %ld\n"
 147                               "#   expected: %ld\n",
 148                               (long)tag, (long)objectTag);
 149                 nsk_jvmti_setFailStatus();
 150             } else {
 151                 NSK_DISPLAY2("SUCCESS: Got tag is equal to initial: %ld = %ld\n",
 152                               (long)tag, (long)objectTag);
 153             }
 154         }
 155 
 156         NSK_DISPLAY0(">>> Clean used data\n");
 157         {
 158             NSK_DISPLAY1("Delete object reference: 0x%p\n", (void*)testedObject);
 159             NSK_TRACE(jni->DeleteGlobalRef(testedObject));
 160         }
 161     }
 162 
 163     NSK_DISPLAY0("Let debugee to finish\n");
 164     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
 165         return;
 166 }
 167 
 168 /* ============================================================================= */
 169 
 170 /** Agent library initialization. */
 171 #ifdef STATIC_BUILD
 172 JNIEXPORT jint JNICALL Agent_OnLoad_settag001(JavaVM *jvm, char *options, void *reserved) {
 173     return Agent_Initialize(jvm, options, reserved);
 174 }
 175 JNIEXPORT jint JNICALL Agent_OnAttach_settag001(JavaVM *jvm, char *options, void *reserved) {
 176     return Agent_Initialize(jvm, options, reserved);
 177 }
 178 JNIEXPORT jint JNI_OnLoad_settag001(JavaVM *jvm, char *options, void *reserved) {
 179     return JNI_VERSION_1_8;
 180 }
 181 #endif
 182 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
 183     jvmtiEnv* jvmti = NULL;
 184 
 185     /* init framework and parse options */
 186     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
 187         return JNI_ERR;
 188 
 189     timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
 190 
 191     /* create JVMTI environment */
 192     if (!NSK_VERIFY((jvmti =
 193             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
 194         return JNI_ERR;
 195 
 196     /* add required capabilities */
 197     {
 198         jvmtiCapabilities caps;
 199 
 200         memset(&caps, 0, sizeof(caps));
 201         caps.can_tag_objects = 1;
 202         if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {
 203             return JNI_ERR;
 204         }
 205     }
 206 
 207     /* register agent proc and arg */
 208     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
 209         return JNI_ERR;
 210 
 211     return JNI_OK;
 212 }
 213 
 214 /* ============================================================================= */
 215 
 216 }