* x86-64-tdep.c (X86_64_NUM_SAVED_REGS): Set to X86_64_NUM_GREGS.
authorMark Kettenis <kettenis@gnu.org>
Sat, 31 May 2003 16:11:47 +0000 (16:11 +0000)
committerMark Kettenis <kettenis@gnu.org>
Sat, 31 May 2003 16:11:47 +0000 (16:11 +0000)
(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.

gdb/ChangeLog
gdb/x86-64-linux-tdep.c
gdb/x86-64-tdep.c

index 11eaae9..e4404c4 100644 (file)
@@ -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'.
index 5615ebd..8532685 100644 (file)
@@ -123,6 +123,38 @@ x86_64_linux_sigcontext_addr (struct frame_info *next_frame)
 }
 \f
 
+/* 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;
 }
 \f
 
index 560fe98..7bcabfd 100644 (file)
@@ -787,7 +787,7 @@ x86_64_push_dummy_call (struct gdbarch *gdbarch, struct regcache *regcache,
 \f
 
 /* 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;