Jan Kratochvil 7f2a1f7
http://sourceware.org/ml/gdb-patches/2014-04/msg00155.html
Jan Kratochvil 7f2a1f7
Subject: [patch] Fix TLS access for -static -pthread
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
--qtZFehHsKgwS5rPz
Jan Kratochvil 7f2a1f7
Content-Type: text/plain; charset=us-ascii
Jan Kratochvil 7f2a1f7
Content-Disposition: inline
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
Hi,
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
testcase results may depend on patch:
Jan Kratochvil 7f2a1f7
	[patch] Fix gdbserver qGetTLSAddr for x86_64 -m32
Jan Kratochvil 7f2a1f7
	https://sourceware.org/ml/gdb-patches/2014-04/msg00154.html
Jan Kratochvil 7f2a1f7
	Message-ID: <20140410114901.GA16411@host2.jankratochvil.net>
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
There is:
Jan Kratochvil 7f2a1f7
 * gdb.threads/staticthreads.exp to test -static -pthread 'info threads'
Jan Kratochvil 7f2a1f7
 * gdb.threads/tls.exp to test TLS access (__thread variables)
Jan Kratochvil 7f2a1f7
but no testcase to test both together - it even does not work.
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
I have posted:
Jan Kratochvil 7f2a1f7
	TLS variables access for -static -lpthread executables
Jan Kratochvil 7f2a1f7
	https://sourceware.org/ml/libc-help/2014-03/msg00024.html
Jan Kratochvil 7f2a1f7
and the GDB patch below has been confirmed as OK for current glibcs.
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
Future glibcs may implement more native support for -static -pthread TLS
Jan Kratochvil 7f2a1f7
	https://sourceware.org/bugzilla/show_bug.cgi?id=16828
Jan Kratochvil 7f2a1f7
which will require also some new GDB support.
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
Still the patch below implements the feature in a fully functional way backward
Jan Kratochvil 7f2a1f7
compatible with current glibcs, it depends on the following glibc source line:
Jan Kratochvil 7f2a1f7
	csu/libc-tls.c
Jan Kratochvil 7f2a1f7
	main_map->l_tls_modid = 1;
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
No regressions on {x86_64,x86_64-m32}-fedorarawhide-linux-gnu.
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
Thanks,
Jan Kratochvil 7f2a1f7
Jan
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
--qtZFehHsKgwS5rPz
Jan Kratochvil 7f2a1f7
Content-Type: text/plain; charset=us-ascii
Jan Kratochvil 7f2a1f7
Content-Disposition: inline; filename="staticthread.patch"
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
gdb/
Jan Kratochvil 7f2a1f7
2014-04-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
	Fix TLS access for -static -pthread.
Jan Kratochvil 7f2a1f7
	* linux-thread-db.c (struct thread_db_info): Add td_thr_tlsbase_p.
Jan Kratochvil 7f2a1f7
	(try_thread_db_load_1): Initialize it.
Jan Kratochvil 7f2a1f7
	(thread_db_get_thread_local_address): Call it if LM is zero.
Jan Kratochvil 7f2a1f7
	* target.c (target_translate_tls_address): Remove LM_ADDR zero check.
Jan Kratochvil 7f2a1f7
	* target.h (struct target_ops) (to_get_thread_local_address): Add
Jan Kratochvil 7f2a1f7
	load_module_addr comment.
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
gdb/gdbserver/
Jan Kratochvil 7f2a1f7
2014-04-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
	Fix TLS access for -static -pthread.
Jan Kratochvil 7f2a1f7
	* gdbserver/thread-db.c (struct thread_db): Add td_thr_tlsbase_p.
Jan Kratochvil 7f2a1f7
	(thread_db_get_tls_address): Call it if LOAD_MODULE is zero.
Jan Kratochvil 7f2a1f7
	(thread_db_load_search, try_thread_db_load_1): Initialize it.
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
gdb/testsuite/
Jan Kratochvil 7f2a1f7
2014-04-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
	Fix TLS access for -static -pthread.
Jan Kratochvil 7f2a1f7
	* gdb.threads/staticthreads.c <HAVE_TLS> (tlsvar): New.
