This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

dwarf2 vs tls


GDB support isn't committed yet, but Elena is working on it.
I'm committing this now to make it easier for her to build a
toolchain to test with.


r~


        * dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.
        (DW_OP_GNU_push_tls_address): New.
        (DW_OP_lo_user): Fix. 
        * dwarf2out.c (INTERNAL_DW_OP_tls_addr): New.
        (dwarf_stack_op_name): Handle it, plus other dwarf3 opcodes.
        (size_of_loc_descr): Likewise.
        (output_loc_operands): Handle INTERNAL_DW_OP_tls_addr.
        (add_AT_location_description): Take a dw_loc_descr_ref not an rtx.
        (loc_descriptor_from_tree): Handle TLS variables.
        (rtl_for_decl_location): Do avoid_constant_pool_reference here ...
        (add_location_or_const_value_attribute): ... not here.  Defer
        to loc_descriptor_from_tree for TLS variables.

        * config/i386/i386.h (ASM_OUTPUT_DWARF_DTPREL): New.
        * config/i386/i386.c (i386_output_dwarf_dtprel): New.
        * config/i386/i386-protos.h: Update.

Index: dwarf2.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2.h,v
retrieving revision 1.23
diff -u -p -u -r1.23 dwarf2.h
--- dwarf2.h	24 Apr 2002 18:49:51 -0000	1.23
+++ dwarf2.h	8 Sep 2002 18:29:07 -0000
@@ -399,10 +399,12 @@ enum dwarf_location_atom
     DW_OP_push_object_address = 0x97,
     DW_OP_call2 = 0x98,
     DW_OP_call4 = 0x99,
-    DW_OP_calli = 0x9a
+    DW_OP_call_ref = 0x9a,
+    /* GNU extensions.  */
+    DW_OP_GNU_push_tls_address = 0xe0
   };
 
-#define DW_OP_lo_user	0x80	/* Implementation-defined range start.  */
+#define DW_OP_lo_user	0xe0	/* Implementation-defined range start.  */
 #define DW_OP_hi_user	0xff	/* Implementation-defined range end.  */
 
 /* Type encodings.  */
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.384
diff -u -p -u -r1.384 dwarf2out.c
--- dwarf2out.c	25 Aug 2002 05:21:10 -0000	1.384
+++ dwarf2out.c	8 Sep 2002 18:29:09 -0000
@@ -2182,6 +2182,11 @@ dwarf2out_frame_finish ()
 /* And now, the subset of the debugging information support code necessary
    for emitting location expressions.  */
 
+/* We need some way to distinguish DW_OP_addr with a direct symbol
+   relocation from DW_OP_addr with a dtp-relative symbol relocation.  */
+#define INTERNAL_DW_OP_tls_addr		(0x100 + DW_OP_addr)
+
+
 typedef struct dw_val_struct *dw_val_ref;
 typedef struct die_struct *dw_die_ref;
 typedef struct dw_loc_descr_struct *dw_loc_descr_ref;
@@ -2307,6 +2312,7 @@ dwarf_stack_op_name (op)
   switch (op)
     {
     case DW_OP_addr:
+    case INTERNAL_DW_OP_tls_addr:
       return "DW_OP_addr";
     case DW_OP_deref:
       return "DW_OP_deref";
@@ -2596,6 +2602,16 @@ dwarf_stack_op_name (op)
       return "DW_OP_xderef_size";
     case DW_OP_nop:
       return "DW_OP_nop";
+    case DW_OP_push_object_address:
+      return "DW_OP_push_object_address";
+    case DW_OP_call2:
+      return "DW_OP_call2";
+    case DW_OP_call4:
+      return "DW_OP_call4";
+    case DW_OP_call_ref:
+      return "DW_OP_call_ref";
+    case DW_OP_GNU_push_tls_address:
+      return "DW_OP_GNU_push_tls_address";
     default:
       return "OP_<unknown>";
     }
@@ -2653,6 +2669,7 @@ size_of_loc_descr (loc)
   switch (loc->dw_loc_opc)
     {
     case DW_OP_addr:
+    case INTERNAL_DW_OP_tls_addr:
       size += DWARF2_ADDR_SIZE;
       break;
     case DW_OP_const1u:
@@ -2738,6 +2755,15 @@ size_of_loc_descr (loc)
     case DW_OP_xderef_size:
       size += 1;
       break;
+    case DW_OP_call2:
+      size += 2;
+      break;
+    case DW_OP_call4:
+      size += 4;
+      break;
+    case DW_OP_call_ref:
+      size += DWARF2_ADDR_SIZE;
+      break;
     default:
       break;
     }
