[PATCH v15 2/8] Add generic 'extra TLS'

Florian Weimer fweimer@redhat.com
Wed Jan 8 10:26:07 GMT 2025


* Michael Jeanson:

> diff --git a/csu/libc-tls.c b/csu/libc-tls.c
> index 15f470aa87..73ba399e8d 100644
> --- a/csu/libc-tls.c
> +++ b/csu/libc-tls.c

> + /* Record the extra TLS block offset from the thread pointer.
> +
> +    With TLS_DTV_AT_TP the TLS blocks are allocated after the thread pointer in
> +    order. Our block is added last which results in it being the last in the
> +    static TLS block, thus record the offset as the size of the static TLS
> +    block minus the size of our block.
> +
> +    On some architectures the TLS blocks are offset from the thread pointer,
> +    include this offset in the extra TLS block offset.
> +
> +    The alignment requirements of the pointer resulting from this offset and
> +    the thread pointer are enforced by 'max_align' which is used to align the
> +    tcb_offset.  */
> +  _dl_extra_tls_set_offset (tls_blocks_size - extra_tls_size - TLS_TP_OFFSET);

Is the API contract that _dl_extra_tls_get_size () is a multiple of
_dl_extra_tls_get_align ()?  It's not clear to me.  The !TLS_DTV_AT_TP
code does not assume it, I think but the subtraction

  tls_blocks_size - extra_tls_size

in the expression above does: tls_blocks_size is aligned, but if
extra_tls_size isn't a multiple, the difference is not.

I don't know what the Linux auxiliary vector interface promises.  If
there is no alignment requirement, we should change how the difference
is computed.

> diff --git a/elf/dl-tls.c b/elf/dl-tls.c
> index c2d17265fb..97566ce45a 100644
> --- a/elf/dl-tls.c
> +++ b/elf/dl-tls.c

> +  /* Insert the extra TLS block after the last TLS block.  */
> +
> +  /* Extra TLS block for internal usage to append at the end of the TLS blocks
> +     (in allocation order).  On Linux systems this is where the rseq area will
> +     be allocated.  On other systems it is currently unused and both values
> +     will be '0'.  */
> +  size_t extra_tls_size = _dl_extra_tls_get_size ();
> +  size_t extra_tls_align = _dl_extra_tls_get_align ();
> +
> +  /* Align and add the extra TLS block to the global offset.  */
> +  offset = roundup (offset, extra_tls_align) + extra_tls_size;

Zero alignment passed to roundup?  I don't think that's valid.

> @@ -368,6 +397,39 @@ _dl_determine_tlsoffset (void)
>        offset = off + slotinfo[cnt].map->l_tls_blocksize - firstbyte;
>      }
>  
> +  /* Insert the extra TLS block after the last TLS block.  */
> +
> +  /* Extra TLS block for internal usage to append at the end of the TLS blocks
> +     (in allocation order).  On Linux systems this is where the rseq area will
> +     be allocated.  On other systems it is currently unused and both values
> +     will be '0'.  */
> +  size_t extra_tls_size = _dl_extra_tls_get_size ();
> +  size_t extra_tls_align = _dl_extra_tls_get_align ();
> +
> +  /* Align the global offset to the beginning of the extra TLS block.  */
> +  offset = roundup (offset, extra_tls_align);

See above about zero argument.

Thanks,
Florian



More information about the Libc-alpha mailing list