diff options
author | Joel Brobecker <brobecker@gnat.com> | 2011-01-13 16:24:27 +0000 |
---|---|---|
committer | Joel Brobecker <brobecker@gnat.com> | 2011-01-13 16:24:27 +0000 |
commit | 77ca787b12516ebb1b0d23710021b26b9c81b018 (patch) | |
tree | c566d4c91a59e95671e251887b36d704ec6e8d1a /gdb/ia64-hpux-nat.c | |
parent | 92c9a4639bb3294d74a36b6d0c0cb07771bbe906 (diff) | |
download | gdb-77ca787b12516ebb1b0d23710021b26b9c81b018.zip gdb-77ca787b12516ebb1b0d23710021b26b9c81b018.tar.gz gdb-77ca787b12516ebb1b0d23710021b26b9c81b018.tar.bz2 |
[ia64-hpux] unwinding bsp value from system call
This fixes unwinding from a thread that is stopped inside a system call.
This can be seen when switching to a thread that is stopped doing a
pthread_cond_wait, for instance...
The comments inside the code should explain what is happening in our
case (the HP-UX exception in the case of system calls): Under certain
circumstances (program stopped inside syscall), the offset to apply to
the current BSP in order to compute the previous BSP is not the usual
CFM & 0x7f.
We parts in this patch:
1. Figuring out that we are stopped inside a syscal: This requires
a TT_LWP_RUREGS ttrace call, which is not directly possible from
ia64-tdep.c. So use defined a new TARGET_OBJECT_HPUX_UREGS object
to request it from the -nat side.
2. Add a gdbarch_tdep method that allows us to change the default
behavior on ia64-hpux, permitting us to have a different "size of
register frame" in that one particular case.
gdb/ChangeLog:
* target.h (enum target_object): Add TARGET_OBJECT_HPUX_UREGS.
* ia64-tdep.h (struct frame_info): forward declaration.
(struct gdbarch_tdep): Add field size_of_register_frame.
* ia64-tdep.c (ia64_access_reg): Use tdep->size_of_register_frame
to determine the size of the register frame.
(ia64_size_of_register_frame): New function.
(ia64_gdbarch_init): Set tdep->size_of_register_frame.
* ia64-hpux-tdep.c: Include "target.h" and "frame.h".
(IA64_HPUX_UREG_REASON): New macro.
(ia64_hpux_stopped_in_syscall, ia64_hpux_size_of_register_frame):
New functions.
(ia64_hpux_init_abi): Set tdep->size_of_register_frame.
* ia64-hpux-nat.c (ia64_hpux_xfer_uregs): New function.
(ia64_hpux_xfer_partial): Add handling of TARGET_OBJECT_HPUX_UREGS
objects.
Diffstat (limited to 'gdb/ia64-hpux-nat.c')
-rw-r--r-- | gdb/ia64-hpux-nat.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/gdb/ia64-hpux-nat.c b/gdb/ia64-hpux-nat.c index ca1c278..fd58bba 100644 --- a/gdb/ia64-hpux-nat.c +++ b/gdb/ia64-hpux-nat.c @@ -568,6 +568,28 @@ ia64_hpux_xfer_memory (struct target_ops *ops, const char *annex, return len; } +/* Handle the transfer of TARGET_OBJECT_HPUX_UREGS objects on ia64-hpux. + ANNEX is currently ignored. + + The current implementation does not support write transfers (because + we do not currently do not need these transfers), and will raise + a failed assertion if WRITEBUF is not NULL. */ + +static LONGEST +ia64_hpux_xfer_uregs (struct target_ops *ops, const char *annex, + gdb_byte *readbuf, const gdb_byte *writebuf, + ULONGEST offset, LONGEST len) +{ + int status; + + gdb_assert (writebuf == NULL); + + status = ia64_hpux_read_register_from_save_state_t (offset, readbuf, len); + if (status < 0) + return -1; + return len; +} + /* The "to_xfer_partial" target_ops routine for ia64-hpux. */ static LONGEST @@ -579,6 +601,8 @@ ia64_hpux_xfer_partial (struct target_ops *ops, enum target_object object, if (object == TARGET_OBJECT_MEMORY) val = ia64_hpux_xfer_memory (ops, annex, readbuf, writebuf, offset, len); + else if (object == TARGET_OBJECT_HPUX_UREGS) + val = ia64_hpux_xfer_uregs (ops, annex, readbuf, writebuf, offset, len); else val = super_xfer_partial (ops, object, annex, readbuf, writebuf, offset, len); |