146 lines
5.1 KiB
Diff
146 lines
5.1 KiB
Diff
|
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);
|