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] elf: Assume TLS is initialized in _dl_map_object_from_fd (was: Re: Question about elf/dl-load.c)


On 11/11/2016 10:17 PM, Florian Weimer wrote:

And so on.  My question is this: Can we actually enter the final part,
under “We can do the TLS right now!” in a shared build?

I doubt that because during the initial link, we will hit the second
break statement for libraries, and the third break statement for the
main program.  Before user code runs, rtld.c sets up the TLS data
structures, so any future dlopen calls hit the second break again
because GL(dl_tls_dtv_slotinfo_list) != NULL at this point.

Is this reasoning correct?  I put in a debug printf and ran the elf
tests, and there was nothing printed.

I've simplified the code accordingly and added asserts.

I have verified that the elf/* test suite still passes on s390, s390x, ppc64, ppc, x86_64, i386. On x86_64, I also performed an installed-tree test (and the assert did not fire).

Thanks,
Florian

elf: Assume TLS is initialized in _dl_map_object_from_fd

libc.so uses TLS data, so when dlopen is called later, the
TLS data structures have already been initialized.

2016-11-14  Florian Weimer  <fweimer@redhat.com>

	* elf/dl-load.c (_dl_map_object_from_fd): Delayed TLS data
	structure initialization is no longer needed.

diff --git a/elf/dl-load.c b/elf/dl-load.c
index c0d6249..51fb0d0 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1135,54 +1135,14 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 	    }
 
 #ifdef SHARED
-	  if (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0)
-	    /* We are loading the executable itself when the dynamic linker
-	       was executed directly.  The setup will happen later.  */
-	    break;
-
-# ifdef _LIBC_REENTRANT
-	  /* In a static binary there is no way to tell if we dynamically
-	     loaded libpthread.  */
-	  if (GL(dl_error_catch_tsd) == &_dl_initial_error_catch_tsd)
-# endif
+	  /* We are loading the executable itself when the dynamic
+	     linker was executed directly.  The setup will happen
+	     later.  Otherwise, the TLS data structures are already
+	     initialized, and we assigned a TLS modid above.  */
+	  assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0);
+#else
+	  assert (false && "TLS not initialized in static application");
 #endif
-	    {
-	      /* We have not yet loaded libpthread.
-		 We can do the TLS setup right now!  */
-
-	      void *tcb;
-
-	      /* The first call allocates TLS bookkeeping data structures.
-		 Then we allocate the TCB for the initial thread.  */
-	      if (__glibc_unlikely (_dl_tls_setup ())
-		  || __glibc_unlikely ((tcb = _dl_allocate_tls (NULL)) == NULL))
-		{
-		  errval = ENOMEM;
-		  errstring = N_("\
-cannot allocate TLS data structures for initial thread");
-		  goto call_lose;
-		}
-
-	      /* Now we install the TCB in the thread register.  */
-	      errstring = TLS_INIT_TP (tcb);
-	      if (__glibc_likely (errstring == NULL))
-		{
-		  /* Now we are all good.  */
-		  l->l_tls_modid = ++GL(dl_tls_max_dtv_idx);
-		  break;
-		}
-
-	      /* The kernel is too old or somesuch.  */
-	      errval = 0;
-	      _dl_deallocate_tls (tcb, 1);
-	      goto call_lose;
-	    }
-
-	  /* Uh-oh, the binary expects TLS support but we cannot
-	     provide it.  */
-	  errval = 0;
-	  errstring = N_("cannot handle TLS data");
-	  goto call_lose;
 	  break;
 
 	case PT_GNU_STACK:

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