From f1e4a288fa16ec23ad70d1af9824f38726f4c5d9 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Mon, 27 May 2024 13:07:11 -0300 Subject: [PATCH] Set storage class of julia globals to dllimport on windows to avoid auto-import weirdness. Also make the compiler error instead of emitting pseudo-relocations when encountering a reference to a non-exported symbol in a dll. Co-authored-by: Keno Fischer Co-authored-by: Cody Tapscott <84105208+topolarity@users.noreply.github.com> --- Make.inc | 2 +- base/linking.jl | 2 +- cli/Makefile | 3 +-- src/aotcompile.cpp | 18 +++++++++++------- src/codegen.cpp | 8 ++++---- src/staticdata.c | 6 +++--- sysimage.mk | 2 +- 7 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Make.inc b/Make.inc index 021508e620cd1..85ef1efded2f9 100644 --- a/Make.inc +++ b/Make.inc @@ -1365,7 +1365,7 @@ ifeq ($(OS), WINNT) HAVE_SSP := 1 OSLIBS += -Wl,--export-all-symbols -Wl,--version-script=$(BUILDROOT)/src/julia.expmap \ $(NO_WHOLE_ARCHIVE) -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -luserenv -lsecur32 -latomic -JLDFLAGS += -Wl,--stack,8388608 +JLDFLAGS += -Wl,--stack,8388608 --disable-auto-import --disable-runtime-pseudo-reloc ifeq ($(ARCH),i686) JLDFLAGS += -Wl,--large-address-aware endif diff --git a/base/linking.jl b/base/linking.jl index 2d68ea730c0fb..4bf0198962346 100644 --- a/base/linking.jl +++ b/base/linking.jl @@ -110,7 +110,7 @@ function ld() # LLD supports mingw style linking flavor = "gnu" m = Sys.ARCH == :x86_64 ? "i386pep" : "i386pe" - default_args = `-m $m -Bdynamic --enable-auto-image-base --allow-multiple-definition` + default_args = `-m $m -Bdynamic --enable-auto-image-base --allow-multiple-definition --disable-auto-import --disable-runtime-pseudo-reloc` elseif Sys.isapple() flavor = "darwin" arch = Sys.ARCH == :aarch64 ? :arm64 : Sys.ARCH diff --git a/cli/Makefile b/cli/Makefile index 911e8ff54e246..e269e9205f496 100644 --- a/cli/Makefile +++ b/cli/Makefile @@ -17,8 +17,7 @@ LOADER_CFLAGS += -DGLIBCXX_LEAST_VERSION_SYMBOL=\"$(shell echo "$(CSL_NEXT_GLIBC endif ifeq ($(OS),WINNT) -LOADER_LDFLAGS += -municode -mconsole -nostdlib --disable-auto-import \ - --disable-runtime-pseudo-reloc -lntdll -lkernel32 -lpsapi +LOADER_LDFLAGS += -municode -mconsole -nostdlib -lntdll -lkernel32 -lpsapi else ifeq ($(OS),Linux) LOADER_LDFLAGS += -Wl,--no-as-needed -ldl -lpthread -rdynamic -lc -Wl,--as-needed else ifeq ($(OS),FreeBSD) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index e2a2fb20b419f..7b3d80061413b 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -1166,6 +1166,8 @@ static void materializePreserved(Module &M, Partition &partition) { GV.setInitializer(nullptr); GV.setLinkage(GlobalValue::ExternalLinkage); GV.setVisibility(GlobalValue::HiddenVisibility); + if (GV.getDLLStorageClass() != GlobalValue::DLLStorageClassTypes::DefaultStorageClass) + continue; // Don't mess with exported or imported globals GV.setDSOLocal(true); } @@ -1645,6 +1647,7 @@ void jl_dump_native_impl(void *native_code, if (jl_small_typeof_copy) { jl_small_typeof_copy->setVisibility(GlobalValue::HiddenVisibility); jl_small_typeof_copy->setDSOLocal(true); + jl_small_typeof_copy->setDLLStorageClass(GlobalValue::DLLStorageClassTypes::DefaultStorageClass); } } @@ -1673,16 +1676,17 @@ void jl_dump_native_impl(void *native_code, // reflect the address of the jl_RTLD_DEFAULT_handle variable // back to the caller, so that we can check for consistency issues GlobalValue *jlRTLD_DEFAULT_var = jl_emit_RTLD_DEFAULT_var(&metadataM); - addComdat(new GlobalVariable(metadataM, - jlRTLD_DEFAULT_var->getType(), - true, - GlobalVariable::ExternalLinkage, - jlRTLD_DEFAULT_var, - "jl_RTLD_DEFAULT_handle_pointer"), TheTriple); - Type *T_size = DL.getIntPtrType(Context); Type *T_psize = T_size->getPointerTo(); + auto FT = FunctionType::get(Type::getInt8Ty(Context)->getPointerTo()->getPointerTo(), {}, false); + auto F = Function::Create(FT, Function::ExternalLinkage, "get_jl_RTLD_DEFAULT_handle_addr", metadataM); + llvm::IRBuilder<> builder(BasicBlock::Create(Context, "top", F)); + builder.CreateRet(jlRTLD_DEFAULT_var); + F->setLinkage(GlobalValue::ExternalLinkage); + if (TheTriple.isOSBinFormatCOFF()) + F->setDLLStorageClass(GlobalValue::DLLStorageClassTypes::DLLExportStorageClass); + if (TheTriple.isOSWindows()) { // Windows expect that the function `_DllMainStartup` is present in an dll. // Normal compilers use something like Zig's crtdll.c instead we provide a diff --git a/src/codegen.cpp b/src/codegen.cpp index dd3376c334a37..4019f6d7e32d1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -493,9 +493,12 @@ struct JuliaVariable { if (GlobalValue *V = m->getNamedValue(name)) return cast(V); auto T_size = m->getDataLayout().getIntPtrType(m->getContext()); - return new GlobalVariable(*m, _type(T_size), + auto var = new GlobalVariable(*m, _type(T_size), isconst, GlobalVariable::ExternalLinkage, NULL, name); + if (Triple(m->getTargetTriple()).isOSWindows()) + var->setDLLStorageClass(GlobalValue::DLLStorageClassTypes::DLLImportStorageClass); // Cross-library imports must be explicit for COFF (Windows) + return var; } GlobalVariable *realize(jl_codectx_t &ctx); }; @@ -1786,9 +1789,6 @@ static inline GlobalVariable *prepare_global_in(Module *M, GlobalVariable *G) G->isConstant(), GlobalVariable::ExternalLinkage, nullptr, G->getName(), nullptr, G->getThreadLocalMode()); proto->copyAttributesFrom(G); - // DLLImport only needs to be set for the shadow module - // it just gets annoying in the JIT - proto->setDLLStorageClass(GlobalValue::DefaultStorageClass); return proto; } return cast(local); diff --git a/src/staticdata.c b/src/staticdata.c index c130c2e7569fe..a55342604f21d 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -2838,9 +2838,9 @@ JL_DLLEXPORT void jl_preload_sysimg_so(const char *fname) // Allow passing in a module handle directly, rather than a path JL_DLLEXPORT void jl_set_sysimg_so(void *handle) { - void* *jl_RTLD_DEFAULT_handle_pointer; - int symbol_found = jl_dlsym(handle, "jl_RTLD_DEFAULT_handle_pointer", (void **)&jl_RTLD_DEFAULT_handle_pointer, 0); - if (!symbol_found || (void*)&jl_RTLD_DEFAULT_handle != *jl_RTLD_DEFAULT_handle_pointer) + void** (*get_jl_RTLD_DEFAULT_handle_addr)(void) = NULL; + int symbol_found = jl_dlsym(handle, "get_jl_RTLD_DEFAULT_handle_addr", (void **)&get_jl_RTLD_DEFAULT_handle_addr, 0); + if (!symbol_found || (void*)&jl_RTLD_DEFAULT_handle != (get_jl_RTLD_DEFAULT_handle_addr())) jl_error("System image file failed consistency check: maybe opened the wrong version?"); if (jl_options.cpu_target == NULL) jl_options.cpu_target = "native"; diff --git a/sysimage.mk b/sysimage.mk index 993ee9a990058..0d2c9aff126e4 100644 --- a/sysimage.mk +++ b/sysimage.mk @@ -16,7 +16,7 @@ $(build_private_libdir)/%.$(SHLIB_EXT): $(build_private_libdir)/%-o.a @$(call PRINT_LINK, $(CXX) $(LDFLAGS) -shared $(fPIC) -L$(build_private_libdir) -L$(build_libdir) -L$(build_shlibdir) -o $@ \ $(WHOLE_ARCHIVE) $< $(NO_WHOLE_ARCHIVE) \ $(if $(findstring -debug,$(notdir $@)),-ljulia-internal-debug -ljulia-debug,-ljulia-internal -ljulia) \ - $$([ $(OS) = WINNT ] && echo '' -lssp)) + $$([ $(OS) = WINNT ] && echo '' -lssp --disable-auto-import --disable-runtime-pseudo-reloc)) @$(INSTALL_NAME_CMD)$(notdir $@) $@ @$(DSYMUTIL) $@