< prev index next >
src/java.base/share/native/libjava/ClassLoader.c
Print this page
*** 1,7 ****
/*
! * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 30,40 ****
#include "jni_util.h"
#include "jlong.h"
#include "jvm.h"
#include "check_classname.h"
#include "java_lang_ClassLoader.h"
- #include "java_lang_ClassLoader_NativeLibrary.h"
#include <string.h>
static JNINativeMethod methods[] = {
{"retrieveDirectives", "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}
};
--- 30,39 ----
*** 252,519 ****
return 0;
} else {
return JVM_FindLoadedClass(env, loader, name);
}
}
-
- static jfieldID handleID;
- static jfieldID jniVersionID;
- static void *procHandle;
-
- static jboolean initIDs(JNIEnv *env)
- {
- if (handleID == 0) {
- jclass this =
- (*env)->FindClass(env, "java/lang/ClassLoader$NativeLibrary");
- if (this == 0)
- return JNI_FALSE;
- handleID = (*env)->GetFieldID(env, this, "handle", "J");
- if (handleID == 0)
- return JNI_FALSE;
- jniVersionID = (*env)->GetFieldID(env, this, "jniVersion", "I");
- if (jniVersionID == 0)
- return JNI_FALSE;
- procHandle = getProcessHandle();
- }
- return JNI_TRUE;
- }
-
- typedef jint (JNICALL *JNI_OnLoad_t)(JavaVM *, void *);
- typedef void (JNICALL *JNI_OnUnload_t)(JavaVM *, void *);
-
- /*
- * Support for finding JNI_On(Un)Load_<lib_name> if it exists.
- * If cname == NULL then just find normal JNI_On(Un)Load entry point
- */
- static void *findJniFunction(JNIEnv *env, void *handle,
- const char *cname, jboolean isLoad) {
- const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
- const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS;
- const char **syms;
- int symsLen;
- void *entryName = NULL;
- char *jniFunctionName;
- int i;
- size_t len;
-
- // Check for JNI_On(Un)Load<_libname> function
- if (isLoad) {
- syms = onLoadSymbols;
- symsLen = sizeof(onLoadSymbols) / sizeof(char *);
- } else {
- syms = onUnloadSymbols;
- symsLen = sizeof(onUnloadSymbols) / sizeof(char *);
- }
- for (i = 0; i < symsLen; i++) {
- // cname + sym + '_' + '\0'
- if ((len = (cname != NULL ? strlen(cname) : 0) + strlen(syms[i]) + 2) >
- FILENAME_MAX) {
- goto done;
- }
- jniFunctionName = malloc(len);
- if (jniFunctionName == NULL) {
- JNU_ThrowOutOfMemoryError(env, NULL);
- goto done;
- }
- buildJniFunctionName(syms[i], cname, jniFunctionName);
- entryName = JVM_FindLibraryEntry(handle, jniFunctionName);
- free(jniFunctionName);
- if(entryName) {
- break;
- }
- }
-
- done:
- return entryName;
- }
-
- /*
- * Class: java_lang_ClassLoader_NativeLibrary
- * Method: load0
- * Signature: (Ljava/lang/String;Z)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_lang_ClassLoader_00024NativeLibrary_load0
- (JNIEnv *env, jobject this, jstring name, jboolean isBuiltin)
- {
- const char *cname;
- jint jniVersion;
- jthrowable cause;
- void * handle;
- jboolean loaded = JNI_FALSE;
-
- if (!initIDs(env))
- return JNI_FALSE;
-
- cname = JNU_GetStringPlatformChars(env, name, 0);
- if (cname == 0)
- return JNI_FALSE;
- handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname);
- if (handle) {
- JNI_OnLoad_t JNI_OnLoad;
- JNI_OnLoad = (JNI_OnLoad_t)findJniFunction(env, handle,
- isBuiltin ? cname : NULL,
- JNI_TRUE);
- if (JNI_OnLoad) {
- JavaVM *jvm;
- (*env)->GetJavaVM(env, &jvm);
- jniVersion = (*JNI_OnLoad)(jvm, NULL);
- } else {
- jniVersion = 0x00010001;
- }
-
- cause = (*env)->ExceptionOccurred(env);
- if (cause) {
- (*env)->ExceptionClear(env);
- (*env)->Throw(env, cause);
- if (!isBuiltin) {
- JVM_UnloadLibrary(handle);
- }
- goto done;
- }
-
- if (!JVM_IsSupportedJNIVersion(jniVersion) ||
- (isBuiltin && jniVersion < JNI_VERSION_1_8)) {
- char msg[256];
- jio_snprintf(msg, sizeof(msg),
- "unsupported JNI version 0x%08X required by %s",
- jniVersion, cname);
- JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError", msg);
- if (!isBuiltin) {
- JVM_UnloadLibrary(handle);
- }
- goto done;
- }
- (*env)->SetIntField(env, this, jniVersionID, jniVersion);
- } else {
- cause = (*env)->ExceptionOccurred(env);
- if (cause) {
- (*env)->ExceptionClear(env);
- (*env)->SetLongField(env, this, handleID, (jlong)0);
- (*env)->Throw(env, cause);
- }
- goto done;
- }
- (*env)->SetLongField(env, this, handleID, ptr_to_jlong(handle));
- loaded = JNI_TRUE;
-
- done:
- JNU_ReleaseStringPlatformChars(env, name, cname);
- return loaded;
- }
-
- /*
- * Class: java_lang_ClassLoader_NativeLibrary
- * Method: unload
- * Signature: (Ljava/lang/String;ZJ)V
- */
- JNIEXPORT void JNICALL
- Java_java_lang_ClassLoader_00024NativeLibrary_unload
- (JNIEnv *env, jclass cls, jstring name, jboolean isBuiltin, jlong address)
- {
- const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS;
- void *handle;
- JNI_OnUnload_t JNI_OnUnload;
- const char *cname;
-
- if (!initIDs(env))
- return;
- cname = JNU_GetStringPlatformChars(env, name, 0);
- if (cname == NULL) {
- return;
- }
- handle = jlong_to_ptr(address);
- JNI_OnUnload = (JNI_OnUnload_t )findJniFunction(env, handle,
- isBuiltin ? cname : NULL,
- JNI_FALSE);
- if (JNI_OnUnload) {
- JavaVM *jvm;
- (*env)->GetJavaVM(env, &jvm);
- (*JNI_OnUnload)(jvm, NULL);
- }
- if (!isBuiltin) {
- JVM_UnloadLibrary(handle);
- }
- JNU_ReleaseStringPlatformChars(env, name, cname);
- }
-
- /*
- * Class: java_lang_ClassLoader_NativeLibrary
- * Method: findEntry
- * Signature: (Ljava/lang/String;)J
- */
- JNIEXPORT jlong JNICALL
- Java_java_lang_ClassLoader_00024NativeLibrary_findEntry
- (JNIEnv *env, jobject this, jstring name)
- {
- jlong handle;
- const char *cname;
- jlong res;
-
- if (!initIDs(env))
- return jlong_zero;
-
- handle = (*env)->GetLongField(env, this, handleID);
- cname = (*env)->GetStringUTFChars(env, name, 0);
- if (cname == 0)
- return jlong_zero;
- res = ptr_to_jlong(JVM_FindLibraryEntry(jlong_to_ptr(handle), cname));
- (*env)->ReleaseStringUTFChars(env, name, cname);
- return res;
- }
- /*
- * Class: java_lang_ClassLoader
- * Method: findBuiltinLib
- * Signature: (Ljava/lang/String;)Ljava/lang/String;
- */
- JNIEXPORT jstring JNICALL
- Java_java_lang_ClassLoader_findBuiltinLib
- (JNIEnv *env, jclass cls, jstring name)
- {
- const char *cname;
- char *libName;
- size_t prefixLen = strlen(JNI_LIB_PREFIX);
- size_t suffixLen = strlen(JNI_LIB_SUFFIX);
- size_t len;
- jstring lib;
- void *ret;
- const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
-
- if (name == NULL) {
- JNU_ThrowInternalError(env, "NULL filename for native library");
- return NULL;
- }
- procHandle = getProcessHandle();
- cname = JNU_GetStringPlatformChars(env, name, 0);
- if (cname == NULL) {
- return NULL;
- }
- // Copy name Skipping PREFIX
- len = strlen(cname);
- if (len <= (prefixLen+suffixLen)) {
- JNU_ReleaseStringPlatformChars(env, name, cname);
- return NULL;
- }
- libName = malloc(len + 1); //+1 for null if prefix+suffix == 0
- if (libName == NULL) {
- JNU_ReleaseStringPlatformChars(env, name, cname);
- JNU_ThrowOutOfMemoryError(env, NULL);
- return NULL;
- }
- if (len > prefixLen) {
- strcpy(libName, cname+prefixLen);
- }
- JNU_ReleaseStringPlatformChars(env, name, cname);
-
- // Strip SUFFIX
- libName[strlen(libName)-suffixLen] = '\0';
-
- // Check for JNI_OnLoad_libname function
- ret = findJniFunction(env, procHandle, libName, JNI_TRUE);
- if (ret != NULL) {
- lib = JNU_NewStringPlatform(env, libName);
- free(libName);
- return lib;
- }
- free(libName);
- return NULL;
- }
--- 251,255 ----
< prev index next >