Jan Kratochvil 7f2a1f7
	<HAVE_TLS> (thread_function, main): Initialize it.
Jan Kratochvil 7f2a1f7
	* gdb.threads/staticthreads.exp: Try gdb_compile_pthreads for $have_tls.
Jan Kratochvil 7f2a1f7
	Add clean_restart.
Jan Kratochvil 7f2a1f7
	<$have_tls != "">: Check TLSVAR.
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
Jan Kratochvil 7f2a1f7
index ca614a3..4578610 100644
Jan Kratochvil 7f2a1f7
--- a/gdb/linux-thread-db.c
Jan Kratochvil 7f2a1f7
+++ b/gdb/linux-thread-db.c
Jan Kratochvil 7f2a1f7
@@ -196,6 +196,9 @@ struct thread_db_info
Jan Kratochvil 7f2a1f7
   td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
Jan Kratochvil 7f2a1f7
 				     psaddr_t map_address,
Jan Kratochvil 7f2a1f7
 				     size_t offset, psaddr_t *address);
Jan Kratochvil 7f2a1f7
+  td_err_e (*td_thr_tlsbase_p) (const td_thrhandle_t *th,
Jan Kratochvil 7f2a1f7
+				unsigned long int modid,
Jan Kratochvil 7f2a1f7
+				psaddr_t *base);
Jan Kratochvil 7f2a1f7
 };
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
 /* List of known processes using thread_db, and the required
Jan Kratochvil 7f2a1f7
@@ -799,6 +802,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
Jan Kratochvil 7f2a1f7
   info->td_ta_event_getmsg_p = dlsym (info->handle, "td_ta_event_getmsg");
Jan Kratochvil 7f2a1f7
   info->td_thr_event_enable_p = dlsym (info->handle, "td_thr_event_enable");
Jan Kratochvil 7f2a1f7
   info->td_thr_tls_get_addr_p = dlsym (info->handle, "td_thr_tls_get_addr");
Jan Kratochvil 7f2a1f7
+  info->td_thr_tlsbase_p = dlsym (info->handle, "td_thr_tlsbase");
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
   if (thread_db_find_new_threads_silently (inferior_ptid) != 0)
Jan Kratochvil 7f2a1f7
     {
Jan Kratochvil 7f2a1f7
@@ -1811,21 +1815,34 @@ thread_db_get_thread_local_address (struct target_ops *ops,
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
       info = get_thread_db_info (ptid_get_pid (ptid));
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
-      /* glibc doesn't provide the needed interface.  */
Jan Kratochvil 7f2a1f7
-      if (!info->td_thr_tls_get_addr_p)
Jan Kratochvil 7f2a1f7
-	throw_error (TLS_NO_LIBRARY_SUPPORT_ERROR,
Jan Kratochvil 7f2a1f7
-		     _("No TLS library support"));
Jan Kratochvil 7f2a1f7
-
Jan Kratochvil 7f2a1f7
-      /* Caller should have verified that lm != 0.  */
Jan Kratochvil 7f2a1f7
-      gdb_assert (lm != 0);
Jan Kratochvil 7f2a1f7
-
Jan Kratochvil 7f2a1f7
       /* Finally, get the address of the variable.  */
