aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog9
-rw-r--r--gdb/x86-64-linux-tdep.c36
-rw-r--r--gdb/x86-64-tdep.c10
3 files changed, 50 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 11eaae9..e4404c4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,14 @@
2003-05-31 Mark Kettenis <kettenis@gnu.org>
+ * x86-64-tdep.c (X86_64_NUM_SAVED_REGS): Set to X86_64_NUM_GREGS.
+ (x86_64_sigtramp_frame_cache): Use `sc_reg_offset' to find saved
+ registers.
+
+ * x86-64-linux-tdep.c (x86_64_linux_sc_reg_offset): New variable.
+ (x86_64_linux_init_abi): Initialize TDEP->sc_reg_offset and
+ TDEP->sc_num_regs instead of TDEP->sc_pc_offset and
+ TDEP->sc_sp_offset.
+
From Michal Ludvig <mludvig@suse.cz>:
* i386-tdep.h (struct gdbarch_tdep): Add members `sc_reg_offset'
and `sc_num_regs'.
diff --git a/gdb/x86-64-linux-tdep.c b/gdb/x86-64-linux-tdep.c
index 5615ebd..8532685 100644
--- a/gdb/x86-64-linux-tdep.c
+++ b/gdb/x86-64-linux-tdep.c
@@ -123,6 +123,38 @@ x86_64_linux_sigcontext_addr (struct frame_info *next_frame)
}
+/* From <asm/sigcontext.h>. */
+static int x86_64_linux_sc_reg_offset[X86_64_NUM_GREGS] =
+{
+ 13 * 8, /* %rax */
+ 11 * 8, /* %rbx */
+ 14 * 8, /* %rcx */
+ 12 * 8, /* %rdx */
+ 9 * 8, /* %rsi */
+ 8 * 8, /* %rdi */
+ 10 * 8, /* %rbp */
+ 15 * 8, /* %rsp */
+ 0 * 8, /* %r8 */
+ 1 * 8, /* %r9 */
+ 2 * 8, /* %r10 */
+ 3 * 8, /* %r11 */
+ 4 * 8, /* %r12 */
+ 5 * 8, /* %r13 */
+ 6 * 8, /* %r14 */
+ 7 * 8, /* %r15 */
+ 16 * 8, /* %rip */
+ 17 * 8, /* %eflags */
+ -1, /* %ds */
+ -1, /* %es */
+
+ /* FIXME: kettenis/2002030531: The registers %fs and %gs are
+ available in `struct sigcontext'. However, they only occupy two
+ bytes instead of four, which makes using them here rather
+ difficult. Leave them out for now. */
+ -1, /* %fs */
+ -1 /* %gs */
+};
+
static void
x86_64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@@ -132,8 +164,8 @@ x86_64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_pc_in_sigtramp (gdbarch, x86_64_linux_pc_in_sigtramp);
tdep->sigcontext_addr = x86_64_linux_sigcontext_addr;
- tdep->sc_pc_offset = 16 * 8; /* From <asm/sigcontext.h>. */
- tdep->sc_sp_offset = 15 * 8;
+ tdep->sc_reg_offset = x86_64_linux_sc_reg_offset;
+ tdep->sc_num_regs = X86_64_NUM_GREGS;
}
diff --git a/gdb/x86-64-tdep.c b/gdb/x86-64-tdep.c
index 560fe98..7bcabfd 100644
--- a/gdb/x86-64-tdep.c
+++ b/gdb/x86-64-tdep.c
@@ -787,7 +787,7 @@ x86_64_push_dummy_call (struct gdbarch *gdbarch, struct regcache *regcache,
/* The maximum number of saved registers. This should include %rip. */
-#define X86_64_NUM_SAVED_REGS 17
+#define X86_64_NUM_SAVED_REGS X86_64_NUM_GREGS
struct x86_64_frame_cache
{
@@ -1035,6 +1035,7 @@ x86_64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
CORE_ADDR addr;
char buf[8];
+ int i;
if (*this_cache)
return *this_cache;
@@ -1045,8 +1046,11 @@ x86_64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
cache->base = extract_unsigned_integer (buf, 8) - 8;
addr = tdep->sigcontext_addr (next_frame);
- cache->saved_regs[X86_64_RIP_REGNUM] = addr + tdep->sc_pc_offset;
- cache->saved_regs[X86_64_RSP_REGNUM] = addr + tdep->sc_sp_offset;
+ gdb_assert (tdep->sc_reg_offset);
+ gdb_assert (tdep->sc_num_regs <= X86_64_NUM_SAVED_REGS);
+ for (i = 0; i < tdep->sc_num_regs; i++)
+ if (tdep->sc_reg_offset[i] != -1)
+ cache->saved_regs[i] = addr + tdep->sc_reg_offset[i];
*this_cache = cache;
return cache;