Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/gnu/dist/toolchain/gdb * Overhaul:



details:   https://anonhg.NetBSD.org/src/rev/71a46fe8ec66
branches:  trunk
changeset: 518813:71a46fe8ec66
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Thu Dec 06 02:07:03 2001 +0000

description:
* Overhaul:
  * move the code that supplies the integer and FP registers into
    separate functions, rather than duplicating the code for the
    ptrace and core file cases.
  * Use supply_register() rather than just copying directly into
    the register array and calling registers_fetched().  This way,
    only the registers actually supplied are marked as valid within
    the debugger.
* Add support for SSE/SSE2 registers via the PT_{GET,SET}XMMREGS
  ptrace(2) request.

(Blocked on the FSF assignment clerk for feeding this back to
the master GDB sources.)

diffstat:

 gnu/dist/toolchain/gdb/i386nbsd-nat.c |  356 +++++++++++++++++++++++++--------
 1 files changed, 269 insertions(+), 87 deletions(-)

diffs (truncated from 433 to 300 lines):

diff -r fd5295f8a30a -r 71a46fe8ec66 gnu/dist/toolchain/gdb/i386nbsd-nat.c
--- a/gnu/dist/toolchain/gdb/i386nbsd-nat.c     Thu Dec 06 02:00:06 2001 +0000
+++ b/gnu/dist/toolchain/gdb/i386nbsd-nat.c     Thu Dec 06 02:07:03 2001 +0000
@@ -26,10 +26,14 @@
 #include <machine/frame.h>
 #include <machine/pcb.h>
 #include "inferior.h"
-#include "gdbcore.h" /* for registers_fetched() */
+#include "gdbcore.h"
+
+#ifdef PT_GETXMMREGS
+static int have_ptrace_xmmregs = -1;
+#endif
 
 #define RF(dst, src) \
-       memcpy(&registers[REGISTER_BYTE(dst)], &src, sizeof(src))
+       supply_register((dst), (char *) &(src))
 
 #define RS(src, dst) \
        memcpy(&dst, &registers[REGISTER_BYTE(src)], sizeof(dst))
@@ -51,54 +55,207 @@
     unsigned char regs[8][10];
   };
 
