Changeset d2bb25e7 in mainline for uspace/lib/c/generic/rtld/rtld.c


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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/** @}
Note: See TracChangeset for help on using the changeset viewer.