summaryrefslogtreecommitdiff
path: root/elf/dl-sym.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-sym.c')
-rw-r--r--elf/dl-sym.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index fa0e3a67fc..88a5adb0d5 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -1,5 +1,5 @@
/* Look up a symbol in a shared object loaded by `dlopen'.
- Copyright (C) 1999-2002,2004,2006,2007 Free Software Foundation, Inc.
+ Copyright (C) 1999,2000,2001,2002,2004,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -26,12 +26,10 @@
#include <ldsodefs.h>
#include <dl-hash.h>
#include <sysdep-cancel.h>
-#ifdef USE_TLS
-# include <dl-tls.h>
-#endif
+#include <dl-tls.h>
-#if defined USE_TLS && defined SHARED
+#ifdef SHARED
/* Systems which do not have tls_index also probably have to define
DONT_USE_TLS_INDEX. */
@@ -100,9 +98,10 @@ do_sym (void *handle, const char *name, void *who,
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
l = l->l_next)
- if (caller >= l->l_map_start && caller < l->l_map_end
- && (l->l_contiguous || _dl_addr_inside_object (l, caller)))
+ if (caller >= l->l_map_start && caller < l->l_map_end)
{
+ /* There must be exactly one DSO for the range of the virtual
+ memory. Otherwise something is really broken. */
match = l;
break;
}
@@ -114,13 +113,15 @@ do_sym (void *handle, const char *name, void *who,
the initial binary. And then the more complex part
where the object is dynamically loaded and the scope
array can change. */
- if (RTLD_SINGLE_THREAD_P)
+ if (match->l_type != lt_loaded || RTLD_SINGLE_THREAD_P)
result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
match->l_scope, vers, 0,
flags | DL_LOOKUP_ADD_DEPENDENCY,
NULL);
else
{
+ __rtld_mrlock_lock (match->l_scope_lock);
+
struct call_dl_lookup_args args;
args.name = name;
args.map = match;
@@ -128,15 +129,13 @@ do_sym (void *handle, const char *name, void *who,
args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY;
args.refp = &ref;
- THREAD_GSCOPE_SET_FLAG ();
-
const char *objname;
const char *errstring = NULL;
bool malloced;
int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced,
call_dl_lookup, &args);
- THREAD_GSCOPE_RESET_FLAG ();
+ __rtld_mrlock_unlock (match->l_scope_lock);
if (__builtin_expect (errstring != NULL, 0))
{
@@ -183,7 +182,7 @@ RTLD_NEXT used in code not dynamically loaded"));
{
void *value;
-#if defined USE_TLS && defined SHARED
+#ifdef SHARED
if (ELFW(ST_TYPE) (ref->st_info) == STT_TLS)
/* The found symbol is a thread-local storage variable.
Return the address for to the current thread. */