7a31f8b
2007-02-08  Joel Brobecker  <brobecker@gnat.com>
7a31f8b
	    Jan Kratochvil  <jan.kratochvil@redhat.com>
7a31f8b
	    Daniel Jacobowitz  <dan@codesourcery.com>
7a31f8b
7a31f8b
	* rs6000-tdep.c (bl_to_blrl_insn_p): New function.
7a31f8b
	(skip_prologue): Allow bl->blrl used by PIC code.
7a31f8b
7a31f8b
--- ./gdb/rs6000-tdep.c	9 Jan 2007 17:58:57 -0000	1.260
7a31f8b
+++ ./gdb/rs6000-tdep.c	8 Feb 2007 14:22:53 -0000	1.261
7a31f8b
@@ -902,6 +902,30 @@ store_param_on_stack_p (unsigned long op
7a31f8b
   return 0;
7a31f8b
 }
7a31f8b
 
7a31f8b
+/* Assuming that INSN is a "bl" instruction located at PC, return
7a31f8b
+   nonzero if the destination of the branch is a "blrl" instruction.
7a31f8b
+   
7a31f8b
+   This sequence is sometimes found in certain function prologues.
7a31f8b
+   It allows the function to load the LR register with a value that
7a31f8b
+   they can use to access PIC data using PC-relative offsets.  */
7a31f8b
+
7a31f8b
+static int
7a31f8b
+bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
7a31f8b
+{
7a31f8b
+  const int opcode = 18;
7a31f8b
+  const CORE_ADDR dest = branch_dest (opcode, insn, pc, -1);
7a31f8b
+  int dest_insn;
7a31f8b
+
7a31f8b
+  if (dest == -1)
7a31f8b
+    return 0;  /* Should never happen, but just return zero to be safe.  */
7a31f8b
+  
7a31f8b
+  dest_insn = read_memory_integer (dest, 4);
7a31f8b
+  if ((dest_insn & 0xfc00ffff) == 0x4c000021) /* blrl */
7a31f8b
+    return 1;
7a31f8b
+
7a31f8b
+  return 0;
7a31f8b
+}
7a31f8b
+
7a31f8b
 static CORE_ADDR
7a31f8b
 skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
