summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jvm/jvm.c6
-rw-r--r--src/jvm/jvm.h3
-rw-r--r--src/libjvm-java.c110
3 files changed, 81 insertions, 38 deletions
diff --git a/src/jvm/jvm.c b/src/jvm/jvm.c
index 20e868a..7ac8c6b 100644
--- a/src/jvm/jvm.c
+++ b/src/jvm/jvm.c
@@ -1627,6 +1627,12 @@ vm_init(JavaVM *vm, struct JNIInvokeInterface *invoke)
*vm = invoke;
}
+const char*
+jvm_get_class_name(struct jvm *jvm, jobject object)
+{
+ return jvm_get_object_of_type(jvm, object, JVM_OBJECT_CLASS)->klass.name.data;
+}
+
void*
jvm_get_native_method(struct jvm *jvm, const char *klass, const char *method)
{
diff --git a/src/jvm/jvm.h b/src/jvm/jvm.h
index e2f99e4..b3f37a1 100644
--- a/src/jvm/jvm.h
+++ b/src/jvm/jvm.h
@@ -72,6 +72,9 @@ struct jvm {
JavaVM vm; // points to invoke
};
+const char*
+jvm_get_class_name(struct jvm *jvm, jobject object);
+
void*
jvm_get_native_method(struct jvm *jvm, const char *klass, const char *method);
diff --git a/src/libjvm-java.c b/src/libjvm-java.c
index b1d8cbd..197df0d 100644
--- a/src/libjvm-java.c
+++ b/src/libjvm-java.c
@@ -6,9 +6,8 @@
#include <assert.h>
#include <err.h>
#include <dlfcn.h>
+#include <err.h>
#include "jvm/jni.h"
-#include "linker/dlfcn.h"
-#include "wrapper/verbose.h"
jstring
java_lang_System_getProperty(JNIEnv *env, jobject object, va_list args)
@@ -19,10 +18,10 @@ java_lang_System_getProperty(JNIEnv *env, jobject object, va_list args)
union {
void *ptr;
- int (*fun)(const char *name, char *value);
+ int (*fun)(const char*, char*);
} __system_property_get;
- if (!(__system_property_get.ptr = bionic_dlsym(NULL, "__system_property_get")))
+ if (!(__system_property_get.ptr = dlsym(RTLD_DEFAULT, "__system_property_get")))
return NULL;
__system_property_get.fun(key, value);
@@ -34,29 +33,51 @@ java_lang_System_load(JNIEnv *env, jobject object, va_list args)
{
assert(env && object);
const char *lib = (*env)->GetStringUTFChars(env, va_arg(args, jstring), NULL);
- verbose("%s", lib);
+
+ struct {
+ union {
+ void *ptr;
+ void* (*fun)(const char*, int);
+ } open;
+
+ union {
+ void *ptr;
+ void* (*fun)(void*, const char*);
+ } sym;
+ } dl;
+
+ if (!(dl.open.ptr = dlsym(RTLD_DEFAULT, "bionic_dlopen")) || !(dl.sym.ptr = dlsym(RTLD_DEFAULT, "bionic_dlsym"))) {
+ dl.open.fun = dlopen;
+ dl.sym.fun = dlsym;
+ }
void *handle;
- if (!(handle = bionic_dlopen(lib, RTLD_NOW | RTLD_GLOBAL)))
+ if (!(handle = dl.open.fun(lib, RTLD_NOW | RTLD_GLOBAL))) {
+ warnx("java/lang/System/load: failed to dlopen `%s`", lib);
return;
+ }
union {
void *ptr;
void* (*fun)(void*, void*);
} JNI_OnLoad;
- if ((JNI_OnLoad.ptr = bionic_dlsym(handle, "JNI_OnLoad"))) {
+ if ((JNI_OnLoad.ptr = dl.sym.fun(handle, "JNI_OnLoad"))) {
JavaVM *vm;
(*env)->GetJavaVM(env, &vm);
JNI_OnLoad.fun(vm, NULL);
}
}
-jclass
-java_lang_Object_getClass(JNIEnv *env, jobject object)
+jobject
+java_lang_ClassLoader_findLibrary(JNIEnv *env, jobject object, va_list args)
{
assert(env && object);
- return (*env)->GetObjectClass(env, object);
+ // XXX: according to docs should return absolute path, but relative is more convenient for us.
+ // fix if breaks anything because of this.
+ char lib[255];
+ snprintf(lib, sizeof(lib), "lib%s.so", (*env)->GetStringUTFChars(env, va_arg(args, jstring), NULL));
+ return (*env)->NewStringUTF(env, lib);
}
jobject
@@ -67,15 +88,48 @@ java_lang_Class_getClassLoader(JNIEnv *env, jobject object)
return (sv ? sv : (sv = (*env)->AllocObject(env, (*env)->FindClass(env, "java/lang/ClassLoader"))));
}
-jobject
-java_lang_ClassLoader_findLibrary(JNIEnv *env, jobject object, va_list args)
+jclass
+java_lang_Class_forName(JNIEnv *env, jobject object, va_list args)
{
assert(env && object);
- // XXX: according to docs should return absolute path, but relative is more convenient for us.
- // fix if breaks anything because of this.
- char lib[255];
- snprintf(lib, sizeof(lib), "lib%s.so", (*env)->GetStringUTFChars(env, va_arg(args, jstring), NULL));
- return (*env)->NewStringUTF(env, lib);
+ jstring str = va_arg(args, jstring);
+ const char *utf = (*env)->GetStringUTFChars(env, str, NULL);
+ return (*env)->FindClass(env, utf);
+}
+
+jstring
+java_lang_Class_getName(JNIEnv *env, jobject object)
+{
+ assert(env && object);
+
+ {
+ struct {
+ union {
+ void *ptr;
+ struct jvm* (*fun)(JNIEnv*);
+ } jnienv_get_jvm;
+
+ union {
+ void *ptr;
+ const char* (*fun)(const struct jvm*, jobject);
+ } jvm_get_class_name;
+ } jvm;
+
+ if ((jvm.jnienv_get_jvm.ptr = dlsym(RTLD_DEFAULT, "jnienv_get_jvm")) && (jvm.jvm_get_class_name.ptr = dlsym(RTLD_DEFAULT, "jvm_get_class_name"))) {
+ struct jvm *jvm_ = jvm.jnienv_get_jvm.fun(env);
+ return (*env)->NewStringUTF(env, jvm.jvm_get_class_name.fun(jvm_, object));
+ }
+ }
+
+ warnx("%s: returning NULL, as running in unknown JVM and don't know how to get class name", __func__);
+ return NULL;
+}
+
+jclass
+java_lang_Object_getClass(JNIEnv *env, jobject object)
+{
+ assert(env && object);
+ return (*env)->GetObjectClass(env, object);
}
jstring
@@ -132,19 +186,10 @@ java_lang_String_getBytes(JNIEnv *env, jobject object, va_list args)
const char *utf = (*env)->GetStringUTFChars(env, object, NULL);
const size_t len = strlen(utf);
jbyteArray bytes = (*env)->NewByteArray(env, len);
- (*env)->SetByteArrayRegion(env, bytes, 0, len, utf);
+ (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)utf);
return bytes;
}
-jclass
-java_lang_Class_forName(JNIEnv *env, jobject object, va_list args)
-{
- assert(env && object);
- jstring str = va_arg(args, jstring);
- const char *utf = (*env)->GetStringUTFChars(env, str, NULL);
- return (*env)->FindClass(env, utf);
-}
-
jstring
java_util_Locale_getLanguage(JNIEnv *env, jobject object)
{
@@ -158,14 +203,3 @@ java_util_Locale_getCountry(JNIEnv *env, jobject object)
assert(env && object);
return (*env)->NewStringUTF(env, "US");
}
-
-#include "jvm/jvm.h"
-#include <stdint.h>
-
-jstring
-java_lang_Class_getName(JNIEnv *env, jobject object)
-{
- assert(env && object);
- const struct jvm *jvm = jnienv_get_jvm(env);
- return (*env)->NewStringUTF(env, jvm->objects[(uintptr_t)object - 1].klass.name.data);
-}