2002-10-21 Jim Blandy <jimb@redhat.com>
authorElena Zannoni <ezannoni@kwikemart.cygnus.com>
Mon, 21 Oct 2002 19:11:50 +0000 (19:11 +0000)
committerElena Zannoni <ezannoni@kwikemart.cygnus.com>
Mon, 21 Oct 2002 19:11:50 +0000 (19:11 +0000)
    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.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/findvar.c
gdb/printcmd.c
gdb/symtab.h

index 738246d66fc5c6f7c41f5f2bc2042bf13afe2869..09ecdbe8e9b3c03303ccc4fbdaf7a93d472ce41c 100644 (file)
@@ -1,3 +1,20 @@
+2002-10-21  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.
+
 2002-10-21  Elena Zannoni  <ezannoni@redhat.com>
 
         * solib-svr4.c (svr4_fetch_objfile_link_map): New function.
index 16a1c4225d6ed4ae160c7383867539a762edd9de..d6de7ef4cc7b359731dceb464496e05663da626d 100644 (file)
@@ -410,6 +410,12 @@ static int islocal;                /* Variable is at the returned offset
                                   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
@@ -4788,6 +4794,14 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
                                 "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,
@@ -4796,7 +4810,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
                     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) +=
@@ -4846,6 +4860,11 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
                    {
                      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);
@@ -6358,6 +6377,7 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
   offreg = 0;
   isderef = 0;
   islocal = 0;
+  is_thread_local = 0;
   optimized_out = 1;
 
   while (i < size)
@@ -6581,6 +6601,16 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
            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));
          return (stack[stacki]);
index e48ccc6f4addb5afa6a3279931adfb3f7b0f8d31..9eff168ddca6a87a80a2cf5c5417e1616bb8c21f 100644 (file)
@@ -542,6 +542,23 @@ addresses have not been bound by the dynamic loader. Try again when executable i
        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:
       error ("Cannot look up value of a typedef");
       break;
index 2f7f865c6f4b4a995024619b7b626b19816fa16a..2bf5fdf4d0014d67736cb96c645ff14614fca17d 100644 (file)
@@ -1285,6 +1285,12 @@ address_info (char *exp, int from_tty)
                        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:
       printf_filtered ("optimized out");
       break;
index 520e81efef750b330444268eb999f01b14555ff5..b84cac69ced8fbfc9c5251e87703751030c31cb3 100644 (file)
@@ -629,6 +629,14 @@ enum address_class
 
   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
+     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.
      The value is ignored.  */
 
@@ -698,6 +706,12 @@ struct symbol
   {
     /* Used by LOC_BASEREG and LOC_BASEREG_ARG.  */
     short basereg;
+
+    /* Used by LOC_THREAD_LOCAL_STATIC.  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;
 
@@ -719,6 +733,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
 \f