7a31f8b
 {
7a31f8b
@@ -1133,6 +1157,12 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR l
7a31f8b
 				   to save fprs??? */
7a31f8b
 
7a31f8b
 	  fdata->frameless = 0;
7a31f8b
+
7a31f8b
+	  /* If the return address has already been saved, we can skip
7a31f8b
+	     calls to blrl (for PIC).  */
7a31f8b
+          if (lr_reg != -1 && bl_to_blrl_insn_p (pc, op))
7a31f8b
+	    continue;
7a31f8b
+
7a31f8b
 	  /* Don't skip over the subroutine call if it is not within
7a31f8b
 	     the first three instructions of the prologue and either
7a31f8b
 	     we have no line table information or the line info tells
7a31f8b
7a31f8b
7a31f8b
7a31f8b
2007-03-27  Andreas Schwab  <schwab@suse.de>
7a31f8b
	    Daniel Jacobowitz  <dan@codesourcery.com>
7a31f8b
7a31f8b
	* dwarf2-frame.c (dwarf2_frame_eh_frame_regnum): Rename to...
7a31f8b
	(dwarf2_frame_adjust_regnum): ...this.  Make static.  Add eh_frame_p
7a31f8b
	argument.  Update all callers.
7a31f8b
	(struct dwarf2_frame_ops): Replace eh_frame_regnum with adjust_regnum.
7a31f8b
	(dwarf2_frame_set_eh_frame_regnum): Rename to...
7a31f8b
	(dwarf2_frame_set_adjust_regnum): ...this.  Update argument type.
7a31f8b
	* dwarf2frame.h (dwarf2_frame_set_eh_frame_regnum): Rename to...
7a31f8b
	(dwarf2_frame_set_adjust_regnum): ...this.
7a31f8b
	(dwarf2_frame_eh_frame_regnum): Delete prototype.
7a31f8b
	* rs6000-tdep.c: Include "dwarf2-frame.h".
7a31f8b
	(rs6000_adjust_frame_regnum): Define.
7a31f8b
	(rs6000_gdbarch_init): Enable use of DWARF CFI frame unwinder.
7a31f8b
	Register rs6000_adjust_frame_regnum.
7a31f8b
7a31f8b
	* Makefile.in (rs6000-tdep.o): Update dependencies.
7a31f8b
7a31f8b
--- ./gdb/dwarf2-frame.c	27 Feb 2007 20:17:18 -0000	1.68
7a31f8b
+++ ./gdb/dwarf2-frame.c	27 Mar 2007 19:02:42 -0000	1.69
7a31f8b
@@ -107,6 +107,9 @@ struct dwarf2_fde
7a31f8b
 };
7a31f8b
 
7a31f8b
 static struct dwarf2_fde *dwarf2_frame_find_fde (CORE_ADDR *pc);
7a31f8b
+
7a31f8b
+static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum,
7a31f8b
+				       int eh_frame_p);
7a31f8b
 
7a31f8b
 
7a31f8b
 /* Structure describing a frame state.  */
7a31f8b
@@ -314,8 +317,7 @@ execute_cfa_program (gdb_byte *insn_ptr,
7a31f8b
       else if ((insn & 0xc0) == DW_CFA_offset)
7a31f8b
 	{
7a31f8b
 	  reg = insn & 0x3f;
7a31f8b
-	  if (eh_frame_p)
7a31f8b
-	    reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg);
7a31f8b
+	  reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
7a31f8b
 	  offset = utmp * fs->data_align;
7a31f8b
 	  dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
@@ -326,8 +328,7 @@ execute_cfa_program (gdb_byte *insn_ptr,
7a31f8b
 	{
7a31f8b
 	  gdb_assert (fs->initial.reg);
7a31f8b
 	  reg = insn & 0x3f;
7a31f8b
-	  if (eh_frame_p)
7a31f8b
-	    reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg);
7a31f8b
+	  reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	  dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
 	  if (reg < fs->initial.num_regs)
7a31f8b
 	    fs->regs.reg[reg] = fs->initial.reg[reg];
7a31f8b
@@ -368,8 +369,7 @@ register %s (#%d) at 0x%s"),
7a31f8b
 
7a31f8b
 	    case DW_CFA_offset_extended:
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, ®);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg);
7a31f8b
+	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
7a31f8b
 	      offset = utmp * fs->data_align;
7a31f8b
 	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
@@ -380,35 +380,30 @@ register %s (#%d) at 0x%s"),
7a31f8b
 	    case DW_CFA_restore_extended:
7a31f8b
 	      gdb_assert (fs->initial.reg);
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, ®);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg);
7a31f8b
+	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
 	      fs->regs.reg[reg] = fs->initial.reg[reg];
7a31f8b
 	      break;
7a31f8b
 
7a31f8b
 	    case DW_CFA_undefined:
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, ®);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg);
7a31f8b
+	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
 	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNDEFINED;
7a31f8b
 	      break;
7a31f8b
 
7a31f8b
 	    case DW_CFA_same_value:
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, ®);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg);
7a31f8b
+	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
 	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAME_VALUE;
7a31f8b
 	      break;
7a31f8b
 
7a31f8b
 	    case DW_CFA_register:
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, ®);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg);
7a31f8b
+	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		utmp = dwarf2_frame_eh_frame_regnum (gdbarch, utmp);
7a31f8b
+	      utmp = dwarf2_frame_adjust_regnum (gdbarch, utmp, eh_frame_p);
7a31f8b
 	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
 	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG;
7a31f8b
 	      fs->regs.reg[reg].loc.reg = utmp;