Jan Kratochvil 7f2a1f7
-      /* Note the cast through uintptr_t: this interface only works if
Jan Kratochvil 7f2a1f7
-	 a target address fits in a psaddr_t, which is a host pointer.
Jan Kratochvil 7f2a1f7
-	 So a 32-bit debugger can not access 64-bit TLS through this.  */
Jan Kratochvil 7f2a1f7
-      err = info->td_thr_tls_get_addr_p (&thread_info->private->th,
Jan Kratochvil 7f2a1f7
-					 (psaddr_t)(uintptr_t) lm,
Jan Kratochvil 7f2a1f7
-					 offset, &address);
Jan Kratochvil 7f2a1f7
+      if (lm != 0)
Jan Kratochvil 7f2a1f7
+	{
Jan Kratochvil 7f2a1f7
+	  /* glibc doesn't provide the needed interface.  */
Jan Kratochvil 7f2a1f7
+	  if (!info->td_thr_tls_get_addr_p)
Jan Kratochvil 7f2a1f7
+	    throw_error (TLS_NO_LIBRARY_SUPPORT_ERROR,
Jan Kratochvil 7f2a1f7
+			 _("No TLS library support"));
Jan Kratochvil 7f2a1f7
+
Jan Kratochvil 7f2a1f7
+	  /* Note the cast through uintptr_t: this interface only works if
Jan Kratochvil 7f2a1f7
+	     a target address fits in a psaddr_t, which is a host pointer.
Jan Kratochvil 7f2a1f7
+	     So a 32-bit debugger can not access 64-bit TLS through this.  */
Jan Kratochvil 7f2a1f7
+	  err = info->td_thr_tls_get_addr_p (&thread_info->private->th,
Jan Kratochvil 7f2a1f7
+					     (psaddr_t)(uintptr_t) lm,
Jan Kratochvil 7f2a1f7
+					     offset, &address);
Jan Kratochvil 7f2a1f7
+	}
Jan Kratochvil 7f2a1f7
+      else
Jan Kratochvil 7f2a1f7
+	{
Jan Kratochvil 7f2a1f7
+	  /* If glibc doesn't provide the needed interface throw an error
Jan Kratochvil 7f2a1f7
+	     that LM is zero - normally cases it should not be.  */
Jan Kratochvil 7f2a1f7
+	  if (!info->td_thr_tlsbase_p)
Jan Kratochvil 7f2a1f7
+	    throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
Jan Kratochvil 7f2a1f7
+			 _("TLS load module not found"));
Jan Kratochvil 7f2a1f7
+
Jan Kratochvil 7f2a1f7
+	  /* GNU __libc_setup_tls initializes l_tls_modid as 1.  */
Jan Kratochvil 7f2a1f7
+	  err = info->td_thr_tlsbase_p (&thread_info->private->th,
Jan Kratochvil 7f2a1f7
+					1, &address);
Jan Kratochvil 7f2a1f7
+	  address = (char *) address + offset;
Jan Kratochvil 7f2a1f7
+	}
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
 #ifdef THREAD_DB_HAS_TD_NOTALLOC
Jan Kratochvil 7f2a1f7
       /* The memory hasn't been allocated, yet.  */
Jan Kratochvil 7f2a1f7
diff --git a/gdb/target.c b/gdb/target.c
Jan Kratochvil 7f2a1f7
index 1b48f79..fce646c 100644
Jan Kratochvil 7f2a1f7
--- a/gdb/target.c
Jan Kratochvil 7f2a1f7
+++ b/gdb/target.c
Jan Kratochvil 7f2a1f7
@@ -753,10 +753,6 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
Jan Kratochvil 7f2a1f7
 	  /* Fetch the load module address for this objfile.  */
Jan Kratochvil 7f2a1f7
 	  lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (),
Jan Kratochvil 7f2a1f7
 	                                                   objfile);
Jan Kratochvil 7f2a1f7
-	  /* If it's 0, throw the appropriate exception.  */
Jan Kratochvil 7f2a1f7
-	  if (lm_addr == 0)
Jan Kratochvil 7f2a1f7
-	    throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
Jan Kratochvil 7f2a1f7
-			 _("TLS load module not found"));
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
 	  addr = target->to_get_thread_local_address (target, ptid,
Jan Kratochvil 7f2a1f7
 						      lm_addr, offset);
Jan Kratochvil 7f2a1f7
diff --git a/gdb/target.h b/gdb/target.h
Jan Kratochvil 7f2a1f7
index d7c6c3d..1aba9e1 100644
Jan Kratochvil 7f2a1f7
--- a/gdb/target.h
Jan Kratochvil 7f2a1f7
+++ b/gdb/target.h
Jan Kratochvil 7f2a1f7
@@ -605,7 +605,8 @@ struct target_ops
Jan Kratochvil 7f2a1f7
        thread-local storage for the thread PTID and the shared library
Jan Kratochvil 7f2a1f7
        or executable file given by OBJFILE.  If that block of
Jan Kratochvil 7f2a1f7
        thread-local storage hasn't been allocated yet, this function