+#ifdef PT_GETXMMREGS
+struct xmmctx
+  {
+    unsigned short control;
+    unsigned short status;
+    unsigned char r0;
+    unsigned char tag;        /* abridged */
+    unsigned short opcode;
+    unsigned long eip;
+    unsigned short code_seg;
+    unsigned short r1;
+    unsigned long operand;
+    unsigned short operand_seg;
+    unsigned short r2;
+    unsigned long mxcsr;
+    unsigned long r3;
+    struct
+      {
+        unsigned char fp_bytes[10];
+        unsigned char fp_rsvd[6];
+      } fpregs[8];
+    struct
+      {
+        unsigned char sse_bytes[16];
+      } sseregs[8];
+    unsigned char r4[16 * 14];
+  };
+#endif /* PT_GETXMMREGS */
+
+static void
+supply_regs (regs)
+     struct reg *regs;
+{
+
+  RF ( 0, regs->r_eax);
+  RF ( 1, regs->r_ecx);
+  RF ( 2, regs->r_edx);
+  RF ( 3, regs->r_ebx);
+  RF ( 4, regs->r_esp);
+  RF ( 5, regs->r_ebp);
+  RF ( 6, regs->r_esi);
+  RF ( 7, regs->r_edi);
+  RF ( 8, regs->r_eip);
+  RF ( 9, regs->r_eflags);
+  RF (10, regs->r_cs);
+  RF (11, regs->r_ss);
+  RF (12, regs->r_ds);
+  RF (13, regs->r_es);
+  RF (14, regs->r_fs);
+  RF (15, regs->r_gs);
+}
+
+static void
+supply_387regs (s87)
+     struct env387 *s87;
+{
+  int i;
+
+  for (i = 0; i < 8; i++)
+    {
+      RF (FP0_REGNUM + i, s87->regs[i]);
+    }
+
+  RF (FCTRL_REGNUM,   s87->control);
+  RF (FSTAT_REGNUM,   s87->status);
+  RF (FTAG_REGNUM,    s87->tag);
+  RF (FCS_REGNUM,     s87->code_seg);
+  RF (FCOFF_REGNUM,   s87->eip);
+  RF (FDS_REGNUM,     s87->operand_seg);
+  RF (FDOFF_REGNUM,   s87->operand);
+  RF (FOP_REGNUM,     s87->opcode);
+}
+
+#ifdef PT_GETXMMREGS
+static void
+supply_xmmregs (sxmm)
+     struct xmmctx *sxmm;
+{
+  static unsigned char empty_significand[8] = { 0 };
+  unsigned long reg;
+  unsigned short exponent;
+  int i;
+
+  for (i = 0; i < 8; i++)
+    {
+      RF (FP0_REGNUM + i,  sxmm->fpregs[i].fp_bytes);
+      RF (XMM0_REGNUM + i, sxmm->sseregs[i].sse_bytes);
+    }
+
+  /* Note: unlike the 387-format, the XMM-format does not have
+     16-bits of padding after the 16-bit registers.  This means
+     that we need to pull these registers into a suitably-padded
+     storage space before letting supply_register() have its
+     way with it.  */
+
+  reg = sxmm->control;
+  RF (FCTRL_REGNUM,   reg);
+
+  reg = sxmm->status;
+  RF (FSTAT_REGNUM,   reg);
+
+  reg = sxmm->code_seg;
+  RF (FCS_REGNUM,     reg);
+
+  RF (FCOFF_REGNUM,   sxmm->eip);
+
+  reg = sxmm->operand_seg;
+  RF (FDS_REGNUM,     reg);
+
+  RF (FDOFF_REGNUM,   sxmm->operand);
+
+  /* The kernel has provided us the "tag" info in XMM format, but
+     GDB expects it in i387 format; convert it.  */
+  for (reg = 0, i = 0; i < 8; i++)
+    {
+      if (sxmm->tag & (1U << i))
+        {
+          exponent = sxmm->fpregs[i].fp_bytes[8] |
+                     (sxmm->fpregs[i].fp_bytes[9] << 8);
+          switch (exponent & 0x7fff)
+            {
+              case 0x7fff:
+                reg |= (2U << (i * 2));
+                break;
+
+              case 0x0000:
+                if (memcmp(empty_significand, sxmm->fpregs[i].fp_bytes,
+                           sizeof (empty_significand)) == 0)
+                  {
+                    reg |= (1U << (i * 2));
+                  }
+                else
+                  {
+                    reg |= (2U << (i * 2));
+                  }
+                break;
+              default:
+                if ((sxmm->fpregs[i].fp_bytes[7] & 0x80) == 0)
+                  {
+                    reg |= (2U << (i * 2));
+                  }
+                /* else reg |= (0U << (i * 2)); */
+                break;
+            }
+        }
+      else
+        {
+          reg |= (3U << (i * 2));
+        }
+    }
+  RF (FTAG_REGNUM,    reg);
+
+  RF (MXCSR_REGNUM,   sxmm->mxcsr);
+}
+#endif
+
 void
 fetch_inferior_registers (regno)
      int regno;
 {
   struct reg inferior_registers;
   struct env387 inferior_fpregisters;
+#ifdef PT_GETXMMREGS
+  struct xmmctx inferior_xmmregisters;
+#endif
 
   ptrace (PT_GETREGS, inferior_pid,
-         (PTRACE_ARG3_TYPE) &inferior_registers, 0);
-  ptrace (PT_GETFPREGS, inferior_pid,
-         (PTRACE_ARG3_TYPE) &inferior_fpregisters, 0);
+          (PTRACE_ARG3_TYPE) &inferior_registers, 0);
 