7a31f8b
@@ -456,9 +451,8 @@ bad CFI data; mismatched DW_CFA_restore_
7a31f8b
 
7a31f8b
 	    case DW_CFA_def_cfa_register:
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		fs->cfa_reg = dwarf2_frame_eh_frame_regnum (gdbarch,
7a31f8b
-							    fs->cfa_reg);
7a31f8b
+	      fs->cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, fs->cfa_reg,
7a31f8b
+							eh_frame_p);
7a31f8b
 	      fs->cfa_how = CFA_REG_OFFSET;
7a31f8b
 	      break;
7a31f8b
 
7a31f8b
@@ -484,8 +478,7 @@ bad CFI data; mismatched DW_CFA_restore_
7a31f8b
 
7a31f8b
 	    case DW_CFA_expression:
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, ®);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg);
7a31f8b
+	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
7a31f8b
 	      fs->regs.reg[reg].loc.exp = insn_ptr;
7a31f8b
@@ -496,8 +489,7 @@ bad CFI data; mismatched DW_CFA_restore_
7a31f8b
 
7a31f8b
 	    case DW_CFA_offset_extended_sf:
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, ®);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		reg = dwarf2_frame_eh_frame_regnum (gdbarch, reg);
7a31f8b
+	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	      insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset);
7a31f8b
 	      offset *= fs->data_align;
7a31f8b
 	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
@@ -535,9 +527,8 @@ bad CFI data; mismatched DW_CFA_restore_
7a31f8b
 
7a31f8b
 	    case DW_CFA_def_cfa_sf:
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg);
7a31f8b
-	      if (eh_frame_p)
7a31f8b
-		fs->cfa_reg = dwarf2_frame_eh_frame_regnum (gdbarch,
7a31f8b
-							    fs->cfa_reg);
7a31f8b
+	      fs->cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, fs->cfa_reg,
7a31f8b
+							eh_frame_p);
7a31f8b
 	      insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset);
7a31f8b
 	      fs->cfa_offset = offset * fs->data_align;
7a31f8b
 	      fs->cfa_how = CFA_REG_OFFSET;
7a31f8b
@@ -581,6 +572,7 @@ bad CFI data; mismatched DW_CFA_restore_
7a31f8b
 
7a31f8b
 	    case DW_CFA_GNU_negative_offset_extended:
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, ®);
7a31f8b
+	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
7a31f8b
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &offset);
7a31f8b
 	      offset *= fs->data_align;
7a31f8b
 	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
7a31f8b
@@ -617,8 +607,9 @@ struct dwarf2_frame_ops
7a31f8b
      trampoline.  */
7a31f8b
   int (*signal_frame_p) (struct gdbarch *, struct frame_info *);
7a31f8b
 
7a31f8b
-  /* Convert .eh_frame register number to DWARF register number.  */
7a31f8b
-  int (*eh_frame_regnum) (struct gdbarch *, int);
7a31f8b
+  /* Convert .eh_frame register number to DWARF register number, or
7a31f8b
+     adjust .debug_frame register number.  */
7a31f8b
+  int (*adjust_regnum) (struct gdbarch *, int, int);
7a31f8b
 };
7a31f8b
 
7a31f8b
 /* Default architecture-specific register state initialization
7a31f8b
@@ -726,29 +717,30 @@ dwarf2_frame_signal_frame_p (struct gdba
7a31f8b
   return ops->signal_frame_p (gdbarch, next_frame);
7a31f8b
 }
7a31f8b
 
7a31f8b
-/* Set the architecture-specific mapping of .eh_frame register numbers to
7a31f8b
-   DWARF register numbers.  */
7a31f8b
+/* Set the architecture-specific adjustment of .eh_frame and .debug_frame
7a31f8b
+   register numbers.  */
7a31f8b
 
7a31f8b
 void
