Skip to content

Commit

Permalink
unbreak win64 COPY_STACK
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Dec 14, 2014
1 parent 502e5fd commit 5cff519
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 38 deletions.
2 changes: 1 addition & 1 deletion Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ endif
ifeq ($(OS), WINNT)
ifneq ($(USEMSVC), 1)
OSLIBS += -Wl,--export-all-symbols -Wl,--version-script=$(JULIAHOME)/src/julia.expmap \
$(NO_WHOLE_ARCHIVE) -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -lssp
$(NO_WHOLE_ARCHIVE) -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp
JLDFLAGS = -Wl,--stack,8388608
ifeq ($(ARCH),i686)
JLDFLAGS += -Wl,--large-address-aware
Expand Down
6 changes: 3 additions & 3 deletions doc/manual/embedding.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ We start with a simple C program that initializes Julia and calls some Julia cod
int main(int argc, char *argv[])
{
/* optional: randomize the stack guard */
char a, b, c;
SET_STACK_CHK_GUARD(a,b,c);
char a=255, b='\n', c=0;
SWAP_STACK_CHK_GUARD(a,b,c);

/* required: setup the julia context */
jl_init(NULL);
Expand All @@ -36,7 +36,7 @@ We start with a simple C program that initializes Julia and calls some Julia cod
jl_atexit_hook();

/* if the stack guard is set: reset the stack guard */
CLR_STACK_CHK_GUARD(a,b,c);
SWAP_STACK_CHK_GUARD(a,b,c);
return 0;
}

Expand Down
3 changes: 0 additions & 3 deletions examples/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
JULIAHOME = $(abspath ..)
include $(JULIAHOME)/Make.inc

override CFLAGS += $(JCFLAGS)
override CXXFLAGS += $(JCXXFLAGS)

FLAGS = -Wall -Wno-strict-aliasing -fno-omit-frame-pointer \
-I$(JULIAHOME)/src -I$(JULIAHOME)/src/support -I$(build_includedir) $(CFLAGS)

Expand Down
11 changes: 6 additions & 5 deletions examples/embedding.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ double my_c_sqrt(double x)

int main()
{
char a, b, c;
SET_STACK_CHK_GUARD(a,b,c);
char a=255, b='\n', c=0;
SWAP_STACK_CHK_GUARD(a,b,c);
jl_init(NULL);

{
Expand Down Expand Up @@ -52,14 +52,15 @@ int main()

double* xData = jl_array_data(x);

for(size_t i=0; i<jl_array_len(x); i++)
size_t i;
for(i=0; i<jl_array_len(x); i++)
xData[i] = i;

jl_function_t *func = jl_get_function(jl_base_module, "reverse!");
jl_call1(func, (jl_value_t*) x);

printf("x = [");
for(size_t i=0; i<jl_array_len(x); i++)
for(i=0; i<jl_array_len(x); i++)
printf("%e ", xData[i]);
printf("]\n");

Expand Down Expand Up @@ -96,6 +97,6 @@ int main()
}

jl_atexit_hook();
CLR_STACK_CHK_GUARD(a,b,c);
SWAP_STACK_CHK_GUARD(a,b,c);
return 0;
}
5 changes: 2 additions & 3 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ extern "C" {

#include "builtin_proto.h"

DLLEXPORT void *__stack_chk_guard = NULL;

extern void *__stack_chk_guard;
#if defined(_OS_WINDOWS_) && !defined(_COMPILER_MINGW_)
void __stack_chk_fail()
#else
Expand Down Expand Up @@ -4359,7 +4358,7 @@ static void init_julia_llvm_env(Module *m)
Function::Create(FunctionType::get(T_void, false),
Function::ExternalLinkage,
"__stack_chk_fail", m);
//jl__stack_chk_fail->setDoesNotReturn();
jl__stack_chk_fail->setDoesNotReturn();
add_named_global(jl__stack_chk_fail, (void*)&__stack_chk_fail);

jltrue_var = global_to_llvm("jl_true", (void*)&jl_true, m);
Expand Down
4 changes: 4 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ jl_compileropts_t jl_compileropts = { NULL, // julia_home
int jl_boot_file_loaded = 0;
int exit_on_sigint = 0;

void *__stack_chk_guard = NULL;
DLLEXPORT unsigned char *jl_stack_chk_guard =
(unsigned char *)&__stack_chk_guard;

char *jl_stack_lo;
char *jl_stack_hi;
size_t jl_page_size;
Expand Down
33 changes: 15 additions & 18 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1347,24 +1347,21 @@ extern DLLEXPORT jl_compileropts_t jl_compileropts;
#define JL_COMPILEROPT_DUMPBITCODE_ON 1
#define JL_COMPILEROPT_DUMPBITCODE_OFF 2

DLLEXPORT extern void *__stack_chk_guard;
#define SET_STACK_CHK_GUARD(a,b,c) do { \
unsigned char *p = (unsigned char *)&__stack_chk_guard; \
a = p[sizeof(__stack_chk_guard)-1]; \
b = p[sizeof(__stack_chk_guard)-2]; \
c = p[0]; \
/* If you have the ability to generate random numbers
* in your kernel then they should be used here */ \
p[sizeof(__stack_chk_guard)-1] = 255; \
p[sizeof(__stack_chk_guard)-2] = '\n'; \
p[0] = 0; \
} while (0)

#define CLR_STACK_CHK_GUARD(a,b,c) do { \
unsigned char *p = (unsigned char *)&__stack_chk_guard; \
p[sizeof(__stack_chk_guard)-1] = a; \
p[sizeof(__stack_chk_guard)-2] = b; \
p[0] = c; \
/* If you have the ability to generate random numbers
* in your kernel then they should be used here */
DLLEXPORT extern unsigned char *jl_stack_chk_guard;
#define SWAP_STACK_CHK_GUARD(a,b,c) do { \
a ^= jl_stack_chk_guard[sizeof(void*)-1]; \
jl_stack_chk_guard[sizeof(void*)-1] ^= a; \
a ^= jl_stack_chk_guard[sizeof(void*)-1]; \
\
b ^= jl_stack_chk_guard[sizeof(void*)-2]; \
jl_stack_chk_guard[sizeof(void*)-2] ^= b; \
b ^= jl_stack_chk_guard[sizeof(void*)-2]; \
\
c ^= jl_stack_chk_guard[0]; \
jl_stack_chk_guard[0] ^= c; \
c ^= jl_stack_chk_guard[0]; \
} while (0)

