gdb/gdb-6.5-bz140532-ppc-debug_frame-return_address.patch

146 lines
5.1 KiB
Diff
Raw Normal View History

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);