7a31f8b
-dwarf2_frame_set_eh_frame_regnum (struct gdbarch *gdbarch,
7a31f8b
-				  int (*eh_frame_regnum) (struct gdbarch *,
7a31f8b
-							  int))
7a31f8b
+dwarf2_frame_set_adjust_regnum (struct gdbarch *gdbarch,
7a31f8b
+				int (*adjust_regnum) (struct gdbarch *,
7a31f8b
+						      int, int))
7a31f8b
 {
7a31f8b
   struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
7a31f8b
 
7a31f8b
-  ops->eh_frame_regnum = eh_frame_regnum;
7a31f8b
+  ops->adjust_regnum = adjust_regnum;
7a31f8b
 }
7a31f8b
 
7a31f8b
-/* Translate a .eh_frame register to DWARF register.  */
7a31f8b
+/* Translate a .eh_frame register to DWARF register, or adjust a .debug_frame
7a31f8b
+   register.  */
7a31f8b
 
7a31f8b
-int
7a31f8b
-dwarf2_frame_eh_frame_regnum (struct gdbarch *gdbarch, int regnum)
7a31f8b
+static int
7a31f8b
+dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum, int eh_frame_p)
7a31f8b
 {
7a31f8b
   struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
7a31f8b
 
7a31f8b
-  if (ops->eh_frame_regnum == NULL)
7a31f8b
+  if (ops->adjust_regnum == NULL)
7a31f8b
     return regnum;
7a31f8b
-  return ops->eh_frame_regnum (gdbarch, regnum);
7a31f8b
+  return ops->adjust_regnum (gdbarch, regnum, eh_frame_p);
7a31f8b
 }
7a31f8b
 
7a31f8b
 static void
7a31f8b
@@ -1726,10 +1718,10 @@ decode_frame_entry_1 (struct comp_unit *
7a31f8b
       else
7a31f8b
 	cie->return_address_register = read_unsigned_leb128 (unit->abfd, buf,
7a31f8b
 							     &bytes_read);
7a31f8b
-      if (eh_frame_p)
7a31f8b
-	cie->return_address_register
7a31f8b
-	  = dwarf2_frame_eh_frame_regnum (current_gdbarch,
7a31f8b
-					  cie->return_address_register);
7a31f8b
+      cie->return_address_register
7a31f8b
+	= dwarf2_frame_adjust_regnum (current_gdbarch,
7a31f8b
+				      cie->return_address_register,
7a31f8b
+				      eh_frame_p);
7a31f8b
 
7a31f8b
       buf += bytes_read;
7a31f8b
 
7a31f8b
--- ./gdb/dwarf2-frame.h	9 Jan 2007 17:58:50 -0000	1.14
7a31f8b
+++ ./gdb/dwarf2-frame.h	27 Mar 2007 19:02:42 -0000	1.15
7a31f8b
@@ -94,18 +94,13 @@ extern void
7a31f8b
 				   int (*signal_frame_p) (struct gdbarch *,
7a31f8b
 							  struct frame_info *));
7a31f8b
 
7a31f8b
-/* Set the architecture-specific mapping of .eh_frame register numbers to
7a31f8b
-   DWARF register numbers.  */
7a31f8b
+/* Set the architecture-specific adjustment of .eh_frame and .debug_frame
7a31f8b
+   register numbers.  */
7a31f8b
 
7a31f8b
 extern void
7a31f8b
-  dwarf2_frame_set_eh_frame_regnum (struct gdbarch *gdbarch,
7a31f8b
-				    int (*eh_frame_regnum) (struct gdbarch *,
7a31f8b
-							    int));
7a31f8b
-
7a31f8b
-/* Translate a .eh_frame register to DWARF register.  */
7a31f8b
-
7a31f8b
-extern int
7a31f8b
-  dwarf2_frame_eh_frame_regnum (struct gdbarch *gdbarch, int regnum);
7a31f8b
+  dwarf2_frame_set_adjust_regnum (struct gdbarch *gdbarch,
7a31f8b
+				  int (*adjust_regnum) (struct gdbarch *,
7a31f8b
+							int, int));
7a31f8b
 
