--- glibc-2.12.2/elf/dl-open.c +++ glibc-2.12.2/elf/dl-open.c @@ -346,7 +346,7 @@ dl_open_worker (void *a) /* If the file is not loaded now as a dependency, add the search list of the newly loaded object to the scope. */ - bool any_tls = false; + bool any_tls = false, any_static_tls = false; for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) { struct link_map *imap = new->l_searchlist.r_list[i]; @@ -426,6 +426,25 @@ dl_open_worker (void *a) _dl_add_to_slotinfo (imap); if (imap->l_need_tls_init) + any_static_tls = true; + + /* We have to bump the generation counter. */ + any_tls = true; + } + } + + /* We need a second pass for static tls data, because _dl_update_slotinfo + must not be run while calls to _dl_add_to_slotinfo are still pending. */ + if (__builtin_expect (any_static_tls, 0)) + { + for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) + { + struct link_map *imap = new->l_searchlist.r_list[i]; + if (__builtin_expect (imap->l_need_tls_init, 0) + /* The following two can likely be dropped, but let's be extra + safe and copy all the conditions for now. */ + && ! imap->l_init_called + && __builtin_expect (imap->l_tls_blocksize > 0, 0)) { /* For static TLS we have to allocate the memory here and now. This includes allocating memory in the DTV. @@ -449,9 +468,6 @@ cannot load any more object with static GL(dl_init_static_tls) (imap); assert (imap->l_need_tls_init == 0); } - - /* We have to bump the generation counter. */ - any_tls = true; } }