[BZ #16046] Static dlopen correction fallout fixes.

Fixes to address issues from BZ #15022 resolution, as follows:

* TLS updates to csu/libc-tls.c -- we now have a proper main map, so
  there's no longer a need to create a separate fake one to keep TLS
  structures,

* random updates to elf/dl-close.c -- LM_ID_BASE is now a valid name
  space ID for static executables as well, so assert that we don't
  unload the main map.  Similarly dl_nns isn't supposed to be 0 for
  static executables anymore,

* actual BZ #16046 fix to elf/dl-iteratephdr.c -- the dl_iterate_phdr
  special function for static executables isn't needed anymore, provided
  that l_phdr and l_phnum members of the main map have been properly
  initialized (done in _dl_non_dynamic_init in elf/dl-support.c now),

* ld.so.cache loader update to elf/dl-load.c --
  GL(dl_ns)[LM_ID_BASE]._ns_loaded is now always initialized in static
  executables so can become the fallback loader map to check for
  DF_1_NODEFLIB, provided that the l_flags_1 member of the main map has
  been properly initialized (done in elf/dl-support.c now); this also
  ensures previous semantics elsewhere in elf/dl-load.c,

* matching updates to elf/dl-support.c -- to complement the two fixes
  above.
This commit is contained in:
Maciej W. Rozycki 2014-01-31 17:51:31 +00:00
parent 0037bb6010
commit 0d23a5c1b1
7 changed files with 43 additions and 71 deletions

View File

@ -1,3 +1,19 @@
2014-01-31 Maciej W. Rozycki <macro@codesourcery.com>
[BZ #16046]
* csu/libc-tls.c (static_map): Remove variable.
(__libc_setup_tls): Use main executable's link map for TLS data.
* elf/dl-close.c (_dl_close_worker) [!SHARED]: Remove special
casing for LM_ID_BASE and GL(dl_nns).
* elf/dl-iteratephdr.c [!SHARED] (dl_iterate_phdr): Remove
function. Alias dl_iterate_phdr to __dl_iterate_phdr.
* elf/dl-load.c (_dl_map_object) [!SHARED]: Remove special
casing for GL(dl_ns)[LM_ID_BASE]._ns_loaded.
* elf/dl-support.c (_dl_main_map): Also initialize l_flags_1
member.
(_dl_non_dynamic_init): Also initialize _dl_main_map's l_phdr and
l_phnum members.
2014-01-30 Alexandre Oliva <aoliva@redhat.com>
* manual/debug.texi: Document MTASC-safety properties.

14
NEWS
View File

@ -20,13 +20,13 @@ Version 2.19
15847, 15849, 15850, 15855, 15856, 15857, 15859, 15867, 15886, 15887,
15890, 15892, 15893, 15895, 15897, 15901, 15905, 15909, 15915, 15917,
15919, 15921, 15923, 15939, 15941, 15948, 15963, 15966, 15985, 15988,
15997, 16032, 16034, 16036, 16037, 16038, 16041, 16055, 16071, 16072,
16074, 16077, 16078, 16103, 16112, 16133, 16143, 16144, 16146, 16150,
16151, 16153, 16167, 16169, 16172, 16195, 16214, 16245, 16271, 16274,
16283, 16289, 16293, 16314, 16316, 16330, 16337, 16338, 16356, 16365,
16366, 16369, 16372, 16375, 16379, 16384, 16385, 16386, 16387, 16390,
16394, 16400, 16407, 16408, 16414, 16430, 16431, 16453, 16474, 16506,
16510
15997, 16032, 16034, 16036, 16037, 16038, 16041, 16046, 16055, 16071,
16072, 16074, 16077, 16078, 16103, 16112, 16133, 16143, 16144, 16146,
16150, 16151, 16153, 16167, 16169, 16172, 16195, 16214, 16245, 16271,
16274, 16283, 16289, 16293, 16314, 16316, 16330, 16337, 16338, 16356,
16365, 16366, 16369, 16372, 16375, 16379, 16384, 16385, 16386, 16387,
16390, 16394, 16400, 16407, 16408, 16414, 16430, 16431, 16453, 16474,
16506, 16510
* Slovenian translations for glibc messages have been contributed by the
Translation Project's Slovenian team of translators.

View File

@ -42,9 +42,6 @@ static struct
struct dtv_slotinfo info[2 + TLS_SLOTINFO_SURPLUS];
} static_slotinfo;
/* Fake link map for the application. */
static struct link_map static_map;
/* Highest dtv index currently needed. */
size_t _dl_tls_max_dtv_idx;
@ -162,14 +159,16 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
_dl_static_dtv[0].counter = (sizeof (_dl_static_dtv) / sizeof (_dl_static_dtv[0])) - 2;
// _dl_static_dtv[1].counter = 0; would be needed if not already done
struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
/* Initialize the TLS block. */
#if TLS_TCB_AT_TP
_dl_static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset
- roundup (memsz, align ?: 1));
static_map.l_tls_offset = roundup (memsz, align ?: 1);
main_map->l_tls_offset = roundup (memsz, align ?: 1);
#elif TLS_DTV_AT_TP
_dl_static_dtv[2].pointer.val = (char *) tlsblock + tcb_offset;
static_map.l_tls_offset = tcb_offset;
main_map->l_tls_offset = tcb_offset;
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
@ -193,19 +192,17 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
if (__builtin_expect (lossage != NULL, 0))
__libc_fatal (lossage);
/* We have to create a fake link map which normally would be created
by the dynamic linker. It just has to have enough information to
make the TLS routines happy. */
static_map.l_tls_align = align;
static_map.l_tls_blocksize = memsz;
static_map.l_tls_initimage = initimage;
static_map.l_tls_initimage_size = filesz;
static_map.l_type = lt_executable;
static_map.l_tls_modid = 1;
/* Update the executable's link map with enough information to make
the TLS routines happy. */
main_map->l_tls_align = align;
main_map->l_tls_blocksize = memsz;
main_map->l_tls_initimage = initimage;
main_map->l_tls_initimage_size = filesz;
main_map->l_tls_modid = 1;
init_slotinfo ();
// static_slotinfo.si.slotinfo[1].gen = 0; already zero
static_slotinfo.si.slotinfo[1].map = &static_map;
static_slotinfo.si.slotinfo[1].map = main_map;
memsz = roundup (memsz, align ?: 1);

