[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