This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[patch] Fix for BZ#11952
- From: ppluzhnikov at google dot com (Paul Pluzhnikov)
- To: libc-alpha at sourceware dot org
- Cc: ppluzhnikov at google dot com
- Date: Tue, 7 Sep 2010 09:12:27 -0700 (PDT)
- Subject: [patch] Fix for BZ#11952
Greetings,
This is a slightly modified version of the patch I attached to
http://sourceware.org/bugzilla/show_bug.cgi?id=11952 a week ago.
I would appreciate review/comments.
[Google has blanket FSF Copyright assignment.]
Thanks,
--
Paul Pluzhnikov
2010-09-07 Paul Pluzhnikov <ppluzhnikov@google.com>
* elf/dl-open.c (dl_open_worker): Fix for [BZ#11952].
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 754a263..a87cc67 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -376,6 +376,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;
+ unsigned int static_tls_counter = 0;
for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
{
struct link_map *imap = new->l_searchlist.r_list[i];
@@ -454,7 +455,27 @@ dl_open_worker (void *a)
might have to increase its size. */
_dl_add_to_slotinfo (imap);
+ /* We have to bump the generation counter. */
+ any_tls = true;
+
if (imap->l_need_tls_init)
+ /* We must iterate over all maps again after we have
+ added them to slotinfo. BZ#11952. */
+ ++static_tls_counter;
+ }
+ }
+
+ if (any_tls)
+ {
+ for (unsigned int i = 0; static_tls_counter > 0; ++i)
+ {
+ assert (i < new->l_searchlist.r_nlist);
+ struct link_map *imap = new->l_searchlist.r_list[i];
+
+ if (! imap->l_init_called
+ /* Only if the module defines thread local data. */
+ && __builtin_expect (imap->l_tls_blocksize > 0, 0)
+ && imap->l_need_tls_init)
{
/* For static TLS we have to allocate the memory here
and now. This includes allocating memory in the DTV.
@@ -477,17 +498,17 @@ cannot load any more object with static TLS"));
GL(dl_init_static_tls) (imap);
assert (imap->l_need_tls_init == 0);
+ --static_tls_counter;
}
-
- /* We have to bump the generation counter. */
- any_tls = true;
}
- }
- /* Bump the generation number if necessary. */
- if (any_tls && __builtin_expect (++GL(dl_tls_generation) == 0, 0))
- _dl_fatal_printf (N_("\
+ assert (static_tls_counter == 0);
+
+ /* Bump the generation number. */
+ if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
+ _dl_fatal_printf (N_("\
TLS generation counter wrapped! Please report this."));
+ }
/* Run the initializer functions of new objects. */
_dl_init (new, args->argc, args->argv, args->env);