http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47324

--- Comment #33 from Iain Sandoe <iains at gcc dot gnu.org> 2011-02-10 14:39:46 
UTC ---
in addition to Mike's fix,

the dw_loc_descr_ref reg numbers need to be adjusted in the loc lists,

below is a hack which works - I don't know the code well enough to know if the
dw_loc_opc should just be written to the translated version in the first place.

=====

Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c    (revision 170000)
+++ gcc/dwarf2out.c    (working copy)
@@ -474,7 +474,7 @@ static bool clobbers_queued_reg_save (const_rtx);
 static void dwarf2out_frame_debug_expr (rtx, const char *);

 /* Support for complex CFA locations.  */
-static void output_cfa_loc (dw_cfi_ref);
+static void output_cfa_loc (dw_cfi_ref, int);
 static void output_cfa_loc_raw (dw_cfi_ref);
 static void get_cfa_from_loc_descr (dw_cfa_location *,
                     struct dw_loc_descr_struct *);
@@ -3317,7 +3317,7 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int fo

     case DW_CFA_def_cfa_expression:
     case DW_CFA_expression:
-      output_cfa_loc (cfi);
+      output_cfa_loc (cfi, for_eh);
       break;

     case DW_CFA_GNU_negative_offset_extended:
@@ -5291,13 +5291,21 @@ output_loc_operands (dw_loc_descr_ref loc)
 /* Output a sequence of location operations.  */

 static void
-output_loc_sequence (dw_loc_descr_ref loc)
+output_loc_sequence (dw_loc_descr_ref loc, int for_eh)
 {
   for (; loc != NULL; loc = loc->dw_loc_next)
     {
       /* Output the opcode.  */
-      dw2_asm_output_data (1, loc->dw_loc_opc,
-               "%s", dwarf_stack_op_name (loc->dw_loc_opc));
+      if (for_eh && loc->dw_loc_opc >= DW_OP_breg0 && loc->dw_loc_opc <=
DW_OP_breg31)
+    {
+      unsigned r = (loc->dw_loc_opc - DW_OP_breg0);
+      r = DWARF2_FRAME_REG_OUT (r, for_eh) ;
+      dw2_asm_output_data (1, (r+DW_OP_breg0),
+                 "%s", dwarf_stack_op_name (r+DW_OP_breg0));
+    }
+      else
+    dw2_asm_output_data (1, loc->dw_loc_opc,
+                 "%s", dwarf_stack_op_name (loc->dw_loc_opc));

       /* Output the operand(s) (if any).  */
       output_loc_operands (loc);
@@ -5451,14 +5459,16 @@ output_loc_sequence_raw (dw_loc_descr_ref loc)
    description based on a cfi entry with a complex address.  */

 static void
-output_cfa_loc (dw_cfi_ref cfi)
+output_cfa_loc (dw_cfi_ref cfi, int for_eh)
 {
   dw_loc_descr_ref loc;
   unsigned long size;

   if (cfi->dw_cfi_opc == DW_CFA_expression)
     {
-      dw2_asm_output_data (1, cfi->dw_cfi_oprnd1.dw_cfi_reg_num, NULL);
+      unsigned long r = 
+    DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+      dw2_asm_output_data (1, r, NULL);
       loc = cfi->dw_cfi_oprnd2.dw_cfi_loc;
     }
   else
@@ -5469,7 +5479,7 @@ static void
   dw2_asm_output_data_uleb128 (size, NULL);

   /* Now output the operations themselves.  */
-  output_loc_sequence (loc);
+  output_loc_sequence (loc, for_eh);
 }

 /* Similar, but used for .cfi_escape.  */
@@ -11075,7 +11085,7 @@ output_loc_list (dw_loc_list_ref list_head)
       gcc_assert (size <= 0xffff);
       dw2_asm_output_data (2, size, "%s", "Location expression size");

-      output_loc_sequence (curr->expr);
+      output_loc_sequence (curr->expr, 0);
     }

   dw2_asm_output_data (DWARF2_ADDR_SIZE, 0,
@@ -11153,7 +11163,7 @@ output_die (dw_die_ref die)
       else
         dw2_asm_output_data (constant_size (size), size, "%s", name);

-      output_loc_sequence (AT_loc (a));
+      output_loc_sequence (AT_loc (a), 0);
       break;

     case dw_val_class_const:

Reply via email to