From 1bcc2c0c831927c308f321497b6fdc007cf1a2ac Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Fri, 27 Oct 2023 05:28:17 +0900 Subject: [PATCH 1/5] WIP work towards msvc support --- dll/msvcrt.cpp | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/dll/msvcrt.cpp b/dll/msvcrt.cpp index df078aa..4558a30 100644 --- a/dll/msvcrt.cpp +++ b/dll/msvcrt.cpp @@ -1,20 +1,50 @@ #include "common.h" +typedef void (WIN_ENTRY *_PVFV)(void); + namespace msvcrt { int _commode; int _fmode; + char **___initenv; + char **__pgmptr; // Stub because we're only ever a console application - void WIN_FUNC __set_app_type(int at) { + void WIN_ENTRY __set_app_type(int at) { } - int* WIN_FUNC __p__fmode() { + int* WIN_ENTRY __p__fmode() { return &_fmode; } - int* WIN_FUNC __p__commode() { + int* WIN_ENTRY __p__commode() { return &_commode; } + + char*** WIN_ENTRY __p___initenv(void) { return &___initenv; } + char **WIN_ENTRY __p__pgmptr(void) { return __pgmptr; } + void* WIN_ENTRY __p__iob(void) { return nullptr; } + + + unsigned int WIN_ENTRY _controlfp(unsigned int _new, unsigned int mask) { + return 0; + } + + void WIN_ENTRY _initterm(_PVFV *start, _PVFV *end) { + _PVFV* it = start; + + while (it < end) { + if (*it != nullptr) { + (**it)(); + } + it++; + } + } + + int WIN_ENTRY __getmainargs(int *argc, char ***argv, char ***envp, int expand_wildcards, int *new_mode) { + DEBUG_LOG("msvcrt::__getmainargs(%p, %p, %p, %d, %p)\n", argc, argv, envp, expand_wildcards, new_mode); + return 0; + } + void WIN_ENTRY setbuf(FILE* file, char *buf) {} } @@ -22,6 +52,14 @@ static void *resolveByName(const char *name) { if (strcmp(name, "__set_app_type") == 0) return (void *) msvcrt::__set_app_type; if (strcmp(name, "__p__fmode") == 0) return (void *) msvcrt::__p__fmode; if (strcmp(name, "__p__commode") == 0) return (void *) msvcrt::__p__commode; + if (strcmp(name, "__p___initenv") == 0) return (void *) msvcrt::__p___initenv; + if (strcmp(name, "__p__pgmptr") == 0) return (void *) msvcrt::__p__pgmptr; + if (strcmp(name, "__p__iob") == 0) return (void *) msvcrt::__p__iob; + if (strcmp(name, "_controlfp") == 0) return (void *) msvcrt::_controlfp; + if (strcmp(name, "_initterm") == 0) return (void *) msvcrt::_initterm; + if (strcmp(name, "__getmainargs") == 0) return (void *) msvcrt::__getmainargs; + if (strcmp(name, "setbuf") == 0) return (void *) msvcrt::setbuf; + if (strcmp(name, "getenv") == 0) return (void *) getenv; return nullptr; } From 34aec2324f001f6e62d4393f34b27e834dfb2936 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Fri, 27 Oct 2023 17:04:29 +0900 Subject: [PATCH 2/5] 7.1 --- dll/msvcrt.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dll/msvcrt.cpp b/dll/msvcrt.cpp index 4558a30..31a1ceb 100644 --- a/dll/msvcrt.cpp +++ b/dll/msvcrt.cpp @@ -71,6 +71,8 @@ wibo::Module lib_msvcrt = { "msvcrt40.dll", "msvcr70", "msvcr70.dll", + "msvcr71", + "msvcr71.dll", nullptr, }, resolveByName, From 02b7b717da29b1c54f6fca20d2bc51cf65f05369 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Fri, 27 Oct 2023 17:40:14 +0900 Subject: [PATCH 3/5] more progress --- dll/msvcrt.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/dll/msvcrt.cpp b/dll/msvcrt.cpp index 31a1ceb..105db1c 100644 --- a/dll/msvcrt.cpp +++ b/dll/msvcrt.cpp @@ -1,10 +1,19 @@ #include "common.h" +#include + +// from https://codebrowser.dev/glibc/glibc/sysdeps/x86/fpu_control.h.html +#define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw)) +#define _FPU_SETCW(cw) __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw)) + typedef void (WIN_ENTRY *_PVFV)(void); namespace msvcrt { int _commode; int _fmode; + + int fpcntrl; + char **___initenv; char **__pgmptr; @@ -20,13 +29,30 @@ namespace msvcrt { return &_commode; } - char*** WIN_ENTRY __p___initenv(void) { return &___initenv; } - char **WIN_ENTRY __p__pgmptr(void) { return __pgmptr; } - void* WIN_ENTRY __p__iob(void) { return nullptr; } + char*** WIN_ENTRY __p___initenv(void) { + return &___initenv; + } + + char **WIN_ENTRY __p__pgmptr(void) { + if (!__pgmptr) { + __pgmptr = (char**)malloc(1000000); + // TODO put something in here? + } + return __pgmptr; + } + + FILE* WIN_ENTRY __p__iob(void) { + return nullptr; + } + + unsigned int WIN_ENTRY _controlfp(unsigned int new_value, unsigned int mask) { + DEBUG_LOG("_controlfp called with value: 0x%X, mask: 0x%X\n", new_value, mask); + _FPU_GETCW(fpcntrl); + fpcntrl = ((fpcntrl & ~mask) | (new_value & mask)); + _FPU_SETCW(fpcntrl); - unsigned int WIN_ENTRY _controlfp(unsigned int _new, unsigned int mask) { - return 0; + return fpcntrl; } void WIN_ENTRY _initterm(_PVFV *start, _PVFV *end) { @@ -40,13 +66,33 @@ namespace msvcrt { } } - int WIN_ENTRY __getmainargs(int *argc, char ***argv, char ***envp, int expand_wildcards, int *new_mode) { - DEBUG_LOG("msvcrt::__getmainargs(%p, %p, %p, %d, %p)\n", argc, argv, envp, expand_wildcards, new_mode); - return 0; + int WIN_ENTRY __getmainargs(int* argc, char*** argv, char*** env, int doWildCard, void* startInfo) { + DEBUG_LOG("__getmainargs: %p, %p, %p, %i, %p\n", argc, argv, env, doWildCard, startInfo); + *argc = wibo::argc; + *argv = wibo::argv; + + return 0; // success + } + + void WIN_ENTRY setbuf(FILE* file, char *buf) { + } - void WIN_ENTRY setbuf(FILE* file, char *buf) {} -} + int WIN_ENTRY _spawnvp(int mode, char* cmdname, char** argv) { + DEBUG_LOG("_spawnvp: %s\n", cmdname); + + setenv("WIBO_DEBUG_INDENT", std::to_string(wibo::debugIndent + 1).c_str(), true); + + char *new_argv[] = {cmdname}; + + pid_t pid; + if (posix_spawn(&pid, wibo::executableName, NULL, NULL, new_argv, environ)) { + return 0; + }; + + return 1; + } +} static void *resolveByName(const char *name) { if (strcmp(name, "__set_app_type") == 0) return (void *) msvcrt::__set_app_type; @@ -59,7 +105,28 @@ static void *resolveByName(const char *name) { if (strcmp(name, "_initterm") == 0) return (void *) msvcrt::_initterm; if (strcmp(name, "__getmainargs") == 0) return (void *) msvcrt::__getmainargs; if (strcmp(name, "setbuf") == 0) return (void *) msvcrt::setbuf; + if (strcmp(name, "_spawnvp") == 0) return (void *) msvcrt::_spawnvp; + + char* (*wibo_strchr)(char* str, int c) = strchr; + + // 1:1 mappings with linux funcs + if (strcmp(name, "exit") == 0) return (void *) exit; + if (strcmp(name, "fopen") == 0) return (void *) fopen; + if (strcmp(name, "fclose") == 0) return (void *) fclose; + if (strcmp(name, "free") == 0) return (void *) free; if (strcmp(name, "getenv") == 0) return (void *) getenv; + if (strcmp(name, "malloc") == 0) return (void *) malloc; + if (strcmp(name, "memcpy") == 0) return (void *) memcpy; + if (strcmp(name, "memmove") == 0) return (void *) memmove; + if (strcmp(name, "memset") == 0) return (void *) memset; + if (strcmp(name, "strcat") == 0) return (void *) strcat; + if (strcmp(name, "strchr") == 0) return (void *) wibo_strchr; + if (strcmp(name, "strcmp") == 0) return (void *) strcmp; + if (strcmp(name, "strncmp") == 0) return (void *) strncmp; + if (strcmp(name, "strcpy") == 0) return (void *) strcpy; + if (strcmp(name, "strlen") == 0) return (void *) strlen; + if (strcmp(name, "strncpy") == 0) return (void *) strncpy; + if (strcmp(name, "strtoul") == 0) return (void *) strtoul; return nullptr; } From aebad970d5c04f0159e42be0ae37d76c70ca19aa Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Fri, 27 Oct 2023 17:45:42 +0900 Subject: [PATCH 4/5] fix strchr? --- dll/msvcrt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dll/msvcrt.cpp b/dll/msvcrt.cpp index 105db1c..a4409cc 100644 --- a/dll/msvcrt.cpp +++ b/dll/msvcrt.cpp @@ -107,7 +107,7 @@ static void *resolveByName(const char *name) { if (strcmp(name, "setbuf") == 0) return (void *) msvcrt::setbuf; if (strcmp(name, "_spawnvp") == 0) return (void *) msvcrt::_spawnvp; - char* (*wibo_strchr)(char* str, int c) = strchr; + const char* (*wibo_strchr)(const char* str, int c) = strchr; // 1:1 mappings with linux funcs if (strcmp(name, "exit") == 0) return (void *) exit; From a3708aae9e1513688dec20fde781fdc739a0d19e Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Fri, 27 Oct 2023 17:53:38 +0900 Subject: [PATCH 5/5] actually fix it --- dll/msvcrt.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dll/msvcrt.cpp b/dll/msvcrt.cpp index a4409cc..e60e343 100644 --- a/dll/msvcrt.cpp +++ b/dll/msvcrt.cpp @@ -1,6 +1,7 @@ #include "common.h" #include +#include // from https://codebrowser.dev/glibc/glibc/sysdeps/x86/fpu_control.h.html #define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw)) @@ -107,8 +108,6 @@ static void *resolveByName(const char *name) { if (strcmp(name, "setbuf") == 0) return (void *) msvcrt::setbuf; if (strcmp(name, "_spawnvp") == 0) return (void *) msvcrt::_spawnvp; - const char* (*wibo_strchr)(const char* str, int c) = strchr; - // 1:1 mappings with linux funcs if (strcmp(name, "exit") == 0) return (void *) exit; if (strcmp(name, "fopen") == 0) return (void *) fopen; @@ -120,7 +119,7 @@ static void *resolveByName(const char *name) { if (strcmp(name, "memmove") == 0) return (void *) memmove; if (strcmp(name, "memset") == 0) return (void *) memset; if (strcmp(name, "strcat") == 0) return (void *) strcat; - if (strcmp(name, "strchr") == 0) return (void *) wibo_strchr; + if (strcmp(name, "strchr") == 0) return (void *) strchr; if (strcmp(name, "strcmp") == 0) return (void *) strcmp; if (strcmp(name, "strncmp") == 0) return (void *) strncmp; if (strcmp(name, "strcpy") == 0) return (void *) strcpy;