This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
gdbserver Solaris [6/9] - gdbserver extra functions
- From: "Pieter Maljaars" <pieter dot maljaars at altenpts dot nl>
- To: gdb-patches at sourceware dot org
- Date: Fri, 23 Apr 2010 17:11:44 +0200
- Subject: gdbserver Solaris [6/9] - gdbserver extra functions
- Reply-to: pieter dot maljaars at altenpts dot nl
gdb/gdbserver ChangeLog entry:
2010-04-23 Pieter Maljaars <pieter.maljaars@altenpts.nl>
* proc-service.c: New functions for Solaris threads.
* server.h: New functions.
* util.c: Likewise.
diff -upN src-orig/src/gdb/gdbserver/proc-service.c src/gdb/gdbserver/proc-service.c
--- src-orig/src/gdb/gdbserver/proc-service.c 2010-01-21 16:33:19.000000000 +0100
+++ src/gdb/gdbserver/proc-service.c 2010-04-21 11:33:08.000000000 +0200
@@ -19,7 +19,11 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#ifdef linux
#include "server.h"
+#else
+#include "solaris-low.h"
+#endif
/* This file is currently tied to GNU/Linux. It should scale well to
another libthread_db implementation, with the approriate gdbserver
@@ -29,10 +33,39 @@
#include "gdb_proc_service.h"
+#include <sys/procfs.h>
+
+/* The prototypes in <proc_service.h> are slightly different on older
+ systems. Compensate for the discrepancies. */
+
+#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
+
+#ifdef HAVE_LINUX_REGSETS
+#define HAVE_REGSETS
+#endif
+
+#ifdef linux
+#define FPREGSET_SET_T void
+#define FPREGSET_GET_T void
+#else
+/* Solaris */
+#define FPREGSET_SET_T const prfpregset_t
+#define FPREGSET_GET_T prfpregset_t
+
+/* Building process ids. */
+#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
+#endif
+
#ifdef HAVE_LINUX_REGSETS
#define HAVE_REGSETS
@@ -55,6 +88,46 @@ gregset_info(void)
}
#endif
+
+/* Stop the target process PH. */
+
+ps_err_e
+ps_pstop (gdb_ps_prochandle_t ph)
+{
+ /* The process is always stopped when under control of GDB. */
+ return PS_OK;
+}
+
+/* Resume the target process PH. */
+
+ps_err_e
+ps_pcontinue (gdb_ps_prochandle_t ph)
+{
+ /* Pretend we did successfully continue the process. GDB will take
+ care of it later on. */
+ return PS_OK;
+}
+
+/* Stop the lightweight process LWPID within the target process PH. */
+
+ps_err_e
+ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
+{
+ /* All lightweight processes are stopped when under control of GDB. */
+ return PS_OK;
+}
+
+/* Resume the lightweight process (LWP) LWPID within the target
+ process PH. */
+
+ps_err_e
+ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
+{
+ /* Pretend we did successfully continue LWPID. GDB will take care
+ of it later on. */
+ return PS_OK;
+}
+
/* Search for the symbol named NAME within the object named OBJ within
the target process PH. If the symbol is found the address of the
symbol is stored in SYM_ADDR. */
@@ -76,6 +149,26 @@ ps_pglobal_lookup (gdb_ps_prochandle_t p
them into BUF. */
ps_err_e
+ps_ptread (gdb_ps_prochandle_t ph, psaddr_t addr,
+ gdb_ps_read_buf_t buf, gdb_ps_size_t size)
+{
+ read_inferior_memory( (unsigned long) addr, (gdb_byte *) buf, size);
+ return PS_OK;
+}
+
+/* Write SIZE bytes from BUF into the target process PH at address ADDR. */
+
+ps_err_e
+ps_ptwrite (gdb_ps_prochandle_t ph, psaddr_t addr,
+ gdb_ps_write_buf_t buf, gdb_ps_size_t size)
+{
+ return write_inferior_memory ((unsigned long) addr, (gdb_byte *) buf, size);
+}
+
+/* Read SIZE bytes from the target process PH at address ADDR and copy
+ them into BUF. */
+
+ps_err_e
ps_pdread (gdb_ps_prochandle_t ph, psaddr_t addr,
gdb_ps_read_buf_t buf, gdb_ps_size_t size)
{
@@ -134,7 +227,7 @@ ps_lsetregs (gdb_ps_prochandle_t ph, lwp
process PH and store them in FPREGSET. */
ps_err_e
-ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, void *fpregset)
+ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, FPREGSET_GET_T *fpregset)
{
/* Unneeded. */
return PS_ERR;
@@ -144,12 +237,13 @@ ps_lgetfpregs (gdb_ps_prochandle_t ph, l
process PH from FPREGSET. */
ps_err_e
-ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, void *fpregset)
+ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, FPREGSET_SET_T *fpregset)
{
/* Unneeded. */
return PS_ERR;
}
+#ifndef sun
/* Return overall process id of the target PH. Special for GNU/Linux
-- not used on Solaris. */
@@ -158,3 +252,32 @@ ps_getpid (gdb_ps_prochandle_t ph)
{
return pid_of (get_thread_lwp (current_inferior));
}
+
+#else
+
+/* Only used on Solaris. */
+
+/* Get size of extra register set. Currently a noop. */
+
+ps_err_e
+ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
+{
+ return PS_OK;
+}
+
+/* Get extra register set. Currently a noop. */
+
+ps_err_e
+ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+ return PS_OK;
+}
+
+/* Set extra register set. Currently a noop. */
+
+ps_err_e
+ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+ return PS_OK;
+}
+#endif
diff -upN src-orig/src/gdb/gdbserver/server.h src/gdb/gdbserver/server.h
--- src-orig/src/gdb/gdbserver/server.h 2010-04-12 15:51:22.000000000 +0200
+++ src/gdb/gdbserver/server.h 2010-04-21 11:39:18.000000000 +0200
@@ -456,6 +456,7 @@ void buffer_xml_printf (struct buffer *b
void *xmalloc (size_t) ATTR_MALLOC;
void *xrealloc (void *, size_t);
void *xcalloc (size_t, size_t) ATTR_MALLOC;
+void xfree (void *);
char *xstrdup (const char *) ATTR_MALLOC;
void freeargv (char **argv);
void perror_with_name (const char *string);
@@ -464,6 +465,7 @@ void fatal (const char *string,...) ATTR
void internal_error (const char *file, int line, const char *, ...)
ATTR_NORETURN ATTR_FORMAT (printf, 3, 4);
void warning (const char *string,...) ATTR_FORMAT (printf, 1, 2);
+void print_sys_errmsg (const char *string, int errcode);
char *paddress (CORE_ADDR addr);
char *pulongest (ULONGEST u);
char *plongest (LONGEST l);
diff -upN src-orig/src/gdb/gdbserver/utils.c src/gdb/gdbserver/utils.c
--- src-orig/src/gdb/gdbserver/utils.c 2010-04-09 05:40:00.000000000 +0200
+++ src/gdb/gdbserver/utils.c 2010-04-21 11:40:49.000000000 +0200
@@ -95,6 +98,13 @@ xcalloc (size_t nelem, size_t elsize)
return newmem;
}
+void
+xfree (void *ptr)
+{
+ if (ptr != NULL)
+ free (ptr); /* OK: free */
+}
+
/* Copy a string into a memory buffer.
If malloc fails, this will print a message to stderr and exit. */
@@ -146,6 +156,45 @@ perror_with_name (const char *string)
error ("%s.", combined);
}
+/* The strerror() function can return NULL for errno values that are
+ out of range. Provide a "safe" version that always returns a
+ printable string. */
+
+char *
+safe_strerror (int errnum)
+{
+ char *msg;
+
+ msg = strerror (errnum);
+ if (msg == NULL)
+ {
+ static char buf[32];
+ snprintf (buf, sizeof buf, "(undocumented errno %d)", errnum);
+ msg = buf;
+ }
+ return (msg);
+}
+
+/* Print the system error message for ERRCODE, and also mention STRING
+ as the file name for which the error was encoutered. */
+
+void
+print_sys_errmsg (const char *string, int errcode)
+{
+ char *err;
+ char *combined;
+ err = safe_strerror (errcode);
+ combined = (char *) alloca (strlen (err) + strlen (string) + 3);
+ strcpy (combined, string);
+ strcat (combined, ": ");
+ strcat (combined, err);
+
+ /* We want anything which was printed on stdout to come out first, before
+ this message. */
+ fflush(stdout);
+ printf ("%s.\n", combined);
+}
+
/* Print an error message and return to command level.
STRING is the error message, used as a fprintf string,
and ARG is passed as an argument to it. */