https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=140532 2007-01-13 Jan Kratochvil * 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);