Changeset b27ae65a in mainline for uspace/lib/c/generic/thread/tls.c


Ignore:
Timestamp:
2025-01-27T12:45:12Z (11 days ago)
Author:
GitHub <noreply@…>
Branches:
master
Children:
97116a2
Parents:
eff458d
git-author:
Matěj Volf <mat.volfik@…> (2025-01-27 12:45:12)
git-committer:
GitHub <noreply@…> (2025-01-27 12:45:12)
Message:

fix calculation of TLS size for main fibril (#240)

  • explain why tcb_t is added at the end of tls allocation
  • fix calculation of TLS size for main fibril

Before this patch, _tcb_data_offset always used progsymbols.elfstart. However,
that is wrong when it is being called from the loader server!! Now we pass to it
a pointer to the correct ELF, falling back to elfstart in the public tls_get call.

(debugging this was quite an ordeal and took me like 5 hours, thanks for asking (':)

  • a few comments for TLS allocation
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/thread/tls.c

    reff458d rb27ae65a  
    5959#endif
    6060
    61 static ptrdiff_t _tcb_data_offset(void)
     61static ptrdiff_t _tcb_data_offset(const void* elf)
    6262{
    6363        const elf_segment_header_t *tls =
    64             elf_get_phdr(__progsymbols.elfstart, PT_TLS);
     64            elf_get_phdr(elf, PT_TLS);
    6565
    6666        size_t tls_align = tls ? tls->p_align : 1;
     
    8080        assert(runtime_env == NULL);
    8181#endif
    82         return (uint8_t *)__tcb_get() + _tcb_data_offset();
     82        return (uint8_t *)__tcb_get() + _tcb_data_offset(__progsymbols.elfstart);
    8383}
    8484
    8585static tcb_t *tls_make_generic(const void *elf, void *(*alloc)(size_t, size_t))
    8686{
     87        /*
     88         * See also rtld/module.c -> modules_process_tls(), where we have less
     89         * messy code for the dynamic-linking version of this.
     90         */
    8791        assert(!elf_get_phdr(elf, PT_DYNAMIC));
    8892#ifdef CONFIG_RTLD
     
    100104        assert(tls_align <= PAGE_SIZE);
    101105
     106        /*
     107         * FIXME: the calculation of alloc_size shouldn't include the alignment
     108         * of tcb_t (at least in Variant II)
     109         * See https://github.com/HelenOS/helenos/pull/240/files/4ef27ebf98a0656e09889b7d00efdec03343f1aa#r1929592924
     110         * (you will also need to fix _tcb_data_offset)
     111         */
     112
    102113#ifdef CONFIG_TLS_VARIANT_1
    103114        size_t alloc_size =
     
    114125#ifdef CONFIG_TLS_VARIANT_1
    115126        tcb_t *tcb = area;
    116         uint8_t *data = (uint8_t *)tcb + _tcb_data_offset();
     127        uint8_t *data = (uint8_t *)tcb + _tcb_data_offset(elf);
    117128        memset(tcb, 0, sizeof(*tcb));
    118129#else
    119130        uint8_t *data = area;
    120         tcb_t *tcb = (tcb_t *) (data - _tcb_data_offset());
     131        tcb_t *tcb = (tcb_t *) (data - _tcb_data_offset(elf));
    121132        memset(tcb, 0, sizeof(tcb_t));
    122133        tcb->self = tcb;
Note: See TracChangeset for help on using the changeset viewer.