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


Ignore:
Files:
15 edited

Legend:

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

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

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

    r32573ff r5035ba05  
    1212#endif
    1313        data PT_LOAD FLAGS(6);
    14         tls PT_TLS;
    1514#if defined(SHLIB) || defined(DLEXE)
    1615        dynamic PT_DYNAMIC;
     
    9695#endif
    9796       
     97#ifndef DLEXE
    9898        .tdata : {
    99 #ifndef DLEXE
    10099                _tdata_start = .;
    101 #endif
    102100                *(.tdata);
    103101                *(.gnu.linkonce.tb.*);
    104 #ifndef DLEXE
    105102                _tdata_end = .;
    106 #endif
    107         } :data :tls
    108         .tbss : {
    109 #ifndef DLEXE
    110103                _tbss_start = .;
    111 #endif
    112104                *(.tbss);
    113 #ifndef DLEXE
    114105                _tbss_end = .;
    115 #endif
    116         } :data :tls
     106        } :data
    117107       
    118 #ifndef DLEXE
    119108        _tls_alignment = ALIGNOF(.tdata);
    120109#endif
  • uspace/lib/c/arch/ia32/src/rtld/reloc.c

    r32573ff r5035ba05  
    171171                        break;
    172172
    173 //              case R_386_TLS_DTPOFF32:
    174 //                      *r_ptr = sym_def->st_value;
    175 //                      break;
    176 
    177173                case R_386_TLS_DTPMOD32:
    178                         *r_ptr = dest->id;
     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");
    179179                        break;
    180180
  • uspace/lib/c/arch/ia32/src/tls.c

    r32573ff r5035ba05  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
    3  * Copyright (c) 2016 Jiri Svoboda
    43 * All rights reserved.
    54 *
     
    4039#include <align.h>
    4140
    42 #ifdef CONFIG_RTLD
    43 #include <rtld/rtld.h>
    44 #endif
    45 
    4641tcb_t *tls_alloc_arch(void **data, size_t size)
    4742{
     
    7368
    7469        /* Calculate size of TLS block */
    75         tls_size = tls_get_size();
     70        tls_size = ALIGN_UP(&_tbss_end - &_tdata_start, &_tls_alignment);
    7671
    7772        /* The TLS block is just before TCB */
    7873        tls = (uint8_t *)__tcb_get() - tls_size;
    7974
    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
    8675        return tls + ti->ti_offset;
    8776}
  • uspace/lib/c/generic/elf/elf_mod.c

    r32573ff r5035ba05  
    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  */
    256 static 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 
    264250/** Process segment header.
    265251 *
    266  * @param elf   Pointer to loader state buffer.
    267252 * @param entry Segment header.
    268253 *
     
    292277        case 0x70000000:
    293278                /* 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));
    300279                break;
    301280        case PT_SHLIB:
  • uspace/lib/c/generic/rtld/module.c

    r32573ff r5035ba05  
    3737#include <adt/list.h>
    3838#include <elf/elf_load.h>
    39 #include <errno.h>
    4039#include <fcntl.h>
    4140#include <loader/pcb.h>
     
    136135
    137136        m = calloc(1, sizeof(module_t));
    138         if (m == NULL) {
     137        if (!m) {
    139138                printf("malloc failed\n");
    140139                exit(1);
     
    142141
    143142        m->rtld = rtld;
    144         m->id = rtld_get_next_id(rtld);
    145 
    146143        if ((flags & mlf_local) != 0)
    147144                m->local = true;
     
    184181        /* Insert into the list of loaded modules */
    185182        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);
    194183
    195184        return m;
     
    254243}
    255244
    256 /** Find module structure by ID. */
    257 module_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 
    267245/** Process relocations in modules.
    268246 *
     
    282260}
    283261
    284 void 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 
    292262/** Clear BFS tags of all modules.
    293263 */
  • uspace/lib/c/generic/rtld/rtld.c

    r32573ff r5035ba05  
    4343rtld_t *runtime_env;
    4444static rtld_t rt_env_static;
     45static module_t prog_mod;
    4546
    4647/** Initialize the runtime linker for use in a statically-linked executable. */
     
    6162{
    6263        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 
    8072        /*
    8173         * First we need to process dynamic sections of the executable
     
    8476
    8577        DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
    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);
     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;
    10084
    10185        /* Initialize list of loaded modules */
    10286        list_initialize(&env->modules);
    103         list_append(&prog->modules_link, &env->modules);
     87        list_append(&prog_mod.modules_link, &env->modules);
    10488
    10589        /* Pointer to program module. Used as root of the module graph. */
    106         env->program = prog;
     90        env->program = &prog_mod;
    10791
    10892        /* Work around non-existent memory space allocation. */
     
    11498
    11599        DPRINTF("Load all program dependencies\n");
    116         module_load_deps(prog, 0);
     100        module_load_deps(&prog_mod, 0);
    117101
    118102        /*
     
    122106        /* Process relocations in all modules */
    123107        DPRINTF("Relocate all modules\n");
    124         modules_process_relocs(env, prog);
    125 
    126         modules_process_tls(env);
     108        modules_process_relocs(env, &prog_mod);
    127109
    128110        *rre = env;
     
    130112}
    131113
    132 /** Create TLS (Thread Local Storage) data structures.
    133  *
    134  * @return Pointer to TCB.
    135  */
    136 tcb_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 
    162 unsigned long rtld_get_next_id(rtld_t *rtld)
    163 {
    164         return rtld->next_id++;
    165 }
    166 
    167 void *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 
    179114/** @}
    180115 */
  • uspace/lib/c/generic/tls.c

    r32573ff r5035ba05  
    3434 * Support for thread-local storage, as described in:
    3535 *      Drepper U.: ELF Handling For Thread-Local Storage, 2005
    36  */
     36 *
     37 * Only static model is supported.
     38 */
    3739
    3840#include <tls.h>
    3941#include <malloc.h>
    4042#include <str.h>
     43#include <align.h>
    4144#include <unistd.h>
    4245
    43 #ifdef CONFIG_RTLD
    44 #include <rtld/rtld.h>
    45 #endif
    46 
    47 size_t tls_get_size(void)
    48 {
    49         return &_tbss_end - &_tdata_start;
    50 }
    51 
    5246/** 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.
    5350 *
    5451 * @return Pointer to TCB.
     
    5956        tcb_t *tcb;
    6057        size_t tls_size = &_tbss_end - &_tdata_start;
    61 
    62 #ifdef CONFIG_RTLD
    63         if (runtime_env != NULL)
    64                 return rtld_tls_make(runtime_env);
    65 #endif
     58       
    6659        tcb = tls_alloc_arch(&data, tls_size);
    6760        if (!tcb)
    6861                return NULL;
    69 
     62       
    7063        /*
    7164         * Copy thread local data from the initialization image.
     
    8477{
    8578        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
    9179        tls_free_arch(tcb, tls_size);
    9280}
     
    133121{
    134122        tcb_t *tcb;
    135 
    136         *data = malloc(sizeof(tcb_t) + size);
    137         if (*data == NULL)
     123       
     124        size = ALIGN_UP(size, &_tls_alignment);
     125        *data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size);
     126        if (!*data)
    138127                return NULL;
    139128        tcb = (tcb_t *) (*data + size);
     
    150139void tls_free_variant_2(tcb_t *tcb, size_t size)
    151140{
     141        size = ALIGN_UP(size, &_tls_alignment);
    152142        void *start = ((void *) tcb) - size;
    153143        free(start);
  • uspace/lib/c/include/elf/elf_mod.h

    r32573ff r5035ba05  
    5858} eld_flags_t;
    5959
    60 /** TLS info for a module */
    61 typedef 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 
    7060/**
    7161 * Some data extracted from the headers are stored here
     
    8070        /** Pointer to the dynamic section */
    8171        void *dynamic;
    82 
    83         /** TLS info */
    84         elf_tls_info_t tls;
    8572} elf_finfo_t;
    8673
  • uspace/lib/c/include/rtld/module.h

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

    r32573ff r5035ba05  
    4141
    4242#include <rtld/dynamic.h>
    43 #include <tls.h>
    4443#include <types/rtld/rtld.h>
    4544
     
    4847extern void rtld_init_static(void);
    4948extern int rtld_prog_process(elf_finfo_t *, rtld_t **);
    50 extern tcb_t *rtld_tls_make(rtld_t *);
    51 extern unsigned long rtld_get_next_id(rtld_t *);
    52 extern void *rtld_tls_get_addr(rtld_t *, void *, unsigned long, unsigned long);
    5349
    5450#endif
  • uspace/lib/c/include/tls.h

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

    r32573ff r5035ba05  
    4646/** Dynamically linked module */
    4747typedef struct module {
    48         /** Module ID */
    49         unsigned long id;
    50         /** Dynamic info for this module */
    5148        dyn_info_t dyn;
    52         /** Load bias */
    5349        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;
    6350
    6451        /** Containing rtld */
  • uspace/lib/c/include/types/rtld/rtld.h

    r32573ff r5035ba05  
    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 
    5650        /** List of all loaded modules including rtld and the program */
    5751        list_t modules;
Note: See TracChangeset for help on using the changeset viewer.