This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][BZ #16046] Static dlopen correction fallout fixes


On Mon, 27 Jan 2014, Maciej W. Rozycki wrote:

> > 16046 suggests that the status quo today is a regression from 2.18.  If
> > that's true, then I think it does need to get fixed in 2.19 so that the
> > user-visible behavior does not differ (except in the intended ways for
> > static executables).  Further cleanup could wait until after 2.19, but if
> > it's straightforward then I'd be just as happy to see it done right away.
> > (The 2.19 release manager may feel differently.)
> 
>  I read the deadline is next Thursday or so; I'll see what I can do.

 And here it is.  Following your encouragement I decided to include all 
updates for all places I have identified so far.  Please let me know if 
you feel uneasy about any of them and I'll leave these out.  Here are 
descriptions of the individual changes:

* 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.

 Questions or comments?  I've looked into turning the program supplied 
with the bug report into a proper test case, but the presence of 
linux-vdso.so.1 implicitly loaded in one of the static dumps made me 
question the ability to make such a test case work reliably.  Suggestions 
are welcome.

 Regression-tested successfully with the mips-linux-gnu target 
(big-endian, o32 ABI) -- as the change is target-agnostic I believe this 
should provide enough coverage; please shout if you disagree.  Also the 
test case provided with the bug report produces correct output now:

$ ./dl-iter-static-orig
addr=(nil) name= phdr=0x400034 phnum=5
addr=(nil) name= phdr=(nil) phnum=0
$ ./dl-iter-static-good
addr=(nil) name= phdr=0x400034 phnum=5
$ 

 OK to apply?

2014-01-29  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.

  Maciej

glibc-static-dlopen-16046.diff
Index: glibc-fsf-trunk-quilt/csu/libc-tls.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/csu/libc-tls.c	2014-01-29 11:23:16.000000000 +0000
+++ glibc-fsf-trunk-quilt/csu/libc-tls.c	2014-01-29 12:09:13.062013406 +0000
@@ -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
   _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
   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);
 
Index: glibc-fsf-trunk-quilt/elf/dl-close.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/dl-close.c	2014-01-29 11:23:16.000000000 +0000
+++ glibc-fsf-trunk-quilt/elf/dl-close.c	2014-01-29 12:09:13.062013406 +0000
@@ -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.  */
Index: glibc-fsf-trunk-quilt/elf/dl-iteratephdr.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/dl-iteratephdr.c	2014-01-29 11:23:16.000000000 +0000
+++ glibc-fsf-trunk-quilt/elf/dl-iteratephdr.c	2014-01-29 12:09:13.062013406 +0000
@@ -86,34 +86,4 @@ __dl_iterate_phdr (int (*callback) (stru
 }
 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
Index: glibc-fsf-trunk-quilt/elf/dl-load.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/dl-load.c	2014-01-29 11:23:16.000000000 +0000
+++ glibc-fsf-trunk-quilt/elf/dl-load.c	2014-01-29 12:09:13.062013406 +0000
@@ -2233,23 +2233,17 @@ _dl_map_object (struct link_map *loader,
 
 	  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;
Index: glibc-fsf-trunk-quilt/elf/dl-support.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/dl-support.c	2014-01-29 11:23:16.000000000 +0000
+++ glibc-fsf-trunk-quilt/elf/dl-support.c	2014-01-29 12:12:22.092011006 +0000
@@ -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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]