Changeset 4f205248 in mainline for uspace/lib/c/generic/rtld


Ignore:
Timestamp:
2018-04-23T18:50:40Z (7 years ago)
Author:
Jiří Zárevúcky <jiri.zarevucky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a2eb85d
Parents:
8d58fca
git-author:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-04-23 17:47:09)
git-committer:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-04-23 18:50:40)
Message:

Honor TLS alignment.

Location:
uspace/lib/c/generic/rtld
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/rtld/module.c

    r8d58fca r4f205248  
    3535 */
    3636
     37#include <align.h>
    3738#include <adt/list.h>
    3839#include <elf/elf_load.h>
     
    4243#include <stdlib.h>
    4344#include <str.h>
     45#include <macros.h>
    4446
    4547#include <rtld/rtld.h>
     
    7274        const elf_segment_header_t *tls =
    7375            elf_get_phdr(__executable_start, PT_TLS);
    74         uintptr_t bias = elf_get_bias(__executable_start);
    75 
    76         module->tdata = (void *) (tls->p_vaddr + bias);
    77         module->tdata_size = tls->p_filesz;
    78         module->tbss_size = tls->p_memsz - tls->p_filesz;
    79         module->tls_align = tls->p_align;
     76
     77        if (tls) {
     78                uintptr_t bias = elf_get_bias(__executable_start);
     79                module->tdata = (void *) (tls->p_vaddr + bias);
     80                module->tdata_size = tls->p_filesz;
     81                module->tbss_size = tls->p_memsz - tls->p_filesz;
     82                module->tls_align = tls->p_align;
     83        } else {
     84                module->tdata = NULL;
     85                module->tdata_size = 0;
     86                module->tbss_size = 0;
     87                module->tls_align = 1;
     88        }
    8089
    8190        list_append(&module->modules_link, &rtld->modules);
     
    324333{
    325334#ifdef CONFIG_TLS_VARIANT_1
    326         list_foreach(rtld->modules, modules_link, module_t, m) {
    327                 m->ioffs = rtld->tls_size;
    328                 list_append(&m->imodules_link, &rtmd->imodules);
     335        rtld->tls_size = sizeof(tcb_t);
     336        rtld->tls_align = _Alignof(tcb_t);
     337
     338        list_foreach(rtld->modules, modules_link, module_t, m) {
     339                list_append(&m->imodules_link, &rtld->imodules);
     340                rtld->tls_align = max(rtld->tls_align, m->tls_align);
     341
     342                rtld->tls_size = ALIGN_UP(rtld->tls_size, m->tls_align);
     343                m->tpoff = rtld->tls_size;
    329344                rtld->tls_size += m->tdata_size + m->tbss_size;
    330345        }
    331 #else /* CONFIG_TLS_VARIANT_2 */
    332         size_t offs;
    333 
    334         list_foreach(rtld->modules, modules_link, module_t, m) {
     346
     347#else
     348        rtld->tls_size = 0;
     349        rtld->tls_align = _Alignof(tcb_t);
     350
     351        list_foreach(rtld->modules, modules_link, module_t, m) {
     352                list_append(&m->imodules_link, &rtld->imodules);
     353                rtld->tls_align = max(rtld->tls_align, m->tls_align);
     354
     355                /* We are allocating spans "backwards", here,
     356                 * as described in U. Drepper's paper.
     357                 */
    335358                rtld->tls_size += m->tdata_size + m->tbss_size;
    336         }
    337 
    338         offs = 0;
    339         list_foreach(rtld->modules, modules_link, module_t, m) {
    340                 offs += m->tdata_size + m->tbss_size;
    341                 m->ioffs = rtld->tls_size - offs;
    342                 list_append(&m->imodules_link, &rtld->imodules);
    343         }
     359                rtld->tls_size = ALIGN_UP(rtld->tls_size, m->tls_align);
     360                m->tpoff = -(ptrdiff_t) rtld->tls_size;
     361        }
     362
     363        /* We are in negative offsets. In order for the alignments to
     364         * be correct, "zero" offset (i.e. the total size) must be aligned
     365         * to the strictest alignment present.
     366         */
     367        rtld->tls_size = ALIGN_UP(rtld->tls_size, rtld->tls_align);
     368
     369        /* Space for the TCB. */
     370        rtld->tls_size += sizeof(tcb_t);
    344371#endif
    345372}
  • uspace/lib/c/generic/rtld/rtld.c

    r8d58fca r4f205248  
    152152tcb_t *rtld_tls_make(rtld_t *rtld)
    153153{
    154         void *data;
    155154        tcb_t *tcb;
    156         size_t offset;
    157155        void **dtv;
    158156        size_t nmods;
    159157        size_t i;
    160158
    161         tcb = tls_alloc_arch(&data, rtld->tls_size);
     159        tcb = tls_alloc_arch(rtld->tls_size, rtld->tls_align);
    162160        if (tcb == NULL)
    163161                return NULL;
     
    182180         */
    183181
    184 #ifdef CONFIG_TLS_VARIANT_1
    185         /*
    186          * Ascending addresses
    187          */
    188         offset = 0;
    189182        i = 1;
    190183        list_foreach(rtld->imodules, imodules_link, module_t, m) {
    191                 assert(i == m->id);
    192                 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size);
    193                 dtv[i++] = data + offset;
    194                 memcpy(data + offset, m->tdata, m->tdata_size);
    195                 offset += m->tdata_size;
    196                 memset(data + offset, 0, m->tbss_size);
    197                 offset += m->tbss_size;
    198         }
    199 #else /* CONFIG_TLS_VARIANT_2 */
    200         /*
    201          * Descending addresses
    202          */
    203         offset = 0;
    204         i = 1;
    205         list_foreach(rtld->imodules, imodules_link, module_t, m) {
    206                 assert(i == m->id);
    207                 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size);
    208                 offset += m->tbss_size;
    209                 memset(data + rtld->tls_size - offset, 0, m->tbss_size);
    210                 offset += m->tdata_size;
    211                 memcpy(data + rtld->tls_size - offset, m->tdata, m->tdata_size);
    212                 dtv[i++] = data + rtld->tls_size - offset;
    213         }
    214 #endif
     184                assert(i++ == m->id);
     185
     186                dtv[m->id] = (void *) tcb + m->tpoff;
     187
     188                assert(((uintptr_t) dtv[m->id]) % m->tls_align == 0);
     189
     190                memcpy(dtv[m->id], m->tdata, m->tdata_size);
     191                memset(dtv[m->id] + m->tdata_size, 0, m->tbss_size);
     192        }
    215193
    216194        tcb->dtv = dtv;
     
    259237                assert(!link_used(&m->imodules_link));
    260238
    261                 tls_block = malloc(m->tdata_size + m->tbss_size);
     239                tls_block = memalign(m->tls_align, m->tdata_size + m->tbss_size);
    262240                /* XXX This can fail if OOM */
    263241                assert(tls_block != NULL);
Note: See TracChangeset for help on using the changeset viewer.