- pthread_t self = __pthread_self();
- struct dso *p;
- for (p=head; p; p=p->next) {
- if (!p->tls_id || !self->dtv[p->tls_id]) continue;
- memcpy(self->dtv[p->tls_id], p->tls_image, p->tls_len);
- memset((char *)self->dtv[p->tls_id]+p->tls_len, 0,
- p->tls_size - p->tls_len);
- if (p->tls_id == (size_t)self->dtv[0]) break;
- }
-}
-
-void *__copy_tls(unsigned char *mem)
-{
- pthread_t td;
- struct dso *p;
- void **dtv;
-
-#ifdef TLS_ABOVE_TP
- dtv = (void **)(mem + libc.tls_size) - (tls_cnt + 1);
-
- mem += -((uintptr_t)mem + sizeof(struct pthread)) & (tls_align-1);
- td = (pthread_t)mem;
- mem += sizeof(struct pthread);
-
- for (p=head; p; p=p->next) {
- if (!p->tls_id) continue;
- dtv[p->tls_id] = mem + p->tls_offset;
- memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
- }
-#else
- dtv = (void **)mem;
-
- mem += libc.tls_size - sizeof(struct pthread);
- mem -= (uintptr_t)mem & (tls_align-1);
- td = (pthread_t)mem;
-
- for (p=head; p; p=p->next) {
- if (!p->tls_id) continue;
- dtv[p->tls_id] = mem - p->tls_offset;
- memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
- }
-#endif
- dtv[0] = (void *)tls_cnt;
- td->dtv = td->dtv_copy = dtv;
- return td;