mirror of
https://sourceware.org/git/glibc.git
synced 2025-09-02 16:01:20 +03:00
.
This commit is contained in:
71
elf/rtld.c
71
elf/rtld.c
@@ -1,5 +1,5 @@
|
||||
/* Run time dynamic linker.
|
||||
Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-2006, 2007 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
|
||||
@@ -207,7 +207,8 @@ DL_SYSINFO_IMPLEMENTATION
|
||||
is fine, too. The latter is important here. We can avoid setting
|
||||
up a temporary link map for ld.so if we can mark _rtld_global as
|
||||
hidden. */
|
||||
#ifdef PI_STATIC_AND_HIDDEN
|
||||
#if defined PI_STATIC_AND_HIDDEN && defined HAVE_HIDDEN \
|
||||
&& defined HAVE_VISIBILITY_ATTRIBUTE
|
||||
# define DONT_USE_BOOTSTRAP_MAP 1
|
||||
#endif
|
||||
|
||||
@@ -291,7 +292,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
|
||||
GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
|
||||
GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext;
|
||||
/* Copy the TLS related data if necessary. */
|
||||
#ifndef DONT_USE_BOOTSTRAP_MAP
|
||||
#if USE_TLS && !defined DONT_USE_BOOTSTRAP_MAP
|
||||
# if USE___THREAD
|
||||
assert (info->l.l_tls_modid != 0);
|
||||
GL(dl_rtld_map).l_tls_blocksize = info->l.l_tls_blocksize;
|
||||
@@ -399,7 +400,7 @@ _dl_start (void *arg)
|
||||
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
|
||||
elf_get_dynamic_info (&bootstrap_map, NULL);
|
||||
|
||||
#if NO_TLS_OFFSET != 0
|
||||
#if defined USE_TLS && NO_TLS_OFFSET != 0
|
||||
bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
|
||||
#endif
|
||||
|
||||
@@ -700,6 +701,7 @@ match_version (const char *string, struct link_map *map)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
static bool tls_init_tp_called;
|
||||
|
||||
static void *
|
||||
@@ -771,6 +773,7 @@ cannot allocate TLS data structures for initial thread");
|
||||
|
||||
return tcbp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC_REENTRANT
|
||||
/* _dl_error_catch_tsd points to this for the single-threaded case.
|
||||
@@ -858,14 +861,18 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
hp_timing_t stop;
|
||||
hp_timing_t diff;
|
||||
#endif
|
||||
#ifdef USE_TLS
|
||||
void *tcbp = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC_REENTRANT
|
||||
/* Explicit initialization since the reloc would just be more work. */
|
||||
GL(dl_error_catch_tsd) = &_dl_initial_error_catch_tsd;
|
||||
#endif
|
||||
|
||||
#ifdef USE_TLS
|
||||
GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
|
||||
#endif
|
||||
|
||||
#if defined SHARED && defined _LIBC_REENTRANT \
|
||||
&& defined __rtld_lock_default_lock_recursive
|
||||
@@ -1150,6 +1157,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
break;
|
||||
|
||||
case PT_TLS:
|
||||
#ifdef USE_TLS
|
||||
if (ph->p_memsz > 0)
|
||||
{
|
||||
/* Note that in the case the dynamic linker we duplicate work
|
||||
@@ -1169,6 +1177,10 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
/* This image gets the ID one. */
|
||||
GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1;
|
||||
}
|
||||
#else
|
||||
_dl_fatal_printf ("\
|
||||
ld.so does not support TLS, but program uses it!\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PT_GNU_STACK:
|
||||
@@ -1180,12 +1192,13 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
main_map->l_relro_size = ph->p_memsz;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Adjust the address of the TLS initialization image in case
|
||||
the executable is actually an ET_DYN object. */
|
||||
if (main_map->l_tls_initimage != NULL)
|
||||
main_map->l_tls_initimage
|
||||
= (char *) main_map->l_tls_initimage + main_map->l_addr;
|
||||
#ifdef USE_TLS
|
||||
/* Adjust the address of the TLS initialization image in case
|
||||
the executable is actually an ET_DYN object. */
|
||||
if (main_map->l_tls_initimage != NULL)
|
||||
main_map->l_tls_initimage
|
||||
= (char *) main_map->l_tls_initimage + main_map->l_addr;
|
||||
#endif
|
||||
if (! main_map->l_map_end)
|
||||
main_map->l_map_end = ~0;
|
||||
if (! main_map->l_text_end)
|
||||
@@ -1388,10 +1401,12 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
/* Add the dynamic linker to the TLS list if it also uses TLS. */
|
||||
if (GL(dl_rtld_map).l_tls_blocksize != 0)
|
||||
/* Assign a module ID. Do this before loading any audit modules. */
|
||||
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
|
||||
#endif
|
||||
|
||||
/* If we have auditing DSOs to load, do it now. */
|
||||
if (__builtin_expect (audit_list != NULL, 0))
|
||||
@@ -1399,8 +1414,15 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
/* Iterate over all entries in the list. The order is important. */
|
||||
struct audit_ifaces *last_audit = NULL;
|
||||
struct audit_list *al = audit_list->next;
|
||||
|
||||
#ifdef USE_TLS
|
||||
/* Since we start using the auditing DSOs right away we need to
|
||||
initialize the data structures now. */
|
||||
tcbp = init_tls ();
|
||||
#endif
|
||||
do
|
||||
{
|
||||
#ifdef USE_TLS
|
||||
int tls_idx = GL(dl_tls_max_dtv_idx);
|
||||
|
||||
/* Now it is time to determine the layout of the static TLS
|
||||
@@ -1408,11 +1430,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
always allocate the static block, we never defer it even if
|
||||
no DF_STATIC_TLS bit is set. The reason is that we know
|
||||
glibc will use the static model. */
|
||||
|
||||
/* Since we start using the auditing DSOs right away we need to
|
||||
initialize the data structures now. */
|
||||
tcbp = init_tls ();
|
||||
|
||||
#endif
|
||||
struct dlmopen_args dlmargs;
|
||||
dlmargs.fname = al->name;
|
||||
dlmargs.map = NULL;
|
||||
@@ -1527,7 +1545,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
assert (GL(dl_ns)[ns]._ns_loaded == NULL);
|
||||
assert (GL(dl_ns)[ns]._ns_nloaded == 0);
|
||||
|
||||
#ifdef USE_TLS
|
||||
GL(dl_tls_max_dtv_idx) = tls_idx;
|
||||
#endif
|
||||
goto not_loaded;
|
||||
}
|
||||
}
|
||||
@@ -1803,6 +1823,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
_dl_receive_error (print_missing_version, version_check_doit, &args);
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
/* We do not initialize any of the TLS functionality unless any of the
|
||||
initial modules uses TLS. This makes dynamic loading of modules with
|
||||
TLS impossible, but to support it requires either eagerly doing setup
|
||||
@@ -1813,6 +1834,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
bool was_tls_init_tp_called = tls_init_tp_called;
|
||||
if (tcbp == NULL)
|
||||
tcbp = init_tls ();
|
||||
#endif
|
||||
|
||||
/* Set up the stack checker's canary. */
|
||||
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
|
||||
@@ -1869,12 +1891,13 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
(size_t) l->l_map_start,
|
||||
(int) sizeof l->l_addr * 2,
|
||||
(size_t) l->l_addr);
|
||||
|
||||
#ifdef USE_TLS
|
||||
if (l->l_tls_modid)
|
||||
_dl_printf (" TLS(0x%Zx, 0x%0*Zx)\n", l->l_tls_modid,
|
||||
(int) sizeof l->l_tls_offset * 2,
|
||||
(size_t) l->l_tls_offset);
|
||||
else
|
||||
#endif
|
||||
_dl_printf ("\n");
|
||||
}
|
||||
}
|
||||
@@ -1942,8 +1965,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
lookup_t result;
|
||||
|
||||
result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map,
|
||||
&ref, main_map->l_scope,
|
||||
NULL, ELF_RTYPE_CLASS_PLT,
|
||||
&ref, main_map->l_scope, NULL,
|
||||
ELF_RTYPE_CLASS_PLT,
|
||||
DL_LOOKUP_ADD_DEPENDENCY, NULL);
|
||||
|
||||
loadbase = LOOKUP_VALUE_ADDRESS (result);
|
||||
@@ -1985,8 +2008,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
{
|
||||
/* Mark the link map as not yet relocated again. */
|
||||
GL(dl_rtld_map).l_relocated = 0;
|
||||
_dl_relocate_object (&GL(dl_rtld_map),
|
||||
main_map->l_scope, 0, 0);
|
||||
_dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope,
|
||||
0, 0);
|
||||
}
|
||||
}
|
||||
#define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
|
||||
@@ -2157,9 +2180,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
if (l->l_relro_size)
|
||||
_dl_protect_relro (l);
|
||||
|
||||
#ifdef USE_TLS
|
||||
/* Add object to slot information data if necessasy. */
|
||||
if (l->l_tls_blocksize != 0 && tls_init_tp_called)
|
||||
_dl_add_to_slotinfo (l);
|
||||
#endif
|
||||
}
|
||||
|
||||
_dl_sysdep_start_cleanup ();
|
||||
@@ -2206,9 +2231,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
_dl_relocate_object (l, l->l_scope, GLRO(dl_lazy),
|
||||
consider_profiling);
|
||||
|
||||
#ifdef USE_TLS
|
||||
/* Add object to slot information data if necessasy. */
|
||||
if (l->l_tls_blocksize != 0 && tls_init_tp_called)
|
||||
_dl_add_to_slotinfo (l);
|
||||
#endif
|
||||
|
||||
l = l->l_prev;
|
||||
}
|
||||
@@ -2237,6 +2264,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
# define NONTLS_INIT_TP do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef USE_TLS
|
||||
if (!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0)
|
||||
++GL(dl_tls_generation);
|
||||
|
||||
@@ -2254,6 +2282,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
_dl_fatal_printf ("cannot set up thread-local storage: %s\n",
|
||||
lossage);
|
||||
}
|
||||
#else
|
||||
NONTLS_INIT_TP;
|
||||
#endif
|
||||
|
||||
if (! prelinked && rtld_multiple_ref)
|
||||
{
|
||||
|
Reference in New Issue
Block a user