Parlib is no PIC-capable We needed some minor changes, mostly to uthread, to be able to build parlib with -fPIC (and as a .so). Thanks to the lack of TLS-clobbers, anytime we set_tls_desc and then access TLS variables in the same function, we need to wrap those accesses with 'begin_safe_access'. Otherwise, the compiler will cache the address of TLS variables and not discard and recompute the address after a TLS change. The other big change is that leaq needed to do PC-relative addressing. Otherwise the asm emits a _32S relocation, which fails when we make a shared library with parlib. For a nice review of relocations, check out: http://www.mindfruit.co.uk/2012/06/relocations-relocations.html
diff --git a/user/parlib/include/vcore.h b/user/parlib/include/vcore.h index daae116..0efaa7f 100644 --- a/user/parlib/include/vcore.h +++ b/user/parlib/include/vcore.h
@@ -208,12 +208,14 @@ * address of TLS variables across loads/stores of the TLS descriptor, in lieu * of a "TLS cmb()". */ #define begin_safe_access_tls_vars() \ +{ \ void __attribute__((noinline, optimize("O0"))) \ safe_access_tls_var_internal() { \ asm(""); \ #define end_safe_access_tls_vars() \ } safe_access_tls_var_internal(); \ +} #else
diff --git a/user/parlib/include/x86/vcore64.h b/user/parlib/include/x86/vcore64.h index d746392..6155d8d 100644 --- a/user/parlib/include/x86/vcore64.h +++ b/user/parlib/include/x86/vcore64.h
@@ -275,7 +275,7 @@ asm volatile ("fnstcw %0" : "=m"(sw_tf->tf_fpucw)); /* Pretty simple: save all the regs, IAW the sys-v ABI */ asm volatile("mov %%rsp, 0x48(%0); " /* save rsp in its slot*/ - "leaq 1f, %%rax; " /* get future rip */ + "leaq 1f(%%rip), %%rax; " /* get future rip */ "mov %%rax, 0x40(%0); " /* save rip in its slot*/ "mov %%r15, 0x38(%0); " "mov %%r14, 0x30(%0); "
diff --git a/user/parlib/uthread.c b/user/parlib/uthread.c index fcd32bb..135e506 100644 --- a/user/parlib/uthread.c +++ b/user/parlib/uthread.c
@@ -62,14 +62,18 @@ * (right before vcore_entry(), don't try and take the address of any of * its TLS vars. */ set_tls_desc(get_vcpd_tls_desc(0), 0); + begin_safe_access_tls_vars(); /* We might have a basic uthread already installed (from slim_init), so * free it before installing the new one. */ if (current_uthread) free(current_uthread); current_uthread = uthread; + end_safe_access_tls_vars(); set_tls_desc(uthread->tls_desc, 0); + begin_safe_access_tls_vars(); __vcoreid = 0; /* setting the uthread's TLS var */ assert(!in_vcore_context()); + end_safe_access_tls_vars(); } /* The real 2LS calls this, passing in a uthread representing thread0. When it @@ -358,8 +362,10 @@ /* Change to the transition context (both TLS (if applicable) and stack). */ if (__uthread_has_tls(uthread)) { set_tls_desc(get_vcpd_tls_desc(vcoreid), vcoreid); + begin_safe_access_tls_vars(); assert(current_uthread == uthread); assert(in_vcore_context()); + end_safe_access_tls_vars(); } else { /* Since uthreads and vcores share TLS (it's always the vcore's TLS, the * uthread one just bootstraps from it), we need to change our state at @@ -475,7 +481,9 @@ if (__uthread_has_tls(uthread)) { assert(uthread->tls_desc); set_tls_desc(uthread->tls_desc, vcoreid); + begin_safe_access_tls_vars(); __vcoreid = vcoreid; /* setting the uthread's TLS var */ + end_safe_access_tls_vars(); } } @@ -486,7 +494,9 @@ { if (__uthread_has_tls(uthread)) { set_tls_desc(uthread->tls_desc, vcoreid); + begin_safe_access_tls_vars(); __vcoreid = vcoreid; /* setting the uthread's TLS var */ + end_safe_access_tls_vars(); } else { __vcore_context = FALSE; }