cvs commit: src/sys/i386/i386 sys_machdep.c

Julian Elischer julian at elischer.org
Tue Aug 5 18:18:54 PDT 2003



On Tue, 5 Aug 2003, Daniel Eischen wrote:

> On Tue, 5 Aug 2003, Julian Elischer wrote:
> 
> > Warning warning warning....
> > 
> > The code that Dan shows ends up pointing %gs to the struct pthread
> > structure.. however the ELF i386 (and amd64) ABI for TLS assumes that it
> > points to a POINTER to the TCB (is that the same thing?). If the TCB
> > (Thread control block) is the same thing as the struct pthread then you
> > should probably make the first entry be a pointer to istelf or the TLS
> > code generated by the linker (when enabled) will point to the wrong
> > thing..
> 
> For libthr, the struct pthread isn't really the thread control
> block.  struct pthread is MI, so you can't rely on it having
> a layout that will satisfy all the ABIs.  It isn't correct
> now for i386.
> 
> libthr will likely need the same sort of arch-dependent
> hooks that libpthread just grew (minus the struct kcb
> stuff).  The patch I posted just addresses auto-ldt
> allocation.
> 
> > 
> > With the array there is now it just happens to come out right.
> 
> But it doesn't really, since the first slot of struct pthread
> is not a pointer to the dynamic TLS.

the i386 TLS spec doesn;t say it needs to be..


What it says is:
%gs references a LDT entry that defines a segment, the forst word of
which is a pointer to the Thread Control block, which, at a known 
offset (defined by a symbol), contains a pointer to the TLS vector
array.

This is satisfied now because %gs defiens a sebment that starts at one
of the array entries in that array, and each array entry holds a pointer
to the associated thread control block (struct pthread) which could hold
a pointer to the TLS vector is it was added there..

if you bypass the array and make the segment contain the TCB directly
then you need to add an artificial pointer to itself at the head
so that the generated code does the right thing..


to get the address of the TLS vector it will do this:

movl %gs:0 %eax      ; get address of TCB
movl tdpoff(%eax), %eax  ; get address of vector in %eax

This is the code that the linger expects to build..

if you don't have %gs pointed to a pointer, but instead, directly
at the TCB
you'd only need:
movl gs:#tdpoff (or whatever the syntax for that is:) , %eax

which MIGHT be a fraction faster, but is NOT what the linker is going to
generate.. the code that the linker is going to generate is
by chance also compatible with libc_r and with libkse as well.
(assuming that we allocated a page at 0 and set %gs to be LUDATA).
(or set a single LDT entry)
(for KSE the indirection is in the KSE info)

It also needs to be able to do -ve offsets from the base of the TCB and
a segment (for normal data) cannot do -ve offsets and +ve offsets.
so you MUST have the segment pointed to by %gs contain a POINTER to the
TCB, not contain the TCB itself.
(unless the pointer is in the tcb)

(which is what the spec suggestes for the 1:1 case anyhow)



> 
> -- 
> Dan Eischen
> 
> 



More information about the freebsd-threads mailing list