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                     NSK_CPP_STUB2(FindClass, jni, 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                     NSK_CPP_STUB4(GetStaticFieldID, jni, debugeeClass,
  73                                     OBJECT_FIELD_NAME, OBJECT_CLASS_SIG)) != NULL)) {
  74                 nsk_jvmti_setFailStatus();
  75                 return;
  76             }
  77             NSK_DISPLAY1("  ... got fieldID: 0x%p\n", (void*)objectField);
  78 
  79             NSK_DISPLAY1("Get object from static field: %s\n", OBJECT_FIELD_NAME);
  80             if (!NSK_JNI_VERIFY(jni, (testedObject =
  81                     NSK_CPP_STUB3(GetStaticObjectField, jni, debugeeClass,
  82                                                             objectField)) != NULL)) {
  83                 nsk_jvmti_setFailStatus();
  84                 return;
  85             }
  86             NSK_DISPLAY1("  ... got object: 0x%p\n", (void*)testedObject);
  87 
  88             NSK_DISPLAY1("Create global reference for object: 0x%p\n", (void*)testedObject);
  89             if (!NSK_JNI_VERIFY(jni, (testedObject =
  90                     NSK_CPP_STUB2(NewGlobalRef, jni, testedObject)) != NULL)) {
  91                 nsk_jvmti_setFailStatus();
  92                 return;
  93             }
  94             NSK_DISPLAY1("  ... got reference: 0x%p\n", (void*)testedObject);
  95         }
  96 
  97         NSK_DISPLAY0(">>> Testcase #1: set tag for the tested object\n");
  98         {
  99             NSK_DISPLAY1("Set tag for object: 0x%p\n", (void*)testedObject);
 100             if (!NSK_JVMTI_VERIFY(
 101                     NSK_CPP_STUB3(SetTag, jvmti, testedObject, objectTag))) {
 102                 nsk_jvmti_setFailStatus();
 103                 return;
 104             }
 105             NSK_DISPLAY1("  ... tag set: %ld\n", (long)objectTag);
 106         }
 107 
 108         NSK_DISPLAY0(">>> Testcase #2: get tag of not changed object and compare with initial\n");
 109         {
 110             jlong tag = 222;
 111 
 112             NSK_DISPLAY1("Get tag for object: 0x%p\n", (void*)testedObject);
 113             if (!NSK_JVMTI_VERIFY(
 114                     NSK_CPP_STUB3(GetTag, jvmti, testedObject, &tag))) {
 115                 nsk_jvmti_setFailStatus();
 116                 return;
 117             }
 118             NSK_DISPLAY1("  ... got tag: %ld\n", (long)tag);
 119 
 120             if (tag != objectTag) {
 121                 NSK_COMPLAIN2("GetTag() returns different tag for not changed object:\n"
 122                               "#   got tag:  %ld\n"
 123                               "#   expected: %ld\n",
 124                               (long)tag, (long)objectTag);
 125                 nsk_jvmti_setFailStatus();
 126             } else {
 127                 NSK_DISPLAY2("SUCCESS: Got tag is equal to initial: %ld = %ld\n",
 128                               (long)tag, (long)objectTag);
 129             }
 130         }
 131 
 132         NSK_DISPLAY0(">>> Testcase #3: get tag of changed object and compare with initial\n");
 133         {
 134             jlong tag = 333;
 135 
 136             NSK_DISPLAY0("Let debugee to change object data\n");
 137             if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
 138                 return;
 139             if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
 140                 return;
 141 
 142             NSK_DISPLAY1("Get tag for object: 0x%p\n", (void*)testedObject);
 143             if (!NSK_JVMTI_VERIFY(
 144                     NSK_CPP_STUB3(GetTag, jvmti, testedObject, &tag))) {
 145                 nsk_jvmti_setFailStatus();
 146                 return;
 147             }
 148             NSK_DISPLAY1("  ... got tag: %ld\n", (long)tag);
 149 
 150             if (tag != objectTag) {
 151                 NSK_COMPLAIN2("GetTag() returns different tag for changed object:\n"
 152                               "#   got tag:  %ld\n"
 153                               "#   expected: %ld\n",
 154                               (long)tag, (long)objectTag);
 155                 nsk_jvmti_setFailStatus();
 156             } else {
 157                 NSK_DISPLAY2("SUCCESS: Got tag is equal to initial: %ld = %ld\n",
 158                               (long)tag, (long)objectTag);
 159             }
 160         }
 161 
 162         NSK_DISPLAY0(">>> Clean used data\n");
 163         {
 164             NSK_DISPLAY1("Delete object reference: 0x%p\n", (void*)testedObject);
 165             NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, testedObject));
 166         }
 167     }
 168 
 169     NSK_DISPLAY0("Let debugee to finish\n");
 170     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
 171         return;
 172 }
 173 
 174 /* ============================================================================= */
 175 
 176 /** Agent library initialization. */
 177 #ifdef STATIC_BUILD
 178 JNIEXPORT jint JNICALL Agent_OnLoad_settag001(JavaVM *jvm, char *options, void *reserved) {
 179     return Agent_Initialize(jvm, options, reserved);
 180 }
 181 JNIEXPORT jint JNICALL Agent_OnAttach_settag001(JavaVM *jvm, char *options, void *reserved) {
 182     return Agent_Initialize(jvm, options, reserved);
 183 }
 184 JNIEXPORT jint JNI_OnLoad_settag001(JavaVM *jvm, char *options, void *reserved) {
 185     return JNI_VERSION_1_8;
 186 }
 187 #endif
 188 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
 189     jvmtiEnv* jvmti = NULL;
 190 
 191     /* init framework and parse options */
 192     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
 193         return JNI_ERR;
 194 
 195     timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
 196 
 197     /* create JVMTI environment */
 198     if (!NSK_VERIFY((jvmti =
 199             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
 200         return JNI_ERR;
 201 
 202     /* add required capabilities */
 203     {
 204         jvmtiCapabilities caps;
 205 
 206         memset(&caps, 0, sizeof(caps));
 207         caps.can_tag_objects = 1;
 208         if (!NSK_JVMTI_VERIFY(
 209                 NSK_CPP_STUB2(AddCapabilities, jvmti, &caps))) {
 210             return JNI_ERR;
 211         }
 212     }
 213 
 214     /* register agent proc and arg */
 215     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
 216         return JNI_ERR;
 217 
 218     return JNI_OK;
 219 }
 220 
 221 /* ============================================================================= */
 222 
 223 }