diff --git a/src/Makefile b/src/Makefile index 88b1e303cb329..f18cfa2a774c3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -153,7 +153,7 @@ endif CLANG_LDFLAGS := $(LLVM_LDFLAGS) ifeq ($(OS), Darwin) CLANG_LDFLAGS += -Wl,-undefined,dynamic_lookup -OSLIBS += -Wl,-U,__dyld_atfork_parent -Wl,-U,__dyld_atfork_prepare -Wl,-U,__dyld_dlopen_atfork_parent -Wl,-U,__dyld_dlopen_atfork_prepare +OSLIBS += -Wl,-U,__dyld_atfork_parent -Wl,-U,__dyld_atfork_prepare -Wl,-U,__dyld_dlopen_atfork_parent -Wl,-U,__dyld_dlopen_atfork_prepare -Wl,-U,_jl_image_pointers -Wl,-U,_jl_system_image_data -Wl,-U,_jl_system_image_size LIBJULIA_PATH_REL := @rpath/libjulia else LIBJULIA_PATH_REL := libjulia diff --git a/src/init.c b/src/init.c index 424cfef2a34bb..a046b4e6dcb21 100644 --- a/src/init.c +++ b/src/init.c @@ -620,7 +620,8 @@ static const char *absformat(const char *in) } static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel) -{ // this function resolves the paths in jl_options to absolute file locations as needed +{ + // this function resolves the paths in jl_options to absolute file locations as needed // and it replaces the pointers to `julia_bindir`, `julia_bin`, `image_file`, and output file paths // it may fail, print an error, and exit(1) if any of these paths are longer than JL_PATH_MAX // @@ -841,7 +842,9 @@ static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_ JL_TIMING(JULIA_INIT, JULIA_INIT); jl_resolve_sysimg_location(rel); // loads sysimg if available, and conditionally sets jl_options.cpu_target - if (jl_options.image_file) + if (rel == JL_IMAGE_IN_MEMORY) + jl_set_sysimg_so(jl_exe_handle); + else if (jl_options.image_file) jl_preload_sysimg_so(jl_options.image_file); if (jl_options.cpu_target == NULL) jl_options.cpu_target = "native"; diff --git a/src/julia.h b/src/julia.h index d56d598248be6..5dabec5409604 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1853,7 +1853,7 @@ JL_DLLEXPORT void jl_exception_clear(void) JL_NOTSAFEPOINT; typedef enum { JL_IMAGE_CWD = 0, JL_IMAGE_JULIA_HOME = 1, - //JL_IMAGE_LIBJULIA = 2, + JL_IMAGE_IN_MEMORY = 2 } JL_IMAGE_SEARCH; JL_DLLIMPORT const char *jl_get_libdir(void); diff --git a/src/julia_internal.h b/src/julia_internal.h index e0567ec1f6cbc..b2ba10d7bd084 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -1645,6 +1645,17 @@ jl_sym_t *_jl_symbol(const char *str, size_t len) JL_NOTSAFEPOINT; #define JL_GC_ASSERT_LIVE(x) (void)(x) #endif +#ifdef _OS_WINDOWS_ +// On Windows, weak symbols do not default to 0 due to a GCC bug +// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90826), use symbol +// aliases with a known value instead. +#define JL_WEAK_SYMBOL_OR_ALIAS_DEFAULT(sym) __attribute__((weak,alias(#sym))) +#define JL_WEAK_SYMBOL_DEFAULT(sym) &sym +#else +#define JL_WEAK_SYMBOL_OR_ALIAS_DEFAULT(sym) __attribute__((weak)) +#define JL_WEAK_SYMBOL_DEFAULT(sym) NULL +#endif + JL_DLLEXPORT float julia__gnu_h2f_ieee(uint16_t param) JL_NOTSAFEPOINT; JL_DLLEXPORT uint16_t julia__gnu_f2h_ieee(float param) JL_NOTSAFEPOINT; JL_DLLEXPORT uint16_t julia__truncdfhf2(double param) JL_NOTSAFEPOINT; diff --git a/src/processor.cpp b/src/processor.cpp index 9a602ba836f89..7ea5763570a0f 100644 --- a/src/processor.cpp +++ b/src/processor.cpp @@ -618,6 +618,11 @@ static inline std::vector> &get_cmdline_targets(F &&feature_cb) return targets; } +extern "C" { +void *image_pointers_unavailable; +extern void * JL_WEAK_SYMBOL_OR_ALIAS_DEFAULT(image_pointers_unavailable) jl_image_pointers; +} + // Load sysimg, use the `callback` for dispatch and perform all relocations // for the selected target. template @@ -627,7 +632,10 @@ static inline jl_image_t parse_sysimg(void *hdl, F &&callback) jl_image_t res{}; const jl_image_pointers_t *pointers; - jl_dlsym(hdl, "jl_image_pointers", (void**)&pointers, 1); + if (hdl == jl_exe_handle && &jl_image_pointers != JL_WEAK_SYMBOL_DEFAULT(image_pointers_unavailable)) + pointers = (const jl_image_pointers_t *)&jl_image_pointers; + else + jl_dlsym(hdl, "jl_image_pointers", (void**)&pointers, 1); const void *ids = pointers->target_data; jl_value_t* rejection_reason = nullptr; diff --git a/src/staticdata.c b/src/staticdata.c index 93f0c8999c180..24ab79fde7c76 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -569,6 +569,9 @@ JL_DLLEXPORT int jl_running_on_valgrind(void) return RUNNING_ON_VALGRIND; } +void *system_image_data_unavailable; +extern void * JL_WEAK_SYMBOL_OR_ALIAS_DEFAULT(system_image_data_unavailable) jl_system_image_data; +extern void * JL_WEAK_SYMBOL_OR_ALIAS_DEFAULT(system_image_data_unavailable) jl_system_image_size; static void jl_load_sysimg_so(void) { int imaging_mode = jl_generating_output() && !jl_options.incremental; @@ -580,9 +583,17 @@ static void jl_load_sysimg_so(void) memset(&sysimage.fptrs, 0, sizeof(sysimage.fptrs)); } const char *sysimg_data; - jl_dlsym(jl_sysimg_handle, "jl_system_image_data", (void **)&sysimg_data, 1); + if (jl_sysimg_handle == jl_exe_handle && + &jl_system_image_data != JL_WEAK_SYMBOL_DEFAULT(system_image_data_unavailable)) + sysimg_data = (const char*)&jl_system_image_data; + else + jl_dlsym(jl_sysimg_handle, "jl_system_image_data", (void **)&sysimg_data, 1); size_t *plen; - jl_dlsym(jl_sysimg_handle, "jl_system_image_size", (void **)&plen, 1); + if (jl_sysimg_handle == jl_exe_handle && + &jl_system_image_size != JL_WEAK_SYMBOL_DEFAULT(system_image_data_unavailable)) + plen = (size_t *)&jl_system_image_size; + else + jl_dlsym(jl_sysimg_handle, "jl_system_image_size", (void **)&plen, 1); jl_restore_system_image_data(sysimg_data, *plen); } @@ -2820,9 +2831,11 @@ JL_DLLEXPORT void jl_preload_sysimg_so(const char *fname) 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) - jl_error("System image file failed consistency check: maybe opened the wrong version?"); + if (handle != jl_RTLD_DEFAULT_handle) { + 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) + jl_error("System image file failed consistency check: maybe opened the wrong version?"); + } if (jl_options.cpu_target == NULL) jl_options.cpu_target = "native"; jl_sysimg_handle = handle;