Jan Kratochvil 7f2a1f7
-       may return an error.  */
Jan Kratochvil 7f2a1f7
+       may return an error.  LOAD_MODULE_ADDR may be zero for statically
Jan Kratochvil 7f2a1f7
+       linked multithreaded inferiors.  */
Jan Kratochvil 7f2a1f7
     CORE_ADDR (*to_get_thread_local_address) (struct target_ops *ops,
Jan Kratochvil 7f2a1f7
 					      ptid_t ptid,
Jan Kratochvil 7f2a1f7
 					      CORE_ADDR load_module_addr,
Jan Kratochvil 7f2a1f7
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
Jan Kratochvil 7f2a1f7
index f63e39e..f2335ab 100644
Jan Kratochvil 7f2a1f7
--- a/gdb/gdbserver/thread-db.c
Jan Kratochvil 7f2a1f7
+++ b/gdb/gdbserver/thread-db.c
Jan Kratochvil 7f2a1f7
@@ -88,6 +88,9 @@ struct thread_db
Jan Kratochvil 7f2a1f7
   td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
Jan Kratochvil 7f2a1f7
 				     psaddr_t map_address,
Jan Kratochvil 7f2a1f7
 				     size_t offset, psaddr_t *address);
Jan Kratochvil 7f2a1f7
+  td_err_e (*td_thr_tlsbase_p) (const td_thrhandle_t *th,
Jan Kratochvil 7f2a1f7
+				unsigned long int modid,
Jan Kratochvil 7f2a1f7
+				psaddr_t *base);
Jan Kratochvil 7f2a1f7
   const char ** (*td_symbol_list_p) (void);
Jan Kratochvil 7f2a1f7
 };
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
@@ -497,7 +500,10 @@ thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
Jan Kratochvil 7f2a1f7
   if (thread_db == NULL || !thread_db->all_symbols_looked_up)
Jan Kratochvil 7f2a1f7
     return TD_ERR;
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
-  if (thread_db->td_thr_tls_get_addr_p == NULL)
Jan Kratochvil 7f2a1f7
+  /* If td_thr_tls_get_addr is missing rather do not expect td_thr_tlsbase
Jan Kratochvil 7f2a1f7
+     could work.  */
Jan Kratochvil 7f2a1f7
+  if (thread_db->td_thr_tls_get_addr_p == NULL
Jan Kratochvil 7f2a1f7
+      || (load_module == 0 && thread_db->td_thr_tlsbase_p == NULL))
Jan Kratochvil 7f2a1f7
     return -1;
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
   lwp = get_thread_lwp (thread);
Jan Kratochvil 7f2a1f7
@@ -508,12 +514,23 @@ thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
   saved_inferior = current_inferior;
Jan Kratochvil 7f2a1f7
   current_inferior = thread;
Jan Kratochvil 7f2a1f7
-  /* Note the cast through uintptr_t: this interface only works if
Jan Kratochvil 7f2a1f7
-     a target address fits in a psaddr_t, which is a host pointer.
Jan Kratochvil 7f2a1f7
-     So a 32-bit debugger can not access 64-bit TLS through this.  */
Jan Kratochvil 7f2a1f7
-  err = thread_db->td_thr_tls_get_addr_p (&lwp->th,
Jan Kratochvil 7f2a1f7
-					  (psaddr_t) (uintptr_t) load_module,
Jan Kratochvil 7f2a1f7
-					  offset, &addr);
Jan Kratochvil 7f2a1f7
+
Jan Kratochvil 7f2a1f7
+  if (load_module != 0)
Jan Kratochvil 7f2a1f7
+    {
Jan Kratochvil 7f2a1f7
+      /* Note the cast through uintptr_t: this interface only works if
Jan Kratochvil 7f2a1f7
+	 a target address fits in a psaddr_t, which is a host pointer.
Jan Kratochvil 7f2a1f7
+	 So a 32-bit debugger can not access 64-bit TLS through this.  */
Jan Kratochvil 7f2a1f7
+      err = thread_db->td_thr_tls_get_addr_p (&lwp->th,
Jan Kratochvil 7f2a1f7
+					     (psaddr_t) (uintptr_t) load_module,
Jan Kratochvil 7f2a1f7
+					      offset, &addr);
Jan Kratochvil 7f2a1f7
+    }
Jan Kratochvil 7f2a1f7
+  else
Jan Kratochvil 7f2a1f7
+    {
Jan Kratochvil 7f2a1f7
+      /* GNU __libc_setup_tls initializes l_tls_modid as 1.  */
Jan Kratochvil 7f2a1f7
+      err = thread_db->td_thr_tlsbase_p (&lwp->th, 1, &addr);
Jan Kratochvil 7f2a1f7
+      addr = (char *) addr + offset;
Jan Kratochvil 7f2a1f7
+    }
Jan Kratochvil 7f2a1f7
+
Jan Kratochvil 7f2a1f7
   current_inferior = saved_inferior;
