Blob Blame History Raw
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=140532


2007-01-13  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* dwarf2-frame.c (decode_frame_entry_1): Call
	dwarf2_frame_return_address_regnum when processing CIE return address.
	(struct dwarf2_frame_ops): Add return_address_regnum.
	(dwarf2_frame_set_return_address_regnum): Define.
	(dwarf2_frame_return_address_regnum): Define.
	* dwarf2-frame.h (dwarf2_frame_set_return_address_regnum): Declare.
	(dwarf2_frame_return_address_regnum): Declare.
	* rs6000-tdep.c (rs6000_dwarf2_reg_to_regnum): Map also 64(CR) and
	65(FPSCR) DWARF2 registers.
	(rs6000_return_address_regnum): Define.
	(rs6000_gdbarch_init): Register rs6000_return_address_regnum.


--- gdb-6.5-ppc/gdb/dwarf2-frame.c	2007-01-12 14:40:32.000000000 -0500
+++ gdb-6.5/gdb/dwarf2-frame.c	2007-01-12 18:46:32.000000000 -0500
@@ -586,6 +586,10 @@ struct dwarf2_frame_ops
 
   /* Convert .eh_frame register number to DWARF register number.  */
   int (*eh_frame_regnum) (struct gdbarch *, int);
+
+  /* Convert .eh_frame/.debug_frame CIE return address register number to DWARF
+     register number.  */
+  int (*return_address_regnum) (struct gdbarch *, int, int);
 };
 
 /* Default architecture-specific register state initialization
@@ -693,6 +697,32 @@ dwarf2_frame_signal_frame_p (struct gdba
   return ops->signal_frame_p (gdbarch, next_frame);
 }
 
+/* Set the architecture-specific mapping of .eh_frame/.debug_frame CIE return
+   address register number to DWARF register number.  */
+
+void
+dwarf2_frame_set_return_address_regnum (struct gdbarch *gdbarch,
+					int (*return_address_regnum)
+					    (struct gdbarch *, int, int))
+{
+  struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
+
+  ops->return_address_regnum = return_address_regnum;
+}
+
+/* Translate a .eh_frame/.debug_frame CIE register to DWARF register.  */
+
+int
+dwarf2_frame_return_address_regnum (struct gdbarch *gdbarch, int regnum,
+				    int eh_frame_p)
+{
+  struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
+
+  if (ops->return_address_regnum == NULL)
+    return regnum;
+  return ops->return_address_regnum (gdbarch, regnum, eh_frame_p);
+}
+
 /* Set the architecture-specific mapping of .eh_frame register numbers to
    DWARF register numbers.  */
 
@@ -1618,6 +1648,11 @@ decode_frame_entry_1 (struct comp_unit *
       else
 	cie->return_address_register = read_unsigned_leb128 (unit->abfd, buf,
 							     &bytes_read);
+
+      cie->return_address_register
+        = dwarf2_frame_return_address_regnum (current_gdbarch,
+					      cie->return_address_register,
+					      eh_frame_p);
       if (eh_frame_p)
 	cie->return_address_register
 	  = dwarf2_frame_eh_frame_regnum (current_gdbarch,
--- gdb-6.5-ppc/gdb/dwarf2-frame.h	2007-01-12 14:40:32.000000000 -0500
+++ gdb-6.5/gdb/dwarf2-frame.h	2007-01-12 18:36:47.000000000 -0500
@@ -107,6 +107,20 @@ extern void
 extern int
   dwarf2_frame_eh_frame_regnum (struct gdbarch *gdbarch, int regnum);
 
+/* Set the architecture-specific mapping of .eh_frame/.debug_frame CIE return
+   address register number to DWARF register number.  */
+
+extern void
+  dwarf2_frame_set_return_address_regnum (struct gdbarch *gdbarch,
+					  int (*return_address_regnum)
+					      (struct gdbarch *, int, int));
+
+/* Translate a .eh_frame/.debug_frame CIE register to DWARF register.  */
+
+extern int
+  dwarf2_frame_return_address_regnum (struct gdbarch *gdbarch, int regnum,
+				      int eh_frame_p);
+
 /* Return the frame unwind methods for the function that contains PC,
    or NULL if it can't be handled by DWARF CFI frame unwinder.  */
 
--- gdb-6.5-ppc/gdb/rs6000-tdep.c	2007-01-12 14:40:32.000000000 -0500
+++ gdb-6.5/gdb/rs6000-tdep.c	2007-01-12 18:44:21.000000000 -0500
@@ -2307,6 +2307,11 @@ rs6000_dwarf2_reg_to_regnum (int num)
   else
     switch (num)
       {
+      case 64:
+        return tdep->ppc_cr_regnum;
+      /* Broken GCC uses it for CIE `Return address column' as LR.  */
+      case 65:
+        return tdep->ppc_fpscr_regnum;
       case 67:
         return tdep->ppc_vrsave_regnum - 1; /* vscr */
       case 99:
@@ -2363,6 +2368,22 @@ rs6000_eh_frame_regnum (struct gdbarch *
       }
 }
 
+/* Convert a .eh_frame/.debug_frame CIE return address register number to DWARF
+   register number.  */
+static int
+rs6000_return_address_regnum (struct gdbarch *gdbarch, int regnum,
+			      int eh_frame_p)
+{
+  if (eh_frame_p != 0)
+    return regnum;
+
+  /* Broken GCC uses it for CIE `Return address column' as LR.  */
+  if (regnum == 65)
+    return 108;
+
+  return regnum;
+}
+
 static void
 rs6000_store_return_value (struct type *type,
                            struct regcache *regcache,
@@ -3584,6 +3605,8 @@ rs6000_gdbarch_init (struct gdbarch_info
   /* Hook in the DWARF CFI frame unwinder.  */
   frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
   dwarf2_frame_set_eh_frame_regnum (gdbarch, rs6000_eh_frame_regnum);
+  dwarf2_frame_set_return_address_regnum (gdbarch,
+					  rs6000_return_address_regnum);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);