aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-open.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-open.c')
-rw-r--r--elf/dl-open.c79
1 files changed, 33 insertions, 46 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c
index c997521126..8d057f82eb 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -31,7 +31,6 @@
#include <ldsodefs.h>
#include <bp-sym.h>
#include <caller.h>
-#include <sysdep-cancel.h>
#include <dl-dst.h>
@@ -164,7 +163,9 @@ dl_open_worker (void *a)
struct link_map *new, *l;
int lazy;
unsigned int i;
+#ifdef USE_TLS
bool any_tls = false;
+#endif
struct link_map *call_map = NULL;
/* Check whether _dl_open() has been called from a valid DSO. */
@@ -378,8 +379,6 @@ dl_open_worker (void *a)
while (*runp != NULL)
{
- if (*runp == &new->l_searchlist)
- break;
++cnt;
++runp;
}
@@ -392,53 +391,37 @@ dl_open_worker (void *a)
{
/* The 'r_scope' array is too small. Allocate a new one
dynamically. */
- size_t new_size;
struct r_scope_elem **newp;
+ size_t new_size = imap->l_scope_max * 2;
-#define SCOPE_ELEMS(imap) \
- (sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0]))
-
- if (imap->l_scope != imap->l_scope_mem
- && imap->l_scope_max < SCOPE_ELEMS (imap))
- {
- new_size = SCOPE_ELEMS (imap);
- newp = imap->l_scope_mem;
- }
- else
+ if (imap->l_scope == imap->l_scope_mem)
{
- new_size = imap->l_scope_max * 2;
newp = (struct r_scope_elem **)
malloc (new_size * sizeof (struct r_scope_elem *));
if (newp == NULL)
_dl_signal_error (ENOMEM, "dlopen", NULL,
N_("cannot create scope list"));
+ imap->l_scope = memcpy (newp, imap->l_scope,
+ cnt * sizeof (imap->l_scope[0]));
}
-
- memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0]));
- struct r_scope_elem **old = imap->l_scope;
-
- if (RTLD_SINGLE_THREAD_P)
- imap->l_scope = newp;
else
{
- __rtld_mrlock_change (imap->l_scope_lock);
+ newp = (struct r_scope_elem **)
+ realloc (imap->l_scope,
+ new_size * sizeof (struct r_scope_elem *));
+ if (newp == NULL)
+ _dl_signal_error (ENOMEM, "dlopen", NULL,
+ N_("cannot create scope list"));
imap->l_scope = newp;
- __rtld_mrlock_done (imap->l_scope_lock);
}
- if (old != imap->l_scope_mem)
- free (old);
-
imap->l_scope_max = new_size;
}
- /* First terminate the extended list. Otherwise a thread
- might use the new last element and then use the garbage
- at offset IDX+1. */
- imap->l_scope[cnt + 1] = NULL;
- atomic_write_barrier ();
- imap->l_scope[cnt] = &new->l_searchlist;
+ imap->l_scope[cnt++] = &new->l_searchlist;
+ imap->l_scope[cnt] = NULL;
}
+#if USE_TLS
/* Only add TLS memory if this object is loaded now and
therefore is not yet initialized. */
else if (! imap->l_init_called
@@ -453,11 +436,11 @@ dl_open_worker (void *a)
if (imap->l_need_tls_init)
{
imap->l_need_tls_init = 0;
-#ifdef SHARED
+# ifdef SHARED
/* Update the slot information data for at least the
generation of the DSO we are allocating data for. */
_dl_update_slotinfo (imap->l_tls_modid);
-#endif
+# endif
GL(dl_init_static_tls) (imap);
assert (imap->l_need_tls_init == 0);
@@ -466,12 +449,15 @@ dl_open_worker (void *a)
/* We have to bump the generation counter. */
any_tls = true;
}
+#endif
}
+#if USE_TLS
/* Bump the generation number if necessary. */
if (any_tls && __builtin_expect (++GL(dl_tls_generation) == 0, 0))
_dl_fatal_printf (N_("\
TLS generation counter wrapped! Please report this."));
+#endif
/* Run the initializer functions of new objects. */
_dl_init (new, args->argc, args->argv, args->env);
@@ -561,13 +547,20 @@ no more namespaces available for dlmopen()"));
_dl_unload_cache ();
#endif
- /* See if an error occurred during loading. */
+ /* Release the lock. */
+ __rtld_lock_unlock_recursive (GL(dl_load_lock));
+
if (__builtin_expect (errstring != NULL, 0))
{
+ /* Some error occurred during loading. */
+ char *local_errstring;
+ size_t len_errstring;
+
/* Remove the object from memory. It may be in an inconsistent
state if relocation failed, for example. */
if (args.map)
{
+#ifdef USE_TLS
/* Maybe some of the modules which were loaded use TLS.
Since it will be removed in the following _dl_close call
we have to mark the dtv array as having gaps to fill the
@@ -577,19 +570,14 @@ no more namespaces available for dlmopen()"));
up. */
if ((mode & __RTLD_AUDIT) == 0)
GL(dl_tls_dtv_gaps) = true;
+#endif
- _dl_close_worker (args.map);
+ _dl_close (args.map);
}
- assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
-
- /* Release the lock. */
- __rtld_lock_unlock_recursive (GL(dl_load_lock));
-
/* Make a local copy of the error string so that we can release the
memory allocated for it. */
- size_t len_errstring = strlen (errstring) + 1;
- char *local_errstring;
+ len_errstring = strlen (errstring) + 1;
if (objname == errstring + len_errstring)
{
size_t total_len = len_errstring + strlen (objname) + 1;
@@ -606,15 +594,14 @@ no more namespaces available for dlmopen()"));
if (malloced)
free ((char *) errstring);
+ assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
+
/* Reraise the error. */
_dl_signal_error (errcode, objname, NULL, local_errstring);
}
assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
- /* Release the lock. */
- __rtld_lock_unlock_recursive (GL(dl_load_lock));
-
#ifndef SHARED
DL_STATIC_INIT (args.map);
#endif