summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-02-19 11:56:51 +0200
committerJari Vetoniemi <mailroxas@gmail.com>2018-02-19 12:00:35 +0200
commita7a253f9d4cc82794c5a5360f3a017fd9b63de9b (patch)
tree540f1dfc6ef3671e710a05cb94e0fd194fee05c8
parent12d58ade2732e7ce0a644371ca10a1dd234c5bc1 (diff)
jvm: rename fakejvm to jvm
-rw-r--r--Makefile8
-rw-r--r--src/app.c2
-rw-r--r--src/jvm/jni.h (renamed from src/fakejvm/jni.h)0
-rw-r--r--src/jvm/jvm.c (renamed from src/fakejvm/jvm.c)83
-rw-r--r--src/jvm/jvm.h (renamed from src/fakejvm/jvm.h)1
5 files changed, 72 insertions, 22 deletions
diff --git a/Makefile b/Makefile
index 0600d3a..f568afe 100644
--- a/Makefile
+++ b/Makefile
@@ -36,15 +36,17 @@ runtime/libpthread.so: private LDLIBS += -lpthread
runtime/libpthread.so: runtime src/libpthread.c
runtime/libandroid.so: runtime src/libandroid.c
runtime/liblog.so: runtime src/liblog.c
+native: runtime/libc.so runtime/libpthread.so runtime/libandroid.so runtime/liblog.so
linker.a: CFLAGS += -D_GNU_SOURCE -DANDROID_X86_LINKER -DLINKER_DEBUG=1
linker.a: CFLAGS += -Wno-pedantic -Wno-variadic-macros -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
linker.a: src/linker/dlfcn.o src/linker/linker.o src/linker/linker_environ.o src/linker/rt.o src/linker/strlcpy.o
+jvm.a: CFLAGS += -D_GNU_SOURCE
jvm.a: CFLAGS += -Wno-unused-variable -Wno-pedantic
-jvm.a: src/fakejvm/jvm.o
+jvm.a: src/jvm/jvm.o
app: private LDLIBS += -ldl -Wl,-rpath,runtime
-app: src/app.c linker.a jvm.a runtime/libc.so runtime/libpthread.so runtime/libandroid.so runtime/liblog.so
+app: src/app.c linker.a native jvm.a
install-bin: $(bins)
install -Dm755 $^ -t "$(DESTDIR)$(PREFIX)$(BINDIR)"
@@ -52,7 +54,7 @@ install-bin: $(bins)
install: install-bin
clean:
- $(RM) $(bins) *.a src/linker/*.o src/fakejvm/*.o
+ $(RM) $(bins) *.a src/linker/*.o src/jvm/*.o
$(RM) -r runtime
.PHONY: all clean install
diff --git a/src/app.c b/src/app.c
index 78bb689..dbcdfe9 100644
--- a/src/app.c
+++ b/src/app.c
@@ -4,7 +4,7 @@
#include <dlfcn.h>
#include <err.h>
#include <assert.h>
-#include "fakejvm/jvm.h"
+#include "jvm/jvm.h"
extern void *apkenv_android_dlopen(const char*, int);
extern void *apkenv_android_dlclose(void*);
diff --git a/src/fakejvm/jni.h b/src/jvm/jni.h
index ad954c8..ad954c8 100644
--- a/src/fakejvm/jni.h
+++ b/src/jvm/jni.h
diff --git a/src/fakejvm/jvm.c b/src/jvm/jvm.c
index db4e3ed..15a925e 100644
--- a/src/fakejvm/jvm.c
+++ b/src/jvm/jvm.c
@@ -4,11 +4,14 @@
#include <stddef.h>
#include <stdint.h>
#include <assert.h>
+#include "dlfcn.h"
#include "jvm.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#define container_of(ptr, type, member) ((type *)((char *)(1 ? (ptr) : &((type *)0)->member) - offsetof(type, member)))
+extern void* create_wrapper(const char *const symbol, void *function);
+
static inline char*
ccopy(const char *str, const size_t len, const bool null_terminate)
{
@@ -95,6 +98,7 @@ jvm_object_release(struct jvm_object *o)
void (*destructor[])(struct jvm_object *o) = {
NULL,
+ NULL,
release_array,
release_method,
release_class,
@@ -102,11 +106,21 @@ jvm_object_release(struct jvm_object *o)
};
assert(o->type < JVM_OBJECT_LAST);
- destructor[o->type](o);
+
+ if (destructor)
+ destructor[o->type](o);
+
*o = (struct jvm_object){0};
}
static bool
+compare_opaque(const struct jvm_object *a, const struct jvm_object *b)
+{
+ assert(a && b);
+ return (a->this_klass == b->this_klass);
+}
+
+static bool
compare_array(const struct jvm_object *a, const struct jvm_object *b)
{
assert(a && b);
@@ -145,6 +159,7 @@ jvm_find_object(struct jvm *jvm, const struct jvm_object *o)
bool (*comparator[])(const struct jvm_object *a, const struct jvm_object *b) = {
NULL,
+ compare_opaque,
compare_array,
compare_method,
compare_class,
@@ -173,16 +188,17 @@ jvm_assing_default_class(struct jvm *jvm, struct jvm_object *o)
switch (o->type) {
case JVM_OBJECT_METHOD:
- o->this_klass = jvm_make_class(jvm, "java.lang.reflect.Method");
+ o->this_klass = jvm_make_class(jvm, "java/lang/reflect/Method");
break;
case JVM_OBJECT_STRING:
- o->this_klass = jvm_make_class(jvm, "java.lang.String");
+ o->this_klass = jvm_make_class(jvm, "java/lang/String");
break;
case JVM_OBJECT_NONE:
case JVM_OBJECT_ARRAY:
case JVM_OBJECT_CLASS:
+ case JVM_OBJECT_LAST:
// arrays have unique classes which is handled on `jvm_new_array`
// `jvm_make_class` points class's `this_class` to first object, which is class definition for a class
assert(0 && "epic failure");
@@ -387,31 +403,40 @@ JNIEnv_EnsureLocalCapacity(JNIEnv* p0, jint p1)
static jobject
JNIEnv_AllocObject(JNIEnv* p0, jclass p1)
{
- return NULL;
+ assert(p0 && p1);
+ struct jvm_object o = { .this_klass = p1, .type = JVM_OBJECT_OPAQUE };
+ return jvm_add_object_if_not_there(jnienv_get_jvm(p0), &o);
}
static jobject
JNIEnv_NewObject(JNIEnv* p0, jclass p1, jmethodID p2, ...)
{
- return NULL;
+ assert(p0 && p1);
+ return JNIEnv_AllocObject(p0, p1);
+ // FIXME: call constructor
}
static jobject
-JNIEnv_NewObjectV(JNIEnv *env, jclass p1, jmethodID p2, va_list p3)
+JNIEnv_NewObjectV(JNIEnv *p0, jclass p1, jmethodID p2, va_list p3)
{
- return 0;
+ assert(p0 && p1);
+ return JNIEnv_AllocObject(p0, p1);
+ // FIXME: call constructor
}
static jobject
JNIEnv_NewObjectA(JNIEnv* p0, jclass p1, jmethodID p2, jvalue* p3)
{
- return NULL;
+ assert(p0 && p1);
+ return JNIEnv_AllocObject(p0, p1);
+ // FIXME: call constructor
}
static jclass
JNIEnv_GetObjectClass(JNIEnv* env, jobject p1)
{
assert(env && p1);
+ printf("%u\n", (uint32_t)(uintptr_t)p1);
return jvm_get_object(jnienv_get_jvm(env), p1)->this_klass;
}
@@ -424,6 +449,8 @@ JNIEnv_IsInstanceOf(JNIEnv* p0, jobject p1, jclass p2)
static jmethodID
jvm_make_method(struct jvm *jvm, jclass klass, const char *name, const char *sig)
{
+ assert(jvm && klass && name && sig);
+ printf("%s::%s::%s\n", jvm_get_object(jvm, klass)->klass.name.data, name, sig);
struct jvm_object o = { .method.klass = klass, .type = JVM_OBJECT_METHOD };
jvm_string_set_cstr(&o.method.name, name, true);
jvm_string_set_cstr(&o.method.signature, sig, true);
@@ -433,7 +460,6 @@ jvm_make_method(struct jvm *jvm, jclass klass, const char *name, const char *sig
static jmethodID
JNIEnv_GetMethodID(JNIEnv* p0, jclass klass, const char* name, const char* sig)
{
- printf("%s::%s\n", name, sig);
return jvm_make_method(jnienv_get_jvm(p0), klass, name, sig);
}
@@ -443,14 +469,38 @@ JNIEnv_CallObjectMethod(JNIEnv* p0, jobject p1, jmethodID p2, ...)
return NULL;
}
+static char*
+cstr_replace(char *cstr, const char replace, const char with)
+{
+ assert(cstr && replace != with);
+
+ if (replace == with)
+ return cstr;
+
+ char *s = cstr;
+ while ((s = strchr(s, replace)))
+ *s = with;
+ return cstr;
+}
+
+static void
+jvm_form_symbol(struct jvm *jvm, jmethodID method_id, char *symbol, const size_t symbol_sz)
+{
+ assert(jvm && method_id);
+ struct jvm_method *method = &jvm_get_object(jvm, method_id)->method;
+ printf("%s::%s::%s\n", jvm_get_object(jvm, method->klass)->klass.name.data, method->name.data, method->signature.data);
+ snprintf(symbol, symbol_sz, "%s_%s", jvm_get_object(jvm, method->klass)->klass.name.data, method->name.data);
+ cstr_replace(symbol, '/', '_');
+}
+
static jobject
JNIEnv_CallObjectMethodV(JNIEnv *p0, jobject p1, jmethodID p2, va_list p3)
{
assert(p0 && p1 && p2);
- struct jvm *jvm = jnienv_get_jvm(p0);
- struct jvm_method *method = &jvm_get_object(jvm, p2)->method;
- printf("%s::%s\n", jvm_get_object(jvm, method->klass)->klass.name.data, method->name.data);
- return NULL;
+ char symbol[255];
+ jvm_form_symbol(jnienv_get_jvm(p0), p2, symbol, sizeof(symbol));
+ jobject (*fun)(JNIEnv*, jobject, va_list) = create_wrapper(symbol, dlsym(RTLD_DEFAULT, symbol));
+ return fun(p0, p1, p3);
}
static jobject
@@ -1141,8 +1191,6 @@ JNIEnv_SetDoubleField(JNIEnv* p0, jobject p1, jfieldID p2, jdouble p3)
static jmethodID
JNIEnv_GetStaticMethodID(JNIEnv* p0, jclass klass, const char* name, const char* sig)
{
- assert(p0 && klass && name && sig);
- printf("%s::%s\n", name, sig);
return jvm_make_method(jnienv_get_jvm(p0), klass, name, sig);
}
@@ -1893,7 +1941,7 @@ jvm_register_native_method(struct jvm *jvm, const jclass klass, const JNINativeM
jvm_string_set_cstr(&jvm->methods[i].method.name, method->name, true);
jvm_string_set_cstr(&jvm->methods[i].method.signature, method->signature, true);
jvm->methods[i].function = method->fnPtr;
- printf("%s::%s\n", jvm_get_object(jvm, klass)->klass.name.data, method->name);
+ printf("%s::%s::%s\n", jvm_get_object(jvm, klass)->klass.name.data, method->name, method->signature);
}
static jint
@@ -2029,7 +2077,6 @@ trace(const char *const symbol)
printf("trace: %s\n", symbol);
}
-extern void* create_wrapper(const char *const symbol, void *function);
#define WRAP(x) create_wrapper(#x, x)
static void
@@ -2351,5 +2398,5 @@ jvm_init(struct jvm *jvm)
*jvm = (struct jvm){0};
vm_init(&jvm->vm, &jvm->invoke);
env_init(&jvm->env, &jvm->native);
- jvm_make_class(jvm, "java.lang.Class");
+ jvm_make_class(jvm, "java/lang/Class");
}
diff --git a/src/fakejvm/jvm.h b/src/jvm/jvm.h
index 937ddfd..cc69cb4 100644
--- a/src/fakejvm/jvm.h
+++ b/src/jvm/jvm.h
@@ -35,6 +35,7 @@ struct jvm_object {
enum jvm_object_type {
JVM_OBJECT_NONE,
+ JVM_OBJECT_OPAQUE,
JVM_OBJECT_ARRAY,
JVM_OBJECT_METHOD,
JVM_OBJECT_CLASS,