diff --git a/make/java/java/mapfile-vers b/make/java/java/mapfile-vers index 81e678d7624833071f024033b653197574d95e64..60f0f8646079725a6ae0771f73c2172d131bacd1 100644 --- a/make/java/java/mapfile-vers +++ b/make/java/java/mapfile-vers @@ -133,6 +133,7 @@ SUNWprivate_1.1 { Java_java_lang_ClassLoader_00024NativeLibrary_find; Java_java_lang_ClassLoader_00024NativeLibrary_load; Java_java_lang_ClassLoader_00024NativeLibrary_unload; + Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib; Java_java_lang_ClassLoader_getCaller; Java_java_lang_ClassLoader_registerNatives; Java_java_lang_Compiler_registerNatives; diff --git a/makefiles/mapfiles/libjava/mapfile-vers b/makefiles/mapfiles/libjava/mapfile-vers index 81e678d7624833071f024033b653197574d95e64..60f0f8646079725a6ae0771f73c2172d131bacd1 100644 --- a/makefiles/mapfiles/libjava/mapfile-vers +++ b/makefiles/mapfiles/libjava/mapfile-vers @@ -133,6 +133,7 @@ SUNWprivate_1.1 { Java_java_lang_ClassLoader_00024NativeLibrary_find; Java_java_lang_ClassLoader_00024NativeLibrary_load; Java_java_lang_ClassLoader_00024NativeLibrary_unload; + Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib; Java_java_lang_ClassLoader_getCaller; Java_java_lang_ClassLoader_registerNatives; Java_java_lang_Compiler_registerNatives; diff --git a/src/share/classes/java/lang/ClassLoader.java b/src/share/classes/java/lang/ClassLoader.java index a1e18ffe62d90872813e7ac5ea9b1854281bcb5e..c41280d3c79cb952392d7742cae2f45ff027a1bd 100644 --- a/src/share/classes/java/lang/ClassLoader.java +++ b/src/share/classes/java/lang/ClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -1683,22 +1683,29 @@ public abstract class ClassLoader { private int jniVersion; // the class from which the library is loaded, also indicates // the loader this native library belongs. - private Class fromClass; + private final Class fromClass; // the canonicalized name of the native library. + // or static library name String name; + // Indicates if the native library is linked into the VM + boolean isBuiltin; + // Indicates if the native library is loaded + boolean loaded; + native void load(String name, boolean isBuiltin); - native void load(String name); native long find(String name); - native void unload(); + native void unload(String name, boolean isBuiltin); + static native String findBuiltinLib(String name); - public NativeLibrary(Class fromClass, String name) { + public NativeLibrary(Class fromClass, String name, boolean isBuiltin) { this.name = name; this.fromClass = fromClass; + this.isBuiltin = isBuiltin; } protected void finalize() { synchronized (loadedLibraryNames) { - if (fromClass.getClassLoader() != null && handle != 0) { + if (fromClass.getClassLoader() != null && loaded) { /* remove the native library name */ int size = loadedLibraryNames.size(); for (int i = 0; i < size; i++) { @@ -1710,7 +1717,7 @@ public abstract class ClassLoader { /* unload the library. */ ClassLoader.nativeLibraryContext.push(this); try { - unload(); + unload(name, isBuiltin); } finally { ClassLoader.nativeLibraryContext.pop(); } @@ -1830,20 +1837,24 @@ public abstract class ClassLoader { } private static boolean loadLibrary0(Class fromClass, final File file) { - boolean exists = AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return file.exists() ? Boolean.TRUE : null; - }}) - != null; - if (!exists) { - return false; - } - String name; - try { - name = file.getCanonicalPath(); - } catch (IOException e) { - return false; + // Check to see if we're attempting to access a static library + String name = NativeLibrary.findBuiltinLib(file.getName()); + boolean isBuiltin = (name != null); + if (!isBuiltin) { + boolean exists = AccessController.doPrivileged( + new PrivilegedAction() { + public Object run() { + return file.exists() ? Boolean.TRUE : null; + }}) + != null; + if (!exists) { + return false; + } + try { + name = file.getCanonicalPath(); + } catch (IOException e) { + return false; + } } ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); @@ -1891,14 +1902,14 @@ public abstract class ClassLoader { } } } - NativeLibrary lib = new NativeLibrary(fromClass, name); + NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin); nativeLibraryContext.push(lib); try { - lib.load(name); + lib.load(name, isBuiltin); } finally { nativeLibraryContext.pop(); } - if (lib.handle != 0) { + if (lib.loaded) { loadedLibraryNames.addElement(name); libs.addElement(lib); return true; diff --git a/src/share/classes/java/lang/Runtime.java b/src/share/classes/java/lang/Runtime.java index 5454707b37144012561c9a2528a329da2a5cf70e..ada915dbb60a79e120207c27d60fad30da5950c0 100644 --- a/src/share/classes/java/lang/Runtime.java +++ b/src/share/classes/java/lang/Runtime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2013, 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 @@ -749,10 +749,21 @@ public class Runtime { public native void traceMethodCalls(boolean on); /** - * Loads the specified filename as a dynamic library. The filename - * argument must be a complete path name, + * Loads the native library specified by the filename argument. The filename + * argument must be an absolute path name. * (for example * Runtime.getRuntime().load("/home/avh/lib/libX11.so");). + * + * If the filename argument, when stripped of any platform-specific library + * prefix, path, and file extension, indicates a library whose name is, + * for example, L, and a native library called L is statically linked + * with the VM, then the JNI_OnLoad_L function exported by the library + * is invoked rather than attempting to load a dynamic library. + * A filename matching the argument does not have to exist in the file + * system. See the JNI Specification for more details. + * + * Otherwise, the filename argument is mapped to a native library image in + * an implementation-dependent manner. *

* First, if there is a security manager, its checkLink * method is called with the filename as its argument. @@ -769,7 +780,10 @@ public class Runtime { * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library - * @exception UnsatisfiedLinkError if the file does not exist. + * @exception UnsatisfiedLinkError if either the filename is not an + * absolute path name, the native library is not statically + * linked with the VM, or the library cannot be mapped to + * a native library image by the host system. * @exception NullPointerException if filename is * null * @see java.lang.Runtime#getRuntime() @@ -793,12 +807,16 @@ public class Runtime { } /** - * Loads the dynamic library with the specified library name. - * A file containing native code is loaded from the local file system - * from a place where library files are conventionally obtained. The - * details of this process are implementation-dependent. The - * mapping from a library name to a specific filename is done in a - * system-specific manner. + * Loads the native library specified by the libname + * argument. The libname argument must not contain any platform + * specific prefix, file extension or path. If a native library + * called libname is statically linked with the VM, then the + * JNI_OnLoad_libname function exported by the library is invoked. + * See the JNI Specification for more details. + * + * Otherwise, the libname argument is loaded from a system library + * location and mapped to a native library image in an implementation- + * dependent manner. *

* First, if there is a security manager, its checkLink * method is called with the libname as its argument. @@ -823,7 +841,10 @@ public class Runtime { * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library - * @exception UnsatisfiedLinkError if the library does not exist. + * @exception UnsatisfiedLinkError if either the libname argument + * contains a file path, the native library is not statically + * linked with the VM, or the library cannot be mapped to a + * native library image by the host system. * @exception NullPointerException if libname is * null * @see java.lang.SecurityException diff --git a/src/share/classes/java/lang/System.java b/src/share/classes/java/lang/System.java index 45ea7190ae85d9af2dd9a3c7ff6accd2932af568..9d1663ae819ef53f71447b33dd75f5f39eb55077 100644 --- a/src/share/classes/java/lang/System.java +++ b/src/share/classes/java/lang/System.java @@ -1037,9 +1037,21 @@ public final class System { } /** - * Loads a code file with the specified filename from the local file - * system as a dynamic library. The filename - * argument must be a complete path name. + * Loads the native library specified by the filename argument. The filename + * argument must be an absolute path name. + * + * If the filename argument, when stripped of any platform-specific library + * prefix, path, and file extension, indicates a library whose name is, + * for example, L, and a native library called L is statically linked + * with the VM, then the JNI_OnLoad_L function exported by the library + * is invoked rather than attempting to load a dynamic library. + * A filename matching the argument does not have to exist in the + * file system. + * See the JNI Specification for more details. + * + * Otherwise, the filename argument is mapped to a native library image in + * an implementation-dependent manner. + * *

* The call System.load(name) is effectively equivalent * to the call: @@ -1051,7 +1063,10 @@ public final class System { * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library - * @exception UnsatisfiedLinkError if the file does not exist. + * @exception UnsatisfiedLinkError if either the filename is not an + * absolute path name, the native library is not statically + * linked with the VM, or the library cannot be mapped to + * a native library image by the host system. * @exception NullPointerException if filename is * null * @see java.lang.Runtime#load(java.lang.String) @@ -1062,9 +1077,16 @@ public final class System { } /** - * Loads the system library specified by the libname - * argument. The manner in which a library name is mapped to the - * actual system library is system dependent. + * Loads the native library specified by the libname + * argument. The libname argument must not contain any platform + * specific prefix, file extension or path. If a native library + * called libname is statically linked with the VM, then the + * JNI_OnLoad_libname function exported by the library is invoked. + * See the JNI Specification for more details. + * + * Otherwise, the libname argument is loaded from a system library + * location and mapped to a native library image in an implementation- + * dependent manner. *

* The call System.loadLibrary(name) is effectively * equivalent to the call @@ -1076,7 +1098,10 @@ public final class System { * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library - * @exception UnsatisfiedLinkError if the library does not exist. + * @exception UnsatisfiedLinkError if either the libname argument + * contains a file path, the native library is not statically + * linked with the VM, or the library cannot be mapped to a + * native library image by the host system. * @exception NullPointerException if libname is * null * @see java.lang.Runtime#loadLibrary(java.lang.String) diff --git a/src/share/javavm/export/jni.h b/src/share/javavm/export/jni.h index dc2c8f645f2dae5e6174611f54afc031b2bb8cd2..2e83cb7e06e5942225418395a044852eb5449588 100644 --- a/src/share/javavm/export/jni.h +++ b/src/share/javavm/export/jni.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -1951,6 +1951,7 @@ JNI_OnUnload(JavaVM *vm, void *reserved); #define JNI_VERSION_1_2 0x00010002 #define JNI_VERSION_1_4 0x00010004 #define JNI_VERSION_1_6 0x00010006 +#define JNI_VERSION_1_8 0x00010008 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/share/native/common/jni_util.h b/src/share/native/common/jni_util.h index 55dd0fa91d8d9774082a993d1a59bb115b7e2017..65cabb7dd631a5e348a91d50e88ec1d25bcbab78 100644 --- a/src/share/native/common/jni_util.h +++ b/src/share/native/common/jni_util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -339,6 +339,10 @@ int getFastEncoding(); void initializeEncoding(); +void* getProcessHandle(); + +void buildJniFunctionName(const char *sym, const char *cname, + char *jniEntryName); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/share/native/java/lang/ClassLoader.c b/src/share/native/java/lang/ClassLoader.c index 8965d0a86d7ffcbc776e0d03fe39adf241bfb06a..47c41b2bd84a7e2b57c7075c09c0f429335355bf 100644 --- a/src/share/native/java/lang/ClassLoader.c +++ b/src/share/native/java/lang/ClassLoader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -32,6 +32,7 @@ #include "jvm.h" #include "java_lang_ClassLoader.h" #include "java_lang_ClassLoader_NativeLibrary.h" +#include /* defined in libverify.so/verify.dll (src file common/check_format.c) */ extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed); @@ -286,6 +287,8 @@ Java_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader, static jfieldID handleID; static jfieldID jniVersionID; +static jfieldID loadedID; +static void *procHandle; static jboolean initIDs(JNIEnv *env) { @@ -300,6 +303,10 @@ static jboolean initIDs(JNIEnv *env) jniVersionID = (*env)->GetFieldID(env, this, "jniVersion", "I"); if (jniVersionID == 0) return JNI_FALSE; + loadedID = (*env)->GetFieldID(env, this, "loaded", "Z"); + if (loadedID == 0) + return JNI_FALSE; + procHandle = getProcessHandle(); } return JNI_TRUE; } @@ -307,14 +314,60 @@ static jboolean initIDs(JNIEnv *env) typedef jint (JNICALL *JNI_OnLoad_t)(JavaVM *, void *); typedef void (JNICALL *JNI_OnUnload_t)(JavaVM *, void *); +/* + * Support for finding JNI_On(Un)Load_ 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; + int 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: load - * Signature: (Ljava/lang/String;)J + * Signature: (Ljava/lang/String;Z)V */ JNIEXPORT void JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_load - (JNIEnv *env, jobject this, jstring name) + (JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) { const char *cname; jint jniVersion; @@ -327,18 +380,12 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load cname = JNU_GetStringPlatformChars(env, name, 0); if (cname == 0) return; - handle = JVM_LoadLibrary(cname); + handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname); if (handle) { - const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; JNI_OnLoad_t JNI_OnLoad; - unsigned int i; - for (i = 0; i < sizeof(onLoadSymbols) / sizeof(char *); i++) { - JNI_OnLoad = (JNI_OnLoad_t) - JVM_FindLibraryEntry(handle, onLoadSymbols[i]); - if (JNI_OnLoad) { - break; - } - } + JNI_OnLoad = (JNI_OnLoad_t)findJniFunction(env, handle, + isBuiltin ? cname : NULL, + JNI_TRUE); if (JNI_OnLoad) { JavaVM *jvm; (*env)->GetJavaVM(env, &jvm); @@ -355,7 +402,8 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load goto done; } - if (!JVM_IsSupportedJNIVersion(jniVersion)) { + 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", @@ -375,6 +423,7 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load goto done; } (*env)->SetLongField(env, this, handleID, ptr_to_jlong(handle)); + (*env)->SetBooleanField(env, this, loadedID, JNI_TRUE); done: JNU_ReleaseStringPlatformChars(env, name, cname); @@ -383,41 +432,40 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load /* * Class: java_lang_ClassLoader_NativeLibrary * Method: unload - * Signature: ()V + * Signature: (Z)V */ JNIEXPORT void JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_unload - (JNIEnv *env, jobject this) +(JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) { const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; void *handle; JNI_OnUnload_t JNI_OnUnload; - unsigned int i; + const char *cname; if (!initIDs(env)) return; - - handle = jlong_to_ptr((*env)->GetLongField(env, this, handleID)); - for (i = 0; i < sizeof(onUnloadSymbols) / sizeof(char *); i++) { - JNI_OnUnload = (JNI_OnUnload_t ) - JVM_FindLibraryEntry(handle, onUnloadSymbols[i]); - if (JNI_OnUnload) { - break; - } + cname = JNU_GetStringPlatformChars(env, name, 0); + if (cname == NULL) { + return; } - + handle = jlong_to_ptr((*env)->GetLongField(env, this, handleID)); + 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); } JVM_UnloadLibrary(handle); + JNU_ReleaseStringPlatformChars(env, name, cname); } /* * Class: java_lang_ClassLoader_NativeLibrary * Method: find - * Signature: (Ljava/lang/String;J)J + * Signature: (Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_find @@ -456,3 +504,63 @@ Java_java_lang_ClassLoader_getCaller(JNIEnv *env, jclass cls, jint index) return NULL; } +/* + * Class: java_lang_ClassLoader_NativeLibrary + * Method: findBuiltinLib + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib + (JNIEnv *env, jclass cls, jstring name) +{ + const char *cname; + char *libName; + int prefixLen = (int) strlen(JNI_LIB_PREFIX); + int suffixLen = (int) strlen(JNI_LIB_SUFFIX); + int len; + jstring lib; + void *ret; + const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; + + if (name == NULL) { + JNU_ThrowInternalError(env, "NULL filename for native library"); + return NULL; + } + // Can't call initIDs because it will recurse into NativeLibrary via + // FindClass to check context so set prochandle here as well. + procHandle = getProcessHandle(); + cname = JNU_GetStringPlatformChars(env, name, 0); + if (cname == NULL) { + JNU_ThrowOutOfMemoryError(env, 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; +} diff --git a/src/solaris/native/common/jni_util_md.c b/src/solaris/native/common/jni_util_md.c index dc9fb9956e0b9fef4a6525d11fde6da53e6734cd..e9e0f4e0f3fb7e598c6f2915cb6cf488acc6a8f2 100644 --- a/src/solaris/native/common/jni_util_md.c +++ b/src/solaris/native/common/jni_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2013, 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 @@ -25,6 +25,7 @@ #include "jni.h" #include "jni_util.h" +#include "dlfcn.h" jstring nativeNewStringPlatform(JNIEnv *env, const char *str) { return NULL; @@ -33,3 +34,22 @@ jstring nativeNewStringPlatform(JNIEnv *env, const char *str) { char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) { return NULL; } + +void* getProcessHandle() { + static void *procHandle = NULL; + if (procHandle != NULL) { + return procHandle; + } + procHandle = (void*)dlopen(NULL, RTLD_LAZY); + return procHandle; +} + +void buildJniFunctionName(const char *sym, const char *cname, + char *jniEntryName) { + strcpy(jniEntryName, sym); + if (cname != NULL) { + strcat(jniEntryName, "_"); + strcat(jniEntryName, cname); + } +} + diff --git a/src/windows/native/common/jni_util_md.c b/src/windows/native/common/jni_util_md.c index 5b90a59ceeacfd5fe5e765572b1cbe6043eea4bd..cdaaa2b5574fa80bcd2e6dd6613830f6e5567d3a 100644 --- a/src/windows/native/common/jni_util_md.c +++ b/src/windows/native/common/jni_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, 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 @@ -137,3 +137,35 @@ char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) else return NULL; } + +void* getProcessHandle() { + return (void*)GetModuleHandle(NULL); +} + +/* + * Windows symbols can be simple like JNI_OnLoad or __stdcall format + * like _JNI_OnLoad@8. We need to handle both. + */ +void buildJniFunctionName(const char *sym, const char *cname, + char *jniEntryName) { + if (cname != NULL) { + char *p = strrchr(sym, '@'); + if (p != NULL && p != sym) { + // sym == _JNI_OnLoad@8 + strncpy(jniEntryName, sym, (p - sym)); + jniEntryName[(p-sym)] = '\0'; + // jniEntryName == _JNI_OnLoad + strcat(jniEntryName, "_"); + strcat(jniEntryName, cname); + strcat(jniEntryName, p); + //jniEntryName == _JNI_OnLoad_cname@8 + } else { + strcpy(jniEntryName, sym); + strcat(jniEntryName, "_"); + strcat(jniEntryName, cname); + } + } else { + strcpy(jniEntryName, sym); + } + return; +}