Changeset d2bb25e7 in mainline


Ignore:
Timestamp:
2016-05-17T22:51:37Z (9 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9c07c3d
Parents:
e2f26002
Message:

Use DTVs. symbol_get_addr() should not implicitly read current thread pointer.

Location:
uspace/lib/c
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/arch/ia32/include/libarch/tls.h

    re2f26002 rd2bb25e7  
    4343        void *self;
    4444        void *fibril_data;
     45        void **dtv;
    4546} tcb_t;
    4647
  • uspace/lib/c/arch/ia32/src/rtld/reloc.c

    re2f26002 rd2bb25e7  
    101101                        sym_def = symbol_def_find(str_tab + sym->st_name,
    102102                            m, ssf_none, &dest);
    103 //                      DPRINTF("dest name: '%s'\n", dest->dyn.soname);
     103                        DPRINTF("dest name: '%s'\n", dest->dyn.soname);
    104104//                      DPRINTF("dest bias: 0x%x\n", dest->bias);
    105105                        if (sym_def) {
    106106                                sym_addr = (uint32_t)
    107                                     symbol_get_addr(sym_def, dest);
     107                                    symbol_get_addr(sym_def, dest, NULL);
    108108//                              DPRINTF("symbol definition found, addr=0x%x\n", sym_addr);
    109109                        } else {
     
    154154                        if (sym_def) {
    155155                                sym_addr = (uint32_t)
    156                                     symbol_get_addr(sym_def, dest);
     156                                    symbol_get_addr(sym_def, dest, NULL);
    157157                        } else {
    158158                                printf("Source definition of '%s' not found.\n",
  • uspace/lib/c/arch/ia32/src/tls.c

    re2f26002 rd2bb25e7  
    7373#ifdef CONFIG_RTLD
    7474        if (runtime_env != NULL) {
    75                 return rtld_tls_get_addr(runtime_env, ti->ti_module,
    76                     ti->ti_offset);
     75                return rtld_tls_get_addr(runtime_env, __tcb_get(),
     76                    ti->ti_module, ti->ti_offset);
    7777        }
    7878#endif
  • uspace/lib/c/generic/dlfcn.c

    re2f26002 rd2bb25e7  
    8484        sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm);
    8585        if (sd != NULL) {
    86                 return symbol_get_addr(sd, sm);
     86                return symbol_get_addr(sd, sm, __tcb_get());
    8787        }
    8888
  • uspace/lib/c/generic/rtld/rtld.c

    re2f26002 rd2bb25e7  
    143143        tcb_t *tcb;
    144144        size_t offset;
     145        void **dtv;
     146        size_t nmods;
     147        size_t i;
    145148
    146149        tcb = tls_alloc_arch(&data, rtld->tls_size);
     
    148151                return NULL;
    149152
    150         /*
    151          * Copy thread local data from the modules' initialization images.
    152          * Zero out thread-local uninitialized data.
     153        /** Allocate dynamic thread vector */
     154        nmods = list_count(&rtld->imodules);
     155        dtv = malloc((nmods + 1) * sizeof(void *));
     156        if (dtv == NULL) {
     157                tls_free(tcb);
     158                return NULL;
     159        }
     160
     161        /*
     162         * We define generation number to be equal to vector length.
     163         * We start with a vector covering the initially loaded modules.
     164         */
     165        DTV_GN(dtv) = nmods;
     166
     167        /*
     168         * Copy thread local data from the initialization images of initial
     169         * modules. Zero out thread-local uninitialized data.
    153170         */
    154171
     
    157174         * Ascending addresses
    158175         */
    159         offset = 0;
     176        offset = 0; i = 1;
    160177        list_foreach(rtld->imodules, imodules_link, module_t, m) {
     178                assert(i == m->id);
    161179                assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size);
     180                dtv[i++] = data + offset;
    162181                memcpy(data + offset, m->tdata, m->tdata_size);
    163182                offset += m->tdata_size;
     
    169188         * Descending addresses
    170189         */
    171         offset = 0;
     190        offset = 0; i = 1;
    172191        list_foreach(rtld->imodules, imodules_link, module_t, m) {
     192                assert(i == m->id);
    173193                assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size);
    174194                offset += m->tbss_size;
     
    176196                offset += m->tdata_size;
    177197                memcpy(data + rtld->tls_size - offset, m->tdata, m->tdata_size);
     198                dtv[i++] = data + rtld->tls_size - offset;
    178199        }
    179200#endif
    180201
     202        tcb->dtv = dtv;
    181203        return tcb;
    182204}
     
    187209}
    188210
    189 void *rtld_tls_get_addr(rtld_t *rtld, unsigned long mod_id,
     211/** Get address of thread-local variable.
     212 *
     213 * @param rtld RTLD instance
     214 * @param tcb TCB of the thread whose instance to return
     215 * @param mod_id Module ID
     216 * @param offset Offset within TLS block of the module
     217 *
     218 * @return Address of thread-local variable
     219 */
     220void *rtld_tls_get_addr(rtld_t *rtld, tcb_t *tcb, unsigned long mod_id,
    190221    unsigned long offset)
    191222{
    192         module_t *m;
    193         uint8_t *tls;
    194 
    195         m = module_by_id(rtld, mod_id);
    196         assert(m != NULL);
    197 
    198         if (!link_used(&m->imodules_link)) {
    199                 printf("module '%s' is not initial. aborting.\n",
    200                     m->dyn.soname);
     223        if (DTV_GN(tcb->dtv) < mod_id || tcb->dtv[mod_id] == NULL) {
     224                printf("Module is not initial. aborting.\n");
    201225                abort();
    202226        }
    203227
    204         tls = tls_get();
    205         return tls + m->ioffs + offset;
    206 }
    207 
     228        return (uint8_t *)(tcb->dtv[mod_id]) + offset;
     229}
    208230
    209231/** @}
  • uspace/lib/c/generic/rtld/symbol.c

    re2f26002 rd2bb25e7  
    249249}
    250250
    251 void *symbol_get_addr(elf_symbol_t *sym, module_t *m)
     251/** Get symbol address.
     252 *
     253 * @param sym Symbol
     254 * @param m Module contaning the symbol
     255 * @param tcb TCB of the thread whose thread-local variable instance should
     256 *            be returned. If @a tcb is @c NULL then @c NULL is returned for
     257 *            thread-local variables.
     258 *
     259 * @return Symbol address
     260 */
     261void *symbol_get_addr(elf_symbol_t *sym, module_t *m, tcb_t *tcb)
    252262{
    253263        if (ELF_ST_TYPE(sym->st_info) == STT_TLS) {
    254                 return rtld_tls_get_addr(m->rtld, m->id, sym->st_value);
     264                if (tcb == NULL)
     265                        return NULL;
     266                return rtld_tls_get_addr(m->rtld, tcb, m->id, sym->st_value);
    255267        } else if (sym->st_shndx == SHN_ABS) {
    256268                /* Do not add bias to absolute symbols */
  • uspace/lib/c/generic/tls.c

    re2f26002 rd2bb25e7  
    9797void tls_free(tcb_t *tcb)
    9898{
     99        free(tcb->dtv);
    99100        tls_free_arch(tcb, tls_get_size());
    100101}
     
    109110tcb_t *tls_alloc_variant_1(void **data, size_t size)
    110111{
    111         tcb_t *result;
     112        tcb_t *tcb;
    112113
    113         result = malloc(sizeof(tcb_t) + size);
    114         if (!result)
     114        tcb = malloc(sizeof(tcb_t) + size);
     115        if (!tcb)
    115116                return NULL;
    116         *data = ((void *)result) + sizeof(tcb_t);
     117        *data = ((void *)tcb) + sizeof(tcb_t);
     118        tcb->dtv = NULL;
    117119
    118         return result;
     120        return tcb;
    119121}
    120122
     
    147149        tcb = (tcb_t *) (*data + size);
    148150        tcb->self = tcb;
     151        tcb->dtv = NULL;
    149152
    150153        return tcb;
  • uspace/lib/c/include/rtld/rtld.h

    re2f26002 rd2bb25e7  
    5050extern tcb_t *rtld_tls_make(rtld_t *);
    5151extern unsigned long rtld_get_next_id(rtld_t *);
    52 extern void *rtld_tls_get_addr(rtld_t *, unsigned long, unsigned long);
     52extern void *rtld_tls_get_addr(rtld_t *, tcb_t *, unsigned long, unsigned long);
    5353
    5454#endif
  • uspace/lib/c/include/rtld/symbol.h

    re2f26002 rd2bb25e7  
    3838#include <elf/elf.h>
    3939#include <rtld/rtld.h>
     40#include <tls.h>
    4041
    4142/** Symbol search flags */
     
    5051extern elf_symbol_t *symbol_def_find(const char *, module_t *,
    5152    symbol_search_flags_t, module_t **);
    52 extern void *symbol_get_addr(elf_symbol_t *, module_t *);
     53extern void *symbol_get_addr(elf_symbol_t *, module_t *, tcb_t *);
    5354
    5455#endif
  • uspace/lib/c/include/tls.h

    re2f26002 rd2bb25e7  
    3939#include <sys/types.h>
    4040
     41/** DTV Generation number - equals vector length */
     42#define DTV_GN(dtv) (((uintptr_t *)(dtv))[0])
     43
    4144/*
    4245 * Symbols defined in the respective linker script.
Note: See TracChangeset for help on using the changeset viewer.