@@ -2887,6 +2913,17 @@ output_loc_operands (loc)
     case DW_OP_xderef_size:
       dw2_asm_output_data (1, val1->v.val_int, NULL);
       break;
+
+    case INTERNAL_DW_OP_tls_addr:
+#ifdef ASM_OUTPUT_DWARF_DTPREL
+      ASM_OUTPUT_DWARF_DTPREL (asm_out_file, DWARF2_ADDR_SIZE,
+			       val1->v.val_addr);
+      fputc ('\n', asm_out_file);
+#else
+      abort ();
+#endif
+      break;
+
     default:
       /* Other codes have no operands.  */
       break;
@@ -3590,7 +3627,8 @@ static unsigned int simple_decl_align_in
 static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree));
 static HOST_WIDE_INT field_byte_offset	PARAMS ((tree));
 static void add_AT_location_description	PARAMS ((dw_die_ref,
-						 enum dwarf_attribute, rtx));
+						 enum dwarf_attribute,
+						 dw_loc_descr_ref));
 static void add_data_member_location_attribute PARAMS ((dw_die_ref, tree));
 static void add_const_value_attribute	PARAMS ((dw_die_ref, rtx));
 static rtx rtl_for_decl_location	PARAMS ((tree));
@@ -8015,6 +8053,42 @@ loc_descriptor_from_tree (loc, addressp)
 	       : 0);
 
     case VAR_DECL:
+      if (DECL_THREAD_LOCAL (loc))
+	{
+	  rtx rtl;
+
+#ifndef ASM_OUTPUT_DWARF_DTPREL
+	  /* If this is not defined, we have no way to emit the data.  */
+	  return 0;
+#endif
+
+	  /* The way DW_OP_GNU_push_tls_address is specified, we can only
+	     look up addresses of objects in the current module.  */
+	  if (! (*targetm.binds_local_p) (loc))
+	    return 0;
+
+	  rtl = rtl_for_decl_location (loc);
+	  if (rtl == NULL_RTX)
+	    return 0;
+
+	  if (GET_CODE (rtl) != MEM)
+	    return 0;
+	  rtl = XEXP (rtl, 0);
+	  if (! CONSTANT_P (rtl))
+	    return 0;
+
+	  ret = new_loc_descr (INTERNAL_DW_OP_tls_addr, 0, 0);
+	  ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
+	  ret->dw_loc_oprnd1.v.val_addr = rtl;
+
+	  ret1 = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0);
+	  add_loc_descr (&ret, ret1);
+
+	  indirect_p = 1;
+	  break;
+	}
+      /* FALLTHRU */
+
     case PARM_DECL:
       {
 	rtx rtl = rtl_for_decl_location (loc);
@@ -8497,14 +8571,12 @@ field_byte_offset (decl)
    whole parameters.  Note that the location attributes for struct fields are
    generated by the routine `data_member_location_attribute' below.  */
 
-static void
-add_AT_location_description (die, attr_kind, rtl)
+static inline void
+add_AT_location_description (die, attr_kind, descr)
      dw_die_ref die;
      enum dwarf_attribute attr_kind;
-     rtx rtl;
+     dw_loc_descr_ref descr;
 {
-  dw_loc_descr_ref descr = loc_descriptor (rtl);
-
   if (descr != 0)
     add_AT_loc (die, attr_kind, descr);
 }
@@ -8929,6 +9001,13 @@ rtl_for_decl_location (decl)
   if (rtl)
     rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
 #endif
+
+  /* If we don't look past the constant pool, we risk emitting a
+     reference to a constant pool entry that isn't referenced from
+     code, and thus is not emitted.  */
+  if (rtl)
+    rtl = avoid_constant_pool_reference (rtl);
+
   return rtl;
 }
 
@@ -8949,6 +9028,7 @@ add_location_or_const_value_attribute (d
      tree decl;
 {
   rtx rtl;
+  dw_loc_descr_ref descr;
 
   if (TREE_CODE (decl) == ERROR_MARK)
     return;
@@ -8959,16 +9039,11 @@ add_location_or_const_value_attribute (d
   if (rtl == NULL_RTX)
     return;
 
-  /* If we don't look past the constant pool, we risk emitting a
-     reference to a constant pool entry that isn't referenced from
-     code, and thus is not emitted.  */
-  rtl = avoid_constant_pool_reference (rtl);
-
   switch (GET_CODE (rtl))
     {
     case ADDRESSOF:
-      /* The address of a variable that was optimized away; don't emit
-	 anything.  */
+      /* The address of a variable that was optimized away;
+	 don't emit anything.  */
       break;
 
     case CONST_INT:
@@ -8983,12 +9058,24 @@ add_location_or_const_value_attribute (d
       break;
 
     case MEM:
-    case REG:
-    case SUBREG:
-    case CONCAT:
-      add_AT_location_description (die, DW_AT_location, rtl);
+      if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+	{
+	  /* Need loc_descriptor_from_tree since that's where we know
+	     how to handle TLS variables.  Want the object's address
+	     since the top-level DW_AT_location assumes such.  See
+	     the confusion in loc_descriptor for reference.  */
+	  descr = loc_descriptor_from_tree (decl, 1);
+	}
+      else
+	{
+	case REG:
+	case SUBREG:
+	case CONCAT:
+	  descr = loc_descriptor (rtl);
+	}
+      add_AT_location_description (die, DW_AT_location, descr);
       break;
-
+	
     default:
       abort ();
     }
@@ -9120,7 +9207,8 @@ add_bound_info (subrange_die, bound_attr
 
 	  add_AT_flag (decl_die, DW_AT_artificial, 1);
 	  add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
-	  add_AT_location_description (decl_die, DW_AT_location, loc);
+	  add_AT_location_description (decl_die, DW_AT_location,
+				       loc_descriptor (loc));
 	  add_AT_die_ref (subrange_die, bound_attr, decl_die);
 	}
 
@@ -10325,7 +10413,7 @@ gen_subprogram_die (decl, context_die)
 	 is not part of the state saved/restored for inline functions.  */
       if (current_function_needs_context)
 	add_AT_location_description (subr_die, DW_AT_static_link,
-				     lookup_static_chain (decl));
+			     loc_descriptor (lookup_static_chain (decl)));
 #endif
     }
 
Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.77
diff -u -p -u -r1.77 i386-protos.h
--- config/i386/i386-protos.h	16 Jul 2002 22:20:09 -0000	1.77
+++ config/i386/i386-protos.h	8 Sep 2002 18:29:10 -0000
@@ -110,6 +110,7 @@ extern const char *output_fix_trunc PARA
 extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int));
 
 extern void i386_dwarf_output_addr_const PARAMS ((FILE*, rtx));
+extern void i386_output_dwarf_dtprel PARAMS ((FILE*, int, rtx));
 extern rtx i386_simplify_dwarf_addr PARAMS ((rtx));
 
 extern void ix86_expand_clear PARAMS ((rtx));
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.452
diff -u -p -u -r1.452 i386.c
--- config/i386/i386.c	6 Sep 2002 20:34:41 -0000	1.452
+++ config/i386/i386.c	8 Sep 2002 18:29:13 -0000
@@ -5956,6 +5956,33 @@ i386_dwarf_output_addr_const (file, x)
   fputc ('\n', file);
 }
 
+/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
+   We need to emit DTP-relative relocations.  */
+
+void
+i386_output_dwarf_dtprel (file, size, x)
+     FILE *file;
+     int size;
+     rtx x;
+{
+  switch (size)
+    {
+    case 4:
+      fputs (ASM_LONG, file);
+      break;
+    case 8:
+#ifdef ASM_QUAD
+      fputs (ASM_QUAD, file);
+      break;
+#endif
+    default:
+      abort ();
+   }
+  
+  output_addr_const (file, x);
+  fputs ("@DTPOFF", file);
+}
+
 /* In the name of slightly smaller debug output, and to cater to
    general assembler losage, recognize PIC+GOTOFF and turn it back
    into a direct symbol reference.  */
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.282
diff -u -p -u -r1.282 i386.h
--- config/i386/i386.h	6 Sep 2002 20:34:41 -0000	1.282
+++ config/i386/i386.h	8 Sep 2002 18:29:14 -0000
@@ -3021,6 +3021,13 @@ extern int const svr4_dbx_register_map[F
 #define ASM_SIMPLIFY_DWARF_ADDR(X) \
   i386_simplify_dwarf_addr (X)
 
+/* Emit a dtp-relative reference to a TLS variable.  */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+  i386_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
 /* Switch to init or fini section via SECTION_OP, emit a call to FUNC,
    and switch back.  For x86 we do this only to save a few bytes that
    would otherwise be unused in the text section.  */


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