diff --git a/include/libc/djthunks.h b/include/libc/djthunks.h index efcdc842..7e888739 100644 --- a/include/libc/djthunks.h +++ b/include/libc/djthunks.h @@ -31,6 +31,7 @@ uint32_t djthunk_get_h(int handle, const char *name); void *djsbrk(int increment); int djelf_load(int num, int libid); int djelf_exec(void); +int djelf_run(int eid, int argc, char **argv); void djregister_init_hook(void (*hook)(void)); void djprocess_init_hooks(void); diff --git a/src/djdev64/djdev64.c b/src/djdev64/djdev64.c index e3589c3e..233e41fd 100644 --- a/src/djdev64/djdev64.c +++ b/src/djdev64/djdev64.c @@ -82,6 +82,7 @@ static const struct elf_ops eops = { djelf64_parse, do_elfparse64, djelf64_exec_self, + djelf64_run, }; #define __S(x) #x diff --git a/src/djdev64/include/djdev64/dj64init.h b/src/djdev64/include/djdev64/dj64init.h index 8099355d..a803c953 100644 --- a/src/djdev64/include/djdev64/dj64init.h +++ b/src/djdev64/include/djdev64/dj64init.h @@ -87,7 +87,8 @@ struct elf_ops { uint32_t *r_entry); char *(*elfparse64)(int eid, uint32_t *r_size); char *(*elfparse64_h)(int handle, uint32_t *r_size); - int (*exec)(void); + int (*exec_self)(void); + int (*exec64)(int eid, int argc, char **argv); }; typedef dj64cdispatch_t **(dj64init_t)(int handle, const struct elf_ops *ops, diff --git a/src/libc/compat/go64/elfexec.c b/src/libc/compat/go64/elfexec.c index 21b62661..fb8cab5d 100644 --- a/src/libc/compat/go64/elfexec.c +++ b/src/libc/compat/go64/elfexec.c @@ -29,6 +29,7 @@ #include #include #include +#include // https://github.com/vonj/snippets.org/blob/master/strrpbrk.c static char *strrpbrk(const char *szString, const char *szChars) @@ -45,33 +46,6 @@ static char *strrpbrk(const char *szString, const char *szChars) return p0; } -static unsigned argv_dup(char *argv[]) -{ - int i = 0, l, tab_l; - unsigned ret; - char *ptr; - - if (argv) - for (i = 0, l = 0; argv[i]; l += strlen(argv[i]) + 1, i++); - tab_l = sizeof(unsigned) * (i + 1); // for ptr table - l += tab_l; - ret = malloc32(l); - if (!ret) - return ret; - ptr = DATA_PTR(ret); - if (argv) { - unsigned dat = ret + tab_l; - char *pdat = ptr + tab_l; - for (i = 0, l = 0; argv[i]; l += strlen(argv[i]) + 1, i++) { - unsigned off = dat + l; - memcpy(ptr + i * sizeof(unsigned), &off, sizeof(off)); - strcpy(pdat + l, argv[i]); - } - } - memset(ptr + i * sizeof(unsigned), 0, sizeof(unsigned)); // trailing NULL - return ret; -} - int elfexec(const char *path, int argc, char **argv) { int err, fd, len, errn, eid, ret; @@ -162,16 +136,19 @@ int elfexec(const char *path, int argc, char **argv) regs.d.ebx = ELFEXEC_LIBID; upltinit32(®s); } +#if 0 memset(®s, 0, sizeof(regs)); regs.d.ebx = 7 | (eid << 16); // run - regs.d.ecx = argc; - regs.d.edx = argv_dup(argv); + regs.d.ecx = 0; // argc - unsupp + regs.d.edx = 0; // argv - unsupp pltcall32(®s, api); +#else + /* run directly to not re-pack args */ + err = djelf_run(eid, argc, argv); +#endif /* returning only 16bit AX allows to distinguish with -1 returns above */ - if (regs.x.flags & 1) - ret = -1; - else - ret = regs.x.ax; + if (err) + ret = (uint16_t)-1; __dpmi_free_shared_memory(shmi.handle); return ret; } @@ -182,7 +159,6 @@ int elfload(int num) __dpmi_regs regs; int ret, err; int eid = -1; - char *dummy_argv[] = { NULL }; switch (num) { case 0: @@ -212,7 +188,7 @@ int elfload(int num) memset(®s, 0, sizeof(regs)); regs.d.ebx = 7 | (eid << 16); // run regs.d.ecx = 0; // argc - unsupp - regs.d.edx = argv_dup(dummy_argv); + regs.d.edx = 0; // argv - unsupp pltcall32(®s, api); /* returning only 16bit AX allows to distinguish with -1 returns above */ if (regs.x.flags & 1) diff --git a/src/libc/dj64/thunks.c b/src/libc/dj64/thunks.c index 99154bac..2d0ae811 100644 --- a/src/libc/dj64/thunks.c +++ b/src/libc/dj64/thunks.c @@ -817,7 +817,14 @@ int djelf_exec(void) if (dj64api_ver < 22) return -1; u = &udisps[dj64api->get_handle()]; - return u->eops->exec(); + return u->eops->exec_self(); +} + +int djelf_run(int eid, int argc, char **argv) +{ + struct udisp *u; + u = &udisps[dj64api->get_handle()]; + return u->eops->exec64(eid, argc, argv); } void djregister_init_hook(void (*hook)(void))