Jan Kratochvil 7f2a1f7
   if (err == TD_OK)
Jan Kratochvil 7f2a1f7
     {
Jan Kratochvil 7f2a1f7
@@ -565,6 +582,7 @@ thread_db_load_search (void)
Jan Kratochvil 7f2a1f7
   tdb->td_ta_set_event_p = &td_ta_set_event;
Jan Kratochvil 7f2a1f7
   tdb->td_ta_event_getmsg_p = &td_ta_event_getmsg;
Jan Kratochvil 7f2a1f7
   tdb->td_thr_tls_get_addr_p = &td_thr_tls_get_addr;
Jan Kratochvil 7f2a1f7
+  tdb->td_thr_tlsbase_p = &td_thr_tlsbase;
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
   return 1;
Jan Kratochvil 7f2a1f7
 }
Jan Kratochvil 7f2a1f7
@@ -633,6 +651,7 @@ try_thread_db_load_1 (void *handle)
Jan Kratochvil 7f2a1f7
   CHK (0, tdb->td_ta_set_event_p = dlsym (handle, "td_ta_set_event"));
Jan Kratochvil 7f2a1f7
   CHK (0, tdb->td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg"));
Jan Kratochvil 7f2a1f7
   CHK (0, tdb->td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr"));
Jan Kratochvil 7f2a1f7
+  CHK (0, tdb->td_thr_tlsbase_p = dlsym (handle, "td_thr_tlsbase"));
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
 #undef CHK
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
diff --git a/gdb/testsuite/gdb.threads/staticthreads.c b/gdb/testsuite/gdb.threads/staticthreads.c
Jan Kratochvil 7f2a1f7
index f98f4f1..93bef56 100644
Jan Kratochvil 7f2a1f7
--- a/gdb/testsuite/gdb.threads/staticthreads.c
Jan Kratochvil 7f2a1f7
+++ b/gdb/testsuite/gdb.threads/staticthreads.c
Jan Kratochvil 7f2a1f7
@@ -28,10 +28,17 @@
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
 sem_t semaphore;
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
+#ifdef HAVE_TLS
Jan Kratochvil 7f2a1f7
+__thread int tlsvar;
Jan Kratochvil 7f2a1f7
+#endif
Jan Kratochvil 7f2a1f7
+
Jan Kratochvil 7f2a1f7
 void *
Jan Kratochvil 7f2a1f7
 thread_function (void *arg)
Jan Kratochvil 7f2a1f7
 {
Jan Kratochvil 7f2a1f7
-  printf ("Thread executing\n");
Jan Kratochvil 7f2a1f7
+#ifdef HAVE_TLS
Jan Kratochvil 7f2a1f7
+  tlsvar = 2;
Jan Kratochvil 7f2a1f7
+#endif
Jan Kratochvil 7f2a1f7
+  printf ("Thread executing\n"); /* tlsvar-is-set */
Jan Kratochvil 7f2a1f7
   while (sem_wait (&semaphore) != 0)
Jan Kratochvil 7f2a1f7
     {
Jan Kratochvil 7f2a1f7
       if (errno != EINTR)
Jan Kratochvil 7f2a1f7
@@ -57,6 +64,9 @@ main (int argc, char **argv)
Jan Kratochvil 7f2a1f7
       return -1;
Jan Kratochvil 7f2a1f7
     }
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
+#ifdef HAVE_TLS
Jan Kratochvil 7f2a1f7
+  tlsvar = 1;
Jan Kratochvil 7f2a1f7
+#endif
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
   /* Create a thread, wait for it to complete.  */
Jan Kratochvil 7f2a1f7
   {
Jan Kratochvil 7f2a1f7
diff --git a/gdb/testsuite/gdb.threads/staticthreads.exp b/gdb/testsuite/gdb.threads/staticthreads.exp
Jan Kratochvil 7f2a1f7
index 80b0ba8..9fa625a 100644
Jan Kratochvil 7f2a1f7
--- a/gdb/testsuite/gdb.threads/staticthreads.exp
Jan Kratochvil 7f2a1f7
+++ b/gdb/testsuite/gdb.threads/staticthreads.exp
Jan Kratochvil 7f2a1f7
@@ -22,11 +22,16 @@
Jan Kratochvil 7f2a1f7
 standard_testfile
Jan Kratochvil 7f2a1f7
 set static_flag "-static"
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
-if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
Jan Kratochvil 7f2a1f7
-	 executable \
Jan Kratochvil 7f2a1f7
-	 [list debug "additional_flags=${static_flag}" \
Jan Kratochvil 7f2a1f7
-	     ]] != "" } {
Jan Kratochvil 7f2a1f7
-    return -1
Jan Kratochvil 7f2a1f7
+foreach have_tls { "-DHAVE_TLS" "" } {
Jan Kratochvil 7f2a1f7
+    if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
Jan Kratochvil 7f2a1f7
+	     executable \
Jan Kratochvil 7f2a1f7
+	     [list debug "additional_flags=${static_flag} ${have_tls}" \
Jan Kratochvil 7f2a1f7
+		 ]] == "" } {
Jan Kratochvil 7f2a1f7
+	break
Jan Kratochvil 7f2a1f7
+    }
Jan Kratochvil 7f2a1f7
+    if { $have_tls == "" } {
Jan Kratochvil 7f2a1f7
+	return -1
Jan Kratochvil 7f2a1f7
+    }
Jan Kratochvil 7f2a1f7
 }
Jan Kratochvil 7f2a1f7
 
Jan Kratochvil 7f2a1f7
 clean_restart ${binfile}
Jan Kratochvil 7f2a1f7
@@ -89,3 +94,18 @@ gdb_test_multiple "quit" "$test" {
Jan Kratochvil 7f2a1f7
         pass "$test"
Jan Kratochvil 7f2a1f7
     }
Jan Kratochvil 7f2a1f7
 }
Jan Kratochvil 7f2a1f7
+clean_restart ${binfile}
Jan Kratochvil 7f2a1f7
+
Jan Kratochvil 7f2a1f7
+
Jan Kratochvil 7f2a1f7
+if { "$have_tls" != "" } {
Jan Kratochvil 7f2a1f7
+    if ![runto_main] {
Jan Kratochvil 7f2a1f7
+	return -1
Jan Kratochvil 7f2a1f7
+    }
Jan Kratochvil 7f2a1f7
+    gdb_breakpoint [gdb_get_line_number "tlsvar-is-set"]
Jan Kratochvil 7f2a1f7
+    gdb_continue_to_breakpoint "tlsvar-is-set" ".* tlsvar-is-set .*"
Jan Kratochvil 7f2a1f7
+    gdb_test "p tlsvar" " = 2" "tlsvar in thread"
Jan Kratochvil 7f2a1f7
+    gdb_test "thread 1" ".*"
Jan Kratochvil 7f2a1f7
+    # Unwind from pthread_join.
Jan Kratochvil 7f2a1f7
+    gdb_test "up 10" " in main .*"
Jan Kratochvil 7f2a1f7
+    gdb_test "p tlsvar" " = 1" "tlsvar in main"
Jan Kratochvil 7f2a1f7
+}
Jan Kratochvil 7f2a1f7
Jan Kratochvil 7f2a1f7
--qtZFehHsKgwS5rPz--
Jan Kratochvil 7f2a1f7