7a31f8b
 /* Return the frame unwind methods for the function that contains PC,
7a31f8b
    or NULL if it can't be handled by DWARF CFI frame unwinder.  */
7a31f8b
--- ./gdb/rs6000-tdep.c	13 Mar 2007 17:34:22 -0000	1.266
7a31f8b
+++ ./gdb/rs6000-tdep.c	27 Mar 2007 19:02:42 -0000	1.267
7a31f8b
@@ -40,6 +40,7 @@
7a31f8b
 #include "sim-regno.h"
7a31f8b
 #include "gdb/sim-ppc.h"
7a31f8b
 #include "reggroups.h"
7a31f8b
+#include "dwarf2-frame.h"
7a31f8b
 
7a31f8b
 #include "libbfd.h"		/* for bfd_default_set_arch_mach */
7a31f8b
 #include "coff/internal.h"	/* for libcoff.h */
7a31f8b
@@ -2294,6 +2295,69 @@ rs6000_dwarf2_reg_to_regnum (int num)
7a31f8b
       }
7a31f8b
 }
7a31f8b
 
7a31f8b
+/* Translate a .eh_frame register to DWARF register, or adjust a
7a31f8b
+   .debug_frame register.  */
7a31f8b
+
7a31f8b
+static int
7a31f8b
+rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p)
7a31f8b
+{
7a31f8b
+  /* GCC releases before 3.4 use GCC internal register numbering in
7a31f8b
+     .debug_frame (and .debug_info, et cetera).  The numbering is
7a31f8b
+     different from the standard SysV numbering for everything except
7a31f8b
+     for GPRs and FPRs.  We can not detect this problem in most cases
7a31f8b
+     - to get accurate debug info for variables living in lr, ctr, v0,
7a31f8b
+     et cetera, use a newer version of GCC.  But we must detect
7a31f8b
+     one important case - lr is in column 65 in .debug_frame output,
7a31f8b
+     instead of 108.
7a31f8b
+
7a31f8b
+     GCC 3.4, and the "hammer" branch, have a related problem.  They
7a31f8b
+     record lr register saves in .debug_frame as 108, but still record
7a31f8b
+     the return column as 65.  We fix that up too.
7a31f8b
+
7a31f8b
+     We can do this because 65 is assigned to fpsr, and GCC never
7a31f8b
+     generates debug info referring to it.  To add support for
7a31f8b
+     handwritten debug info that restores fpsr, we would need to add a
7a31f8b
+     producer version check to this.  */
7a31f8b
+  if (!eh_frame_p)
7a31f8b
+    {
7a31f8b
+      if (num == 65)
7a31f8b
+	return 108;
7a31f8b
+      else
7a31f8b
+	return num;
7a31f8b
+    }
7a31f8b
+
7a31f8b
+  /* .eh_frame is GCC specific.  For binary compatibility, it uses GCC
7a31f8b
+     internal register numbering; translate that to the standard DWARF2
7a31f8b
+     register numbering.  */
7a31f8b
+  if (0 <= num && num <= 63)	/* r0-r31,fp0-fp31 */
7a31f8b
+    return num;
7a31f8b
+  else if (68 <= num && num <= 75) /* cr0-cr8 */
7a31f8b
+    return num - 68 + 86;
7a31f8b
+  else if (77 <= num && num <= 108) /* vr0-vr31 */
7a31f8b
+    return num - 77 + 1124;
7a31f8b
+  else
7a31f8b
+    switch (num)
7a31f8b
+      {
7a31f8b
+      case 64: /* mq */
7a31f8b
+	return 100;
7a31f8b
+      case 65: /* lr */
7a31f8b
+	return 108;
7a31f8b
+      case 66: /* ctr */
7a31f8b
+	return 109;
7a31f8b
+      case 76: /* xer */
7a31f8b
+	return 101;
7a31f8b
+      case 109: /* vrsave */
7a31f8b
+	return 356;
7a31f8b
+      case 110: /* vscr */
7a31f8b
+	return 67;
7a31f8b
+      case 111: /* spe_acc */
7a31f8b
+	return 99;
7a31f8b
+      case 112: /* spefscr */
7a31f8b
+	return 612;
7a31f8b
+      default:
7a31f8b
+	return num;
7a31f8b
+      }
7a31f8b
+}
7a31f8b
 