View File

@ -643,9 +643,7 @@ _dl_close_worker (struct link_map *map)
imap->l_prev->l_next = imap->l_next;
else
{
#ifdef SHARED
assert (nsid != LM_ID_BASE);
#endif
ns->_ns_loaded = imap->l_next;
/* Update the pointer to the head of the list
@ -736,13 +734,7 @@ _dl_close_worker (struct link_map *map)
if (__builtin_expect (ns->_ns_loaded == NULL, 0)
&& nsid == GL(dl_nns) - 1)
do
{
--GL(dl_nns);
#ifndef SHARED
if (GL(dl_nns) == 0)
break;
#endif
}
--GL(dl_nns);
while (GL(dl_ns)[GL(dl_nns) - 1]._ns_loaded == NULL);
/* Notify the debugger those objects are finalized and gone. */

View File

@ -86,34 +86,4 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
}
hidden_def (__dl_iterate_phdr)
#ifdef SHARED
weak_alias (__dl_iterate_phdr, dl_iterate_phdr);
#else
int
dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
size_t size, void *data), void *data)
{
if (_dl_phnum != 0)
{
/* This entry describes this statically-linked program itself. */
struct dl_phdr_info info;
int ret;
info.dlpi_addr = 0;
info.dlpi_name = "";
info.dlpi_phdr = _dl_phdr;
info.dlpi_phnum = _dl_phnum;
info.dlpi_adds = GL(dl_load_adds);
info.dlpi_subs = GL(dl_load_adds) - GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
ret = (*callback) (&info, sizeof (struct dl_phdr_info), data);
if (ret)
return ret;
}
return __dl_iterate_phdr (callback, data);
}
#endif

View File

@ -2233,23 +2233,17 @@ _dl_map_object (struct link_map *loader, const char *name,
if (cached != NULL)
{
# ifdef SHARED
// XXX Correct to unconditionally default to namespace 0?
l = (loader
?: GL(dl_ns)[LM_ID_BASE]._ns_loaded
?: &GL(dl_rtld_map));
# else
l = loader;
# ifdef SHARED
?: &GL(dl_rtld_map)
# endif
);
/* If the loader has the DF_1_NODEFLIB flag set we must not
use a cache entry from any of these directories. */
if (
# ifndef SHARED
/* 'l' is always != NULL for dynamically linked objects. */
l != NULL &&
# endif
__builtin_expect (l->l_flags_1 & DF_1_NODEFLIB, 0))
if (__builtin_expect (l->l_flags_1 & DF_1_NODEFLIB, 0))
{
const char *dirp = system_dirs;
unsigned int cnt = 0;

View File

@ -91,6 +91,7 @@ static struct link_map _dl_main_map =
.l_scope = _dl_main_map.l_scope_mem,
.l_local_scope = { &_dl_main_map.l_searchlist },
.l_used = 1,
.l_flags_1 = DF_1_NODEFLIB,
.l_tls_offset = NO_TLS_OFFSET,
.l_serial = 1,
};
@ -311,6 +312,8 @@ internal_function
_dl_non_dynamic_init (void)
{
_dl_main_map.l_origin = _dl_get_origin ();
_dl_main_map.l_phdr = GL(dl_phdr);
_dl_main_map.l_phnum = GL(dl_phnum);
if (HP_TIMING_AVAIL)
HP_TIMING_NOW (_dl_cpuclock_offset);