From cc72850f95d062076e557cba1a4a402d45f0b548 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Tue, 7 Dec 2004 18:04:11 +0000 Subject: [PATCH] * hppa-tdep.h (hppa_read_pc, hppa_write_pc, hppa_unwind_pc): New prototypes. * hppa-tdep.c (hppa_read_pc): Rename from hppa_target_read_pc. Make global. Remove HP-UX specific code. Use frame_unwind_register_unsigned instead of frame_unwind_register_signed. (hppa_write_pc): Rename from hppa_target_write_pc. Make global. Remove HP-UX specific code. (hppa_unwind_pc): Make global. Remove HP-UX specific code. (hppa_frame_prev_register_helper): Set "flags" register to zero for all unwound frames. (hppa_gdbarch_init): Adjust. * hppa-hpux-tdep.c (HPPA_HPUX_SS_INSYSCALL): New define. (hppa_hpux_read_pc, hppa_hpux_write_pc) (hppa_hpux_unwind_pc): New functions. (hppa_hpux_init_abi): Set read_pc, write_pc and unwind_pc. --- gdb/ChangeLog | 19 ++++++++++++ gdb/hppa-hpux-tdep.c | 50 +++++++++++++++++++++++++++++++ gdb/hppa-tdep.c | 85 +++++++++++++++++++++++++--------------------------- gdb/hppa-tdep.h | 5 ++++ 4 files changed, 114 insertions(+), 45 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 953c707..49d9e5f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,22 @@ +2004-12-07 Mark Kettenis + + * hppa-tdep.h (hppa_read_pc, hppa_write_pc, hppa_unwind_pc): New + prototypes. + * hppa-tdep.c (hppa_read_pc): Rename from hppa_target_read_pc. + Make global. Remove HP-UX specific code. Use + frame_unwind_register_unsigned instead of + frame_unwind_register_signed. + (hppa_write_pc): Rename from hppa_target_write_pc. Make global. + Remove HP-UX specific code. + (hppa_unwind_pc): Make global. Remove HP-UX specific code. + (hppa_frame_prev_register_helper): Set "flags" register to zero + for all unwound frames. + (hppa_gdbarch_init): Adjust. + * hppa-hpux-tdep.c (HPPA_HPUX_SS_INSYSCALL): New define. + (hppa_hpux_read_pc, hppa_hpux_write_pc) + (hppa_hpux_unwind_pc): New functions. + (hppa_hpux_init_abi): Set read_pc, write_pc and unwind_pc. + 2004-12-07 Andreas Schwab * main.c (long_options): Add entry for "-l". diff --git a/gdb/hppa-hpux-tdep.c b/gdb/hppa-hpux-tdep.c index 3e16a47..cd5c016 100644 --- a/gdb/hppa-hpux-tdep.c +++ b/gdb/hppa-hpux-tdep.c @@ -1415,6 +1415,52 @@ hppa_hpux_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, return sp; } + + +/* Bit in the `ss_flag' member of `struct save_state' that indicates + the state was saved from a system call. From + . */ +#define HPPA_HPUX_SS_INSYSCALL 0x02 + +static CORE_ADDR +hppa_hpux_read_pc (ptid_t ptid) +{ + ULONGEST flags; + + /* If we're currently in a system call return the contents of %r31. */ + flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid); + if (flags & HPPA_HPUX_SS_INSYSCALL) + return read_register_pid (HPPA_R31_REGNUM, ptid) & ~0x3; + + return hppa_read_pc (ptid); +} + +static void +hppa_hpux_write_pc (CORE_ADDR pc, ptid_t ptid) +{ + ULONGEST flags; + + /* If we're currently in a system call also write PC into %r31. */ + flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid); + if (flags & HPPA_HPUX_SS_INSYSCALL) + write_register_pid (HPPA_R31_REGNUM, pc | 0x3, ptid); + + return hppa_write_pc (pc, ptid); +} + +static CORE_ADDR +hppa_hpux_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + ULONGEST flags; + + /* If we're currently in a system call return the contents of %r31. */ + flags = frame_unwind_register_unsigned (next_frame, HPPA_FLAGS_REGNUM); + if (flags & HPPA_HPUX_SS_INSYSCALL) + return frame_unwind_register_unsigned (next_frame, HPPA_R31_REGNUM) & ~0x3; + + return hppa_unwind_pc (gdbarch, next_frame); +} + static void hppa_hpux_inferior_created (struct target_ops *objfile, int from_tty) @@ -1442,6 +1488,10 @@ hppa_hpux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_push_dummy_code (gdbarch, hppa_hpux_push_dummy_code); set_gdbarch_call_dummy_location (gdbarch, ON_STACK); + set_gdbarch_read_pc (gdbarch, hppa_hpux_read_pc); + set_gdbarch_write_pc (gdbarch, hppa_hpux_write_pc); + set_gdbarch_unwind_pc (gdbarch, hppa_hpux_unwind_pc); + frame_unwind_append_sniffer (gdbarch, hppa_hpux_sigtramp_unwind_sniffer); observer_attach_inferior_created (hppa_hpux_inferior_created); diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index 98db121..3bd058d 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -1034,54 +1034,31 @@ hppa64_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) return align_up (addr, 16); } - -/* Get the PC from %r31 if currently in a syscall. Also mask out privilege - bits. */ - -static CORE_ADDR -hppa_target_read_pc (ptid_t ptid) +CORE_ADDR +hppa_read_pc (ptid_t ptid) { - int flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid); - ULONGEST ipsw = read_register_pid (HPPA_IPSW_REGNUM, ptid); + ULONGEST ipsw; CORE_ADDR pc; - /* The following test does not belong here. It is OS-specific, and belongs - in native code. */ - /* Test SS_INSYSCALL */ - if (flags & 2) - return read_register_pid (31, ptid) & ~0x3; - - pc = read_register_pid (HPPA_PCOQ_HEAD_REGNUM, ptid) & ~0x3; + ipsw = read_register_pid (HPPA_IPSW_REGNUM, ptid); + pc = read_register_pid (HPPA_PCOQ_HEAD_REGNUM, ptid); /* If the current instruction is nullified, then we are effectively still executing the previous instruction. Pretend we are still - there. This is needed when single stepping; if the nullified instruction - is on a different line, we don't want gdb to think we've stepped onto - that line. */ + there. This is needed when single stepping; if the nullified + instruction is on a different line, we don't want GDB to think + we've stepped onto that line. */ if (ipsw & 0x00200000) pc -= 4; - return pc; + return pc & ~0x3; } -/* Write out the PC. If currently in a syscall, then also write the new - PC value into %r31. */ - -static void -hppa_target_write_pc (CORE_ADDR v, ptid_t ptid) +void +hppa_write_pc (CORE_ADDR pc, ptid_t ptid) { - int flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid); - - /* The following test does not belong here. It is OS-specific, and belongs - in native code. */ - /* If in a syscall, then set %r31. Also make sure to get the - privilege bits set correctly. */ - /* Test SS_INSYSCALL */ - if (flags & 2) - write_register_pid (31, v | 0x3, ptid); - - write_register_pid (HPPA_PCOQ_HEAD_REGNUM, v, ptid); - write_register_pid (HPPA_PCOQ_TAIL_REGNUM, v + 4, ptid); + write_register_pid (HPPA_PCOQ_HEAD_REGNUM, pc, ptid); + write_register_pid (HPPA_PCOQ_TAIL_REGNUM, pc + 4, ptid); } /* return the alignment of a type in bytes. Structures have the maximum @@ -2194,24 +2171,24 @@ hppa_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) frame_pc_unwind (next_frame)); } -static CORE_ADDR +CORE_ADDR hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { ULONGEST ipsw; CORE_ADDR pc; - ipsw = frame_unwind_register_signed (next_frame, HPPA_IPSW_REGNUM); - pc = frame_unwind_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM) & ~3; + ipsw = frame_unwind_register_unsigned (next_frame, HPPA_IPSW_REGNUM); + pc = frame_unwind_register_unsigned (next_frame, HPPA_PCOQ_HEAD_REGNUM); /* If the current instruction is nullified, then we are effectively still executing the previous instruction. Pretend we are still - there. This is needed when single stepping; if the nullified instruction - is on a different line, we don't want gdb to think we've stepped onto - that line. */ + there. This is needed when single stepping; if the nullified + instruction is on a different line, we don't want GDB to think + we've stepped onto that line. */ if (ipsw & 0x00200000) pc -= 4; - return pc; + return pc & ~0x3; } /* Instead of this nasty cast, add a method pvoid() that prints out a @@ -2449,6 +2426,24 @@ hppa_frame_prev_register_helper (struct frame_info *next_frame, return; } + /* Make sure the "flags" register is zero in all unwound frames. + The "flags" registers is a HP-UX specific wart, and only the code + in hppa-hpux-tdep.c depends on it. However, it is easier to deal + with it here. This shouldn't affect other systems since those + should provide zero for the "flags" register anyway. */ + if (regnum == HPPA_FLAGS_REGNUM) + { + if (valuep) + store_unsigned_integer (valuep, 4, 0); + + /* It's a computed value. */ + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + return; + } + trad_frame_get_prev_register (next_frame, saved_regs, regnum, optimizedp, lvalp, addrp, realnump, valuep); } @@ -2562,8 +2557,8 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_addr_bits_remove (gdbarch, hppa_smash_text_address); set_gdbarch_smash_text_address (gdbarch, hppa_smash_text_address); set_gdbarch_believe_pcc_promotion (gdbarch, 1); - set_gdbarch_read_pc (gdbarch, hppa_target_read_pc); - set_gdbarch_write_pc (gdbarch, hppa_target_write_pc); + set_gdbarch_read_pc (gdbarch, hppa_read_pc); + set_gdbarch_write_pc (gdbarch, hppa_write_pc); /* Helper for function argument information. */ set_gdbarch_fetch_pointer_argument (gdbarch, hppa_fetch_pointer_argument); diff --git a/gdb/hppa-tdep.h b/gdb/hppa-tdep.h index 857b874..a0632de 100644 --- a/gdb/hppa-tdep.h +++ b/gdb/hppa-tdep.h @@ -209,4 +209,9 @@ hppa_frame_prev_register_helper (struct frame_info *next_frame, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep); +extern CORE_ADDR hppa_read_pc (ptid_t ptid); +extern void hppa_write_pc (CORE_ADDR pc, ptid_t ptid); +extern CORE_ADDR hppa_unwind_pc (struct gdbarch *gdbarch, + struct frame_info *next_frame); + #endif /* HPPA_TDEP_H */ -- 2.7.4