summaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-close.c24
-rw-r--r--elf/dl-lookup.c6
-rw-r--r--elf/dl-open.c10
-rw-r--r--elf/dl-runtime.c17
-rw-r--r--elf/dl-sym.c7
5 files changed, 41 insertions, 23 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 84e57e09d0..bfcceea4bc 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -30,6 +30,7 @@
#include <ldsodefs.h>
#include <sys/types.h>
#include <sys/mman.h>
+#include <sysdep-cancel.h>
/* Type of the constructor functions. */
@@ -419,16 +420,21 @@ _dl_close (void *_map)
struct r_scoperec *old = imap->l_scoperec;
- __rtld_mrlock_change (imap->l_scoperec_lock);
- imap->l_scoperec = newp;
- __rtld_mrlock_done (imap->l_scoperec_lock);
-
- if (catomic_increment_val (&old->nusers) != 1)
+ if (SINGLE_THREAD_P)
+ imap->l_scoperec = newp;
+ else
{
- old->remove_after_use = true;
- old->notify = true;
- if (catomic_decrement_val (&old->nusers) != 0)
- __rtld_waitzero (old->nusers);
+ __rtld_mrlock_change (imap->l_scoperec_lock);
+ imap->l_scoperec = newp;
+ __rtld_mrlock_done (imap->l_scoperec_lock);
+
+ if (atomic_increment_val (&old->nusers) != 1)
+ {
+ old->remove_after_use = true;
+ old->notify = true;
+ if (atomic_decrement_val (&old->nusers) != 0)
+ __rtld_waitzero (old->nusers);
+ }
}
/* No user anymore, we can free it now. */
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 7cfcc620a7..72381698db 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -207,7 +207,11 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
/* Search loaded objects' symbol tables for a definition of the symbol
- UNDEF_NAME, perhaps with a requested version for the symbol. */
+ UNDEF_NAME, perhaps with a requested version for the symbol.
+
+ We must never have calls to the audit functions inside this function
+ or in any function which gets called. If this would happen the audit
+ code might create a thread which can throw off all the scope locking. */
lookup_t
internal_function
_dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 35712b5ac0..85b9637305 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -31,6 +31,7 @@
#include <ldsodefs.h>
#include <bp-sym.h>
#include <caller.h>
+#include <sysdep-cancel.h>
#include <dl-dst.h>
@@ -423,15 +424,20 @@ dl_open_worker (void *a)
if (old == &imap->l_scoperec_mem)
imap->l_scoperec = newp;
+ else if (SINGLE_THREAD_P)
+ {
+ imap->l_scoperec = newp;
+ free (old);
+ }
else
{
__rtld_mrlock_change (imap->l_scoperec_lock);
imap->l_scoperec = newp;
__rtld_mrlock_done (imap->l_scoperec_lock);
- catomic_increment (&old->nusers);
+ atomic_increment (&old->nusers);
old->remove_after_use = true;
- if (catomic_decrement_val (&old->nusers) == 0)
+ if (atomic_decrement_val (&old->nusers) == 0)
/* No user, we can free it here and now. */
free (old);
}
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 05fd974bf5..8bf5b89eb6 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -24,6 +24,7 @@
#include <unistd.h>
#include <sys/param.h>
#include <ldsodefs.h>
+#include <sysdep-cancel.h>
#include "dynamic-link.h"
#if (!defined ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
@@ -93,11 +94,11 @@ _dl_fixup (
}
struct r_scoperec *scoperec = l->l_scoperec;
- if (l->l_type == lt_loaded)
+ if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
{
__rtld_mrlock_lock (l->l_scoperec_lock);
scoperec = l->l_scoperec;
- catomic_increment (&scoperec->nusers);
+ atomic_increment (&scoperec->nusers);
__rtld_mrlock_unlock (l->l_scoperec_lock);
}
@@ -106,8 +107,8 @@ _dl_fixup (
ELF_RTYPE_CLASS_PLT,
DL_LOOKUP_ADD_DEPENDENCY, NULL);
- if (l->l_type == lt_loaded
- && catomic_decrement_val (&scoperec->nusers) == 0
+ if (l->l_type == lt_loaded && !SINGLE_THREAD_P
+ && atomic_decrement_val (&scoperec->nusers) == 0
&& __builtin_expect (scoperec->remove_after_use, 0))
{
if (scoperec->notify)
@@ -195,11 +196,11 @@ _dl_profile_fixup (
}
struct r_scoperec *scoperec = l->l_scoperec;
- if (l->l_type == lt_loaded)
+ if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
{
__rtld_mrlock_lock (l->l_scoperec_lock);
scoperec = l->l_scoperec;
- catomic_increment (&scoperec->nusers);
+ atomic_increment (&scoperec->nusers);
__rtld_mrlock_unlock (l->l_scoperec_lock);
}
@@ -208,8 +209,8 @@ _dl_profile_fixup (
ELF_RTYPE_CLASS_PLT,
DL_LOOKUP_ADD_DEPENDENCY, NULL);
- if (l->l_type == lt_loaded
- && catomic_decrement_val (&scoperec->nusers) == 0
+ if (l->l_type == lt_loaded && !SINGLE_THREAD_P
+ && atomic_decrement_val (&scoperec->nusers) == 0
&& __builtin_expect (scoperec->remove_after_use, 0))
{
if (scoperec->notify)
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 43933466b4..34d75a1a67 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -25,6 +25,7 @@
#include <dlfcn.h>
#include <ldsodefs.h>
#include <dl-hash.h>
+#include <sysdep-cancel.h>
#ifdef USE_TLS
# include <dl-tls.h>
#endif
@@ -115,7 +116,7 @@ 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 (match->l_type != lt_loaded)
+ if (match->l_type != lt_loaded || SINGLE_THREAD_P)
result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
match->l_scoperec->scope, vers, 0,
flags | DL_LOOKUP_ADD_DEPENDENCY,
@@ -124,7 +125,7 @@ do_sym (void *handle, const char *name, void *who,
{
__rtld_mrlock_lock (match->l_scoperec_lock);
struct r_scoperec *scoperec = match->l_scoperec;
- catomic_increment (&scoperec->nusers);
+ atomic_increment (&scoperec->nusers);
__rtld_mrlock_unlock (match->l_scoperec_lock);
struct call_dl_lookup_args args;
@@ -141,7 +142,7 @@ do_sym (void *handle, const char *name, void *who,
int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced,
call_dl_lookup, &args);
- if (catomic_decrement_val (&scoperec->nusers) == 0
+ if (atomic_decrement_val (&scoperec->nusers) == 0
&& __builtin_expect (scoperec->remove_after_use, 0))
{
if (scoperec->notify)