gdb/gdbserver/
authorDaniel Jacobowitz <drow@false.org>
Tue, 28 Nov 2006 22:21:23 +0000 (22:21 +0000)
committerDaniel Jacobowitz <drow@false.org>
Tue, 28 Nov 2006 22:21:23 +0000 (22:21 +0000)
* Makefile.in (clean): Remove reg-mips64.c.
(reg-mips64.c, reg-mips64.o): New rules.
* configure.srv: Handle mips64.  Include regset support for mips.
* linux-mips-low.c (union mips_register): New.
(mips_get_pc, mips_set_pc, mips_reinsert_addr): Use it.
(mips_breakpoint, mips_breakpoint_at): Use int.
(mips_collect_register, mips_supply_register)
(mips_collect_register_32bit, mips_supply_register_32bit)
(mips_fill_gregset, mips_store_gregset, mips_fill_fpregset)
(mips_store_fpregset, target_regsets): New.
* thread-db.c (thread_db_get_tls_address): Use uintptr_t.
gdb/
* regformats/reg-mips64.dat: New file.

gdb/ChangeLog
gdb/gdbserver/ChangeLog
gdb/gdbserver/Makefile.in
gdb/gdbserver/configure.srv
gdb/gdbserver/linux-mips-low.c
gdb/gdbserver/thread-db.c
gdb/regformats/reg-mips64.dat [new file with mode: 0644]

index 96f8c93891666a7c8ca5f350fd55dc421ba692a4..c92e9acc1c902ec5a8f3e56f973c34ceac16ffcf 100644 (file)
@@ -1,3 +1,7 @@
+2006-11-28  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * regformats/reg-mips64.dat: New file.
+
 2006-11-28  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * Makefile.in (mips-tdep.o, target-descriptions.o): Update.
index 52c34e98bf30428115e5a10386267eaee67401b0..29c69043d15054a8b7b33391d685ece4e5c1fdd7 100644 (file)
@@ -1,3 +1,17 @@
+2006-11-28  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * Makefile.in (clean): Remove reg-mips64.c.
+       (reg-mips64.c, reg-mips64.o): New rules.
+       * configure.srv: Handle mips64.  Include regset support for mips.
+       * linux-mips-low.c (union mips_register): New.
+       (mips_get_pc, mips_set_pc, mips_reinsert_addr): Use it.
+       (mips_breakpoint, mips_breakpoint_at): Use int.
+       (mips_collect_register, mips_supply_register)
+       (mips_collect_register_32bit, mips_supply_register_32bit)
+       (mips_fill_gregset, mips_store_gregset, mips_fill_fpregset)
+       (mips_store_fpregset, target_regsets): New.
+       * thread-db.c (thread_db_get_tls_address): Use uintptr_t.
+
 2006-11-22  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * configure.srv: Add target "spu*-*-*".
index 9748c95c625d2d2aa15dc484bc319dcf398039cb..eda775110cadd0eb634acc297558b8c9272e828c 100644 (file)
@@ -206,7 +206,7 @@ clean:
        rm -f gdbserver gdbreplay core make.log
        rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m32r.c reg-m68k.c reg-mips.c
        rm -f reg-ppc.c reg-sh.c reg-spu.c reg-x86-64.c reg-i386-linux.c
-       rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c
+       rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c reg-mips64.c
 
 maintainer-clean realclean distclean: clean
        rm -f nm.h tm.h xm.h config.status config.h stamp-h config.log
@@ -318,6 +318,9 @@ reg-m68k.c : $(srcdir)/../regformats/reg-m68k.dat $(regdat_sh)
 reg-mips.o : reg-mips.c $(regdef_h)
 reg-mips.c : $(srcdir)/../regformats/reg-mips.dat $(regdat_sh)
        sh $(regdat_sh) $(srcdir)/../regformats/reg-mips.dat reg-mips.c
