This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB 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]

[RFC/RFA] TLS support part 2


Here is the thread/target related part of the TLS support.

A new thread layer op has been added, to fetch the address of the variable.

Elena


2002-10-02  Elena Zannoni  <ezannoni@redhat.com>
            Jim Blandy  <jimb@redhat.com>
	
	* gdb_thread_db.h (enum): Add TD_NOTALLOC.
	* target.c (update_current_target): Add
	to_get_thread_local_address.
	* target.h (to_get_thread_local_address): Export.
	(target_get_thread_local_address): Define.
	(target_get_thread_local_address_p): Define.
	* thread-db.c: Include solib-svr4.h.
	(td_thr_tls_get_addr_p): Define.
	(thread_db_load): Get a pointer to td_thr_tls_get_addr.
	(thread_db_get_thread_local_address): New function.
	(init_thread_db_ops): Initialize to_get_thread_local_address.

Index: gdb_thread_db.h
===================================================================
RCS file: /cvs/src/src/gdb/gdb_thread_db.h,v
retrieving revision 1.3
diff -u -p -r1.3 gdb_thread_db.h
--- gdb_thread_db.h	6 Mar 2001 08:21:07 -0000	1.3
+++ gdb_thread_db.h	2 Oct 2002 13:36:40 -0000
@@ -63,7 +63,8 @@ typedef enum
   TD_NOTSD,	  /* No thread-specific data available.  */
   TD_MALLOC,	  /* Out of memory.  */
   TD_PARTIALREG,  /* Not entire register set was read or written.  */
-  TD_NOXREGS	  /* X register set not available for given thread.  */
+  TD_NOXREGS,	  /* X register set not available for given thread.  */
+  TD_NOTALLOC	  /* TLS memory not yet allocated.  */
 } td_err_e;

Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.40
diff -u -p -r1.40 target.c
--- target.c	26 Aug 2002 19:18:33 -0000	1.40
+++ target.c	2 Oct 2002 13:36:12 -0000
@@ -666,6 +666,7 @@ update_current_target (void)
       INHERIT (to_async_mask_value, t);
       INHERIT (to_find_memory_regions, t);
       INHERIT (to_make_corefile_notes, t);
+      INHERIT (to_get_thread_local_address, t);
       INHERIT (to_magic, t);
 
 #undef INHERIT

Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.26
diff -u -p -r1.26 target.h
--- target.h	26 Aug 2002 19:18:33 -0000	1.26
+++ target.h	2 Oct 2002 13:37:08 -0000
@@ -328,6 +328,16 @@ struct target_ops
 					    void *), 
 				   void *);
     char * (*to_make_corefile_notes) (bfd *, int *);
+
+    /* Return the thread-local address at OFFSET in the
+       thread-local storage for the thread PTID and the shared library
+       or executable file given by OBJFILE.  If that block of
+       thread-local storage hasn't been allocated yet, this function
+       may return an error.  */
+    CORE_ADDR (*to_get_thread_local_address) (ptid_t ptid,
+					      struct objfile *objfile,
+					      CORE_ADDR offset);
+
     int to_magic;
     /* Need sub-structure for target machine related rather than comm related?
      */