7a31f8b
 /* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG).
7a31f8b
 
7a31f8b
@@ -3428,6 +3492,10 @@ rs6000_gdbarch_init (struct gdbarch_info
7a31f8b
     (gdbarch, rs6000_in_solib_return_trampoline);
7a31f8b
   set_gdbarch_skip_trampoline_code (gdbarch, rs6000_skip_trampoline_code);
7a31f8b
 
7a31f8b
+  /* Hook in the DWARF CFI frame unwinder.  */
7a31f8b
+  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
7a31f8b
+  dwarf2_frame_set_adjust_regnum (gdbarch, rs6000_adjust_frame_regnum);
7a31f8b
+
7a31f8b
   /* Hook in ABI-specific overrides, if they have been registered.  */
7a31f8b
   gdbarch_init_osabi (info, gdbarch);
7a31f8b
 
7a31f8b
--- ./gdb/Makefile.in.orig	2007-07-31 16:42:29.000000000 -0400
7a31f8b
+++ ./gdb/Makefile.in	2007-08-01 13:42:51.000000000 -0400
7a31f8b
@@ -2468,7 +2468,7 @@ rs6000-tdep.o: rs6000-tdep.c $(defs_h) $
7a31f8b
 	$(reggroups_h) $(libbfd_h) $(coff_internal_h) $(libcoff_h) \
7a31f8b
 	$(coff_xcoff_h) $(libxcoff_h) $(elf_bfd_h) $(solib_svr4_h) \
7a31f8b
 	$(ppc_tdep_h) $(gdb_assert_h) $(dis_asm_h) $(trad_frame_h) \
7a31f8b
-	$(frame_unwind_h) $(frame_base_h) $(rs6000_tdep_h)
7a31f8b
+	$(frame_unwind_h) $(frame_base_h) $(rs6000_tdep_h) $(dwarf2_frame_h)
7a31f8b
 rs6000-aix-tdep.o: rs6000-aix-tdep.c $(defs_h) $(osabi_h) $(rs6000_tdep_h)
7a31f8b
 s390-nat.o: s390-nat.c $(defs_h) $(tm_h) $(regcache_h) $(inferior_h) \
7a31f8b
 	$(s390_tdep_h) $(observer_h) $(linux_nat_h)
7a31f8b
 s390-tdep.o: s390-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) $(inferior_h) \
7a31f8b
7a31f8b
7a31f8b
7a31f8b
2007-04-10  Andreas Schwab  <schwab@suse.de>
7a31f8b
7a31f8b
	* rs6000-tdep.c (rs6000_dwarf2_reg_to_regnum): Decode 64 as CR
7a31f8b
	register.
7a31f8b
7a31f8b
--- ./gdb/rs6000-tdep.c	1 Apr 2007 18:24:59 -0000	1.269
7a31f8b
+++ ./gdb/rs6000-tdep.c	10 Apr 2007 16:02:41 -0000	1.270
7a31f8b
@@ -2274,6 +2274,8 @@ rs6000_dwarf2_reg_to_regnum (int num)
7a31f8b
   else
7a31f8b
     switch (num)
7a31f8b
       {
7a31f8b
+      case 64:
7a31f8b
+	return tdep->ppc_cr_regnum;
7a31f8b
       case 67:
7a31f8b
         return tdep->ppc_vrsave_regnum - 1; /* vscr */
7a31f8b
       case 99: