forked from Imagelibrary/binutils-gdb
[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.
This commit is contained in:
@@ -195,11 +195,20 @@
|
||||
#define IA64_NAT32_REGNUM (IA64_NAT0_REGNUM + 32)
|
||||
#define IA64_NAT127_REGNUM (IA64_NAT0_REGNUM + 127)
|
||||
|
||||
struct frame_info;
|
||||
|
||||
struct gdbarch_tdep
|
||||
{
|
||||
CORE_ADDR (*sigcontext_register_address) (struct gdbarch *, CORE_ADDR, int);
|
||||
int (*pc_in_sigtramp) (CORE_ADDR);
|
||||
|
||||
/* Return the total size of THIS_FRAME's register frame.
|
||||
CFM is THIS_FRAME's cfm register value.
|
||||
|
||||
Normally, the size of the register frame is always obtained by
|
||||
extracting the lowest 7 bits ("cfm & 0x7f"). */
|
||||
int (*size_of_register_frame) (struct frame_info *this_frame, ULONGEST cfm);
|
||||
|
||||
/* ISA-specific data types. */
|
||||
struct type *ia64_ext_type;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user