From c97d0c0062546eae869b086ccfedb400ce32465d Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 9 Sep 2017 17:41:02 +0100 Subject: [PATCH] More fixes for native code on Windows --- src/cgen.c | 17 +++++++++++++++-- src/rt/jit.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/cgen.c b/src/cgen.c index bfe60f61..aa7e3197 100644 --- a/src/cgen.c +++ b/src/cgen.c @@ -2922,9 +2922,11 @@ static void cgen_function(LLVMTypeRef display_type) assert(vcode_unit_kind() == VCODE_UNIT_FUNCTION); LLVMValueRef fn = LLVMGetNamedFunction(module, istr(vcode_unit_name())); - if (fn == NULL) + if (fn == NULL) { fn = LLVMAddFunction(module, istr(vcode_unit_name()), cgen_subprogram_type(display_type, false)); + LLVMSetDLLStorageClass(fn, LLVMDLLExportStorageClass); + } cgen_add_func_attr(fn, FUNC_ATTR_NOUNWIND); @@ -3106,6 +3108,7 @@ static void cgen_process(vcode_unit_t code) LLVMTypeRef ftype = LLVMFunctionType(LLVMVoidType(), pargs, 1, false); LLVMValueRef fn = LLVMAddFunction(module, istr(vcode_unit_name()), ftype); cgen_add_func_attr(fn, FUNC_ATTR_NOUNWIND); + LLVMSetDLLStorageClass(fn, LLVMDLLExportStorageClass); LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock(fn, "entry"); LLVMBasicBlockRef reset_bb = LLVMAppendBasicBlock(fn, "reset"); @@ -3196,6 +3199,7 @@ static void cgen_reset_function(tree_t top) LLVMValueRef fn = LLVMAddFunction(module, name, LLVMFunctionType(LLVMVoidType(), NULL, 0, false)); + LLVMSetDLLStorageClass(fn, LLVMDLLExportStorageClass); LLVMBasicBlockRef init_bb = NULL; @@ -3775,6 +3779,8 @@ static void cgen_native(tree_t top) char *imparg LOCAL = xasprintf("-Wl,--out-implib=%s", imp_path); APPEND_ARG(imparg); + APPEND_ARG(xasprintf("-L%s", lib_path(lib_work()))); + const int ncontext = tree_contexts(top); for (int i = 0; i < ncontext; i++) { tree_t c = tree_context(top, i); @@ -3789,10 +3795,17 @@ static void cgen_native(tree_t top) lib_realpath(lib, imp_name, import_imp, PATH_MAX); if (access(import_imp, F_OK) == 0) { - APPEND_ARG(xasprintf("-L%s", lib_path(lib))); + if (lib != lib_work()) + APPEND_ARG(xasprintf("-L%s", lib_path(lib))); APPEND_ARG(xasprintf("-l_%s", istr(unit_name))); } } + + if (tree_kind(top) == T_PACK_BODY) { + tree_t pack = lib_get(lib_work(), ident_until(tree_ident(top), '-')); + if (pack_needs_cgen(pack)) + APPEND_ARG(xasprintf("-l_%s", istr(tree_ident(pack)))); + } #endif const char *obj = getenv("NVC_FOREIGN_OBJ"); diff --git a/src/rt/jit.c b/src/rt/jit.c index 46752c76..c86e4c5f 100644 --- a/src/rt/jit.c +++ b/src/rt/jit.c @@ -64,6 +64,10 @@ extern void ___chkstk_ms(void); #undef _alloca extern void _alloca(void); #endif + +static HMODULE *search_modules; +static size_t nmodules = 0, max_modules = 0; + #endif static void *jit_search_loaded_syms(const char *name, bool required) @@ -74,7 +78,6 @@ static void *jit_search_loaded_syms(const char *name, bool required) #endif #ifdef __MINGW32__ - const char *search_modules[] = { NULL, "MSVCRT.DLL" }; #ifdef _WIN64 if (strcmp(name, "___chkstk_ms") == 0) @@ -87,15 +90,17 @@ static void *jit_search_loaded_syms(const char *name, bool required) if (strcmp(name, "exp2") == 0) return (void *)(uintptr_t)exp2; - for (size_t i = 0; i < ARRAY_LEN(search_modules); i++) { - HMODULE hmodule = GetModuleHandle(search_modules[i]); - void *ptr = (void *)(uintptr_t)GetProcAddress(hmodule, name); + for (size_t i = 0; i < nmodules; i++) { + void *ptr = (void *)(uintptr_t)GetProcAddress(search_modules[i], name); if (ptr != NULL) return ptr; } + if (required) + fatal("cannot find symbol %s", name); + return NULL; -#else + dlerror(); // Clear any previous error void *sym = dlsym(NULL, name); @@ -269,8 +274,16 @@ static void jit_load_module(ident_t name, LLVMModuleRef module) #endif } else { +#ifdef __MINGW32__ + HMODULE hModule = LoadLibrary(so_path); + if (hModule == NULL) + fatal("failed to load %s", so_path); + + ARRAY_APPEND(search_modules, hModule, nmodules, max_modules); +#else if (dlopen(so_path, RTLD_LAZY | RTLD_GLOBAL) == NULL) fatal("%s: %s", so_path, dlerror()); +#endif // Free LLVM module as we no longer need it LLVMDisposeModule(module); @@ -279,6 +292,15 @@ static void jit_load_module(ident_t name, LLVMModuleRef module) void jit_init(tree_t top) { +#ifdef __MINGW32__ + max_modules = 16; + nmodules = 0; + search_modules = xmalloc(sizeof(HMODULE) * max_modules); + ARRAY_APPEND(search_modules, GetModuleHandle(NULL), nmodules, max_modules); + ARRAY_APPEND(search_modules, GetModuleHandle("MSVCRT.DLL"), + nmodules, max_modules); +#endif + const int ncontext = tree_contexts(top); for (int i = 0; i < ncontext; i++) { tree_t c = tree_context(top, i); -- 2.39.2