2003-08-26 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / i386-linux-nat.c
index 3744124ebc52b44284aaac37143b4597f7208202..dbf91b7658ed7ee8b4edfa6a3262ba2732350b73 100644 (file)
@@ -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"
 /* Defines I386_LINUX_ORIG_EAX_REGNUM.  */
 #include "i386-linux-tdep.h"
 
+/* Defines ps_err_e, struct ps_prochandle.  */
+#include "gdb_proc_service.h"
+
 /* Prototypes for local functions.  */
 static void dummy_sse_values (void);
-
 \f
 
 /* The register sets used in GNU/Linux ELF core-dumps are identical to
@@ -233,10 +236,10 @@ supply_gregset (elf_gregset_t *gregsetp)
   int i;
 
   for (i = 0; i < I386_NUM_GREGS; i++)
-    supply_register (i, (char *) (regp + regmap[i]));
+    supply_register (i, regp + regmap[i]);
 
   if (I386_LINUX_ORIG_EAX_REGNUM < NUM_REGS)
-    supply_register (I386_LINUX_ORIG_EAX_REGNUM, (char *) (regp + ORIG_EAX));
+    supply_register (I386_LINUX_ORIG_EAX_REGNUM, regp + ORIG_EAX);
 }
 
 /* Fill register REGNO (if it is a general-purpose register) in
@@ -317,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 ((const char *) fpregsetp, -1);
   dummy_sse_values ();
 }
 
@@ -382,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 ((const char *) fpxregsetp, -1);
 }
 
 /* Fill register REGNO (if it is a floating-point or SSE register) in
@@ -684,6 +687,41 @@ i386_linux_dr_set (int regnum, unsigned long value)
     perror_with_name ("Couldn't write debug register");
 }
 
+/* Called by libthread_db.  Return's a pointer to the thread local
+   storage (or it's descriptor).  */
+extern 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.  Perhaphs 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);
+#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)
 {
@@ -853,7 +891,7 @@ child_resume (ptid_t ptid, int step, enum target_signal signal)
          /* Then check the system call number.  */
          if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn)
            {
-             CORE_ADDR sp = read_register (SP_REGNUM);
+             CORE_ADDR sp = read_register (I386_ESP_REGNUM);
              CORE_ADDR addr = sp;
              unsigned long int eflags;
 
@@ -873,6 +911,13 @@ 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");
 }
+
+void
+child_post_startup_inferior (ptid_t ptid)
+{
+  i386_cleanup_dregs ();
+  linux_child_post_startup_inferior (ptid);
+}
 \f
 
 /* Register that we are able to handle GNU/Linux ELF core file
This page took 0.083364 seconds and 4 git commands to generate.