Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix symbol trampolines for OSX and export jl_n_threads #38938

Merged
merged 10 commits into from
Dec 24, 2020
6 changes: 5 additions & 1 deletion cli/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ $(BUILDDIR)/loader_exe.o : $(SRCDIR)/loader_exe.c $(HEADERS)
$(BUILDDIR)/loader_exe.dbg.obj : $(SRCDIR)/loader_exe.c $(HEADERS)
@$(call PRINT_CC, $(CC) $(DEBUGFLAGS) $(LOADER_CFLAGS) -c $< -o $@)
$(BUILDDIR)/loader_trampolines.o : $(SRCDIR)/trampolines/trampolines_$(ARCH).S
@$(call PRINT_CC, $(CC) $(DEBUGFLAGS) $(LOADER_CFLAGS) $< -c -o $@)
@$(call PRINT_CC, $(CC) $(SHIPFLAGS) $(LOADER_CFLAGS) $< -c -o $@)

# Debugging target to help us see what kind of code is being generated for our trampolines
dump-trampolines: $(SRCDIR)/trampolines/trampolines_$(ARCH).S
$(CC) $(SHIPFLAGS) $(LOADER_CFLAGS) $< -S | sed -E 's/ ((%%)|;) /\n/g' | sed -E 's/.global/\n.global/g'

DIRS = $(build_bindir) $(build_libdir)
$(DIRS):
Expand Down
9 changes: 7 additions & 2 deletions cli/jl_exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@
#include "../src/jl_exported_data.inc"
#include "../src/jl_exported_funcs.inc"

// Define data symbols as `const void * $(name);`
// Define pointer data as `const void * $(name);`
#define XX(name) JL_DLLEXPORT const void * name;
JL_EXPORTED_DATA(XX)
JL_EXPORTED_DATA_POINTERS(XX)
#undef XX

// Define symbol data as `$type) $(name);`
#define XX(name, type) JL_DLLEXPORT type name;
JL_EXPORTED_DATA_SYMBOLS(XX)
#undef XX

// Define holder locations for function addresses as `const void * $(name)_addr`
Expand Down
29 changes: 22 additions & 7 deletions cli/trampolines/trampolines_aarch64.S
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
#include "../../src/jl_exported_funcs.inc"

// On macOS, we need to prepend underscores on symbols
#if defined(__APPLE__) && defined(__MACH__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When were you running 9.x Classic MacOS userpace, and not using the mach kernel???

#define CNAME(x) _##x
#define PAGE(x) x##@PAGE
#define PAGEOFF(x) x##@PAGEOFF
#define SEP %%
#else
#define CNAME(x) x
#define PAGE(x) x
#define PAGEOFF(x) #:lo12:##x
#define SEP ;
#endif

