Changeset View
Changeset View
Standalone View
Standalone View
head/libexec/rtld-elf/rtld.c
Show First 20 Lines • Show All 4,973 Lines • ▼ Show 20 Lines | allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign) | ||||
char *tls; | char *tls; | ||||
Elf_Addr *dtv, *olddtv; | Elf_Addr *dtv, *olddtv; | ||||
Elf_Addr segbase, oldsegbase, addr; | Elf_Addr segbase, oldsegbase, addr; | ||||
size_t i; | size_t i; | ||||
ralign = tcbalign; | ralign = tcbalign; | ||||
if (tls_static_max_align > ralign) | if (tls_static_max_align > ralign) | ||||
ralign = tls_static_max_align; | ralign = tls_static_max_align; | ||||
size = round(tls_static_space, ralign) + round(tcbsize, ralign); | size = roundup(tls_static_space, ralign) + roundup(tcbsize, ralign); | ||||
assert(tcbsize >= 2*sizeof(Elf_Addr)); | assert(tcbsize >= 2*sizeof(Elf_Addr)); | ||||
tls = malloc_aligned(size, ralign, 0 /* XXX */); | tls = malloc_aligned(size, ralign, 0 /* XXX */); | ||||
dtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr)); | dtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr)); | ||||
segbase = (Elf_Addr)(tls + round(tls_static_space, ralign)); | segbase = (Elf_Addr)(tls + roundup(tls_static_space, ralign)); | ||||
((Elf_Addr*)segbase)[0] = segbase; | ((Elf_Addr*)segbase)[0] = segbase; | ||||
((Elf_Addr*)segbase)[1] = (Elf_Addr) dtv; | ((Elf_Addr*)segbase)[1] = (Elf_Addr) dtv; | ||||
dtv[0] = tls_dtv_generation; | dtv[0] = tls_dtv_generation; | ||||
dtv[1] = tls_max_index; | dtv[1] = tls_max_index; | ||||
if (oldtls) { | if (oldtls) { | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | free_tls(void *tls, size_t tcbsize __unused, size_t tcbalign) | ||||
/* | /* | ||||
* Figure out the size of the initial TLS block so that we can | * Figure out the size of the initial TLS block so that we can | ||||
* find stuff which ___tls_get_addr() allocated dynamically. | * find stuff which ___tls_get_addr() allocated dynamically. | ||||
*/ | */ | ||||
ralign = tcbalign; | ralign = tcbalign; | ||||
if (tls_static_max_align > ralign) | if (tls_static_max_align > ralign) | ||||
ralign = tls_static_max_align; | ralign = tls_static_max_align; | ||||
size = round(tls_static_space, ralign); | size = roundup(tls_static_space, ralign); | ||||
dtv = ((Elf_Addr**)tls)[1]; | dtv = ((Elf_Addr**)tls)[1]; | ||||
dtvsize = dtv[1]; | dtvsize = dtv[1]; | ||||
tlsend = (Elf_Addr) tls; | tlsend = (Elf_Addr) tls; | ||||
tlsstart = tlsend - size; | tlsstart = tlsend - size; | ||||
for (i = 0; i < dtvsize; i++) { | for (i = 0; i < dtvsize; i++) { | ||||
if (dtv[i + 2] != 0 && (dtv[i + 2] < tlsstart || dtv[i + 2] > tlsend)) { | if (dtv[i + 2] != 0 && (dtv[i + 2] < tlsstart || dtv[i + 2] > tlsend)) { | ||||
free_aligned((void *)dtv[i + 2]); | free_aligned((void *)dtv[i + 2]); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | allocate_tls_offset(Obj_Entry *obj) | ||||
return true; | return true; | ||||
if (obj->tlssize == 0) { | if (obj->tlssize == 0) { | ||||
obj->tls_done = true; | obj->tls_done = true; | ||||
return true; | return true; | ||||
} | } | ||||
if (tls_last_offset == 0) | if (tls_last_offset == 0) | ||||
off = calculate_first_tls_offset(obj->tlssize, obj->tlsalign); | off = calculate_first_tls_offset(obj->tlssize, obj->tlsalign, | ||||
obj->tlspoffset); | |||||
else | else | ||||
off = calculate_tls_offset(tls_last_offset, tls_last_size, | off = calculate_tls_offset(tls_last_offset, tls_last_size, | ||||
obj->tlssize, obj->tlsalign); | obj->tlssize, obj->tlsalign, obj->tlspoffset); | ||||
/* | /* | ||||
* If we have already fixed the size of the static TLS block, we | * If we have already fixed the size of the static TLS block, we | ||||
* must stay within that size. When allocating the static TLS, we | * must stay within that size. When allocating the static TLS, we | ||||
* leave a small amount of space spare to be used for dynamically | * leave a small amount of space spare to be used for dynamically | ||||
* loading modules which use static TLS. | * loading modules which use static TLS. | ||||
*/ | */ | ||||
if (tls_static_space != 0) { | if (tls_static_space != 0) { | ||||
▲ Show 20 Lines • Show All 654 Lines • Show Last 20 Lines |