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]

[PATCH/RFC] TLS support part 1


This part of the tls changes deal with the symbol handling.
I.e. recognizes the debug information, and sets up variables with the
appropriate address information.  Then it requests the address to be
computed by the target/thread code.

BTW: the debug info looks like this (in a simple case):

 <1><1e2c>: Abbrev Number: 32 (DW_TAG_variable)
     DW_AT_name        : (indirect string, offset: 0xc0d): a_tls        
     DW_AT_decl_file   : 1      
     DW_AT_decl_line   : 4      
     DW_AT_type        : <c75>  
     DW_AT_external    : 1      
     DW_AT_location    : 6 byte block: 3 0 0 0 0 e0     (DW_OP_addr: 0; DW_OP_GNU_push_tls_address; )
 <1><1e3f>: Abbrev Number: 32 (DW_TAG_variable)
     DW_AT_name        : (indirect string, offset: 0xb42): b_tls        
     DW_AT_decl_file   : 1      
     DW_AT_decl_line   : 5      
     DW_AT_type        : <c75>  
     DW_AT_external    : 1      
     DW_AT_location    : 6 byte block: 3 4 0 0 0 e0     (DW_OP_addr: 4; DW_OP_GNU_push_tls_address; )
 <1><1e52>: Abbrev Number: 32 (DW_TAG_variable)
     DW_AT_name        : (indirect string, offset: 0xaa8): c_tls        
     DW_AT_decl_file   : 1      
     DW_AT_decl_line   : 6      
     DW_AT_type        : <c75>  
     DW_AT_external    : 1      
     DW_AT_location    : 6 byte block: 3 8 0 0 0 e0     (DW_OP_addr: 8; DW_OP_GNU_push_tls_address; )

I.e. a_tls, b_tls, c_tls are thread local storage variables at offset
0, 4, 8 respectively within the thread local storage.

The next patch will deal with the actual computation of the address.

Elena

2002-10-01  Jim Blandy  <jimb@redhat.com>
	    Elena Zannoni  <ezannoni@redhat.com>

	* symtab.h (address_class): Re-add LOC_THREAD_LOCAL_STATIC
	for thread local storage locations.
	(struct symbol): Add objfile field.
	(SYMBOL_OBJFILE): Define.
	* dwarf2read.c (is_thread_local): New static variable.
	(new_symbol): If variable is in thread local fill in address class
	and objfile appropriately.
	(decode_locdesc): Recognize and handle DW_OP_GNU_push_tls_address
	stack operation.
	* printcmd.c (address_info): Print the information for thread
	local storage variable.
	* findvar.c (read_var_value): In case of thread local variable,
	defer to the target vector code to compute address.

Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.42
diff -u -p -r1.42 symtab.h
--- symtab.h	20 Sep 2002 14:58:58 -0000	1.42
+++ symtab.h	2 Oct 2002 02:52:57 -0000
@@ -611,8 +611,16 @@ enum address_class
     target-specific method. This is used only by hppa.  */
 
   LOC_HP_THREAD_LOCAL_STATIC,
+
+  /* Value is at a thread-specific location calculated by a
+     target-specific method.  SYMBOL_OBJFILE gives the object file
+     in which the symbol is defined; the symbol's value is the
+     o
+  /* Value is at a thread-specific location calculated by a
+     target-specific method.  SYMBOL_OBJFILE gives the object file
+     in which the symbol is defined; the symbol's value is the
+     offset into that objfile's thread-local storage for the current
+     thread.  */
+      
   LOC_THREAD_LOCAL_STATIC,
 
   /* The variable does not actually exist in the program.
@@ -684,6 +692,12 @@ struct symbol
   {
     /* Used by LOC_BASEREG and LOC_BASEREG_ARG.  */
     short basereg;
+
+    /* The objfile in which this symbol is defined.  To find a
+       thread-local variable (e.g., a variable declared with the
+       `__thread' storage class), we may need to know which object
+       file it's in.  */
+    struct objfile *objfile;
   }
   aux_value;
 
@@ -705,6 +719,7 @@ struct symbol
 #define SYMBOL_TYPE(symbol)		(symbol)->type
 #define SYMBOL_LINE(symbol)		(symbol)->line
 #define SYMBOL_BASEREG(symbol)		(symbol)->aux_value.basereg
+#define SYMBOL_OBJFILE(symbol)          (symbol)->aux_value.objfile
 #define SYMBOL_ALIASES(symbol)		(symbol)->aliases
 #define SYMBOL_RANGES(symbol)		(symbol)->ranges
 
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.67
diff -u -p -r1.67 dwarf2read.c
--- dwarf2read.c	1 Oct 2002 23:51:43 -0000	1.67
+++ dwarf2read.c	2 Oct 2002 02:58:26 -0000
@@ -389,6 +389,12 @@ static int islocal;		/* Variable is at t
 				   this function, so we can't say
 				   which register it's relative to;
 				   use LOC_LOCAL.  */
