Replacing a bogus file with a semi-bogus one (sharing through devo).
[deliverable/binutils-gdb.git] / gdb / sol-thread.c
index fbbbbcb02b2c0cf96d0adfc672e2faf309c159fe..ca20bdef8880eb801b759329e16bb8041ffc0c8d 100644 (file)
@@ -1,5 +1,5 @@
 /* Low level interface for debugging Solaris threads for GDB, the GNU debugger.
-   Copyright 1996 Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -91,8 +91,8 @@ extern char *procfs_pid_to_str PARAMS ((int pid));
 
 extern void supply_gregset PARAMS ((const prgregset_t));
 extern void fill_gregset PARAMS ((prgregset_t, int));
-extern void supply_fpregset PARAMS ((const prfpregset_t));
-extern void fill_fpregset PARAMS ((prfpregset_t, int));
+extern void supply_fpregset PARAMS ((const prfpregset_t *));
+extern void fill_fpregset PARAMS ((prfpregset_t *, int));
 
 /* This struct is defined by us, but mainly used for the proc_service interface.
    We don't have much use for it, except as a handy place to get a real pid
@@ -385,7 +385,7 @@ lwp_to_thread (lwp)
   if (val == TD_NOTHR)
     return -1;         /* thread must have terminated */
   else if (val != TD_OK)
-    error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val));
+    error ("lwp_to_thread: td_ta_map_lwp2thr: %s.", td_err_string (val));
 
   val = p_td_thr_validate (&th);
   if (val == TD_NOTHR)
@@ -653,7 +653,7 @@ sol_thread_fetch_registers (regno)
    registers array.  */
 
   supply_gregset (gregset);
-  supply_fpregset (fpregset);
+  supply_fpregset (&fpregset);
 
 #if 0
 /* thread_db doesn't seem to handle this right */
@@ -717,7 +717,7 @@ sol_thread_store_registers (regno)
        error ("sol_thread_store_registers: td_thr_getfpregs %s",
               td_err_string (val));
 
-      /* restore register value */
+      /* restore new register value */
       memcpy(& registers[REGISTER_BYTE(regno)], old_value, REGISTER_SIZE);
 
 #if 0
@@ -739,7 +739,7 @@ sol_thread_store_registers (regno)
     }
 
   fill_gregset (regset, regno);
-  fill_fpregset (fpregset, regno);
+  fill_fpregset (&fpregset, regno);
 
   val = p_td_thr_setgregs (&thandle, regset);
   if (val != TD_OK)
@@ -822,7 +822,7 @@ static void
 sol_thread_notice_signals (pid)
      int pid;
 {
-  procfs_ops.to_notice_signals (pid);
+  procfs_ops.to_notice_signals (PIDGET (pid));
 }
 
 /* Fork an inferior process, and start debugging it with /proc.  */
@@ -956,37 +956,65 @@ sol_thread_stop ()
 /* These routines implement the lower half of the thread_db interface.  Ie: the
    ps_* routines.  */
 
+/* Various versions of <proc_service.h> have slightly
+   different function prototypes.  In particular, we have
+
+      NEWER                    OLDER
+      struct ps_prochandle *   const struct ps_prochandle *
+      void*                    char*
+      const void*              char*
+      int                      size_t
+
+   Which one you have depends on solaris version and what
+   patches you've applied.  On the theory that there are
+   only two major variants, we have configure check the
+   prototype of ps_pdwrite (), and use that info to make
+   appropriate typedefs here. */
+
+#ifdef PROC_SERVICE_IS_OLD
+typedef const struct ps_prochandle * gdb_ps_prochandle_t;
+typedef char * gdb_ps_read_buf_t;
+typedef char * gdb_ps_write_buf_t;
+typedef int gdb_ps_size_t;
+#else
+typedef struct ps_prochandle * gdb_ps_prochandle_t;
+typedef void * gdb_ps_read_buf_t;
+typedef const void * gdb_ps_write_buf_t;
+typedef size_t gdb_ps_size_t;
+#endif
+
+
 /* The next four routines are called by thread_db to tell us to stop and stop
    a particular process or lwp.  Since GDB ensures that these are all stopped
    by the time we call anything in thread_db, these routines need to do
    nothing.  */
 
 ps_err_e
-ps_pstop (const struct ps_prochandle *ph)
+ps_pstop (gdb_ps_prochandle_t ph)
 {
   return PS_OK;
 }
 
 ps_err_e
-ps_pcontinue (const struct ps_prochandle *ph)
+ps_pcontinue (gdb_ps_prochandle_t ph)
 {
   return PS_OK;
 }
 
 ps_err_e
-ps_lstop (const struct ps_prochandle *ph, lwpid_t lwpid)
+ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
 {
   return PS_OK;
 }
 
 ps_err_e
-ps_lcontinue (const struct ps_prochandle *ph, lwpid_t lwpid)
+ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
 {
   return PS_OK;
 }
 
 ps_err_e
-ps_pglobal_lookup (const struct ps_prochandle *ph, const char *ld_object_name,
+ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
                   const char *ld_symbol_name, paddr_t *ld_symbol_addr)
 {
   struct minimal_symbol *ms;
@@ -1046,33 +1074,37 @@ rw_common (int dowrite, const struct ps_prochandle *ph, paddr_t addr,
 }
 
 ps_err_e
-ps_pdread (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size)
+ps_pdread (gdb_ps_prochandle_t ph, paddr_t addr,
+          gdb_ps_read_buf_t buf, gdb_ps_size_t size)
 {
   return rw_common (0, ph, addr, buf, size);
 }
 
 ps_err_e
-ps_pdwrite (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size)
+ps_pdwrite (gdb_ps_prochandle_t ph, paddr_t addr,
+           gdb_ps_write_buf_t buf, gdb_ps_size_t size)
 {
-  return rw_common (1, ph, addr, buf, size);
+  return rw_common (1, ph, addr, (char*) buf, size);
 }
 
 ps_err_e
-ps_ptread (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size)
+ps_ptread (gdb_ps_prochandle_t ph, paddr_t addr,
+          gdb_ps_read_buf_t buf, gdb_ps_size_t size)
 {
   return rw_common (0, ph, addr, buf, size);
 }
 
 ps_err_e
-ps_ptwrite (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size)
+ps_ptwrite (gdb_ps_prochandle_t ph, paddr_t addr,
+           gdb_ps_write_buf_t buf, gdb_ps_size_t size)
 {
-  return rw_common (1, ph, addr, buf, size);
+  return rw_common (1, ph, addr, (char*) buf, size);
 }
 
 /* Get integer regs */
 
 ps_err_e
-ps_lgetregs (const struct ps_prochandle *ph, lwpid_t lwpid,
+ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
             prgregset_t gregset)
 {
   struct cleanup *old_chain;
@@ -1095,7 +1127,7 @@ ps_lgetregs (const struct ps_prochandle *ph, lwpid_t lwpid,
 /* Set integer regs */
 
 ps_err_e
-ps_lsetregs (const struct ps_prochandle *ph, lwpid_t lwpid,
+ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
             const prgregset_t gregset)
 {
   struct cleanup *old_chain;
@@ -1128,7 +1160,7 @@ ps_plog (const char *fmt, ...)
 /* Get size of extra register set.  Currently a noop.  */
 
 ps_err_e
-ps_lgetxregsize (const struct ps_prochandle *ph, lwpid_t lwpid, int *xregsize)
+ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
 {
 #if 0
   int lwp_fd;
@@ -1156,7 +1188,7 @@ ps_lgetxregsize (const struct ps_prochandle *ph, lwpid_t lwpid, int *xregsize)
 /* Get extra register set.  Currently a noop.  */
 
 ps_err_e
-ps_lgetxregs (const struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
+ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
 {
 #if 0
   int lwp_fd;
@@ -1179,7 +1211,7 @@ ps_lgetxregs (const struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
 /* Set extra register set.  Currently a noop.  */
 
 ps_err_e
-ps_lsetxregs (const struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
+ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
 {
 #if 0
   int lwp_fd;
@@ -1202,7 +1234,7 @@ ps_lsetxregs (const struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
 /* Get floating-point regs.  */
 
 ps_err_e
-ps_lgetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid,
+ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
               prfpregset_t *fpregset)
 {
   struct cleanup *old_chain;
@@ -1215,7 +1247,7 @@ ps_lgetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid,
     procfs_ops.to_fetch_registers (-1);
   else
     orig_core_ops.to_fetch_registers (-1);
-  fill_fpregset (*fpregset, -1);
+  fill_fpregset (fpregset, -1);
 
   do_cleanups (old_chain);
 
@@ -1225,7 +1257,7 @@ ps_lgetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid,
 /* Set floating-point regs.  */
 
 ps_err_e
-ps_lsetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid,
+ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
               const prfpregset_t *fpregset)
 {
   struct cleanup *old_chain;
@@ -1234,7 +1266,7 @@ ps_lsetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid,
 
   inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));
   
-  supply_fpregset (*fpregset);
+  supply_fpregset (fpregset);
   if (target_has_execution)
     procfs_ops.to_store_registers (-1);
   else
@@ -1244,6 +1276,64 @@ ps_lsetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid,
 
   return PS_OK;
 }
+
+#ifdef TM_I386SOL2_H
+
+/* Get local descriptor table.  */
+
+#include <sys/procfs.h>
+#include <sys/reg.h>
+#include <sys/sysi86.h>
+
+static int nldt_allocated = 0;
+static struct ssd *ldt_bufp = NULL;
+
+ps_err_e
+ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+           struct ssd *pldt)
+{
+  gregset_t gregset;
+  int lwp_fd;
+  ps_err_e val;
+  int nldt;
+  int i;
+
+  /* Get procfs file descriptor for the LWP.  */
+  lwp_fd = procfs_get_pid_fd (BUILD_LWP (lwpid, PIDGET (inferior_pid)));
+  if (lwp_fd < 0)
+    return PS_BADLID;
+
+  /* Fetch registers und LDT descriptors.  */
+  if (ioctl (lwp_fd, PIOCGREG, &gregset) == -1)
+    return PS_ERR;
+
+  if (ioctl (lwp_fd, PIOCNLDT, &nldt) == -1)
+    return PS_ERR;
+
+  if (nldt_allocated < nldt)
+    {
+      ldt_bufp
+       = (struct ssd *) xrealloc (ldt_bufp, (nldt + 1) * sizeof (struct ssd));
+      nldt_allocated = nldt;
+    }
+
+  if (ioctl (lwp_fd, PIOCLDT, ldt_bufp) == -1)
+    return PS_ERR;
+
+  /* Search LDT for the LWP via register GS.  */
+  for (i = 0; i < nldt; i++)
+    {
+      if (ldt_bufp[i].sel == (gregset[GS] & 0xffff))
+       {
+         *pldt = ldt_bufp[i];
+         return PS_OK;
+       }
+    }
+
+  /* LDT not found.  */
+  return PS_ERR;
+}        
+#endif /* TM_I386SOL2_H */
 \f
 /* Convert a pid to printable form. */
 
@@ -1306,6 +1396,10 @@ sol_find_new_threads_callback(th, ignored)
 void
 sol_find_new_threads()
 {
+  /* don't do anything if init failed to resolve the libthread_db library */
+  if (!procfs_suppress_run)
+    return;
+
   if (inferior_pid == -1)
     {
       printf_filtered("No process.\n");
This page took 0.02889 seconds and 4 git commands to generate.