+reg-mips64.o : reg-mips64.c $(regdef_h)
+reg-mips64.c : $(srcdir)/../regformats/reg-mips64.dat $(regdat_sh)
+       sh $(regdat_sh) $(srcdir)/../regformats/reg-mips64.dat reg-mips64.c
 reg-ppc.o : reg-ppc.c $(regdef_h)
 reg-ppc.c : $(srcdir)/../regformats/reg-ppc.dat $(regdat_sh)
        sh $(regdat_sh) $(srcdir)/../regformats/reg-ppc.dat reg-ppc.c
index 5a4792cece23421e6bdfdb184c42204cb79be70d..a1f6971e2c1046517496286f661d3941814c9922 100644 (file)
@@ -67,8 +67,15 @@ case "${target}" in
                        srv_linux_regsets=yes
                        srv_linux_thread_db=yes
                        ;;
+  mips*64*-*-linux*)   srv_regobj=reg-mips64.o
+                       srv_tgtobj="linux-low.o linux-mips-low.o"
+                       srv_linux_regsets=yes
+                       srv_linux_usrregs=yes
+                       srv_linux_thread_db=yes
+                       ;;
   mips*-*-linux*)      srv_regobj=reg-mips.o
                        srv_tgtobj="linux-low.o linux-mips-low.o"
+                       srv_linux_regsets=yes
                        srv_linux_usrregs=yes
                        srv_linux_thread_db=yes
                        ;;
index 78295505f31ee913de4b17ab0dca9769d52d6cc4..797d0461f0f22e4ecebb72ab3d8ed65cdc7342de 100644 (file)
@@ -23,6 +23,7 @@
 #include "linux-low.h"
 
 #include <sys/ptrace.h>
+#include <endian.h>
 
 #include "gdb_proc_service.h"
 
 
 #include <asm/ptrace.h>
 
+union mips_register
+{
+  unsigned char buf[8];
+
+  /* Deliberately signed, for proper sign extension.  */
+  int reg32;
+  long long reg64;
+};
+
 /* Return the ptrace ``address'' of register REGNO. */
 
 /* Matches mips_generic32_regs */
@@ -107,20 +117,25 @@ mips_cannot_store_register (int regno)
 static CORE_ADDR
 mips_get_pc ()
 {
-  unsigned long pc;
-  collect_register_by_name ("pc", &pc);
-  return pc;
+  union mips_register pc;
+  collect_register_by_name ("pc", pc.buf);
+  return register_size (0) == 4 ? pc.reg32 : pc.reg64;
 }
 
 static void
 mips_set_pc (CORE_ADDR pc)
 {
-  unsigned long newpc = pc;
-  supply_register_by_name ("pc", &newpc);
+  union mips_register newpc;
+  if (register_size (0) == 4)
+    newpc.reg32 = pc;
+  else
+    newpc.reg64 = pc;
+
+  supply_register_by_name ("pc", newpc.buf);
 }
 
 /* Correct in either endianness.  */