-  RF ( 0, inferior_registers.r_eax);
-  RF ( 1, inferior_registers.r_ecx);
-  RF ( 2, inferior_registers.r_edx);
-  RF ( 3, inferior_registers.r_ebx);
-  RF ( 4, inferior_registers.r_esp);
-  RF ( 5, inferior_registers.r_ebp);
-  RF ( 6, inferior_registers.r_esi);
-  RF ( 7, inferior_registers.r_edi);
-  RF ( 8, inferior_registers.r_eip);
-  RF ( 9, inferior_registers.r_eflags);
-  RF (10, inferior_registers.r_cs);
-  RF (11, inferior_registers.r_ss);
-  RF (12, inferior_registers.r_ds);
-  RF (13, inferior_registers.r_es);
-  RF (14, inferior_registers.r_fs);
-  RF (15, inferior_registers.r_gs);
+#ifdef PT_GETXMMREGS
+  if (have_ptrace_xmmregs != 0 &&
+      ptrace(PT_GETXMMREGS, inferior_pid,
+             (PTRACE_ARG3_TYPE) &inferior_xmmregisters, 0) == 0)
+    {
+      have_ptrace_xmmregs = 1;
+    }
+  else
+    {
+      ptrace (PT_GETFPREGS, inferior_pid,
+              (PTRACE_ARG3_TYPE) &inferior_fpregisters, 0);
+      have_ptrace_xmmregs = 0;
+    }
+#else
+    ptrace (PT_GETFPREGS, inferior_pid,
+            (PTRACE_ARG3_TYPE) &inferior_fpregisters, 0);
+#endif
 
-  RF (FP0_REGNUM,     inferior_fpregisters.regs[0]);
-  RF (FP0_REGNUM + 1, inferior_fpregisters.regs[1]);
-  RF (FP0_REGNUM + 2, inferior_fpregisters.regs[2]);
-  RF (FP0_REGNUM + 3, inferior_fpregisters.regs[3]);
-  RF (FP0_REGNUM + 4, inferior_fpregisters.regs[4]);
-  RF (FP0_REGNUM + 5, inferior_fpregisters.regs[5]);
-  RF (FP0_REGNUM + 6, inferior_fpregisters.regs[6]);
-  RF (FP0_REGNUM + 7, inferior_fpregisters.regs[7]);
+  supply_regs (&inferior_registers);
 
-  RF (FCTRL_REGNUM,   inferior_fpregisters.control);
-  RF (FSTAT_REGNUM,   inferior_fpregisters.status);
-  RF (FTAG_REGNUM,    inferior_fpregisters.tag);
-  RF (FCS_REGNUM,     inferior_fpregisters.code_seg);
-  RF (FCOFF_REGNUM,   inferior_fpregisters.eip);
-  RF (FDS_REGNUM,     inferior_fpregisters.operand_seg);
-  RF (FDOFF_REGNUM,   inferior_fpregisters.operand);
-  RF (FOP_REGNUM,     inferior_fpregisters.opcode);
-
-  registers_fetched ();
+#ifdef PT_GETXMMREGS
+  if (have_ptrace_xmmregs)
+    {
+      supply_xmmregs (&inferior_xmmregisters);
+    }
+  else
+    {
+      supply_387regs (&inferior_fpregisters);
+    }
+#else
+  supply_387regs (&inferior_fpregisters);
+#endif
 }
 
 void
@@ -107,6 +264,10 @@
 {
   struct reg inferior_registers;
   struct env387 inferior_fpregisters;
+#ifdef PT_GETXMMREGS
+  struct xmmctx inferior_xmmregisters;
+#endif
+  int i;
 
   RS ( 0, inferior_registers.r_eax);
   RS ( 1, inferior_registers.r_ecx);
@@ -125,29 +286,72 @@
   RS (14, inferior_registers.r_fs);
   RS (15, inferior_registers.r_gs);
 
-  
-  RS (FP0_REGNUM,     inferior_fpregisters.regs[0]);
-  RS (FP0_REGNUM + 1, inferior_fpregisters.regs[1]);
-  RS (FP0_REGNUM + 2, inferior_fpregisters.regs[2]);
-  RS (FP0_REGNUM + 3, inferior_fpregisters.regs[3]);
-  RS (FP0_REGNUM + 4, inferior_fpregisters.regs[4]);
-  RS (FP0_REGNUM + 5, inferior_fpregisters.regs[5]);
-  RS (FP0_REGNUM + 6, inferior_fpregisters.regs[6]);
-  RS (FP0_REGNUM + 7, inferior_fpregisters.regs[7]);
+#ifdef PT_GETXMMREGS
+  if (have_ptrace_xmmregs != 0)
+    {
+      unsigned short tag;
+
+      for (i = 0; i < 8; i++)
+        {
+          RS (FP0_REGNUM + i,  inferior_xmmregisters.fpregs[i].fp_bytes);
+          RS (XMM0_REGNUM + i, inferior_xmmregisters.sseregs[i].sse_bytes);
+        }
+



Home | Main Index | Thread Index | Old Index