#ifdef __cplusplus
Expand Down
8 changes: 6 additions & 2 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,20 +341,24 @@ static void ctx_switch(jl_task_t *t, jl_jmp_buf *where)
restore_stack(t, where, NULL);
} else {
#ifdef ASM_COPY_STACKS
void *stackbase = jl_stackbase - 0x10;
#ifdef _CPU_X86_64_
#ifdef _OS_WINDOWS_
stackbase -= 0x20;
#endif
asm(" movq %0, %%rsp;\n"
" xorq %%rbp, %%rbp;\n"
" push %%rbp;\n" // instead of RSP
" jmp %P1;\n" // call stack_task with fake stack frame
" ud2"
: : "r"(jl_stackbase-0x10), "i"(start_task) : "memory" );
: : "r"(stackbase), "i"(start_task) : "memory" );
#elif defined(_CPU_X86_)
asm(" movl %0, %%esp;\n"
" xorl %%ebp, %%ebp;\n"
" push %%ebp;\n" // instead of ESP
" jmp %P1;\n" // call stack_task with fake stack frame
" ud2"
: : "r"(jl_stackbase-0x10), "i"(start_task) : "memory" );
: : "r"(stackbase), "i"(start_task) : "memory" );
#else
#error ASM_COPY_STACKS not supported on this cpu architecture
#endif
Expand Down
6 changes: 3 additions & 3 deletions ui/repl.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ int wmain(int argc, wchar_t *argv[], wchar_t *envp[])
argv[i] = (wchar_t*)arg;
}
#endif
char a,b,c;
SET_STACK_CHK_GUARD(a,b,c);
char a=255,b='\n',c=0;
SWAP_STACK_CHK_GUARD(a,b,c);
libsupport_init();
parse_opts(&argc, (char***)&argv);
if (lisp_prompt) {
Expand All @@ -342,7 +342,7 @@ int wmain(int argc, wchar_t *argv[], wchar_t *envp[])
int ret = true_main(argc, (char**)argv);
jl_atexit_hook();
julia_save();
CLR_STACK_CHK_GUARD(a,b,c);
SWAP_STACK_CHK_GUARD(a,b,c);
return ret;
}

Expand Down

5 comments on commit 5cff519

@tkelman
Copy link
Contributor

Choose a reason for hiding this comment

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

Not quite. Now dies during the numbers test, and julia-debug.exe is still failing to link.

@vtjnash
Copy link
Member Author

Choose a reason for hiding this comment

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

i don't have a llvm33 build to test with. i didn't realize the numbers test would depend on any of this. can you try increasing the stack offset slight more (increase in increments of 16 / 0x10)?

i could take gcc's approach in ssp.c and do this stack-smashing protector in a constructor. it would be even more preferable to get gcc to stop trying to link in it's own libssp. however, I don't understand all of the interactions here

@vtjnash
Copy link
Member Author

Choose a reason for hiding this comment

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

annoyingly, this code is different everywhere. clang gets it completely right (all this code is redundant, but the linker doesn't care and does the right thing). gcc doesn't defined it at all on ubuntu, so we need to handle everything. gcc defines it on mingw, but only mediocre, so ???

@vtjnash
Copy link
Member Author

Choose a reason for hiding this comment

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

scratch that. the issue with ubuntu is that they build their gcc without support for the stack-smashing protector, and then we're trying to turn it on, which is invalid

@tkelman
Copy link
Contributor

Choose a reason for hiding this comment

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

however, I don't understand all of the interactions here

Yeah neither do I. Still failing the parallel tests on win64, I'll see if I can figure anything out. Did this stack management change really need to be tied into the same PR as cleaning up the initialization? Seems at least partly orthogonal.

Please sign in to comment.