aboutsummaryrefslogtreecommitdiff
path: root/gdb/hppa-hpux-tdep.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2004-12-07 18:04:11 +0000
committerMark Kettenis <kettenis@gnu.org>2004-12-07 18:04:11 +0000
commitcc72850f95d062076e557cba1a4a402d45f0b548 (patch)
treefb89db7842d00c8118cafbd8bb6c3e4e8e035d37 /gdb/hppa-hpux-tdep.c
parentcb9faf63f8bbbba7d825217184007ad0061e8ce2 (diff)
downloadgdb-cc72850f95d062076e557cba1a4a402d45f0b548.zip
gdb-cc72850f95d062076e557cba1a4a402d45f0b548.tar.gz
gdb-cc72850f95d062076e557cba1a4a402d45f0b548.tar.bz2
* 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.
Diffstat (limited to 'gdb/hppa-hpux-tdep.c')
-rw-r--r--gdb/hppa-hpux-tdep.c50
1 files changed, 50 insertions, 0 deletions
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
+ <machine/save_state.h>. */
+#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);