From 9a59d14d0a457a714dc9421a1f9bd28b6ae3a86f Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sun, 18 Nov 2018 16:35:05 +0200 Subject: standalone libjvm-java --- src/jvm/jvm.c | 6 +++ src/jvm/jvm.h | 3 ++ src/libjvm-java.c | 110 +++++++++++++++++++++++++++++++++++------------------- 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 #include #include +#include #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 - -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); -} -- cgit v1.2.3