/* src/native/native.cpp - native library support
- Copyright (C) 1996-2005, 2006, 2007, 2008
+ Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include <functional>
#include <map>
-#include "mm/memory.h"
+#include "mm/memory.hpp"
#include "native/jni.hpp"
#include "native/native.hpp"
#include "threads/mutex.hpp"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
#include "vm/jit/builtin.hpp"
#include "vm/exceptions.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
+#include "vm/hook.hpp"
#include "vm/loader.hpp"
#include "vm/options.h"
#include "vm/os.hpp"
#include "vm/jit/asmpart.h"
#include "vm/jit/jit.hpp"
-#if defined(ENABLE_JVMTI)
-#include "native/jvmti/cacaodbg.h"
-#endif
-
/* native_make_overloaded_function *********************************************
utf* newname = native_make_overloaded_function(name, m->descriptor);
// Try to find the symbol.
- void* symbol = NULL;
+ void* symbol;
+
+ // Try to find the native method symbol in the native methods registered
+ // with the VM.
+ symbol = find_registered_method(m);
+
+ if (symbol != NULL)
+ if (opt_verbosejni)
+ printf("internal ]\n");
#if defined(ENABLE_DL)
- // Get the classloader.
- classloader_t* classloader = class_get_classloader(m->clazz);
+ classloader_t* classloader;
+ if (symbol == NULL) {
+ // Get the classloader.
+ classloader = class_get_classloader(m->clazz);
- // Resolve the native method name from the native libraries.
- NativeLibraries& libraries = VM::get_current()->get_nativelibraries();
- symbol = libraries.resolve_symbol(name, classloader);
+ // Resolve the native method name from the native libraries.
+ NativeLibraries& libraries = VM::get_current()->get_nativelibraries();
- if (symbol == NULL)
- symbol = libraries.resolve_symbol(newname, classloader);
+ symbol = libraries.resolve_symbol(name, classloader);
+
+ if (symbol == NULL)
+ symbol = libraries.resolve_symbol(newname, classloader);
+ }
# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
if (symbol == NULL) {
class_java_lang_ClassLoader,
true);
- if (method_findNative == NULL)
- return NULL;
-
- // Try the normal name.
- java_handle_t* s = javastring_new(name);
- symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s);
-
- // If not found, try the mangled name.
- if (symbol == NULL) {
- s = javastring_new(newname);
+ if (method_findNative != NULL) {
+ // Try the normal name.
+ java_handle_t* s = javastring_new(name);
symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s);
+
+ // If not found, try the mangled name.
+ if (symbol == NULL) {
+ s = javastring_new(newname);
+ symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s);
+ }
}
}
# endif
printf("JNI ]\n");
#endif
- // If not found already, try to find the native method symbol in
- // the native methods registered with the VM.
- if (symbol == NULL) {
- symbol = find_registered_method(m);
-
- if (symbol != NULL)
- if (opt_verbosejni)
- printf("internal ]\n");
- }
-
-#if defined(ENABLE_JVMTI)
- /* fire Native Method Bind event */
- if (jvmti) jvmti_NativeMethodBind(m, f, &f);
-#endif
-
// Symbol not found? Throw an exception.
if (symbol == NULL) {
if (opt_verbosejni)
exceptions_throw_unsatisfiedlinkerror(m->name);
}
+ // Hook point just after method resolving finished.
+ Hook::native_resolved(m, symbol, &symbol);
+
return symbol;
}
if (opt_verbosejni)
printf("failed ]\n");
- if (opt_verbose) {
- log_start();
- log_print("NativeLibrary::open: os::dlopen failed: ");
- log_print(os::dlerror());
- log_finish();
- }
+ if (opt_PrintWarnings)
+ log_println("NativeLibrary::open: os::dlopen failed: %s", os::dlerror());
return NULL;
}
if (opt_verbosejni)
printf("failed ]\n");
- if (opt_verbose) {
- log_start();
- log_print("NativeLibrary::close: os::dlclose failed: ");
- log_print(os::dlerror());
- log_finish();
- }
+ if (opt_PrintWarnings)
+ log_println("NativeLibrary::close: os::dlclose failed: %s", os::dlerror());
}
if (opt_verbosejni)
}
+/**
+ * Registers a new native agent by specified by it's library name
+ * and with an optional options string.
+ *
+ * @param library Name of the native agent library.
+ * @param options The options string or NULL if not specified.
+ */
+#if defined(ENABLE_JVMTI)
+void NativeAgents::register_agent_library(char* library, char* options)
+{
+ NativeAgent na(library, options);
+
+ // Insert native agent into list of agents.
+ _agents.push_back(na);
+}
+#endif
+
+
+/**
+ * Registers a new native agent by specified by a path to it's library
+ * and with an optional options string.
+ *
+ * @param path Path of the native agent library.
+ * @param options The options string or NULL if not specified.
+ */
+#if defined(ENABLE_JVMTI)
+void NativeAgents::register_agent_path(char* path, char* options)
+{
+ os::abort("NativeAgents::register_agent_library: Implement me!");
+}
+#endif
+
+
+/**
+ * Loads all registered native agents and in turn calls their exported
+ * start-up functions (Agent_OnLoad). If one of the agents reports an
+ * error during start-up, the loading is stopped.
+ *
+ * @return True if all agents were loaded successfully, false if
+ * one of them was not found or reported an error.
+ */
+#if defined(ENABLE_JVMTI)
+bool NativeAgents::load_agents()
+{
+ // Iterate over all registered agents.
+ for (std::vector<NativeAgent>::iterator it = _agents.begin(); it != _agents.end(); ++it) {
+ NativeAgent& na = *(it);
+
+ // Construct agent library name.
+ size_t len =
+ os::strlen(NATIVE_LIBRARY_PREFIX) +
+ os::strlen(na.get_library()) +
+ os::strlen(NATIVE_LIBRARY_SUFFIX) +
+ os::strlen("0");
+
+ char* p = MNEW(char, len);
+
+ os::strcpy(p, NATIVE_LIBRARY_PREFIX);
+ os::strcat(p, na.get_library());
+ os::strcat(p, NATIVE_LIBRARY_SUFFIX);
+
+ utf* u = utf_new_char(p);
+
+ MFREE(p, char, len);
+
+ // Construct new native library.
+ NativeLibrary nl(u);
+
+ // Try to open the library.
+ if (nl.open() == NULL)
+ return false;
+
+ // Resolve Agent_OnLoad function.
+ void* onload = os::dlsym(nl.get_handle(), "Agent_OnLoad");
+
+ // Call Agent_OnLoad function if present.
+ if (onload != NULL) {
+ JNIEXPORT jint (JNICALL *Agent_OnLoad) (JavaVM*, char*, void*);
+ JavaVM* vm = VM::get_current()->get_javavm();
+
+ Agent_OnLoad = (JNIEXPORT jint (JNICALL *)(JavaVM*, char*, void*)) (uintptr_t) onload;
+
+ jint result = Agent_OnLoad(vm, na.get_options(), NULL);
+
+ // Check for error in Agent_OnLoad.
+ if (result != 0) {
+ nl.close();
+ return false;
+ }
+ }
+
+ // According to the interface spec, the library _must_ export
+ // a start-up function.
+ else {
+ log_println("NativeAgents::load_agents: Native agent library does not export Agent_OnLoad");
+ return false;
+ }
+ }
+
+ return true;
+}
+#endif
+
+
/* native_new_and_init *********************************************************
Creates a new object on the heap and calls the initializer.