/* src/native/native.c - table of native functions
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
bool native_init(void)
{
+ TRACESUBSYSTEMINITIALIZATION("native_init");
+
#if defined(ENABLE_LTDL)
/* initialize libltdl */
char *utf_ptr;
u2 c;
s4 i;
- s4 dumpsize;
utf *u;
+ int32_t dumpmarker;
/* mark memory */
- dumpsize = dump_size();
+ DMARKER;
utf_ptr = descriptor->text;
namelen = strlen(name->text) + strlen("__") + strlen("0");
/* release memory */
- dump_release(dumpsize);
+ DRELEASE;
return u;
}
char *utf_endptr;
u2 c;
u4 pos;
- s4 dumpsize;
utf *u;
+ int32_t dumpmarker;
/* mark memory */
- dumpsize = dump_size();
+ DMARKER;
/* Calculate length of native function name. We multiply the
class and method name length by 6 as this is the maxium
/* release memory */
- dump_release(dumpsize);
+ DRELEASE;
return u;
}
/* fill the temporary structure used for searching the tree */
- tmpnmn.classname = m->class->name;
+ tmpnmn.classname = m->clazz->name;
tmpnmn.name = m->name;
tmpnmn.descriptor = m->descriptor;
}
+/* native_method_resolve *******************************************************
+
+ Resolves a native method, maybe from a dynamic library.
+
+ IN:
+ m ... methodinfo of the native Java method to resolve
+
+ RESULT:
+ pointer to the resolved method (symbol)
+
+*******************************************************************************/
+
+functionptr native_method_resolve(methodinfo *m)
+{
+ utf *name;
+ utf *newname;
+ functionptr f;
+#if defined(ENABLE_LTDL)
+ classloader_t *cl;
+ hashtable_library_loader_entry *le;
+ hashtable_library_name_entry *ne;
+ u4 key; /* hashkey */
+ u4 slot; /* slot in hashtable */
+#endif
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+ methodinfo *method_findNative;
+ java_handle_t *s;
+#endif
+
+ /* verbose output */
+
+ if (opt_verbosejni) {
+ printf("[Dynamic-linking native method ");
+ utf_display_printable_ascii_classname(m->clazz->name);
+ printf(".");
+ utf_display_printable_ascii(m->name);
+ printf(" ... ");
+ }
+
+ /* generate method symbol string */
+
+ name = native_method_symbol(m->clazz->name, m->name);
+
+ /* generate overloaded function (having the types in it's name) */
+
+ newname = native_make_overloaded_function(name, m->descriptor);
+
+ /* check the library hash entries of the classloader of the
+ methods's class */
+
+ f = NULL;
+
+#if defined(ENABLE_LTDL)
+ /* Get the classloader. */
+
+ cl = class_get_classloader(m->clazz);
+
+ /* normally addresses are aligned to 4, 8 or 16 bytes */
+
+ key = ((u4) (ptrint) cl) >> 4; /* align to 16-byte */
+ slot = key & (hashtable_library->size - 1);
+ le = hashtable_library->ptr[slot];
+
+ /* iterate through loaders in this hash slot */
+
+ while ((le != NULL) && (f == NULL)) {
+ /* iterate through names in this loader */
+
+ ne = le->namelink;
+
+ while ((ne != NULL) && (f == NULL)) {
+ f = (functionptr) (ptrint) lt_dlsym(ne->handle, name->text);
+
+ if (f == NULL)
+ f = (functionptr) (ptrint) lt_dlsym(ne->handle, newname->text);
+
+ ne = ne->hashlink;
+ }
+
+ le = le->hashlink;
+ }
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+ if (f == NULL) {
+ /* We can resolve the function directly from
+ java.lang.ClassLoader as it's a static function. */
+ /* XXX should be done in native_init */
+
+ method_findNative =
+ class_resolveclassmethod(class_java_lang_ClassLoader,
+ utf_findNative,
+ utf_java_lang_ClassLoader_java_lang_String__J,
+ class_java_lang_ClassLoader,
+ true);
+
+ if (method_findNative == NULL)
+ return NULL;
+
+ /* try the normal name */
+
+ s = javastring_new(name);
+
+ f = (functionptr) (intptr_t) vm_call_method_long(method_findNative,
+ NULL, cl, s);
+
+ /* if not found, try the mangled name */
+
+ if (f == NULL) {
+ s = javastring_new(newname);
+
+ f = (functionptr) (intptr_t) vm_call_method_long(method_findNative,
+ NULL, cl, s);
+ }
+ }
+# endif
+
+ if (f != NULL)
+ if (opt_verbosejni)
+ printf("JNI ]\n");
+#endif
+
+ /* If not found, try to find the native function symbol in the
+ main program. */
+
+ if (f == NULL) {
+ f = native_method_find(m);
+
+ if (f != NULL)
+ if (opt_verbosejni)
+ printf("internal ]\n");
+ }
+
+#if defined(ENABLE_JVMTI)
+ /* fire Native Method Bind event */
+ if (jvmti) jvmti_NativeMethodBind(m, f, &f);
+#endif
+
+ /* no symbol found? throw exception */
+
+ if (f == NULL) {
+ if (opt_verbosejni)
+ printf("failed ]\n");
+
+ exceptions_throw_unsatisfiedlinkerror(m->name);
+ }
+
+ return f;
+}
+
+
/* native_library_open *********************************************************
Open a native library with the given utf8 name.
+ IN:
+ filename ... filename of the library to open
+
+ RETURN:
+ handle of the opened library
+
*******************************************************************************/
#if defined(ENABLE_LTDL)
handle = lt_dlopen(filename->text);
if (handle == NULL) {
+ if (opt_verbosejni)
+ printf("failed ]\n");
+
if (opt_verbose) {
log_start();
- log_print("native_library_load: lt_dlopen failed: ");
+ log_print("native_library_open: lt_dlopen failed: ");
log_print(lt_dlerror());
log_finish();
}
return NULL;
}
+ if (opt_verbosejni)
+ printf("OK ]\n");
+
return handle;
}
#endif
+/* native_library_close ********************************************************
+
+ Close the native library of the given handle.
+
+ IN:
+ handle ... handle of the open library
+
+*******************************************************************************/
+
+#if defined(ENABLE_LTDL)
+void native_library_close(lt_dlhandle handle)
+{
+ int result;
+
+ if (opt_verbosejni) {
+ printf("[Unloading native library ");
+/* utf_display_printable_ascii(filename); */
+ printf(" ... ");
+ }
+
+ /* Close the library. */
+
+ result = lt_dlclose(handle);
+
+ if (result != 0) {
+ if (opt_verbose) {
+ log_start();
+ log_print("native_library_close: lt_dlclose failed: ");
+ log_print(lt_dlerror());
+ log_finish();
+ }
+ }
+}
+#endif
+
+
/* native_library_add **********************************************************
Adds an entry to the native library hashtable.
*******************************************************************************/
#if defined(ENABLE_LTDL)
-void native_library_add(utf *filename, classloader *loader, lt_dlhandle handle)
+void native_library_add(utf *filename, classloader_t *loader, lt_dlhandle handle)
{
hashtable_library_loader_entry *le;
hashtable_library_name_entry *ne; /* library name */
#if defined(ENABLE_LTDL)
hashtable_library_name_entry *native_library_find(utf *filename,
- classloader *loader)
+ classloader_t *loader)
{
hashtable_library_loader_entry *le;
hashtable_library_name_entry *ne; /* library name */
return ne;
}
-
-
-/* native_resolve_function *****************************************************
-
- Resolves a native function, maybe from a dynamic library.
-
-*******************************************************************************/
-
-functionptr native_resolve_function(methodinfo *m)
-{
- utf *name;
- utf *newname;
- functionptr f;
-#if defined(ENABLE_LTDL)
- classloader *cl;
- hashtable_library_loader_entry *le;
- hashtable_library_name_entry *ne;
- u4 key; /* hashkey */
- u4 slot; /* slot in hashtable */
-#endif
-#if defined(WITH_CLASSPATH_SUN)
- methodinfo *method_findNative;
- java_handle_t *s;
#endif
- /* verbose output */
- if (opt_verbosejni) {
- printf("[Dynamic-linking native method ");
- utf_display_printable_ascii_classname(m->class->name);
- printf(".");
- utf_display_printable_ascii(m->name);
- printf(" ... ");
- }
+/* native_library_load *********************************************************
- /* generate method symbol string */
+ Load a native library and initialize it, if possible.
- name = native_method_symbol(m->class->name, m->name);
-
- /* generate overloaded function (having the types in it's name) */
+ IN:
+ name ... name of the library
+ cl ..... classloader which loads this library
- newname = native_make_overloaded_function(name, m->descriptor);
+ RETURN:
+ 1 ... library loaded successfully
+ 0 ... error
- /* check the library hash entries of the classloader of the
- methods's class */
-
- f = NULL;
+*******************************************************************************/
+int native_library_load(JNIEnv *env, utf *name, classloader_t *cl)
+{
#if defined(ENABLE_LTDL)
- /* Get the classloader. */
-
- cl = class_get_classloader(m->class);
-
- /* normally addresses are aligned to 4, 8 or 16 bytes */
+ lt_dlhandle handle;
+# if defined(ENABLE_JNI)
+ lt_ptr onload;
+ int32_t version;
+# endif
- key = ((u4) (ptrint) cl) >> 4; /* align to 16-byte */
- slot = key & (hashtable_library->size - 1);
- le = hashtable_library->ptr[slot];
+ if (name == NULL) {
+ exceptions_throw_nullpointerexception();
+ return 0;
+ }
- /* iterate through loaders in this hash slot */
+ /* Is the library already loaded? */
- while ((le != NULL) && (f == NULL)) {
- /* iterate through names in this loader */
+ if (native_library_find(name, cl) != NULL)
+ return 1;
- ne = le->namelink;
-
- while ((ne != NULL) && (f == NULL)) {
- f = (functionptr) (ptrint) lt_dlsym(ne->handle, name->text);
+ /* Open the library. */
- if (f == NULL)
- f = (functionptr) (ptrint) lt_dlsym(ne->handle, newname->text);
+ handle = native_library_open(name);
- ne = ne->hashlink;
- }
+ if (handle == NULL)
+ return 0;
- le = le->hashlink;
- }
+# if defined(ENABLE_JNI)
+ /* Resolve JNI_OnLoad function. */
-# if defined(WITH_CLASSPATH_SUN)
- if (f == NULL) {
- /* We can resolve the function directly from
- java.lang.ClassLoader as it's a static function. */
- /* XXX should be done in native_init */
+ onload = lt_dlsym(handle, "JNI_OnLoad");
- method_findNative =
- class_resolveclassmethod(class_java_lang_ClassLoader,
- utf_findNative,
- utf_java_lang_ClassLoader_java_lang_String__J,
- class_java_lang_ClassLoader,
- true);
-
- if (method_findNative == NULL)
- return NULL;
-
- /* try the normal name */
+ if (onload != NULL) {
+ JNIEXPORT int32_t (JNICALL *JNI_OnLoad) (JavaVM *, void *);
+ JavaVM *vm;
- s = javastring_new(name);
+ JNI_OnLoad = (JNIEXPORT int32_t (JNICALL *)(JavaVM *, void *)) (ptrint) onload;
- f = (functionptr) (intptr_t) vm_call_method_long(method_findNative,
- NULL, cl, s);
+ (*env)->GetJavaVM(env, &vm);
- /* if not found, try the mangled name */
+ version = JNI_OnLoad(vm, NULL);
- if (f == NULL) {
- s = javastring_new(newname);
+ /* If the version is not 1.2 and not 1.4 the library cannot be
+ loaded. */
- f = (functionptr) (intptr_t) vm_call_method_long(method_findNative,
- NULL, cl, s);
+ if ((version != JNI_VERSION_1_2) && (version != JNI_VERSION_1_4)) {
+ lt_dlclose(handle);
+ return 0;
}
}
# endif
- if (f != NULL)
- if (opt_verbosejni)
- printf("JNI ]\n");
-#endif
+ /* Insert the library name into the library hash. */
- /* If not found, try to find the native function symbol in the
- main program. */
+ native_library_add(name, cl, handle);
- if (f == NULL) {
- f = native_method_find(m);
+ return 1;
+#else
+ vm_abort("native_library_load: not available");
- if (f != NULL)
- if (opt_verbosejni)
- printf("internal ]\n");
- }
+ /* Keep compiler happy. */
-#if defined(ENABLE_JVMTI)
- /* fire Native Method Bind event */
- if (jvmti) jvmti_NativeMethodBind(m, f, &f);
+ return 0;
#endif
-
- /* no symbol found? throw exception */
-
- if (f == NULL) {
- if (opt_verbosejni)
- printf("failed ]\n");
-
- exceptions_throw_unsatisfiedlinkerror(m->name);
- }
-
- return f;
}
-#endif
/* native_new_and_init *********************************************************