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;
}