From 924f18438f1ff33c4852ef2a266830aa16a4bec8 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 19 Nov 2018 11:34:35 +0200 Subject: support running bionic binaries more properly --- src/app.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 7 deletions(-) (limited to 'src/app.c') diff --git a/src/app.c b/src/app.c index 879de20..326fd3a 100644 --- a/src/app.c +++ b/src/app.c @@ -1,16 +1,23 @@ #include +#include #include #include #include +#include #include #include #include "linker/dlfcn.h" +#include "linker/linker.h" #include "jvm/jvm.h" +#include static int run_jni_game(struct jvm *jvm) { // Works only with unity libs for now + // XXX: What this basically is that, we port the Java bits to C + // XXX: This will become unneccessary as we make dalvik interpreter + struct { union { void *ptr; @@ -154,19 +161,38 @@ run_jni_game(struct jvm *jvm) return EXIT_SUCCESS; } +static void +raw_start(void *entry, int argc, const char *argv[]) +{ + // XXX: make this part of the linker when it's rewritten +#if ANDROID_X86_LINKER + __asm__("mov 2*4(%ebp),%eax"); /* entry */ + __asm__("mov 3*4(%ebp),%ecx"); /* original_argc */ + __asm__("mov 4*4(%ebp),%edx"); /* original_argv */ + __asm__("mov %edx,%esp"); /* Trim stack. */ + __asm__("push %edx"); /* New argv */ + __asm__("push %ecx"); /* New argc */ + __asm__("sub %edx,%edx"); /* no rtld_fini function */ + __asm__("jmp *%eax"); /* Goto entry. */ +#else + warnx("raw_start not implemented for this asm platform, can't execute binaries."); +#endif +} + int main(int argc, const char *argv[]) { if (argc < 2) - errx(EXIT_FAILURE, "usage: so-file"); + errx(EXIT_FAILURE, "usage: "); printf("loading module: %s\n", argv[1]); { // FIXME: when bionic linker is rewritten it will just use system search path - char abs[PATH_MAX]; + char abs[PATH_MAX], paths[4096]; realpath(argv[1], abs); - dl_parse_library_path(dirname(abs), ";"); + snprintf(paths, sizeof(paths), "%s:%s", dirname(abs), "runtime-ndk"); + dl_parse_library_path(paths, ":"); } void *handle; @@ -183,10 +209,27 @@ main(int argc, const char *argv[]) union { void *ptr; - int (*fun)(int, const char*[]); - } main; + } start; } entry; + { + union { + char bytes[sizeof(Elf32_Ehdr)]; + Elf32_Ehdr hdr; + } elf; + + FILE *f; + if (!(f = fopen(argv[1], "rb"))) + err(EXIT_FAILURE, "fopen(%s)", argv[1]); + + fread(elf.bytes, 1, sizeof(elf.bytes), f); + fclose(f); + + struct soinfo *si = handle; + if (elf.hdr.e_entry) + entry.start.ptr = (void*)(intptr_t)(si->base + elf.hdr.e_entry); + } + int ret = EXIT_FAILURE; if ((entry.JNI_OnLoad.ptr = bionic_dlsym(handle, "JNI_OnLoad"))) { struct jvm jvm; @@ -194,8 +237,9 @@ main(int argc, const char *argv[]) entry.JNI_OnLoad.fun(&jvm.vm, NULL); ret = run_jni_game(&jvm); jvm_release(&jvm); - } else if ((entry.main.ptr = bionic_dlsym(handle, "main"))) { - ret = entry.main.fun(argc - 1, &argv[1]); + } else if (entry.start.ptr) { + printf("jumping to %p\n", entry.start.ptr); + raw_start(entry.start.ptr, argc - 1, &argv[1]); } else { warnx("no entrypoint found in %s", argv[1]); } -- cgit v1.2.3