+static int is_thread_local;     /* Variable is at a constant offset in the
+                                   thread-local storage block for the
+                                   current thread and the dynamic linker
+                                   module containing this expression.
+                                   decode_locdesc returns the offset from
+                                   that base.  */
 
 /* DW_AT_frame_base values for the current function.
    frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it
@@ -4724,6 +4730,14 @@ new_symbol (struct die_info *die, struct
                                 "external variable");
                     }
 		  add_symbol_to_list (sym, &global_symbols);
+                  if (is_thread_local)
+                    {
+                      /* SYMBOL_VALUE_ADDRESS contains at this point the
+		         offset of the variable within the thread local
+			 storage.  */
+                      SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
+                      SYMBOL_OBJFILE (sym) = objfile;
+                    }
 
 		  /* In shared libraries the address of the variable
 		     in the location descriptor might still be relocatable,
@@ -4732,7 +4746,7 @@ new_symbol (struct die_info *die, struct
 		     value is zero, the address of the variable will then
 		     be determined from the minimal symbol table whenever
 		     the variable is referenced.  */
-		  if (SYMBOL_VALUE_ADDRESS (sym))
+		  else if (SYMBOL_VALUE_ADDRESS (sym))
 		    {
 		      fixup_symbol_section (sym, objfile);
 		      SYMBOL_VALUE_ADDRESS (sym) +=
@@ -4782,6 +4796,11 @@ new_symbol (struct die_info *die, struct
 		    {
 		      SYMBOL_CLASS (sym) = LOC_LOCAL;
 		    }
+                  else if (is_thread_local)
+                    {
+                      SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
+                      SYMBOL_OBJFILE (sym) = objfile;
+                    }
 		  else
 		    {
 		      fixup_symbol_section (sym, objfile);
@@ -6294,6 +6313,7 @@ decode_locdesc (struct dwarf_block *blk,
   offreg = 0;
   isderef = 0;
   islocal = 0;
+  is_thread_local = 0;
   optimized_out = 1;
 
   while (i < size)
@@ -6516,6 +6536,16 @@ decode_locdesc (struct dwarf_block *blk,
 	  if (i < size)
 	    complain (&dwarf2_complex_location_expr);
 	  break;
+
+        case DW_OP_GNU_push_tls_address:
+          is_thread_local = 1;
+	  /* The top of the stack has the offset from the beginning
+	     of the thread control block at which the variable is located.  */
+	  /* Nothing should follow this operator, so the top of stack would
+	     be returned.  */
+	  if (i < size)
+	    complain (&dwarf2_complex_location_expr);
+          break;
 
 	default:
 	  complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name (op));

Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.35
diff -u -p -r1.35 findvar.c
--- findvar.c	24 Jul 2002 22:46:48 -0000	1.35
+++ findvar.c	2 Oct 2002 02:59:09 -0000
@@ -540,6 +540,23 @@ addresses have not been bound by the dyn
 	addr = value_as_address (regval);
 	addr += SYMBOL_VALUE (var);
 	break;
+      }
+
+    case LOC_THREAD_LOCAL_STATIC:
+      {
+        /* We want to let the target / ABI-specific code construct
+           this value for us, so we need to dispose of the value
+           allocated for us above.  */
+        if (target_get_thread_local_address_p ())
+          addr = target_get_thread_local_address (inferior_ptid,
+                                                  SYMBOL_OBJFILE (var),
+                                                  SYMBOL_VALUE_ADDRESS (var));
+        /* It wouldn't be wrong here to try a gdbarch method, too;
+           finding TLS is an ABI-specific thing.  But we don't do that
+           yet.  */
+        else
+          error ("Cannot find thread-local variables on this target");
+        break;
       }
 
     case LOC_TYPEDEF:

Index: printcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/printcmd.c,v
retrieving revision 1.43
diff -u -p -r1.43 printcmd.c
--- printcmd.c	19 Sep 2002 03:58:41 -0000	1.43
+++ printcmd.c	2 Oct 2002 03:00:20 -0000
@@ -1275,10 +1275,16 @@ address_info (char *exp, int from_tty)
 			"a thread-local variable at offset %ld from the thread base register %s",
 			val, REGISTER_NAME (basereg));
+      break;
+
+    case LOC_THREAD_LOCAL_STATIC:
+      printf_filtered ("a thread-local variable at offset %ld in the "
+                       "thread-local storage for `%s'",
+                       val, SYMBOL_OBJFILE (sym)->name);
       break;
 
     case LOC_OPTIMIZED_OUT:


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