#define XX(name) \
.global name; \
.cfi_startproc; \
name##:; \
adrp x0, name##_addr; \
ldr x0, [x0, #:lo12:name##_addr]; \
br x0; \
.cfi_endproc; \
.global CNAME(name) SEP \
.cfi_startproc SEP \
.p2align 2 SEP \
CNAME(name)##: SEP \
adrp x16, PAGE(CNAME(name##_addr)) SEP \
ldr x16, [x16, PAGEOFF(CNAME(name##_addr))] SEP \
br x16 SEP \
.cfi_endproc SEP \

JL_EXPORTED_FUNCS(XX)
#undef XX
4 changes: 2 additions & 2 deletions cli/trampolines/trampolines_i686.S
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@

#define XX(name) \
DEBUGINFO(name); \
.global name; \
.global CNAME(name); \
.cfi_startproc; \
name##:; \
CNAME(name)##:; \
CET_START(); \
jmpl *(CNAME(name##_addr)); \
ud2; \
Expand Down
4 changes: 2 additions & 2 deletions cli/trampolines/trampolines_x86_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@

#define XX(name) \
DEBUGINFO(name); \
.global name; \
.global CNAME(name); \
.cfi_startproc; \
SEH_START1(name); \
name##:; \
CNAME(name)##:; \
SEH_START2(); \
CET_START(); \
mov CNAME(name##_addr)(%rip),%r11; \
Expand Down
6 changes: 3 additions & 3 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ static bool runtime_sym_gvs(jl_codegen_params_t &emission_context, const char *f
GlobalVariable *libptrgv;
jl_codegen_params_t::SymMapGV *symMap;
#ifdef _OS_WINDOWS_
if ((intptr_t)f_lib == 1) {
if ((intptr_t)f_lib == (intptr_t)JL_EXE_LIBNAME) {
libptrgv = prepare_global_in(M, jlexe_var);
symMap = &emission_context.symMapExe;
}
else if ((intptr_t)f_lib == 2) {
else if ((intptr_t)f_lib == (intptr_t)JL_LIBJULIA_INTERNAL_DL_LIBNAME) {
libptrgv = prepare_global_in(M, jldll_var);
symMap = &emission_context.symMapDl;
}
Expand Down Expand Up @@ -1266,7 +1266,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
auto _is_libjulia_func = [&] (uintptr_t ptr, const char *name) {
if ((uintptr_t)fptr == ptr)
return true;
return (!f_lib || f_lib == JL_DL_LIBNAME) && f_name && !strcmp(f_name, name);
return (!f_lib || f_lib == JL_LIBJULIA_INTERNAL_DL_LIBNAME) && f_name && !strcmp(f_name, name);
};
#define is_libjulia_func(name) _is_libjulia_func((uintptr_t)&(name), #name)

Expand Down
4 changes: 2 additions & 2 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ static const auto jlexe_var = new JuliaVariable{
[](LLVMContext &C) { return T_pint8; },
};
static const auto jldll_var = new JuliaVariable{
"jl_dl_handle",
"jl_libjulia_internal_handle",
true,
[](LLVMContext &C) { return T_pint8; },
};
Expand Down Expand Up @@ -7531,7 +7531,7 @@ static void init_jit_functions(void)
add_named_global(jlRTLD_DEFAULT_var, &jl_RTLD_DEFAULT_handle);
#ifdef _OS_WINDOWS_
add_named_global(jlexe_var, &jl_exe_handle);
add_named_global(jldll_var, &jl_dl_handle);
add_named_global(jldll_var, &jl_libjulia_internal_handle);
#endif
global_jlvalue_to_llvm(new JuliaVariable{"jl_true", true, get_pjlvalue}, &jl_true);
global_jlvalue_to_llvm(new JuliaVariable{"jl_false", true, get_pjlvalue}, &jl_false);
Expand Down
10 changes: 6 additions & 4 deletions src/dlload.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,10 @@ const char *jl_dlfind_win32(const char *f_name)
void * dummy;
if (jl_dlsym(jl_exe_handle, f_name, &dummy, 0))
return JL_EXE_LIBNAME;
if (jl_dlsym(jl_dl_handle, f_name, &dummy, 0))
return JL_DL_LIBNAME;
if (jl_dlsym(jl_libjulia_internal_handle, f_name, &dummy, 0))
return JL_LIBJULIA_INTERNAL_DL_LIBNAME;
if (jl_dlsym(jl_libjulia_handle, f_name, &dummy, 0))
return JL_LIBJULIA_DL_LIBNAME;
if (jl_dlsym(jl_kernel32_handle, f_name, &dummy, 0))
return "kernel32";
if (jl_dlsym(jl_ntdll_handle, f_name, &dummy, 0))
Expand All @@ -334,8 +336,8 @@ const char *jl_dlfind_win32(const char *f_name)
// explicit is preferred over implicit
return NULL;
// oops, we didn't find it. NULL defaults to searching jl_RTLD_DEFAULT_handle,
// which defaults to jl_dl_handle, where we won't find it, and will throw the
// appropriate error.
// which defaults to jl_libjulia_internal_handle, where we won't find it, and
// will throw the appropriate error.
}
#endif

Expand Down
8 changes: 6 additions & 2 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,8 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode)

static void post_boot_hooks(void);

JL_DLLEXPORT void *jl_dl_handle;
JL_DLLEXPORT void *jl_libjulia_internal_handle;
JL_DLLEXPORT void *jl_libjulia_handle;
void *jl_RTLD_DEFAULT_handle;
JL_DLLEXPORT void *jl_exe_handle;
#ifdef _OS_WINDOWS_
Expand Down Expand Up @@ -657,7 +658,10 @@ void _julia_init(JL_IMAGE_SEARCH rel)
jl_prep_sanitizers();
void *stack_lo, *stack_hi;
jl_init_stack_limits(1, &stack_lo, &stack_hi);
jl_dl_handle = jl_load_dynamic_library(NULL, JL_RTLD_DEFAULT, 1);

// Load libjulia-internal (which contains this function), and libjulia, explicitly.
jl_libjulia_internal_handle = jl_load_dynamic_library(NULL, JL_RTLD_DEFAULT, 1);
jl_libjulia_handle = jl_load_dynamic_library(JL_LIBJULIA_DL_LIBNAME, JL_RTLD_DEFAULT, 1);
#ifdef _OS_WINDOWS_
jl_ntdll_handle = jl_dlopen("ntdll.dll", 0); // bypass julia's pathchecking for system dlls
jl_kernel32_handle = jl_dlopen("kernel32.dll", 0);
Expand Down
8 changes: 7 additions & 1 deletion src/jl_exported_data.inc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#define JL_EXPORTED_DATA(XX) \
// Pointers that are exposed through the public libjulia
#define JL_EXPORTED_DATA_POINTERS(XX) \
XX(jl_abstractarray_type) \
XX(jl_abstractslot_type) \
XX(jl_abstractstring_type) \
Expand Down Expand Up @@ -115,3 +116,8 @@
XX(jl_void_type) \
XX(jl_voidpointer_type) \
XX(jl_weakref_type)


// Data symbols that are defined inside the public libjulia
#define JL_EXPORTED_DATA_SYMBOLS(XX) \
XX(jl_n_threads, int)
1 change: 1 addition & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1515,6 +1515,7 @@ JL_DLLEXPORT int jl_is_debugbuild(void) JL_NOTSAFEPOINT;
JL_DLLEXPORT jl_sym_t *jl_get_UNAME(void) JL_NOTSAFEPOINT;
JL_DLLEXPORT jl_sym_t *jl_get_ARCH(void) JL_NOTSAFEPOINT;
JL_DLLEXPORT jl_value_t *jl_get_libllvm(void) JL_NOTSAFEPOINT;
extern JL_DLLIMPORT int jl_n_threads;

// environment entries
JL_DLLEXPORT jl_value_t *jl_environ(int i);
Expand Down
12 changes: 9 additions & 3 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,8 @@ STATIC_INLINE uint64_t cong(uint64_t max, uint64_t unbias, uint64_t *seed)
}

// libuv stuff:
JL_DLLEXPORT extern void *jl_dl_handle;
JL_DLLEXPORT extern void *jl_libjulia_handle;
JL_DLLEXPORT extern void *jl_libjulia_internal_handle;
JL_DLLEXPORT extern void *jl_RTLD_DEFAULT_handle;
#if defined(_OS_WINDOWS_)
JL_DLLEXPORT extern void *jl_exe_handle;
Expand All @@ -1012,8 +1013,13 @@ JL_DLLEXPORT jl_value_t *jl_get_cfunction_trampoline(


// Windows only
#define JL_EXE_LIBNAME ((const char*)1)
#define JL_DL_LIBNAME ((const char*)2)
#define JL_EXE_LIBNAME ((const char*)1)
#define JL_LIBJULIA_INTERNAL_DL_LIBNAME ((const char*)2)
#if defined(JL_DEBUG_BUILD)
#define JL_LIBJULIA_DL_LIBNAME "libjulia-debug"
#else
#define JL_LIBJULIA_DL_LIBNAME "libjulia"
#endif
const char *jl_dlfind_win32(const char *name);

// libuv wrappers:
Expand Down
6 changes: 4 additions & 2 deletions src/runtime_ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ void *jl_get_library_(const char *f_lib, int throw_err) JL_NOTSAFEPOINT
#ifdef _OS_WINDOWS_
if (f_lib == JL_EXE_LIBNAME)
return jl_exe_handle;
if (f_lib == JL_DL_LIBNAME)
return jl_dl_handle;
if (f_lib == JL_LIBJULIA_INTERNAL_DL_LIBNAME)
return jl_libjulia_internal_handle;
if (f_lib == JL_LIBJULIA_DL_LIBNAME)
return jl_libjulia_handle;
#endif
if (f_lib == NULL)
return jl_RTLD_DEFAULT_handle;
Expand Down
1 change: 0 additions & 1 deletion src/threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ jl_get_ptls_states_func jl_get_ptls_states_getter(void)
}
#endif

JL_DLLEXPORT int jl_n_threads;
jl_ptls_t *jl_all_tls_states JL_GLOBALLY_ROOTED;

// return calling thread's ID
Expand Down
1 change: 0 additions & 1 deletion src/threading.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ extern "C" {
#define PROFILE_JL_THREADING 0

extern jl_ptls_t *jl_all_tls_states JL_GLOBALLY_ROOTED; /* thread local storage */
extern JL_DLLEXPORT int jl_n_threads; /* # threads we're actually using */

typedef struct _jl_threadarg_t {
int16_t tid;
Expand Down