summaryrefslogtreecommitdiff
path: root/elf/dl-reloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-reloc.c')
-rw-r--r--elf/dl-reloc.c42
1 files changed, 19 insertions, 23 deletions
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index e9784c2094..a303cb4ce6 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -1,5 +1,5 @@
/* Relocate a shared object and resolve its references to other loaded objects.
- Copyright (C) 1995-2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1995-2004, 2005, 2006, 2008 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
@@ -43,9 +43,9 @@
This function intentionally does not return any value but signals error
directly, as static TLS should be rare and code handling it should
not be inlined as much as possible. */
-void
-internal_function __attribute_noinline__
-_dl_allocate_static_tls (struct link_map *map)
+int
+internal_function
+_dl_try_allocate_static_tls (struct link_map *map)
{
/* If we've already used the variable with dynamic access, or if the
alignment requirements are too high, fail. */
@@ -53,8 +53,7 @@ _dl_allocate_static_tls (struct link_map *map)
|| map->l_tls_align > GL(dl_tls_static_align))
{
fail:
- _dl_signal_error (0, map->l_name, NULL, N_("\
-cannot allocate memory in static TLS block"));
+ return -1;
}
#if TLS_TCB_AT_TP
@@ -108,6 +107,20 @@ cannot allocate memory in static TLS block"));
}
else
map->l_need_tls_init = 1;
+
+ return 0;
+}
+
+void
+internal_function __attribute_noinline__
+_dl_allocate_static_tls (struct link_map *map)
+{
+ if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
+ || _dl_try_allocate_static_tls (map))
+ {
+ _dl_signal_error (0, map->l_name, NULL, N_("\
+cannot allocate memory in static TLS block"));
+ }
}
/* Initialize static TLS area and DTV for current (only) thread.
@@ -248,23 +261,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
l->l_lookup_cache.value = _lr; })) \
: l)
- /* This macro is used as a callback from elf_machine_rel{a,} when a
- static TLS reloc is about to be performed. Since (in dl-load.c) we
- permit dynamic loading of objects that might use such relocs, we
- have to check whether each use is actually doable. If the object
- whose TLS segment the reference resolves to was allocated space in
- the static TLS block at startup, then it's ok. Otherwise, we make
- an attempt to allocate it in surplus space on the fly. If that
- can't be done, we fall back to the error that DF_STATIC_TLS is
- intended to produce. */
-#define CHECK_STATIC_TLS(map, sym_map) \
- do { \
- if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET \
- || ((sym_map)->l_tls_offset \
- == FORCED_DYNAMIC_TLS_OFFSET), 0)) \
- _dl_allocate_static_tls (sym_map); \
- } while (0)
-
#include "dynamic-link.h"
ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling);