2004-07-17 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / i386-linux-nat.c
index 81be404a0f4ebdac14dc2687feff16f72c892e38..061f645c8cf09fd6d67a02dcb5896fea685b12f2 100644 (file)
@@ -1,6 +1,6 @@
-/* Native-dependent code for GNU/Linux x86.
+/* Native-dependent code for GNU/Linux i386.
 
-   Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -23,6 +23,7 @@
 #include "inferior.h"
 #include "gdbcore.h"
 #include "regcache.h"
+#include "linux-nat.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -319,7 +320,7 @@ static void store_regs (int tid, int regno) {}
 void 
 supply_fpregset (elf_fpregset_t *fpregsetp)
 {
-  i387_supply_fsave ((char *) fpregsetp);
+  i387_supply_fsave (current_regcache, -1, fpregsetp);
   dummy_sse_values ();
 }
 
@@ -384,7 +385,7 @@ static void store_fpregs (int tid, int regno) {}
 void
 supply_fpxregset (elf_fpxregset_t *fpxregsetp)
 {
-  i387_supply_fxsave ((char *) fpxregsetp);
+  i387_supply_fxsave (current_regcache, -1, fpxregsetp);
 }
 
 /* Fill register REGNO (if it is a floating-point or SSE register) in
@@ -640,6 +641,8 @@ store_inferior_registers (int regno)
 }
 \f
 
+/* Support for debug registers.  */
+
 static unsigned long
 i386_linux_dr_get (int regnum)
 {
@@ -686,21 +689,6 @@ i386_linux_dr_set (int regnum, unsigned long value)
     perror_with_name ("Couldn't write debug register");
 }
 
-extern ps_err_e
-ps_get_thread_area(const struct ps_prochandle *ph, 
-                  lwpid_t lwpid, int idx, void **base)
-{
-  unsigned long int desc[3];
-#define PTRACE_GET_THREAD_AREA 25
-
-  if  (ptrace (PTRACE_GET_THREAD_AREA, 
-              lwpid, (void *) idx, (unsigned long) &desc) < 0)
-    return PS_ERR;
-
-  *(int *)base = desc[1];
-  return PS_OK;
-}
-
 void
 i386_linux_dr_set_control (unsigned long control)
 {
@@ -730,77 +718,43 @@ i386_linux_dr_get_status (void)
 }
 \f
 
-/* Interpreting register set info found in core files.  */
-
-/* Provide registers to GDB from a core file.
-
-   (We can't use the generic version of this function in
-   core-regset.c, because GNU/Linux has *three* different kinds of
-   register set notes.  core-regset.c would have to call
-   supply_fpxregset, which most platforms don't have.)
-
-   CORE_REG_SECT points to an array of bytes, which are the contents
-   of a `note' from a core file which BFD thinks might contain
-   register contents.  CORE_REG_SIZE is its size.
-
-   WHICH says which register set corelow suspects this is:
-     0 --- the general-purpose register set, in elf_gregset_t format
-     2 --- the floating-point register set, in elf_fpregset_t format
-     3 --- the extended floating-point register set, in elf_fpxregset_t format
-
-   REG_ADDR isn't used on GNU/Linux.  */
-
-static void
-fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
-                     int which, CORE_ADDR reg_addr)
-{
-  elf_gregset_t gregset;
-  elf_fpregset_t fpregset;
-
-  switch (which)
-    {
-    case 0:
-      if (core_reg_size != sizeof (gregset))
-       warning ("Wrong size gregset in core file.");
-      else
-       {
-         memcpy (&gregset, core_reg_sect, sizeof (gregset));
-         supply_gregset (&gregset);
-       }
-      break;
-
-    case 2:
-      if (core_reg_size != sizeof (fpregset))
-       warning ("Wrong size fpregset in core file.");
-      else
-       {
-         memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
-         supply_fpregset (&fpregset);
-       }
-      break;
-
-#ifdef HAVE_PTRACE_GETFPXREGS
-      {
-       elf_fpxregset_t fpxregset;
-
-      case 3:
-       if (core_reg_size != sizeof (fpxregset))
-         warning ("Wrong size fpxregset in core file.");
-       else
-         {
-           memcpy (&fpxregset, core_reg_sect, sizeof (fpxregset));
-           supply_fpxregset (&fpxregset);
-         }
-       break;
-      }
+/* Called by libthread_db.  Returns a pointer to the thread local
+   storage (or its descriptor).  */
+
+ps_err_e
+ps_get_thread_area (const struct ps_prochandle *ph, 
+                   lwpid_t lwpid, int idx, void **base)
+{
+  /* NOTE: cagney/2003-08-26: The definition of this buffer is found
+     in the kernel header <asm-i386/ldt.h>.  It, after padding, is 4 x
+     4 byte integers in size: `entry_number', `base_addr', `limit',
+     and a bunch of status bits.
+
+     The values returned by this ptrace call should be part of the
+     regcache buffer, and ps_get_thread_area should channel its
+     request through the regcache.  That way remote targets could
+     provide the value using the remote protocol and not this direct
+     call.
+
+     Is this function needed?  I'm guessing that the `base' is the
+     address of a a descriptor that libthread_db uses to find the
+     thread local address base that GDB needs.  Perhaps that
+     descriptor is defined by the ABI.  Anyway, given that
+     libthread_db calls this function without prompting (gdb
+     requesting tls base) I guess it needs info in there anyway.  */
+  unsigned int desc[4];
+  gdb_assert (sizeof (int) == 4);
+
+#ifndef PTRACE_GET_THREAD_AREA
+#define PTRACE_GET_THREAD_AREA 25
 #endif
 
-    default:
-      /* We've covered all the kinds of registers we know about here,
-         so this must be something we wouldn't know what to do with
-         anyway.  Just ignore it.  */
-      break;
-    }
+  if (ptrace (PTRACE_GET_THREAD_AREA, lwpid,
+             (void *) idx, (unsigned long) &desc) < 0)
+    return PS_ERR;
+
+  *(int *)base = desc[1];
+  return PS_OK;
 }
 \f
 
@@ -890,22 +844,10 @@ child_resume (ptid_t ptid, int step, enum target_signal signal)
   if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1)
     perror_with_name ("ptrace");
 }
-\f
-
-/* Register that we are able to handle GNU/Linux ELF core file
-   formats.  */
-
-static struct core_fns linux_elf_core_fns =
-{
-  bfd_target_elf_flavour,              /* core_flavour */
-  default_check_format,                        /* check_format */
-  default_core_sniffer,                        /* core_sniffer */
-  fetch_core_registers,                        /* core_read_registers */
-  NULL                                 /* next */
-};
 
 void
-_initialize_i386_linux_nat (void)
+child_post_startup_inferior (ptid_t ptid)
 {
-  add_core_fns (&linux_elf_core_fns);
+  i386_cleanup_dregs ();
+  linux_child_post_startup_inferior (ptid);
 }
This page took 0.026986 seconds and 4 git commands to generate.