Changes in / [5035ba05:32573ff] in mainline


Ignore:
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • abi/include/abi/elf.h

    r5035ba05 r32573ff  
    170170#define PT_SHLIB    5
    171171#define PT_PHDR     6
     172#define PT_TLS      7
    172173#define PT_LOPROC   0x70000000
    173174#define PT_HIPROC   0x7fffffff
  • kernel/generic/src/lib/elf.c

    r5035ba05 r32573ff  
    163163        case PT_LOAD:
    164164                return load_segment(entry, elf, as);
     165        case PT_TLS:
     166                break;
    165167        case PT_DYNAMIC:
    166168        case PT_INTERP:
  • uspace/lib/c/arch/ia32/_link.ld.in

    r5035ba05 r32573ff  
    1212#endif
    1313        data PT_LOAD FLAGS(6);
     14        tls PT_TLS;
    1415#if defined(SHLIB) || defined(DLEXE)
    1516        dynamic PT_DYNAMIC;
     
    9596#endif
    9697       
     98        .tdata : {
    9799#ifndef DLEXE
    98         .tdata : {
    99100                _tdata_start = .;
     101#endif
    100102                *(.tdata);
    101103                *(.gnu.linkonce.tb.*);
     104#ifndef DLEXE
    102105                _tdata_end = .;
     106#endif
     107        } :data :tls
     108        .tbss : {
     109#ifndef DLEXE
    103110                _tbss_start = .;
     111#endif
    104112                *(.tbss);
     113#ifndef DLEXE
    105114                _tbss_end = .;
    106         } :data
     115#endif
     116        } :data :tls
    107117       
     118#ifndef DLEXE
    108119        _tls_alignment = ALIGNOF(.tdata);
    109120#endif
  • uspace/lib/c/arch/ia32/src/rtld/reloc.c

    r5035ba05 r32573ff  
    171171                        break;
    172172
     173//              case R_386_TLS_DTPOFF32:
     174//                      *r_ptr = sym_def->st_value;
     175//                      break;
     176
    173177                case R_386_TLS_DTPMOD32:
    174                         /*
    175                          * We can ignore this as long as the only module
    176                          * with TLS variables is libc.so.
    177                          */
    178                         DPRINTF("Ignoring R_386_TLS_DTPMOD32\n");
     178                        *r_ptr = dest->id;
    179179                        break;
    180180
  • uspace/lib/c/arch/ia32/src/tls.c

    r5035ba05 r32573ff  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
     3 * Copyright (c) 2016 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3940#include <align.h>
    4041
     42#ifdef CONFIG_RTLD
     43#include <rtld/rtld.h>
     44#endif
     45
    4146tcb_t *tls_alloc_arch(void **data, size_t size)
    4247{
     
    6873
    6974        /* Calculate size of TLS block */
    70         tls_size = ALIGN_UP(&_tbss_end - &_tdata_start, &_tls_alignment);
     75        tls_size = tls_get_size();
    7176
    7277        /* The TLS block is just before TCB */
    7378        tls = (uint8_t *)__tcb_get() - tls_size;
    7479
     80#ifdef CONFIG_RTLD
     81        if (runtime_env != NULL) {
     82                return rtld_tls_get_addr(runtime_env, tls, ti->ti_module,
     83                    ti->ti_offset);
     84        }
     85#endif
    7586        return tls + ti->ti_offset;
    7687}
  • uspace/lib/c/generic/elf/elf_mod.c

    r5035ba05 r32573ff  
    248248}
    249249
     250/** Process TLS program header.
     251 *
     252 * @param elf  Pointer to loader state buffer.
     253 * @param hdr  TLS program header
     254 * @param info Place to store TLS info
     255 */
     256static void tls_program_header(elf_ld_t *elf, elf_segment_header_t *hdr,
     257    elf_tls_info_t *info)
     258{
     259        info->tdata = (void *)((uint8_t *)hdr->p_vaddr + elf->bias);
     260        info->tdata_size = hdr->p_filesz;
     261        info->tbss_size = hdr->p_memsz - hdr->p_filesz;
     262}
     263
    250264/** Process segment header.
    251265 *
     266 * @param elf   Pointer to loader state buffer.
    252267 * @param entry Segment header.
    253268 *
     
    277292        case 0x70000000:
    278293                /* FIXME: MIPS reginfo */
     294                break;
     295        case PT_TLS:
     296                /* Parse TLS program header */
     297                tls_program_header(elf, entry, &elf->info->tls);
     298                DPRINTF("TLS header found at %p\n",
     299                    (void *)((uint8_t *)entry->p_vaddr + elf->bias));
    279300                break;
    280301        case PT_SHLIB:
  • uspace/lib/c/generic/rtld/module.c

    r5035ba05 r32573ff  
    3737#include <adt/list.h>
    3838#include <elf/elf_load.h>
     39#include <errno.h>
    3940#include <fcntl.h>
    4041#include <loader/pcb.h>
     
    135136
    136137        m = calloc(1, sizeof(module_t));
    137         if (!m) {
     138        if (m == NULL) {
    138139                printf("malloc failed\n");
    139140                exit(1);
     
    141142
    142143        m->rtld = rtld;
     144        m->id = rtld_get_next_id(rtld);
     145
    143146        if ((flags & mlf_local) != 0)
    144147                m->local = true;
     
    181184        /* Insert into the list of loaded modules */
    182185        list_append(&m->modules_link, &rtld->modules);
     186
     187        /* Copy TLS info */
     188        m->tdata = info.tls.tdata;
     189        m->tdata_size = info.tls.tdata_size;
     190        m->tbss_size = info.tls.tbss_size;
     191
     192        printf("tdata at %p size %zu, tbss size %zu\n",
     193            m->tdata, m->tdata_size, m->tbss_size);
    183194
    184195        return m;
     
    243254}
    244255
     256/** Find module structure by ID. */
     257module_t *module_by_id(rtld_t *rtld, unsigned long id)
     258{
     259        list_foreach(rtld->modules, modules_link, module_t, m) {
     260                if (m->id == id)
     261                        return m;
     262        }
     263
     264        return NULL;
     265}
     266
    245267/** Process relocations in modules.
    246268 *
     
    260282}
    261283
     284void modules_process_tls(rtld_t *rtld)
     285{
     286        list_foreach(rtld->modules, modules_link, module_t, m) {
     287                m->ioffs = rtld->tls_size;
     288                rtld->tls_size += m->tdata_size + m->tbss_size;
     289        }
     290}
     291
    262292/** Clear BFS tags of all modules.
    263293 */
  • uspace/lib/c/generic/rtld/rtld.c

    r5035ba05 r32573ff  
    4343rtld_t *runtime_env;
    4444static rtld_t rt_env_static;
    45 static module_t prog_mod;
    4645
    4746/** Initialize the runtime linker for use in a statically-linked executable. */
     
    6261{
    6362        rtld_t *env;
     63        module_t *prog;
    6464
    6565        DPRINTF("Load dynamically linked program.\n");
     
    7070                return ENOMEM;
    7171
     72        env->next_id = 1;
     73
     74        prog = calloc(1, sizeof(module_t));
     75        if (prog == NULL) {
     76                free(env);
     77                return ENOMEM;
     78        }
     79
    7280        /*
    7381         * First we need to process dynamic sections of the executable
     
    7684
    7785        DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
    78         dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn);
    79         prog_mod.bias = 0;
    80         prog_mod.dyn.soname = "[program]";
    81         prog_mod.rtld = env;
    82         prog_mod.exec = true;
    83         prog_mod.local = false;
     86        dynamic_parse(p_info->dynamic, 0, &prog->dyn);
     87        prog->bias = 0;
     88        prog->dyn.soname = "[program]";
     89        prog->rtld = env;
     90        prog->id = rtld_get_next_id(env);
     91        prog->exec = true;
     92        prog->local = false;
     93
     94        prog->tdata = p_info->tls.tdata;
     95        prog->tdata_size = p_info->tls.tdata_size;
     96        prog->tbss_size = p_info->tls.tbss_size;
     97
     98        printf("prog tdata at %p size %zu, tbss size %zu\n",
     99            prog->tdata, prog->tdata_size, prog->tbss_size);
    84100
    85101        /* Initialize list of loaded modules */
    86102        list_initialize(&env->modules);
    87         list_append(&prog_mod.modules_link, &env->modules);
     103        list_append(&prog->modules_link, &env->modules);
    88104
    89105        /* Pointer to program module. Used as root of the module graph. */
    90         env->program = &prog_mod;
     106        env->program = prog;
    91107
    92108        /* Work around non-existent memory space allocation. */
     
    98114
    99115        DPRINTF("Load all program dependencies\n");
    100         module_load_deps(&prog_mod, 0);
     116        module_load_deps(prog, 0);
    101117
    102118        /*
     
    106122        /* Process relocations in all modules */
    107123        DPRINTF("Relocate all modules\n");
    108         modules_process_relocs(env, &prog_mod);
     124        modules_process_relocs(env, prog);
     125
     126        modules_process_tls(env);
    109127
    110128        *rre = env;
     
    112130}
    113131
     132/** Create TLS (Thread Local Storage) data structures.
     133 *
     134 * @return Pointer to TCB.
     135 */
     136tcb_t *rtld_tls_make(rtld_t *rtld)
     137{
     138        void *data;
     139        tcb_t *tcb;
     140        size_t offset;
     141
     142        tcb = tls_alloc_arch(&data, rtld->tls_size);
     143        if (tcb == NULL)
     144                return NULL;
     145
     146        /*
     147         * Copy thread local data from the modules' initialization images.
     148         * Zero out thread-local uninitialized data.
     149         */
     150
     151        offset = 0;
     152        list_foreach(rtld->modules, modules_link, module_t, m) {
     153                memcpy(data + offset, m->tdata, m->tdata_size);
     154                offset += m->tdata_size;
     155                memset(data + offset, 0, m->tbss_size);
     156                offset += m->tbss_size;
     157        }
     158
     159        return tcb;
     160}
     161
     162unsigned long rtld_get_next_id(rtld_t *rtld)
     163{
     164        return rtld->next_id++;
     165}
     166
     167void *rtld_tls_get_addr(rtld_t *rtld, void *tls, unsigned long mod_id,
     168    unsigned long offset)
     169{
     170        module_t *m;
     171
     172        m = module_by_id(rtld, mod_id);
     173        assert(m != NULL);
     174
     175        return tls + m->ioffs + offset;
     176}
     177
     178
    114179/** @}
    115180 */
  • uspace/lib/c/generic/tls.c

    r5035ba05 r32573ff  
    3434 * Support for thread-local storage, as described in:
    3535 *      Drepper U.: ELF Handling For Thread-Local Storage, 2005
    36  *
    37  * Only static model is supported.
    38  */
     36 */
    3937
    4038#include <tls.h>
    4139#include <malloc.h>
    4240#include <str.h>
    43 #include <align.h>
    4441#include <unistd.h>
    4542
     43#ifdef CONFIG_RTLD
     44#include <rtld/rtld.h>
     45#endif
     46
     47size_t tls_get_size(void)
     48{
     49        return &_tbss_end - &_tdata_start;
     50}
     51
    4652/** Create TLS (Thread Local Storage) data structures.
    47  *
    48  * The code requires, that sections .tdata and .tbss are adjacent. It may be
    49  * changed in the future.
    5053 *
    5154 * @return Pointer to TCB.
     
    5659        tcb_t *tcb;
    5760        size_t tls_size = &_tbss_end - &_tdata_start;
    58        
     61
     62#ifdef CONFIG_RTLD
     63        if (runtime_env != NULL)
     64                return rtld_tls_make(runtime_env);
     65#endif
    5966        tcb = tls_alloc_arch(&data, tls_size);
    6067        if (!tcb)
    6168                return NULL;
    62        
     69
    6370        /*
    6471         * Copy thread local data from the initialization image.
     
    7784{
    7885        size_t tls_size = &_tbss_end - &_tdata_start;
     86
     87#ifdef CONFIG_RTLD
     88        if (runtime_env != NULL)
     89                tls_size = runtime_env->tls_size;
     90#endif
    7991        tls_free_arch(tcb, tls_size);
    8092}
     
    121133{
    122134        tcb_t *tcb;
    123        
    124         size = ALIGN_UP(size, &_tls_alignment);
    125         *data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size);
    126         if (!*data)
     135
     136        *data = malloc(sizeof(tcb_t) + size);
     137        if (*data == NULL)
    127138                return NULL;
    128139        tcb = (tcb_t *) (*data + size);
     
    139150void tls_free_variant_2(tcb_t *tcb, size_t size)
    140151{
    141         size = ALIGN_UP(size, &_tls_alignment);
    142152        void *start = ((void *) tcb) - size;
    143153        free(start);
  • uspace/lib/c/include/elf/elf_mod.h

    r5035ba05 r32573ff  
    5858} eld_flags_t;
    5959
     60/** TLS info for a module */
     61typedef struct {
     62        /** tdata section image */
     63        void *tdata;
     64        /** Size of tdata section image in bytes */
     65        size_t tdata_size;
     66        /** Size of tbss section */
     67        size_t tbss_size;
     68} elf_tls_info_t;
     69
    6070/**
    6171 * Some data extracted from the headers are stored here
     
    7080        /** Pointer to the dynamic section */
    7181        void *dynamic;
     82
     83        /** TLS info */
     84        elf_tls_info_t tls;
    7285} elf_finfo_t;
    7386
  • uspace/lib/c/include/rtld/module.h

    r5035ba05 r32573ff  
    4646extern module_t *module_load(rtld_t *, const char *, mlflags_t);
    4747extern void module_load_deps(module_t *, mlflags_t);
     48extern module_t *module_by_id(rtld_t *, unsigned long);
    4849
    4950extern void modules_process_relocs(rtld_t *, module_t *);
     51extern void modules_process_tls(rtld_t *);
    5052extern void modules_untag(rtld_t *);
    5153
  • uspace/lib/c/include/rtld/rtld.h

    r5035ba05 r32573ff  
    4141
    4242#include <rtld/dynamic.h>
     43#include <tls.h>
    4344#include <types/rtld/rtld.h>
    4445
     
    4748extern void rtld_init_static(void);
    4849extern int rtld_prog_process(elf_finfo_t *, rtld_t **);
     50extern tcb_t *rtld_tls_make(rtld_t *);
     51extern unsigned long rtld_get_next_id(rtld_t *);
     52extern void *rtld_tls_get_addr(rtld_t *, void *, unsigned long, unsigned long);
    4953
    5054#endif
  • uspace/lib/c/include/tls.h

    r5035ba05 r32573ff  
    5252extern void tls_free(tcb_t *);
    5353extern void tls_free_arch(tcb_t *, size_t);
     54extern size_t tls_get_size(void);
    5455
    5556#ifdef CONFIG_TLS_VARIANT_1
  • uspace/lib/c/include/types/rtld/module.h

    r5035ba05 r32573ff  
    4646/** Dynamically linked module */
    4747typedef struct module {
     48        /** Module ID */
     49        unsigned long id;
     50        /** Dynamic info for this module */
    4851        dyn_info_t dyn;
     52        /** Load bias */
    4953        size_t bias;
     54
     55        /** tdata image start */
     56        void *tdata;
     57        /** tdata image size */
     58        size_t tdata_size;
     59        /** tbss size */
     60        size_t tbss_size;
     61
     62        size_t ioffs;
    5063
    5164        /** Containing rtld */
  • uspace/lib/c/include/types/rtld/rtld.h

    r5035ba05 r32573ff  
    4848        module_t *program;
    4949
     50        /** Next module ID */
     51        unsigned long next_id;
     52
     53        /** Size of initial TLS tdata + tbss */
     54        size_t tls_size;
     55
    5056        /** List of all loaded modules including rtld and the program */
    5157        list_t modules;
Note: See TracChangeset for help on using the changeset viewer.