On Wed, Aug 31, 2016 at 4:26 PM, Benoît Canet <ben...@cloudius-systems.com>
wrote:

>
>
> Go use it's own tls see: http://blog.altoros.com/golang-internals-part-5-
> runtime-bootstrap-process.html
>

Thanks. Interesting.

It is very sad, and surprising, that Go does this: If I understand
correctly, it only has two variables in TLS - "g" and "m". It could have
re-used the existing C TLS ABI (see https://www.akkadia.org/drepper/tls.pdf)
whose main purpose is to allow different parts of the program (different
shared objects, etc.) to add their own TLS variables without needing one
entity to "take over" the fs register as Go does. Or it could have put the
f-ing variable, "g" in a register....

I think we have two ways to proceed now:

1. Find a way where Go uses the C TLS ABI so it can co-exist with a C
program. I believe this is exactly the "c-shared" build mode (but correct
me if I'm wrong)... You tried to use it, but TLS didn't work. I assume we
still have some unknown bug in our "initial exec" TLS mode which Go uses
(there is a R_X86_64_TPOFF64 relocation in the shared object) which makes
this work incorrectly.

2. Give up on c-shared and go back to shared (or pie) which cannot co-exist
with C code which uses TLS.
It looks like this is the direction you're going in now.
Let's think what is the implication of this:

This option uses arch_prctl(), as you noticed, which sets the FS_BASE MSR.
But OSv (and other shared objects written in C and might be loaded) need
the FS_BASE MSR to be set up in a particular way - to point to OSv's TCB of
this thread and have a particular structure which the dynamic linker built
considering the need of all the loaded shared objects and the ELF TLS ABI.

SO, what this means is that:
1. After the arch_prctl() call, the thread which ran it cannot run OSv
code! When we switch to OSv code - either by calling a function (e.g.,
malloc()) or a system call - we need to temporarily restore OSv's FS_BASE,
and return it back when going back to the Go code.
2. Moreover, when we context switch out of the thread, we need to save its
FS_BASE and restore it when returning to the thread. We don't have exactly
that at the moment - currently, thread::switch_to() changes the FS_BASE to
the thread's fixed "_tcb" area, but when entering a thread which previously
used arch_prctl() we need to restore that address - not _tcb! So we need to
save and restore fs_base on context switch rather than set it to a fixed
address.

I really think this option will be very difficult to achieve, and fixing
c-shared will be easier. But maybe I'm missing something important here.

Something I don't understand now is how, even in Linux, the Go code, with
its funky FS_BASE setup, can use glibc functions like malloc(). What if
those functions use TLS (I would like to think that malloc() in particular
does)? Or does Go have special glue code to restore glibc's fs_base before
calling a glibc function?

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to