From: Joel Brobecker <brobecker@adacore.com>
To: gdb-patches@sourceware.org
Subject: Re: [PATCH 7/8] ia64-hpux: unwinding bsp value from system call
Date: Fri, 31 Dec 2010 18:15:00 -0000 [thread overview]
Message-ID: <20101231063258.GK2396@adacore.com> (raw)
In-Reply-To: <201012291042.14627.pedro@codesourcery.com>
[-- Attachment #1: Type: text/plain, Size: 206 bytes --]
Following Pedro's suggestion, here is a new revised version of this
patch that defines a new TARGET_OBJECT_HPUX_UREGS target object to
get to the __reason pseudo-register...
Thanks again, Pedro.
--
Joel
[-- Attachment #2: uregs.diff --]
[-- Type: text/x-diff, Size: 9335 bytes --]
commit e246563d5cc60890c2ceba3d5b85d30e3f1ce5b2
Author: Joel Brobecker <brobecker@adacore.com>
Date: Tue Dec 21 07:04:13 2010 -0500
[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.
diff --git a/gdb/ia64-hpux-nat.c b/gdb/ia64-hpux-nat.c
index 53941a7..80f7d99 100644
--- a/gdb/ia64-hpux-nat.c
+++ b/gdb/ia64-hpux-nat.c
@@ -567,6 +567,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
@@ -578,6 +600,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);
diff --git a/gdb/ia64-hpux-tdep.c b/gdb/ia64-hpux-tdep.c
index 139ff83..a4d2fa7 100644
--- a/gdb/ia64-hpux-tdep.c
+++ b/gdb/ia64-hpux-tdep.c
@@ -23,6 +23,17 @@
#include "osabi.h"
#include "gdbtypes.h"
#include "solib.h"
+#include "target.h"
+#include "frame.h"
+
+/* The offset to be used in order to get the __reason pseudo-register
+ when using one of the *UREGS ttrace requests (see system header file
+ /usr/include/ia64/sys/uregs.h for more details).
+
+ The documentation for this pseudo-register says that a nonzero value
+ indicates that the thread stopped due to a fault, trap, or interrupt.
+ A null value indicates a stop inside a syscall. */
+#define IA64_HPUX_UREG_REASON 0x00070000
/* Return nonzero if the value of the register identified by REGNUM
can be modified. */
@@ -74,6 +85,47 @@ ia64_hpux_cannot_store_register (struct gdbarch *gdbarch, int regnum)
return 0;
}
+/* Return nonzero if the inferior is stopped inside a system call. */
+
+static int
+ia64_hpux_stopped_in_syscall (struct gdbarch *gdbarch)
+{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ struct target_ops *ops = ¤t_target;
+ gdb_byte buf[8];
+ int len;
+
+ len = target_read (ops, TARGET_OBJECT_HPUX_UREGS, NULL,
+ buf, IA64_HPUX_UREG_REASON, sizeof (buf));
+ if (len == -1)
+ /* The target wasn't able to tell us. Assume we are not stopped
+ in a system call, which is the normal situation. */
+ return 0;
+ gdb_assert (len == 8);
+
+ return (extract_unsigned_integer (buf, len, byte_order) == 0);
+}
+
+/* The "size_of_register_frame" gdbarch_tdep routine for ia64-hpux. */
+
+static int
+ia64_hpux_size_of_register_frame (struct frame_info *this_frame,
+ ULONGEST cfm)
+{
+ int sof;
+
+ if (frame_relative_level (this_frame) == 0
+ && ia64_hpux_stopped_in_syscall (get_frame_arch (this_frame)))
+ /* If the inferior stopped in a system call, the base address
+ of the register frame is at BSP - SOL instead of BSP - SOF.
+ This is an HP-UX exception. */
+ sof = (cfm & 0x3f80) >> 7;
+ else
+ sof = (cfm & 0x7f);
+
+ return sof;
+}
+
/* Should be set to non-NULL if the ia64-hpux solib module is linked in.
This may not be the case because the shared library support code can
only be compiled on ia64-hpux. */
@@ -83,6 +135,10 @@ struct target_so_ops *ia64_hpux_so_ops = NULL;
static void
ia64_hpux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->size_of_register_frame = ia64_hpux_size_of_register_frame;
+
set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
set_gdbarch_cannot_store_register (gdbarch, ia64_hpux_cannot_store_register);
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 1cd6a38..1cfffc7 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -2423,7 +2423,7 @@ ia64_is_fpreg (int uw_regnum)
{
return unw_is_fpreg (uw_regnum);
}
-
+
/* Libunwind callback accessor function for general registers. */
static int
ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
@@ -2460,7 +2460,7 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
bsp = extract_unsigned_integer (buf, 8, byte_order);
get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
cfm = extract_unsigned_integer (buf, 8, byte_order);
- sof = (cfm & 0x7f);
+ sof = gdbarch_tdep (gdbarch)->size_of_register_frame (this_frame, cfm);
*val = ia64_rse_skip_regs (bsp, -sof);
break;
@@ -3812,6 +3812,14 @@ ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
return print_insn_ia64 (memaddr, info);
}
+/* The default "size_of_register_frame" gdbarch_tdep routine for ia64. */
+
+static int
+ia64_size_of_register_frame (struct frame_info *this_frame, ULONGEST cfm)
+{
+ return (cfm & 0x7f);
+}
+
static struct gdbarch *
ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
@@ -3826,6 +3834,8 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep = xzalloc (sizeof (struct gdbarch_tdep));
gdbarch = gdbarch_alloc (&info, tdep);
+ tdep->size_of_register_frame = ia64_size_of_register_frame;
+
/* According to the ia64 specs, instructions that store long double
floats in memory use a long-double format different than that
used in the floating registers. The memory format matches the
diff --git a/gdb/ia64-tdep.h b/gdb/ia64-tdep.h
index b7a8eaf..b88031e 100644
--- a/gdb/ia64-tdep.h
+++ b/gdb/ia64-tdep.h
@@ -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;
};
diff --git a/gdb/target.h b/gdb/target.h
index 7290d90..24221ce 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -265,6 +265,9 @@ enum target_object
TARGET_OBJECT_THREADS,
/* Collected static trace data. */
TARGET_OBJECT_STATIC_TRACE_DATA,
+ /* The HP-UX registers (those that can be obtained or modified by using
+ the TT_LWP_RUREGS/TT_LWP_WUREGS ttrace requests). */
+ TARGET_OBJECT_HPUX_UREGS,
/* Possible future objects: TARGET_OBJECT_FILE, ... */
};
next prev parent reply other threads:[~2010-12-31 6:33 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-28 4:43 Porting GDB to ia64-hpux Joel Brobecker
2010-12-28 4:43 ` [PATCH 2/8] small integral parameters and return values Joel Brobecker
2010-12-28 4:43 ` [PATCH 4/8] libunwind-frame.c: handle functions with no minimal symbol/debug info Joel Brobecker
2010-12-28 4:43 ` [PATCH 1/8] Add a big-endian version of the ia64-ext floatformat Joel Brobecker
2010-12-28 4:44 ` [PATCH 6/8] port GDB to ia64-hpux (native) Joel Brobecker
2011-01-11 23:26 ` Steve Ellcey
2011-01-12 1:26 ` Joel Brobecker
2011-01-12 16:57 ` Steve Ellcey
2011-01-12 20:11 ` Joel Brobecker
2011-01-13 1:01 ` Joel Brobecker
2011-01-13 5:13 ` Steve Ellcey
[not found] ` <1299014508.30497.20.camel@hpsje.cup.hp.com>
[not found] ` <20110302044549.GU2513@adacore.com>
[not found] ` <1299171098.30497.88.camel@hpsje.cup.hp.com>
[not found] ` <20110303172717.GJ2513@adacore.com>
[not found] ` <1299173882.30497.114.camel@hpsje.cup.hp.com>
2011-06-17 16:30 ` Joel Brobecker
2011-01-13 18:07 ` Joel Brobecker
2010-12-28 4:44 ` [PATCH 3/8] Make sure __LITTLE_ENDIAN/__BIG_ENDIAN are defined in libunwind-frame.c Joel Brobecker
2010-12-28 4:44 ` [PATCH 5/8] inf-ttrace: Determine attached process LWP immediately after attaching Joel Brobecker
2010-12-28 11:04 ` Pedro Alves
2010-12-28 11:26 ` Joel Brobecker
2010-12-28 4:54 ` [PATCH 7/8] ia64-hpux: unwinding bsp value from system call Joel Brobecker
2010-12-28 11:35 ` Pedro Alves
2010-12-28 12:01 ` Joel Brobecker
2010-12-28 16:17 ` Pedro Alves
2010-12-29 5:49 ` Joel Brobecker
2010-12-29 12:05 ` Pedro Alves
2010-12-29 13:16 ` Joel Brobecker
2010-12-31 18:15 ` Joel Brobecker [this message]
2010-12-28 15:29 ` [RFA/commit] Add documentation for TARGET_OBJECT_OSDATA Joel Brobecker
2010-12-28 15:46 ` Pedro Alves
2010-12-29 3:29 ` Joel Brobecker
2010-12-28 5:00 ` [PATCH 8/8] [ia64-hpux] inferior function call support Joel Brobecker
2010-12-31 19:18 ` Joel Brobecker
2011-01-13 16:53 ` Porting GDB to ia64-hpux Joel Brobecker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101231063258.GK2396@adacore.com \
--to=brobecker@adacore.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox