[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Implementing TLS: step 1



On Thu, Jun 19, 2003 at 04:03:30PM -0700, Julian Elischer wrote:
> 
> > The compiler generates access sequences according to the runtime
> > specification which in general means that all offsets to the TLS
> > are based on some TLS base address. On ia64 the thread pointer
> > points to the TLS and serves as the TLS base address. On other
> > architectures there may be an indirection. This means that on ia64
> > the lack of TLS still requires us to allocate something for the
> > thread pointer to point to. On other architectures this may not be
> > the case.
> > 
> > A typical access sequence on i386 is:
> > 
> > 00000000 <x>:
> >    0:   55                      push   %ebp
> >    1:   89 e5                   mov    %esp,%ebp
> >    3:   65 a1 00 00 00 00       mov    %gs:0x0,%eax
> >    9:   8b 80 00 00 00 00       mov    0x0(%eax),%eax
> >    f:   c9                      leave
> >   10:   c3                      ret
> 
> The example you show doesn't have any offset into the TLS,
> just returning the base address of the dtv, correct?

This is an access sequence for static TLS. There's no DTV in that
case.

> you still need do significant work to get from teh dtv to the address of
> the variable. (at least according to Figure 1.) or are you talking about
> something else?

The access sequence in the dynamic TLS model is more complex (and
dog slow due to the call). For the same C code that yields the
static TLS access sequence above:

00000000 <x>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   53                      push   %ebx
   4:   e8 00 00 00 00          call   9 <x+0x9>
   9:   5b                      pop    %ebx
   a:   81 c3 03 00 00 00       add    $0x3,%ebx
  10:   8d 04 1d 00 00 00 00    lea    0x0(,%ebx,1),%eax
  17:   e8 fc ff ff ff          call   18 <x+0x18>
  1c:   8b 00                   mov    (%eax),%eax
  1e:   8b 1c 24                mov    (%esp,1),%ebx
  21:   c9                      leave
  22:   c3                      ret

The DTV fodder is abstracted y the  __tls_get_addr() function.

Here the relocations are:

RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE
0000000c R_386_GOTPC       _GLOBAL_OFFSET_TABLE_
00000013 R_386_TLS_GD      i
00000018 R_386_PLT32       ___tls_get_addr
 
> that's fine.. I can arrange that at the address specified by %gs:0
> is a pointer to anything that is needed.
> What I can't arrange is that %gs:0 IS the address of the TLS.
> (well maybe I can.. hmmmm...)

On i386, gs:0x0 does not have to point to the TLS. There's no
equivelent of gs:0x0 on ia64.

> > > > 1. The kernel already iterates over the program headers and can
> > > >    pass the address and size of the TLS template to the process
> > > >    (or RTLD) by means of the auxargs (ie have AT_TLS_ADDR and
> > > >    AT_TLS_SIZE). If no template exists AT_TLS_* will be zero.
> > > >    This prevents coding object file dependencies on thread and
> > > >    allows the RTLD to modify the args even in the event that the
> > > >    program itself does not have TLS, but libraries in the startup
> > > >    set do.
> > > 
> > > I need to go out to the car and get my copy of the TLS proposal....
> > > this supports exec-time linking but does it support run-time (i.e after
> > > exec has begun) linking?
> > 
> > Yes. The rtld will dynamicly construct the TLS template from the
> > images in the ELF files in the startup set and pass this in
> > AT_TLS_* by overriding the values (at least that was the idea).
> > 
> 
> But if you add a nwe library after threads already exist then you need
> to add those extra TLS segments to teh existing TLS objects that are
> attached to already running threads. The code you show can't do that..

See above. In the static TLS model there's no support for accessing
TLS in dynamicly loaded libraries. That's where the dynamic TLS
model kicks in.

-- 
 Marcel Moolenaar	  USPA: A-39004		 marcel_(_at_)_xcllnt_(_dot_)_net