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 #include <stdio.h> 24 #include <string.h> 25 #include <jvmti.h> 26 #include "agent_common.h" 27 28 #include "nsk_tools.h" 29 #include "JVMTITools.h" 30 #include "jvmti_tools.h" 31 #include "jni_tools.h" 32 33 extern "C" { 34 35 #define FOO 1 36 #define WRAPPED_FOO 2 37 38 /* ============================================================================= */ 39 40 JNIEXPORT jint JNICALL 41 Java_nsk_jvmti_SetNativeMethodPrefix_AutomaticResolution1_foo ( 42 JNIEnv *jni 43 , jclass klass 44 ) 45 { 46 NSK_DISPLAY0(" >>> AutomaticResolution1.foo()\n"); 47 return FOO; 48 } 49 50 /* ============================================================================= */ 51 52 JNIEXPORT jint JNICALL 53 Java_nsk_jvmti_SetNativeMethodPrefix_AutomaticResolution1_wrapped_1foo ( 54 JNIEnv *jni 55 , jclass klass 56 ) 57 { 58 NSK_DISPLAY0(" >>> AutomaticResolution1.wrapped_foo()\n"); 59 return WRAPPED_FOO; 60 } 61 62 /* ============================================================================= */ 63 64 JNIEXPORT jint JNICALL 65 Java_nsk_jvmti_SetNativeMethodPrefix_AutomaticResolution2_foo ( 66 JNIEnv *jni 67 , jclass klass 68 ) 69 { 70 NSK_DISPLAY0(" >>> AutomaticResolution2.foo()\n"); 71 return FOO; 72 } 73 74 /* ============================================================================= */ 75 76 JNIEXPORT jint JNICALL 77 Java_nsk_jvmti_SetNativeMethodPrefix_AutomaticResolution3_foo ( 78 JNIEnv *jni 79 , jclass klass 80 ) 81 { 82 NSK_DISPLAY0(" >>> AutomaticResolution3.foo()\n"); 83 return FOO; 84 } 85 /* ============================================================================= */ 86 87 JNIEXPORT jint JNICALL foo (JNIEnv *jni, jclass klass) 88 { 89 NSK_DISPLAY0(" >>> ::foo()\n"); 90 return FOO; 91 } 92 93 /* ============================================================================= */ 94 95 JNIEXPORT jint JNICALL wrapped_foo (JNIEnv *jni, jclass klass) 96 { 97 NSK_DISPLAY0(" >>> ::wrapped_foo()\n"); 98 return WRAPPED_FOO; 99 } 100 101 /* ============================================================================= */ 102 103 #define METHODS_COUNT 2 104 static const void *METHODS [METHODS_COUNT] = { 105 (void *) &foo, 106 (void *) &wrapped_foo, 107 }; 108 109 /* ============================================================================= */ 110 111 static jvmtiEnv *jvmti = NULL; 112 113 /* ============================================================================= */ 114 115 JNIEXPORT jboolean JNICALL 116 Java_nsk_jvmti_SetNativeMethodPrefix_Binder_setMethodPrefix ( 117 JNIEnv *jni 118 , jclass klass 119 , jstring prefix 120 ) 121 { 122 jboolean result = JNI_TRUE; 123 char *str = NULL; 124 125 if (prefix != NULL) { 126 if (!NSK_VERIFY( 127 (str = (char *) NSK_CPP_STUB3( 128 GetStringUTFChars 129 , jni 130 , prefix 131 , 0 132 ) 133 ) != NULL 134 ) 135 ) 136 { result = JNI_FALSE; goto finally; } 137 } 138 139 if (!NSK_JVMTI_VERIFY( 140 NSK_CPP_STUB2( 141 SetNativeMethodPrefix 142 , jvmti 143 , str 144 ) 145 ) 146 ) 147 { result = JNI_FALSE; goto finally; } 148 149 if (str != NULL) { 150 NSK_DISPLAY1("New PREFIX is set: %s\n" 151 , str 152 ); 153 } else { 154 NSK_DISPLAY0("Old PREFIX is reset\n"); 155 } 156 157 finally: 158 if (str != NULL) { 159 jni->ReleaseStringUTFChars(prefix, str); 160 } 161 162 return JNI_TRUE; 163 } 164 165 /* ============================================================================= */ 166 167 JNIEXPORT jboolean JNICALL 168 Java_nsk_jvmti_SetNativeMethodPrefix_Binder_setMultiplePrefixes ( 169 JNIEnv *jni 170 , jclass klass 171 , jstring prefix 172 ) 173 { 174 jboolean result = JNI_TRUE; 175 char *str = NULL; 176 177 if (prefix != NULL) { 178 if (!NSK_VERIFY( 179 (str = (char *) NSK_CPP_STUB3( 180 GetStringUTFChars 181 , jni 182 , prefix 183 , 0 184 ) 185 ) != NULL 186 ) 187 ) 188 { result = JNI_FALSE; goto finally; } 189 190 if (!NSK_JVMTI_VERIFY( 191 NSK_CPP_STUB3( 192 SetNativeMethodPrefixes 193 , jvmti 194 , 1 195 , (char **) &str 196 ) 197 ) 198 ) 199 { result = JNI_FALSE; goto finally; } 200 201 NSK_DISPLAY1("MultiplePrefixes: New PREFIX is set: %s\n" 202 , str 203 ); 204 } else { 205 char* prefixes[1]; 206 prefixes[0] = NULL; 207 208 if (!NSK_JVMTI_VERIFY( 209 NSK_CPP_STUB3( 210 SetNativeMethodPrefixes 211 , jvmti 212 , 0 213 , (char **)&prefixes 214 ) 215 ) 216 ) 217 { result = JNI_FALSE; goto finally; } 218 219 NSK_DISPLAY0("Old PREFIX is reset\n"); 220 } 221 222 finally: 223 if (str != NULL) { 224 jni->ReleaseStringUTFChars(prefix, str); 225 } 226 227 return JNI_TRUE; 228 } 229 230 /* ============================================================================= */ 231 232 JNIEXPORT jboolean JNICALL 233 Java_nsk_jvmti_SetNativeMethodPrefix_Binder_registerMethod ( 234 JNIEnv *jni 235 , jclass klass 236 , jclass bound_klass 237 , jstring method_name_obj 238 , jstring method_sig_obj 239 , jint native_method_number 240 ) 241 { 242 JNINativeMethod method; 243 jboolean result = JNI_FALSE; 244 245 if (native_method_number < 0 || native_method_number >= METHODS_COUNT) { 246 NSK_DISPLAY2("Method index is out of the bound: %d of %d" 247 , native_method_number 248 , METHODS_COUNT 249 ); 250 return JNI_FALSE; 251 } 252 253 if (!NSK_VERIFY( 254 (method.name = 255 (char *) NSK_CPP_STUB3( 256 GetStringUTFChars 257 , jni 258 , method_name_obj 259 , 0 260 ) 261 ) != NULL 262 ) 263 ) 264 { 265 goto finally; 266 } 267 268 if (!NSK_VERIFY( 269 (method.signature = 270 (char *) NSK_CPP_STUB3( 271 GetStringUTFChars 272 , jni 273 , method_sig_obj 274 , 0 275 ) 276 ) != NULL 277 ) 278 ) 279 { 280 goto finally; 281 } 282 283 method.fnPtr = (void *) METHODS[native_method_number]; 284 285 NSK_DISPLAY2(">>>> Register native method: %s %s\n" 286 , method.name 287 , method.signature 288 ); 289 290 if (jni->RegisterNatives(bound_klass, (const JNINativeMethod*) &method, 1) != 0) 291 { 292 if (jni->ExceptionOccurred() != NULL) { 293 jni->ExceptionClear(); 294 } 295 296 goto finally; 297 } 298 299 NSK_DISPLAY0("<<<< Finished native method registration\n"); 300 301 result = JNI_TRUE; 302 finally: 303 if (method.name != NULL) { 304 jni->ReleaseStringUTFChars(method_name_obj, method.name); 305 } 306 307 if (method.signature != NULL) { 308 jni->ReleaseStringUTFChars(method_sig_obj, method.signature); 309 } 310 311 return result; 312 } 313 314 /* ============================================================================= */ 315 316 /* Agent initialization procedure */ 317 #ifdef STATIC_BUILD 318 JNIEXPORT jint JNICALL Agent_OnLoad_SetNativeMethodPrefix001(JavaVM *jvm, char *options, void *reserved) { 319 return Agent_Initialize(jvm, options, reserved); 320 } 321 JNIEXPORT jint JNICALL Agent_OnAttach_SetNativeMethodPrefix001(JavaVM *jvm, char *options, void *reserved) { 322 return Agent_Initialize(jvm, options, reserved); 323 } 324 JNIEXPORT jint JNI_OnLoad_SetNativeMethodPrefix001(JavaVM *jvm, char *options, void *reserved) { 325 return JNI_VERSION_1_8; 326 } 327 #endif 328 jint Agent_Initialize(JavaVM *vm, char *options, void *reserved) 329 { 330 jvmtiCapabilities caps; 331 332 if (!NSK_VERIFY( 333 nsk_jvmti_parseOptions(options) 334 ) 335 ) 336 return JNI_ERR; 337 338 if (!NSK_VERIFY( 339 (jvmti = nsk_jvmti_createJVMTIEnv(vm, reserved)) != NULL 340 ) 341 ) 342 return JNI_ERR; 343 344 if (!NSK_JVMTI_VERIFY( 345 NSK_CPP_STUB2( 346 GetCapabilities 347 , jvmti 348 , &caps) 349 ) 350 ) 351 return JNI_ERR; 352 353 // Register all necessary JVM capabilities 354 caps.can_set_native_method_prefix = 1; 355 356 if (!NSK_JVMTI_VERIFY( 357 NSK_CPP_STUB2( 358 AddCapabilities 359 , jvmti 360 , &caps) 361 ) 362 ) 363 return JNI_ERR; 364 365 return JNI_OK; 366 } 367 368 }