@@ -1038,6 +1048,12 @@ extern void (*target_new_objfile_hook) (
 
 #define target_make_corefile_notes(BFD, SIZE_P) \
      (current_target.to_make_corefile_notes) (BFD, SIZE_P)
+
+/* Thread-local values.  */
+#define target_get_thread_local_address \
+    (current_target.to_get_thread_local_address)
+#define target_get_thread_local_address_p() \
+    (target_get_thread_local_address != NULL)
 
 /* Hook to call target-dependent code after reading in a new symbol table.  */
 

Index: thread-db.c
===================================================================
RCS file: /cvs/src/src/gdb/thread-db.c,v
retrieving revision 1.22
diff -u -p -r1.22 thread-db.c
--- thread-db.c	23 Mar 2002 17:38:13 -0000	1.22
+++ thread-db.c	2 Oct 2002 13:36:04 -0000
@@ -32,6 +32,7 @@
 #include "objfiles.h"
 #include "target.h"
 #include "regcache.h"
+#include "solib-svr4.h"
 
 #ifndef LIBTHREAD_DB_SO
 #define LIBTHREAD_DB_SO "libthread_db.so.1"
@@ -108,6 +109,11 @@ static td_err_e (*td_thr_setgregs_p) (co
 				      prgregset_t gregs);
 static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
 
+static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
+                                          void *map_address,
+                                          size_t offset,
+                                          void **address);
+
 /* Location of the thread creation event breakpoint.  The code at this
    location in the child process will be called by the pthread library
    whenever a new thread is created.  By setting a special breakpoint
@@ -348,6 +354,7 @@ thread_db_load (void)
   td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
   td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
   td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
+  td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
 
   return 1;
 }
@@ -1003,6 +1010,97 @@ thread_db_pid_to_str (ptid_t ptid)
   return normal_pid_to_str (ptid);
 }
 
+/* Get the address of the thread local variable in OBJFILE which is
+   stored at OFFSET within the thread local storage for thread PTID.  */
+
+static CORE_ADDR
+thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile,
+                                    CORE_ADDR offset)
+{
+  if (is_thread (ptid))
+    {
+      int objfile_is_library = (objfile->flags & OBJF_SHARED);
+      td_err_e err;
+      td_thrhandle_t th;
+      void *address;
+      CORE_ADDR lm;
+
+      /* glibc doesn't provide the needed interface.  */
+      if (! td_thr_tls_get_addr_p)
+        error ("Cannot find thread-local variables in this thread library.");
+
+      /* Get the address of the link map for this objfile.  */
+      lm = svr4_fetch_objfile_link_map (objfile);
+
+      /* Whoops, we couldn't find one. Bail out.  */
+      if (!lm)
+        {
+          if (objfile_is_library)
+            error ("Cannot find shared library `%s' link_map in dynamic"
+		   " linker's module list", objfile->name);
+	  else
+            error ("Cannot find executable file `%s' link_map in dynamic"
+		   " linker's module list", objfile->name);
+	}
+
+      /* Get info about the thread.  */
+      err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
+      if (err != TD_OK)
+	error ("Cannot find thread %ld: %s",
+	       (long) GET_THREAD (ptid), thread_db_err_str (err));
+      
+      /* Finally, get the address of the variable.  */
+      err = td_thr_tls_get_addr_p (&th, (void *) lm, offset, &address);
+
+#ifdef THREAD_DB_HAS_TD_NOTALLOC
+      /* The memory hasn't been allocated, yet.  */
+      if (err == TD_NOTALLOC)
+        {
+          /* Now, if libthread_db provided the initialization image's
+             address, we *could* try to build a non-lvalue value from
+             the initialization image.  */
+          if (objfile_is_library)
+            error ("The inferior has not yet allocated storage for"
+                   " thread-local variables in\n"
+                   "the shared library `%s'\n"
+                   "for the thread %ld",
+		   objfile->name, (long) GET_THREAD (ptid));
+          else
+            error ("The inferior has not yet allocated storage for"
+                   " thread-local variables in\n"
+                   "the executable `%s'\n"
+                   "for the thread %ld",
+		   objfile->name, (long) GET_THREAD (ptid));
+	}
+#endif
+
+      /* Something else went wrong.  */
+      if (err != TD_OK)
+	{
+	  if (objfile_is_library)
+	    error ("Cannot find thread-local storage for thread %ld, "
+		   "shared library %s:\n%s",
+		   (long) GET_THREAD (ptid),
+		   objfile->name,
+		   thread_db_err_str (err));
+	  else
+	    error ("Cannot find thread-local storage for thread %ld, "
+		   "executable file %s:\n%s",
+		   (long) GET_THREAD (ptid),
+		   objfile->name,
+		   thread_db_err_str (err));
+	}
+
+      /* Cast assuming host == target.  Joy.  */
+      return (CORE_ADDR) address;
+    }
+
+  if (target_beneath->to_get_thread_local_address)
+    return target_beneath->to_get_thread_local_address (ptid, objfile, offset);
+
+  error ("Cannot find thread-local values on this target.");
+}
+
 static void
 init_thread_db_ops (void)
 {
@@ -1025,6 +1123,8 @@ init_thread_db_ops (void)
   thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
   thread_db_ops.to_stratum = thread_stratum;
   thread_db_ops.to_has_thread_control = tc_schedlock;
+  thread_db_ops.to_get_thread_local_address
+    = thread_db_get_thread_local_address;
   thread_db_ops.to_magic = OPS_MAGIC;
 }
 


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