-static const unsigned long mips_breakpoint = 0x0005000d;
+static const unsigned int mips_breakpoint = 0x0005000d;
 #define mips_breakpoint_len 4
 
 /* We only place breakpoints in empty marker functions, and thread locking
@@ -129,15 +144,15 @@ static const unsigned long mips_breakpoint = 0x0005000d;
 static CORE_ADDR
 mips_reinsert_addr ()
 {
-  unsigned long pc;
-  collect_register_by_name ("ra", &pc);
-  return pc;
+  union mips_register ra;
+  collect_register_by_name ("ra", ra.buf);
+  return register_size (0) == 4 ? ra.reg32 : ra.reg64;
 }
 
 static int
 mips_breakpoint_at (CORE_ADDR where)
 {
-  unsigned long insn;
+  unsigned int insn;
 
   (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
   if (insn == mips_breakpoint)
@@ -165,6 +180,155 @@ ps_get_thread_area (const struct ps_prochandle *ph,
   return PS_OK;
 }
 
+#ifdef HAVE_PTRACE_GETREGS
+
+static void
+mips_collect_register (int use_64bit, int regno, union mips_register *reg)
+{
+  union mips_register tmp_reg;
+
+  if (use_64bit)
+    {
+      collect_register (regno, &tmp_reg.reg64);
+      *reg = tmp_reg;
+    }
+  else
+    {
+      collect_register (regno, &tmp_reg.reg32);
+      reg->reg64 = tmp_reg.reg32;
+    }
+}
+
+static void
+mips_supply_register (int use_64bit, int regno, const union mips_register *reg)
+{
+  int offset = 0;
+
+  /* For big-endian 32-bit targets, ignore the high four bytes of each
+     eight-byte slot.  */
+  if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit)
+    offset = 4;
+
+  supply_register (regno, reg->buf + offset);
+}
+
+static void
+mips_collect_register_32bit (int use_64bit, int regno, unsigned char *buf)
+{
+  union mips_register tmp_reg;
+  int reg32;
+
+  mips_collect_register (use_64bit, regno, &tmp_reg);
+  reg32 = tmp_reg.reg64;
+  memcpy (buf, &reg32, 4);
+}
+
+static void
+mips_supply_register_32bit (int use_64bit, int regno, const unsigned char *buf)
+{
+  union mips_register tmp_reg;
+  int reg32;
+
+  memcpy (&reg32, buf, 4);
+  tmp_reg.reg64 = reg32;
+  mips_supply_register (use_64bit, regno, &tmp_reg);
+}
+
+static void
+mips_fill_gregset (void *buf)
+{
+  union mips_register *regset = buf;
+  int i, use_64bit;
+
+  use_64bit = (register_size (0) == 8);
+
+  for (i = 0; i < 32; i++)
+    mips_collect_register (use_64bit, i, regset + i);
+
+  mips_collect_register (use_64bit, find_regno ("lo"), regset + 32);
+  mips_collect_register (use_64bit, find_regno ("hi"), regset + 33);
+  mips_collect_register (use_64bit, find_regno ("pc"), regset + 34);
+  mips_collect_register (use_64bit, find_regno ("bad"), regset + 35);
+  mips_collect_register (use_64bit, find_regno ("sr"), regset + 36);
+  mips_collect_register (use_64bit, find_regno ("cause"), regset + 37);
+}
+
+static void
+mips_store_gregset (const void *buf)
+{
+  const union mips_register *regset = buf;
+  int i, use_64bit;
+
+  use_64bit = (register_size (0) == 8);
+
+  for (i = 0; i < 32; i++)
+    mips_supply_register (use_64bit, i, regset + i);
+
+  mips_supply_register (use_64bit, find_regno ("lo"), regset + 32);
+  mips_supply_register (use_64bit, find_regno ("hi"), regset + 33);
+  mips_supply_register (use_64bit, find_regno ("pc"), regset + 34);
+  mips_supply_register (use_64bit, find_regno ("bad"), regset + 35);
+  mips_supply_register (use_64bit, find_regno ("sr"), regset + 36);
+  mips_supply_register (use_64bit, find_regno ("cause"), regset + 37);
+}
+
+static void
+mips_fill_fpregset (void *buf)
+{
+  union mips_register *regset = buf;
+  int i, use_64bit, first_fp, big_endian;
+
+  use_64bit = (register_size (0) == 8);
+  first_fp = find_regno ("f0");
+  big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
+
+  /* See GDB for a discussion of this peculiar layout.  */
+  for (i = 0; i < 32; i++)
+    if (use_64bit)
+      collect_register (first_fp + i, regset[i].buf);
+    else
+      collect_register (first_fp + i,
+                       regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
+
+  mips_collect_register_32bit (use_64bit, find_regno ("fsr"), regset[32].buf);
+  mips_collect_register_32bit (use_64bit, find_regno ("fir"),
+                              regset[32].buf + 4);
+}
+
+static void
+mips_store_fpregset (const void *buf)
+{
+  const union mips_register *regset = buf;
+  int i, use_64bit, first_fp, big_endian;
+
+  use_64bit = (register_size (0) == 8);
+  first_fp = find_regno ("f0");
+  big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
+
+  /* See GDB for a discussion of this peculiar layout.  */
+  for (i = 0; i < 32; i++)
+    if (use_64bit)
+      supply_register (first_fp + i, regset[i].buf);
+    else
+      supply_register (first_fp + i,
+                      regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
+
+  mips_supply_register_32bit (use_64bit, find_regno ("fsr"), regset[32].buf);
+  mips_supply_register_32bit (use_64bit, find_regno ("fir"),
+                             regset[32].buf + 4);
+}
+#endif /* HAVE_PTRACE_GETREGS */
+
+struct regset_info target_regsets[] = {
+#ifdef HAVE_PTRACE_GETREGS
+  { PTRACE_GETREGS, PTRACE_SETREGS, 38 * 8, GENERAL_REGS,
+    mips_fill_gregset, mips_store_gregset },
+  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 33 * 8, FP_REGS,
+    mips_fill_fpregset, mips_store_fpregset },
+#endif /* HAVE_PTRACE_GETREGS */
+  { 0, 0, -1, -1, NULL, NULL }
+};
+
 struct linux_target_ops the_low_target = {
   mips_num_regs,
   mips_regmap,
index 78bc6434076a0b6de675d2348d11a365736d6515..e1f0653df4da35bfcd3e1558656b2fbc0eb22af8 100644 (file)
@@ -33,6 +33,8 @@ extern int debug_threads;
 
 #include "gdb_proc_service.h"
 
+#include <stdint.h>
+
 /* Structure that identifies the child process for the
    <proc_service.h> interface.  */
 static struct ps_prochandle proc_handle;
@@ -333,11 +335,14 @@ thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
   if (!process->thread_known)
     return TD_NOTHR;
 
-  err = td_thr_tls_get_addr (&process->th, (psaddr_t) load_module, offset,
-                            &addr);
+  /* Note the cast through uintptr_t: this interface only works if
+     a target address fits in a psaddr_t, which is a host pointer.
+     So a 32-bit debugger can not access 64-bit TLS through this.  */
+  err = td_thr_tls_get_addr (&process->th, (psaddr_t) (uintptr_t) load_module,
+                            offset, &addr);
   if (err == TD_OK)
     {
-      *address = (CORE_ADDR) addr;
+      *address = (CORE_ADDR) (uintptr_t) addr;
       return 0;
     }
   else
diff --git a/gdb/regformats/reg-mips64.dat b/gdb/regformats/reg-mips64.dat
new file mode 100644 (file)
index 0000000..3f5889e
--- /dev/null
@@ -0,0 +1,112 @@
+name:mips
+expedite:pc,sp
+64:zero
+64:at
+64:v0
+64:v1
+
+64:a0
+64:a1
+64:a2
+64:a3
+
+64:t0
+64:t1
+64:t2
+64:t3
+
+64:t4
+64:t5
+64:t6
+64:t7
+
+64:s0
+64:s1
+64:s2
+64:s3
+
+64:s4
+64:s5
+64:s6
+64:s7
+
+64:t8
+64:t9
+64:k0
+64:k1
+
+64:gp
+64:sp
+64:s8
+64:ra
+
+64:sr
+64:lo
+64:hi
+64:bad
+
+64:cause
+64:pc
+
+64:f0
+64:f1
+64:f2
+64:f3
+
+64:f4
+64:f5
+64:f6
+64:f7
+
+64:f8
+64:f9
+64:f10
+64:f11
+
+64:f12
+64:f13
+64:f14
+64:f15
+
+64:f16
+64:f17
+64:f18
+64:f19
+
+64:f20
+64:f21
+64:f22
+64:f23
+
+64:f24
+64:f25
+64:f26
+64:f27
+
+64:f28
+64:f29
+64:f30
+64:f31
+
+64:fsr
+64:fir
+
+64:fp
+64:
+
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64: