]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.
authorRichard Henderson <rth@redhat.com>
Sun, 8 Sep 2002 18:36:54 +0000 (11:36 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 8 Sep 2002 18:36:54 +0000 (11:36 -0700)
        * 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.

From-SVN: r56957

gcc/ChangeLog
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/dwarf2.h
gcc/dwarf2out.c

index 43f4844e1f531298f2436f937cec6b537d690e75..9a2754e3c5e902076239eb2bf729cc5b97220733 100644 (file)
@@ -1,3 +1,22 @@
+2002-09-08  Richard Henderson  <rth@redhat.com>
+
+       * 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.
+
 2002-09-08  Roger Sayle  <roger@eyesopen.com>
 
        PR optimization/6405
index a81e0f537b2c009f3ff68153ac8294ee01c625a9..bec35aebeeef2986c2f112f8865911d5f694f668 100644 (file)
@@ -110,6 +110,7 @@ extern const char *output_fix_trunc PARAMS ((rtx, rtx*));
 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 a000bae754c3ec43d13567f87f21fa70dbbc4ab3..1d0d1601820b3c87818e1f89b0e6fbcb018a7f5d 100644 (file)
@@ -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 1c75c20591f8c0ca82a2c5ddcea471b1d4675de5..d04c60569a626bd43cda7660313aa25bb6f6acfd 100644 (file)
@@ -3021,6 +3021,13 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
 #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 a84eb2cabd1c0a7188dbb350340e67d005eea7aa..a7f5f0f8d682a334908ae45daefcfa0ff63dadff 100644 (file)
@@ -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 e8f02e62f5f56a1edefa8985188bc10f6e3124c5..5757d247d71ab5b74a4c3a7c92f715d711d6d1f0 100644 (file)
@@ -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_bits PARAMS ((tree));
 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 (die, decl)
      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 (die, decl)
   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 (die, decl)
       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, bound)
 
          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
     }