243 if (clname != buf) { 244 free(clname); 245 } 246 247 return cls; 248 } 249 250 JNIEXPORT jclass JNICALL 251 Java_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader, 252 jstring name) 253 { 254 if (name == NULL) { 255 return 0; 256 } else { 257 return JVM_FindLoadedClass(env, loader, name); 258 } 259 } 260 261 static jfieldID handleID; 262 static jfieldID jniVersionID; 263 static jfieldID loadedID; 264 static void *procHandle; 265 266 static jboolean initIDs(JNIEnv *env) 267 { 268 if (handleID == 0) { 269 jclass this = 270 (*env)->FindClass(env, "java/lang/ClassLoader$NativeLibrary"); 271 if (this == 0) 272 return JNI_FALSE; 273 handleID = (*env)->GetFieldID(env, this, "handle", "J"); 274 if (handleID == 0) 275 return JNI_FALSE; 276 jniVersionID = (*env)->GetFieldID(env, this, "jniVersion", "I"); 277 if (jniVersionID == 0) 278 return JNI_FALSE; 279 loadedID = (*env)->GetFieldID(env, this, "loaded", "Z"); 280 if (loadedID == 0) 281 return JNI_FALSE; 282 procHandle = getProcessHandle(); 283 } 284 return JNI_TRUE; 285 } 286 287 typedef jint (JNICALL *JNI_OnLoad_t)(JavaVM *, void *); 288 typedef void (JNICALL *JNI_OnUnload_t)(JavaVM *, void *); 289 290 /* 291 * Support for finding JNI_On(Un)Load_<lib_name> if it exists. 292 * If cname == NULL then just find normal JNI_On(Un)Load entry point 293 */ 294 static void *findJniFunction(JNIEnv *env, void *handle, 295 const char *cname, jboolean isLoad) { 296 const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; 297 const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; 298 const char **syms; 299 int symsLen; 300 void *entryName = NULL; 301 char *jniFunctionName; 318 } 319 jniFunctionName = malloc(len); 320 if (jniFunctionName == NULL) { 321 JNU_ThrowOutOfMemoryError(env, NULL); 322 goto done; 323 } 324 buildJniFunctionName(syms[i], cname, jniFunctionName); 325 entryName = JVM_FindLibraryEntry(handle, jniFunctionName); 326 free(jniFunctionName); 327 if(entryName) { 328 break; 329 } 330 } 331 332 done: 333 return entryName; 334 } 335 336 /* 337 * Class: java_lang_ClassLoader_NativeLibrary 338 * Method: load 339 * Signature: (Ljava/lang/String;Z)V 340 */ 341 JNIEXPORT void JNICALL 342 Java_java_lang_ClassLoader_00024NativeLibrary_load 343 (JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) 344 { 345 const char *cname; 346 jint jniVersion; 347 jthrowable cause; 348 void * handle; 349 350 if (!initIDs(env)) 351 return; 352 353 cname = JNU_GetStringPlatformChars(env, name, 0); 354 if (cname == 0) 355 return; 356 handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname); 357 if (handle) { 358 JNI_OnLoad_t JNI_OnLoad; 359 JNI_OnLoad = (JNI_OnLoad_t)findJniFunction(env, handle, 360 isBuiltin ? cname : NULL, 361 JNI_TRUE); 362 if (JNI_OnLoad) { 363 JavaVM *jvm; 364 (*env)->GetJavaVM(env, &jvm); 365 jniVersion = (*JNI_OnLoad)(jvm, NULL); 366 } else { 367 jniVersion = 0x00010001; 368 } 369 370 cause = (*env)->ExceptionOccurred(env); 371 if (cause) { 372 (*env)->ExceptionClear(env); 373 (*env)->Throw(env, cause); 374 if (!isBuiltin) { 375 JVM_UnloadLibrary(handle); 383 jio_snprintf(msg, sizeof(msg), 384 "unsupported JNI version 0x%08X required by %s", 385 jniVersion, cname); 386 JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError", msg); 387 if (!isBuiltin) { 388 JVM_UnloadLibrary(handle); 389 } 390 goto done; 391 } 392 (*env)->SetIntField(env, this, jniVersionID, jniVersion); 393 } else { 394 cause = (*env)->ExceptionOccurred(env); 395 if (cause) { 396 (*env)->ExceptionClear(env); 397 (*env)->SetLongField(env, this, handleID, (jlong)0); 398 (*env)->Throw(env, cause); 399 } 400 goto done; 401 } 402 (*env)->SetLongField(env, this, handleID, ptr_to_jlong(handle)); 403 (*env)->SetBooleanField(env, this, loadedID, JNI_TRUE); 404 405 done: 406 JNU_ReleaseStringPlatformChars(env, name, cname); 407 } 408 409 /* 410 * Class: java_lang_ClassLoader_NativeLibrary 411 * Method: unload 412 * Signature: (Z)V 413 */ 414 JNIEXPORT void JNICALL 415 Java_java_lang_ClassLoader_00024NativeLibrary_unload 416 (JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) 417 { 418 const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; 419 void *handle; 420 JNI_OnUnload_t JNI_OnUnload; 421 const char *cname; 422 423 if (!initIDs(env)) 424 return; 425 cname = JNU_GetStringPlatformChars(env, name, 0); 426 if (cname == NULL) { 427 return; 428 } 429 handle = jlong_to_ptr((*env)->GetLongField(env, this, handleID)); 430 JNI_OnUnload = (JNI_OnUnload_t )findJniFunction(env, handle, 431 isBuiltin ? cname : NULL, 432 JNI_FALSE); 433 if (JNI_OnUnload) { 434 JavaVM *jvm; 435 (*env)->GetJavaVM(env, &jvm); 436 (*JNI_OnUnload)(jvm, NULL); 437 } 438 if (!isBuiltin) { 439 JVM_UnloadLibrary(handle); 440 } 441 JNU_ReleaseStringPlatformChars(env, name, cname); 442 } 443 444 /* 445 * Class: java_lang_ClassLoader_NativeLibrary 446 * Method: find 447 * Signature: (Ljava/lang/String;)J 448 */ 449 JNIEXPORT jlong JNICALL 450 Java_java_lang_ClassLoader_00024NativeLibrary_find 451 (JNIEnv *env, jobject this, jstring name) 452 { 453 jlong handle; 454 const char *cname; 455 jlong res; 456 457 if (!initIDs(env)) 458 return jlong_zero; 459 460 handle = (*env)->GetLongField(env, this, handleID); 461 cname = (*env)->GetStringUTFChars(env, name, 0); 462 if (cname == 0) 463 return jlong_zero; 464 res = ptr_to_jlong(JVM_FindLibraryEntry(jlong_to_ptr(handle), cname)); 465 (*env)->ReleaseStringUTFChars(env, name, cname); 466 return res; 467 } 468 /* 469 * Class: java_lang_ClassLoader 470 * Method: findBuiltinLib | 243 if (clname != buf) { 244 free(clname); 245 } 246 247 return cls; 248 } 249 250 JNIEXPORT jclass JNICALL 251 Java_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader, 252 jstring name) 253 { 254 if (name == NULL) { 255 return 0; 256 } else { 257 return JVM_FindLoadedClass(env, loader, name); 258 } 259 } 260 261 static jfieldID handleID; 262 static jfieldID jniVersionID; 263 static void *procHandle; 264 265 static jboolean initIDs(JNIEnv *env) 266 { 267 if (handleID == 0) { 268 jclass this = 269 (*env)->FindClass(env, "java/lang/ClassLoader$NativeLibrary"); 270 if (this == 0) 271 return JNI_FALSE; 272 handleID = (*env)->GetFieldID(env, this, "handle", "J"); 273 if (handleID == 0) 274 return JNI_FALSE; 275 jniVersionID = (*env)->GetFieldID(env, this, "jniVersion", "I"); 276 if (jniVersionID == 0) 277 return JNI_FALSE; 278 procHandle = getProcessHandle(); 279 } 280 return JNI_TRUE; 281 } 282 283 typedef jint (JNICALL *JNI_OnLoad_t)(JavaVM *, void *); 284 typedef void (JNICALL *JNI_OnUnload_t)(JavaVM *, void *); 285 286 /* 287 * Support for finding JNI_On(Un)Load_<lib_name> if it exists. 288 * If cname == NULL then just find normal JNI_On(Un)Load entry point 289 */ 290 static void *findJniFunction(JNIEnv *env, void *handle, 291 const char *cname, jboolean isLoad) { 292 const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; 293 const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; 294 const char **syms; 295 int symsLen; 296 void *entryName = NULL; 297 char *jniFunctionName; 314 } 315 jniFunctionName = malloc(len); 316 if (jniFunctionName == NULL) { 317 JNU_ThrowOutOfMemoryError(env, NULL); 318 goto done; 319 } 320 buildJniFunctionName(syms[i], cname, jniFunctionName); 321 entryName = JVM_FindLibraryEntry(handle, jniFunctionName); 322 free(jniFunctionName); 323 if(entryName) { 324 break; 325 } 326 } 327 328 done: 329 return entryName; 330 } 331 332 /* 333 * Class: java_lang_ClassLoader_NativeLibrary 334 * Method: load0 335 * Signature: (Ljava/lang/String;Z)Z 336 */ 337 JNIEXPORT jboolean JNICALL 338 Java_java_lang_ClassLoader_00024NativeLibrary_load0 339 (JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) 340 { 341 const char *cname; 342 jint jniVersion; 343 jthrowable cause; 344 void * handle; 345 jboolean loaded = JNI_FALSE; 346 347 if (!initIDs(env)) 348 return JNI_FALSE; 349 350 cname = JNU_GetStringPlatformChars(env, name, 0); 351 if (cname == 0) 352 return JNI_FALSE; 353 handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname); 354 if (handle) { 355 JNI_OnLoad_t JNI_OnLoad; 356 JNI_OnLoad = (JNI_OnLoad_t)findJniFunction(env, handle, 357 isBuiltin ? cname : NULL, 358 JNI_TRUE); 359 if (JNI_OnLoad) { 360 JavaVM *jvm; 361 (*env)->GetJavaVM(env, &jvm); 362 jniVersion = (*JNI_OnLoad)(jvm, NULL); 363 } else { 364 jniVersion = 0x00010001; 365 } 366 367 cause = (*env)->ExceptionOccurred(env); 368 if (cause) { 369 (*env)->ExceptionClear(env); 370 (*env)->Throw(env, cause); 371 if (!isBuiltin) { 372 JVM_UnloadLibrary(handle); 380 jio_snprintf(msg, sizeof(msg), 381 "unsupported JNI version 0x%08X required by %s", 382 jniVersion, cname); 383 JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError", msg); 384 if (!isBuiltin) { 385 JVM_UnloadLibrary(handle); 386 } 387 goto done; 388 } 389 (*env)->SetIntField(env, this, jniVersionID, jniVersion); 390 } else { 391 cause = (*env)->ExceptionOccurred(env); 392 if (cause) { 393 (*env)->ExceptionClear(env); 394 (*env)->SetLongField(env, this, handleID, (jlong)0); 395 (*env)->Throw(env, cause); 396 } 397 goto done; 398 } 399 (*env)->SetLongField(env, this, handleID, ptr_to_jlong(handle)); 400 loaded = JNI_TRUE; 401 402 done: 403 JNU_ReleaseStringPlatformChars(env, name, cname); 404 return loaded; 405 } 406 407 /* 408 * Class: java_lang_ClassLoader_NativeLibrary 409 * Method: unload 410 * Signature: (Ljava/lang/String;ZJ)V 411 */ 412 JNIEXPORT void JNICALL 413 Java_java_lang_ClassLoader_00024NativeLibrary_unload 414 (JNIEnv *env, jclass cls, jstring name, jboolean isBuiltin, jlong address) 415 { 416 const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; 417 void *handle; 418 JNI_OnUnload_t JNI_OnUnload; 419 const char *cname; 420 421 if (!initIDs(env)) 422 return; 423 cname = JNU_GetStringPlatformChars(env, name, 0); 424 if (cname == NULL) { 425 return; 426 } 427 handle = jlong_to_ptr(address); 428 JNI_OnUnload = (JNI_OnUnload_t )findJniFunction(env, handle, 429 isBuiltin ? cname : NULL, 430 JNI_FALSE); 431 if (JNI_OnUnload) { 432 JavaVM *jvm; 433 (*env)->GetJavaVM(env, &jvm); 434 (*JNI_OnUnload)(jvm, NULL); 435 } 436 if (!isBuiltin) { 437 JVM_UnloadLibrary(handle); 438 } 439 JNU_ReleaseStringPlatformChars(env, name, cname); 440 } 441 442 /* 443 * Class: java_lang_ClassLoader_NativeLibrary 444 * Method: findEntry 445 * Signature: (Ljava/lang/String;)J 446 */ 447 JNIEXPORT jlong JNICALL 448 Java_java_lang_ClassLoader_00024NativeLibrary_findEntry 449 (JNIEnv *env, jobject this, jstring name) 450 { 451 jlong handle; 452 const char *cname; 453 jlong res; 454 455 if (!initIDs(env)) 456 return jlong_zero; 457 458 handle = (*env)->GetLongField(env, this, handleID); 459 cname = (*env)->GetStringUTFChars(env, name, 0); 460 if (cname == 0) 461 return jlong_zero; 462 res = ptr_to_jlong(JVM_FindLibraryEntry(jlong_to_ptr(handle), cname)); 463 (*env)->ReleaseStringUTFChars(env, name, cname); 464 return res; 465 } 466 /* 467 * Class: java_lang_ClassLoader 468 * Method: findBuiltinLib |