public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver
@ 2011-07-12 18:31 Kwok Cheung Yeung
  2011-07-19 20:27 ` Tom Tromey
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Kwok Cheung Yeung @ 2011-07-12 18:31 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 6676 bytes --]

Currently, the implementations of the 'info os' command in gdb and gdbserver are maintained separately. This leads to a large amount of code duplication, and discrepencies in the behaviour of the command have already arisen between the two (gdb lists the available info types if 'info os' is issued while gdbserver does not, and gdbserver supports 'info os threads' while gdb does not). This patch attempts to fix that by making the implementation of 'info os' for Linux systems shared between gdb and gdbserver.

Auxilliary functions needed to implement 'info os' are moved into the common/ subdirectory. gdb_assert.h, gdb_locale.h and gdb_dirent.h are moved completely, while a subset of the following files are moved to common/:

gdbserver/server.h -> common/buffer.h
gdbserver/remote-utils -> common/buffer.c
inferior.h, defs.h -> common/ptid.h
infrun.c -> common/ptid.c
xml-support.[hc] -> common/xml-utils.[hc]
defs.h -> common/common-utils.h
utils.c -> common/common-utils.c

This necessitates various changes to the makefiles and config files to make sure the right object files are built/linked in. Duplicated functions in gdbserver are removed and the ones in common/ used instead.

The implementations of 'info os' for Linux (linux_nat_xfer_osdata in linux-nat.c and linux_qxfer_osdata in gdbserver/linux-low.c) are merged into common/linux-osdata.[ch]. For most part the gdbserver version is used since it has more functionality and doesn't depend on the availability of obstacks (it uses the routines now in common/buffer.c instead).

The subcommands of 'info os' (currently 'processes' and 'threads) are now dispatched by looking up the information type in a table (osdata_table) and calling the function for the matching entry. Listing the available OS info types with 'info os' is also implemented by scanning through this table. This makes it much easier to extend the range of OS information types later.

Kwok

ChangeLog:

2011-07-12  Kwok Cheung Yeung  <kcy@codesourcery.com>

	* defs.h: Add guard against inclusion in gdbserver.
	(struct ptid, ptid_t): Move to common/ptid.h.
	(xfree, xzalloc, xasprintf, xvasprintf, xstrprintf, xstrvprintf,
	xsnprintf, internal_error): Move to common/common-utils.h.
	(nomem): Delete.
	* gdb_assert.h: Move into common/ sub-directory.
	* gdb_locale.h: Ditto.
	* gdb_dirent.h: Ditto.
	* inferior.h (minus_one_ptid, null_ptid, ptid_build, pid_to_ptid,
	ptid_get_pid, ptid_get_lwp, ptid_get_tid, ptid_equal, ptid_is_pid):
	Move into common/ptid.h.
	* xml-support.c (xml_escape_text): Move into common/xml-utils.c.
	(gdb_xml_create_parser_and_cleanup_1, xml_fetch_context_from_file):
	Change nomem to malloc_failure.
	* xml-support.h (xml_escape_text): Move into common/xml-utils.h.
	* utils.c (nomem) Rename to malloc_failure.
	(xmalloc, xzalloc, xrealloc, xcalloc, xfree, xstrprintf, xasprintf,
	xvasprintf, xstrvprintf, xsnprintf) Move to common/common-utils.c.
	(gdb_buildargv): Change nomem to malloc_failure.
	* infrun.c (null_ptid, minus_one_ptid, ptid_build, pid_to_ptid,
	ptid_get_pid, ptid_get_lwp, ptid_get_tid, ptid_equal,
	ptid_is_pid): Move into common/ptid.c.
	(initialize_infrun): Delete initialization of null_ptid and
	minus_one_ptid.
	* linux-nat.c (linux_nat_xfer_osdata): Defer to
	linux_common_xfer_osdata.
	* Makefile.in (SFILES): Add common/common-utils.c, common/xml-utils.c,
	common/ptid.c and common/buffer.c.
	(HFILES_NO_SRCDIR): Add common/common-utils.h, common/xml-utils.h,
	common/ptid.h, common/buffer.h and common/linux-osdata.h.
	(COMMON_OBS): Add xml-utils.o, common-utils.o, buffer.o and ptid.o.
	(common-utils.o, xml-utils.o, ptid.o, buffer.o, linux-osdata.o): New
	rules.
	* common/gdb_assert.h: New.
	* common/gdb_dirent.h: New.
	* common/gdb_locale.h: New.
	* common/buffer.c: New.
	* common/buffer.h: New.
	* common/ptid.c: New.
	* common/ptid.h: New.
	* common/xml-utils.c: New.
	* common/xml-utils.h: New.
	* common/common-utils.c: New.
	* common/common-utils.h: New.
	* common/linux-osdata.c: New.
	* common/linux-osdata.h: New.
	* config/alpha/alpha-linux.mh (NATDEPFILES): Add linux-osdata.o.
	* config/arm/linux.mh (NATDEPFILES): Ditto.
	* config/i386/linux.mh (NATDEPFILES): Ditto.
	* config/i386/linux64.mh (NATDEPFILES): Ditto.
	* config/ia64/linux.mh (NATDEPFILES): Ditto.
	* config/m32r/linux.mh (NATDEPFILES): Ditto.
	* config/m68k/linux.mh (NATDEPFILES): Ditto.
	* config/mips/linux.mh (NATDEPFILES): Ditto.
	* config/pa/linux.mh (NATDEPFILES): Ditto.
	* config/powerpc/linux.mh (NATDEPFILES): Ditto.
	* config/powerpc/ppc64-linux.mh (NATDEPFILES): Ditto.
	* config/s390/s390.mh (NATDEPFILES): Ditto.
	* config/sparc/linux.mh (NATDEPFILES): Ditto.
	* config/sparc/linux64.mh (NATDEPFILES): Ditto.
	* config/xtensa/linux.mh (NATDEPFILES): Ditto.

gdbserver/ChangeLog:

2011-07-12  Kwok Cheung Yeung  <kcy@codesourcery.com>

	* linux-low.c (compare_ints, unique, list_threads, show_process,
	linux_core_of_thread): Delete.
	(linux_target_ops): Change linux_core_of_thread to
	linux_common_core_of_thread.
	(linux_qxfer_osdata): Defer to linux_common_xfer_osdata.
	* utils.c (malloc_failure): Change type of argument.
	(xmalloc, xrealloc, xcalloc, xsnprintf): Delete.
	* Makefile.in (SFILES): Add common/common-utils.c, common/xml-utils.c,
	common/linux-osdata.c, common/ptid.c and common/buffer.c.
	(OBS): Add xml-utils.o, common-utils.o, ptid.o and buffer.o.
	(IPA_OBJS): Add common-utils-ipa.o.
	(ptid_h, linux_osdata_h): New macros.
	(server_h): Add common/common-utils.h, common/xml-utils.h,
	common/buffer.h, common/gdb_assert.h, common/gdb_locale.h and
	common/ptid.h.
	(common-utils-ipa.o, common-utils.o, xml-utils.o, linux-osdata.o,
	ptid.o, buffer.o): New rules.
	(linux-low.o): Add common/linux-osdata.h as a dependency.
	* configure.srv (srv_tgtobj): Add linux-osdata.o to Linux targets.
	* configure.ac: Add AC_HEADER_DIRENT check.
	* config.in: Regenerate.
	* configure: Regenerate.
	* remote-utils.c (xml_escape_text): Delete.
	(buffer_grow, buffer_free, buffer_init, buffer_finish,
	buffer_xml_printf): Move to common/buffer.c.
	* server.c (main): Remove call to initialize_inferiors.
	* server.h (struct ptid, ptid_t, minus_one_ptid, null_ptid,
	ptid_build, pid_to_ptid, ptid_get_pid, ptid_get_lwp, ptid_get_tid,
	ptid_equal, ptid_is_pid, initialize_inferiors, xml_escape_text,
	internal_error, gdb_assert, gdb_assert_fail): Delete.
	(struct buffer, buffer_grow, buffer_free, buffer_init, buffer_finish,
	buffer_xml_printf, buffer_grow_str, buffer_grow_str0): Move to
	common/buffer.h.
	* inferiors.c (null_ptid, minus_one_ptid, ptid_build, pid_to_ptid,
	ptid_get_pid, ptid_get_lwp, ptid_get_tid, ptid_equal, ptid_is_pid,
	initialize_inferiors): Delete.

[-- Attachment #2: gdb-move-to-common.diff --]
[-- Type: text/plain, Size: 122153 bytes --]

Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1168
diff -u -p -r1.1168 Makefile.in
--- gdb/Makefile.in	30 Jun 2011 17:01:29 -0000	1.1168
+++ gdb/Makefile.in	12 Jul 2011 15:32:34 -0000
@@ -737,7 +737,9 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
 	jit.c \
 	xml-syscall.c \
 	annotate.c common/signals.c copying.c dfp.c gdb.c inf-child.c \
-	regset.c sol-thread.c windows-termcap.c
+	regset.c sol-thread.c windows-termcap.c \
+	common/common-utils.c common/xml-utils.c \
+	common/ptid.c common/buffer.c
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
 
@@ -816,7 +818,9 @@ osdata.h procfs.h python/py-event.h pyth
 python/python-internal.h python/python.h ravenscar-thread.h record.h \
 solib-darwin.h solib-ia64-hpux.h solib-spu.h windows-nat.h xcoffread.h \
 gnulib/extra/arg-nonnull.h gnulib/extra/c++defs.h gnulib/extra/warn-on-use.h \
-gnulib/stddef.in.h inline-frame.h
+gnulib/stddef.in.h inline-frame.h \
+common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
+common/linux-osdata.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -898,10 +902,12 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
 	trad-frame.o \
 	tramp-frame.o \
 	solib.o solib-target.o \
-	prologue-value.o memory-map.o memrange.o xml-support.o xml-syscall.o \
+	prologue-value.o memory-map.o memrange.o \
+	xml-support.o xml-syscall.o xml-utils.o \
 	target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
 	inferior.o osdata.o gdb_usleep.o record.o gcore.o \
-	jit.o progspace.o
+	jit.o progspace.o \
+	common-utils.o buffer.o ptid.o
 
 TSOBS = inflow.o
 
@@ -1933,6 +1939,26 @@ signals.o: $(srcdir)/common/signals.c
 	$(COMPILE) $(srcdir)/common/signals.c
 	$(POSTCOMPILE)
 
+common-utils.o: ${srcdir}/common/common-utils.c
+	$(COMPILE) $(srcdir)/common/common-utils.c
+	$(POSTCOMPILE)
+
+xml-utils.o: ${srcdir}/common/xml-utils.c
+	$(COMPILE) $(srcdir)/common/xml-utils.c
+	$(POSTCOMPILE)
+
+ptid.o: ${srcdir}/common/ptid.c
+	$(COMPILE) $(srcdir)/common/ptid.c
+	$(POSTCOMPILE)
+
+buffer.o: ${srcdir}/common/buffer.c
+	$(COMPILE) $(srcdir)/common/buffer.c
+	$(POSTCOMPILE)
+
+linux-osdata.o: ${srcdir}/common/linux-osdata.c
+	$(COMPILE) $(srcdir)/common/linux-osdata.c
+	$(POSTCOMPILE)
+
 #
 # gdb/tui/ dependencies
 #
Index: gdb/defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.298
diff -u -p -r1.298 defs.h
--- gdb/defs.h	29 Jun 2011 22:05:15 -0000	1.298
+++ gdb/defs.h	12 Jul 2011 15:32:35 -0000
@@ -23,6 +23,10 @@
 #ifndef DEFS_H
 #define DEFS_H
 
+#ifdef GDBSERVER
+#  error gdbserver should not include gdb/defs.h
+#endif
+
 #include "config.h"		/* Generated by configure.  */
 
 #include <sys/types.h>
@@ -142,6 +146,8 @@ typedef bfd_vma CORE_ADDR;
 #define max(a, b) ((a) > (b) ? (a) : (b))
 #endif
 
+#include "ptid.h"
+
 /* Check if a character is one of the commonly used C++ marker characters.  */
 extern int is_cplus_marker (int);
 
@@ -753,41 +759,6 @@ enum val_prettyprint
     Val_pretty_default
   };
 
-/* The ptid struct is a collection of the various "ids" necessary
-   for identifying the inferior.  This consists of the process id
-   (pid), thread id (tid), and other fields necessary for uniquely
-   identifying the inferior process/thread being debugged.  When
-   manipulating ptids, the constructors, accessors, and predicate
-   declared in inferior.h should be used.  These are as follows:
-
-      ptid_build	- Make a new ptid from a pid, lwp, and tid.
-      pid_to_ptid	- Make a new ptid from just a pid.
-      ptid_get_pid	- Fetch the pid component of a ptid.
-      ptid_get_lwp	- Fetch the lwp component of a ptid.
-      ptid_get_tid	- Fetch the tid component of a ptid.
-      ptid_equal	- Test to see if two ptids are equal.
-      ptid_is_pid	- Test to see if this ptid represents a process id.
-
-   Please do NOT access the struct ptid members directly (except, of
-   course, in the implementation of the above ptid manipulation
-   functions).  */
-
-struct ptid
-  {
-    /* Process id */
-    int pid;
-
-    /* Lightweight process id */
-    long lwp;
-
-    /* Thread id */
-    long tid;
-  };
-
-typedef struct ptid ptid_t;
-
-\f
-
 /* Optional native machine support.  Non-native (and possibly pure
    multi-arch) targets do not need a "nm.h" file.  This will be a
    symlink to one of the nm-*.h files, built by the `configure'
@@ -851,13 +822,6 @@ extern int longest_to_int (LONGEST);
 
 extern char *savestring (const char *, size_t);
 
-/* xmalloc(), xrealloc() and xcalloc() have already been declared in
-   "libiberty.h".  */
-extern void xfree (void *);
-
-/* Like xmalloc, but zero the memory.  */
-extern void *xzalloc (size_t);
-
 /* Utility macros to allocate typed memory.  Avoids errors like:
    struct foo *foo = xmalloc (sizeof struct bar); and memset (foo,
    sizeof (struct foo), 0).  */
@@ -865,22 +829,7 @@ extern void *xzalloc (size_t);
 #define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
 #define XCALLOC(NMEMB, TYPE) ((TYPE*) xcalloc ((NMEMB), sizeof (TYPE)))
 
-/* Like asprintf/vasprintf but get an internal_error if the call
-   fails.  */
-extern void xasprintf (char **ret, const char *format, ...)
-     ATTRIBUTE_PRINTF (2, 3);
-extern void xvasprintf (char **ret, const char *format, va_list ap)
-     ATTRIBUTE_PRINTF (2, 0);
-
-/* Like asprintf and vasprintf, but return the string, throw an error
-   if no memory.  */
-extern char *xstrprintf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
-extern char *xstrvprintf (const char *format, va_list ap)
-     ATTRIBUTE_PRINTF (1, 0);
-
-/* Like snprintf, but throw an error if the output buffer is too small.  */
-extern int xsnprintf (char *str, size_t size, const char *format, ...)
-     ATTRIBUTE_PRINTF (3, 4);
+#include "common-utils.h"
 
 extern int parse_escape (struct gdbarch *, char **);
 
@@ -914,9 +863,6 @@ extern void internal_verror (const char 
 			     va_list ap)
      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0);
 
-extern void internal_error (const char *file, int line, const char *, ...)
-     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 4);
-
 extern void internal_vwarning (const char *file, int line,
 			       const char *, va_list ap)
      ATTRIBUTE_PRINTF (3, 0);
@@ -924,8 +870,6 @@ extern void internal_vwarning (const cha
 extern void internal_warning (const char *file, int line,
 			      const char *, ...) ATTRIBUTE_PRINTF (3, 4);
 
-extern void nomem (long) ATTRIBUTE_NORETURN;
-
 extern void warning (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
 extern void vwarning (const char *, va_list args) ATTRIBUTE_PRINTF (1, 0);
Index: gdb/gdb_assert.h
===================================================================
RCS file: gdb/gdb_assert.h
diff -N gdb/gdb_assert.h
--- gdb/gdb_assert.h	7 Jan 2011 19:36:17 -0000	1.15
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,68 +0,0 @@
-/* GDB-friendly replacement for <assert.h>.
-   Copyright (C) 2000, 2001, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef GDB_ASSERT_H
-#define GDB_ASSERT_H
-
-/* PRAGMATICS: "gdb_assert.h":gdb_assert() is a lower case (rather
-   than upper case) macro since that provides the closest fit to the
-   existing lower case macro <assert.h>:assert() that it is
-   replacing.  */
-
-#define gdb_assert(expr)                                                      \
-  ((void) ((expr) ? 0 :                                                       \
-	   (gdb_assert_fail (#expr, __FILE__, __LINE__, ASSERT_FUNCTION), 0)))
-
-/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
-   which contains the name of the function currently being defined.
-   This is broken in G++ before version 2.6.
-   C9x has a similar variable called __func__, but prefer the GCC one since
-   it demangles C++ function names.  */
-#if (GCC_VERSION >= 2004)
-#define ASSERT_FUNCTION		__PRETTY_FUNCTION__
-#else
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
-#define ASSERT_FUNCTION		__func__
-#endif
-#endif
-
-/* This prints an "Assertion failed" message, asking the user if they
-   want to continue, dump core, or just exit.  */
-#if defined (ASSERT_FUNCTION)
-#define gdb_assert_fail(assertion, file, line, function)                      \
-  internal_error (file, line, _("%s: Assertion `%s' failed."),                \
-		  function, assertion)
-#else
-#define gdb_assert_fail(assertion, file, line, function)                      \
-  internal_error (file, line, _("Assertion `%s' failed."),                    \
-		  assertion)
-#endif
-
-/* The canonical form of gdb_assert (0).
-   MESSAGE is a string to include in the error message.  */
-
-#if defined (ASSERT_FUNCTION)
-#define gdb_assert_not_reached(message) \
-  internal_error (__FILE__, __LINE__, "%s: %s", ASSERT_FUNCTION, _(message))
-#else
-#define gdb_assert_not_reached(message) \
-  internal_error (__FILE__, __LINE__, _(message))
-#endif
-
-#endif /* gdb_assert.h */
Index: gdb/gdb_dirent.h
===================================================================
RCS file: gdb/gdb_dirent.h
diff -N gdb/gdb_dirent.h
--- gdb/gdb_dirent.h	5 Jan 2011 22:22:49 -0000	1.12
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,41 +0,0 @@
-/* Portable <dirent.h>.
-   Copyright (C) 2000, 2002, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef GDB_DIRENT_H
-#define GDB_DIRENT_H 1
-
-/* See description of `AC_HEADER_DIRENT' in the Autoconf manual.  */
-#ifdef HAVE_DIRENT_H
-# include <dirent.h>		/* ARI: dirent.h */
-# define NAMELEN(dirent) strlen ((dirent)->d_name)    /* ARI: strlen d_name */
-#else
-# define dirent direct
-# define NAMELEN(dirent) (dirent)->d_namelen	/* ARI: d_namelen */
-# ifdef HAVE_SYS_NDIR_H
-#  include <sys/ndir.h>
-# endif
-# ifdef HAVE_SYS_DIR_H
-#  include <sys/dir.h>
-# endif
-# ifdef HAVE_NDIR_H
-#  include <ndir.h>
-# endif
-#endif
-
-#endif /* not GDB_DIRENT_H */
Index: gdb/gdb_locale.h
===================================================================
RCS file: gdb/gdb_locale.h
diff -N gdb/gdb_locale.h
--- gdb/gdb_locale.h	1 Jan 2011 15:33:05 -0000	1.9
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,49 +0,0 @@
-/* GDB-friendly replacement for <locale.h>.
-   Copyright (C) 2002, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef GDB_LOCALE_H
-#define GDB_LOCALE_H
-
-#ifdef HAVE_LOCALE_H
-# include <locale.h>
-#endif
-
-#ifdef ENABLE_NLS
-# include <libintl.h>
-# define _(String) gettext (String)
-# ifdef gettext_noop
-#  define N_(String) gettext_noop (String)
-# else
-#  define N_(String) (String)
-# endif
-#else
-# define gettext(Msgid) (Msgid)
-# define dgettext(Domainname, Msgid) (Msgid)
-# define dcgettext(Domainname, Msgid, Category) (Msgid)
-# define textdomain(Domainname) while (0) /* nothing */
-# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */
-# define _(String) (String)
-# define N_(String) (String)
-#endif
-
-#ifdef HAVE_LANGINFO_CODESET
-#include <langinfo.h>
-#endif
-
-#endif /* GDB_LOCALE_H */
Index: gdb/inferior.h
===================================================================
RCS file: /cvs/src/src/gdb/inferior.h,v
retrieving revision 1.160
diff -u -p -r1.160 inferior.h
--- gdb/inferior.h	3 Jun 2011 15:32:44 -0000	1.160
+++ gdb/inferior.h	12 Jul 2011 15:32:35 -0000
@@ -32,6 +32,8 @@ struct regcache;
 struct ui_out;
 struct terminal_info;
 
+#include "ptid.h"
+
 /* For bpstat.  */
 #include "breakpoint.h"
 
@@ -63,36 +65,6 @@ extern void discard_infcall_control_stat
 extern struct regcache *
   get_infcall_suspend_state_regcache (struct infcall_suspend_state *);
 
-/* The -1 ptid, often used to indicate either an error condition
-   or a "don't care" condition, i.e, "run all threads."  */
-extern ptid_t minus_one_ptid;
-
-/* The null or zero ptid, often used to indicate no process.  */
-extern ptid_t null_ptid;
-
-/* Attempt to find and return an existing ptid with the given PID, LWP,
-   and TID components.  If none exists, create a new one and return
-   that.  */
-ptid_t ptid_build (int pid, long lwp, long tid);
-
-/* Find/Create a ptid from just a pid.  */
-ptid_t pid_to_ptid (int pid);
-
-/* Fetch the pid (process id) component from a ptid.  */
-int ptid_get_pid (ptid_t ptid);
-
-/* Fetch the lwp (lightweight process) component from a ptid.  */
-long ptid_get_lwp (ptid_t ptid);
-
-/* Fetch the tid (thread id) component from a ptid.  */
-long ptid_get_tid (ptid_t ptid);
-
-/* Compare two ptids to see if they are equal.  */
-extern int ptid_equal (ptid_t p1, ptid_t p2);
-
-/* Return true if PTID represents a process id.  */
-extern int ptid_is_pid (ptid_t ptid);
-
 /* Returns true if PTID matches filter FILTER.  FILTER can be the wild
    card MINUS_ONE_PTID (all ptid match it); can be a ptid representing
    a process (ptid_is_pid returns true), in which case, all lwps and
Index: gdb/infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.494
diff -u -p -r1.494 infrun.c
--- gdb/infrun.c	23 Jun 2011 15:08:01 -0000	1.494
+++ gdb/infrun.c	12 Jul 2011 15:32:38 -0000
@@ -6774,77 +6774,6 @@ inferior_has_called_syscall (ptid_t pid,
   return 1;
 }
 
-/* Oft used ptids */
-ptid_t null_ptid;
-ptid_t minus_one_ptid;
-
-/* Create a ptid given the necessary PID, LWP, and TID components.  */
-
-ptid_t
-ptid_build (int pid, long lwp, long tid)
-{
-  ptid_t ptid;
-
-  ptid.pid = pid;
-  ptid.lwp = lwp;
-  ptid.tid = tid;
-  return ptid;
-}
-
-/* Create a ptid from just a pid.  */
-
-ptid_t
-pid_to_ptid (int pid)
-{
-  return ptid_build (pid, 0, 0);
-}
-
-/* Fetch the pid (process id) component from a ptid.  */
-
-int
-ptid_get_pid (ptid_t ptid)
-{
-  return ptid.pid;
-}
-
-/* Fetch the lwp (lightweight process) component from a ptid.  */
-
-long
-ptid_get_lwp (ptid_t ptid)
-{
-  return ptid.lwp;
-}
-
-/* Fetch the tid (thread id) component from a ptid.  */
-
-long
-ptid_get_tid (ptid_t ptid)
-{
-  return ptid.tid;
-}
-
-/* ptid_equal() is used to test equality of two ptids.  */
-
-int
-ptid_equal (ptid_t ptid1, ptid_t ptid2)
-{
-  return (ptid1.pid == ptid2.pid && ptid1.lwp == ptid2.lwp
-	  && ptid1.tid == ptid2.tid);
-}
-
-/* Returns true if PTID represents a process.  */
-
-int
-ptid_is_pid (ptid_t ptid)
-{
-  if (ptid_equal (minus_one_ptid, ptid))
-    return 0;
-  if (ptid_equal (null_ptid, ptid))
-    return 0;
-
-  return (ptid_get_lwp (ptid) == 0 && ptid_get_tid (ptid) == 0);
-}
-
 int
 ptid_match (ptid_t ptid, ptid_t filter)
 {
@@ -7234,8 +7163,6 @@ Tells gdb whether to detach the child of
 			   NULL, NULL, &setlist, &showlist);
 
   /* ptid initializations */
-  null_ptid = ptid_build (0, 0, 0);
-  minus_one_ptid = ptid_build (-1, 0, 0);
   inferior_ptid = null_ptid;
   target_last_wait_ptid = minus_one_ptid;
 
Index: gdb/linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.c,v
retrieving revision 1.208
diff -u -p -r1.208 linux-nat.c
--- gdb/linux-nat.c	6 Jun 2011 12:47:07 -0000	1.208
+++ gdb/linux-nat.c	12 Jul 2011 15:32:38 -0000
@@ -57,6 +57,7 @@
 #include "terminal.h"
 #include <sys/vfs.h>
 #include "solib.h"
+#include "linux-osdata.h"
 
 #ifndef SPUFS_MAGIC
 #define SPUFS_MAGIC 0x23c9b64e
@@ -5114,148 +5115,9 @@ linux_nat_xfer_osdata (struct target_ops
 		       const char *annex, gdb_byte *readbuf,
 		       const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
 {
-  /* We make the process list snapshot when the object starts to be
-     read.  */
-  static const char *buf;
-  static LONGEST len_avail = -1;
-  static struct obstack obstack;
-
-  DIR *dirp;
-
   gdb_assert (object == TARGET_OBJECT_OSDATA);
 
-  if (!annex)
-    {
-      if (offset == 0)
-	{
-	  if (len_avail != -1 && len_avail != 0)
-	    obstack_free (&obstack, NULL);
-	  len_avail = 0;
-	  buf = NULL;
-	  obstack_init (&obstack);
-	  obstack_grow_str (&obstack, "<osdata type=\"types\">\n");
-
-	  obstack_xml_printf (&obstack,
-			      "<item>"
-			      "<column name=\"Type\">processes</column>"
-			      "<column name=\"Description\">"
-			      "Listing of all processes</column>"
-			      "</item>");
-
-	  obstack_grow_str0 (&obstack, "</osdata>\n");
-	  buf = obstack_finish (&obstack);
-	  len_avail = strlen (buf);
-	}
-
-      if (offset >= len_avail)
-	{
-	  /* Done.  Get rid of the obstack.  */
-	  obstack_free (&obstack, NULL);
-	  buf = NULL;
-	  len_avail = 0;
-	  return 0;
-	}
-
-      if (len > len_avail - offset)
-	len = len_avail - offset;
-      memcpy (readbuf, buf + offset, len);
-
-      return len;
-    }
-
-  if (strcmp (annex, "processes") != 0)
-    return 0;
-
-  gdb_assert (readbuf && !writebuf);
-
-  if (offset == 0)
-    {
-      if (len_avail != -1 && len_avail != 0)
-	obstack_free (&obstack, NULL);
-      len_avail = 0;
-      buf = NULL;
-      obstack_init (&obstack);
-      obstack_grow_str (&obstack, "<osdata type=\"processes\">\n");
-
-      dirp = opendir ("/proc");
-      if (dirp)
-	{
-	  struct dirent *dp;
-
-	  while ((dp = readdir (dirp)) != NULL)
-	    {
-	      struct stat statbuf;
-	      char procentry[sizeof ("/proc/4294967295")];
-
-	      if (!isdigit (dp->d_name[0])
-		  || NAMELEN (dp) > sizeof ("4294967295") - 1)
-		continue;
-
-	      sprintf (procentry, "/proc/%s", dp->d_name);
-	      if (stat (procentry, &statbuf) == 0
-		  && S_ISDIR (statbuf.st_mode))
-		{
-		  char *pathname;
-		  FILE *f;
-		  char cmd[MAXPATHLEN + 1];
-		  struct passwd *entry;
-
-		  pathname = xstrprintf ("/proc/%s/cmdline", dp->d_name);
-		  entry = getpwuid (statbuf.st_uid);
-
-		  if ((f = fopen (pathname, "r")) != NULL)
-		    {
-		      size_t length = fread (cmd, 1, sizeof (cmd) - 1, f);
-
-		      if (length > 0)
-			{
-			  int i;
-
-			  for (i = 0; i < length; i++)
-			    if (cmd[i] == '\0')
-			      cmd[i] = ' ';
-			  cmd[length] = '\0';
-
-			  obstack_xml_printf (
-			    &obstack,
-			    "<item>"
-			    "<column name=\"pid\">%s</column>"
-			    "<column name=\"user\">%s</column>"
-			    "<column name=\"command\">%s</column>"
-			    "</item>",
-			    dp->d_name,
-			    entry ? entry->pw_name : "?",
-			    cmd);
-			}
-		      fclose (f);
-		    }
-
-		  xfree (pathname);
-		}
-	    }
-
-	  closedir (dirp);
-	}
-
-      obstack_grow_str0 (&obstack, "</osdata>\n");
-      buf = obstack_finish (&obstack);
-      len_avail = strlen (buf);
-    }
-
-  if (offset >= len_avail)
-    {
-      /* Done.  Get rid of the obstack.  */
-      obstack_free (&obstack, NULL);
-      buf = NULL;
-      len_avail = 0;
-      return 0;
-    }
-
-  if (len > len_avail - offset)
-    len = len_avail - offset;
-  memcpy (readbuf, buf + offset, len);
-
-  return len;
+  return linux_common_xfer_osdata (annex, readbuf, offset, len);
 }
 
 static LONGEST
Index: gdb/utils.c
===================================================================
RCS file: /cvs/src/src/gdb/utils.c,v
retrieving revision 1.257
diff -u -p -r1.257 utils.c
--- gdb/utils.c	27 May 2011 14:00:25 -0000	1.257
+++ gdb/utils.c	12 Jul 2011 15:32:39 -0000
@@ -1210,7 +1210,7 @@ quit (void)
    memory requested in SIZE.  */
 
 void
-nomem (long size)
+malloc_failure (long size)
 {
   if (size > 0)
     {
@@ -1224,146 +1224,6 @@ nomem (long size)
     }
 }
 
-/* The xmalloc() (libiberty.h) family of memory management routines.
-
-   These are like the ISO-C malloc() family except that they implement
-   consistent semantics and guard against typical memory management
-   problems.  */
-
-/* NOTE: These are declared using PTR to ensure consistency with
-   "libiberty.h".  xfree() is GDB local.  */
-
-PTR				/* ARI: PTR */
-xmalloc (size_t size)
-{
-  void *val;
-
-  /* See libiberty/xmalloc.c.  This function need's to match that's
-     semantics.  It never returns NULL.  */
-  if (size == 0)
-    size = 1;
-
-  val = malloc (size);		/* ARI: malloc */
-  if (val == NULL)
-    nomem (size);
-
-  return (val);
-}
-
-void *
-xzalloc (size_t size)
-{
-  return xcalloc (1, size);
-}
-
-PTR				/* ARI: PTR */
-xrealloc (PTR ptr, size_t size)	/* ARI: PTR */
-{
-  void *val;
-
-  /* See libiberty/xmalloc.c.  This function need's to match that's
-     semantics.  It never returns NULL.  */
-  if (size == 0)
-    size = 1;
-
-  if (ptr != NULL)
-    val = realloc (ptr, size);	/* ARI: realloc */
-  else
-    val = malloc (size);		/* ARI: malloc */
-  if (val == NULL)
-    nomem (size);
-
-  return (val);
-}
-
-PTR				/* ARI: PTR */
-xcalloc (size_t number, size_t size)
-{
-  void *mem;
-
-  /* See libiberty/xmalloc.c.  This function need's to match that's
-     semantics.  It never returns NULL.  */
-  if (number == 0 || size == 0)
-    {
-      number = 1;
-      size = 1;
-    }
-
-  mem = calloc (number, size);		/* ARI: xcalloc */
-  if (mem == NULL)
-    nomem (number * size);
-
-  return mem;
-}
-
-void
-xfree (void *ptr)
-{
-  if (ptr != NULL)
-    free (ptr);		/* ARI: free */
-}
-\f
-
-/* Like asprintf/vasprintf but get an internal_error if the call
-   fails.  */
-
-char *
-xstrprintf (const char *format, ...)
-{
-  char *ret;
-  va_list args;
-
-  va_start (args, format);
-  ret = xstrvprintf (format, args);
-  va_end (args);
-  return ret;
-}
-
-void
-xasprintf (char **ret, const char *format, ...)
-{
-  va_list args;
-
-  va_start (args, format);
-  (*ret) = xstrvprintf (format, args);
-  va_end (args);
-}
-
-void
-xvasprintf (char **ret, const char *format, va_list ap)
-{
-  (*ret) = xstrvprintf (format, ap);
-}
-
-char *
-xstrvprintf (const char *format, va_list ap)
-{
-  char *ret = NULL;
-  int status = vasprintf (&ret, format, ap);
-
-  /* NULL is returned when there was a memory allocation problem, or
-     any other error (for instance, a bad format string).  A negative
-     status (the printed length) with a non-NULL buffer should never
-     happen, but just to be sure.  */
-  if (ret == NULL || status < 0)
-    internal_error (__FILE__, __LINE__, _("vasprintf call failed"));
-  return ret;
-}
-
-int
-xsnprintf (char *str, size_t size, const char *format, ...)
-{
-  va_list args;
-  int ret;
-
-  va_start (args, format);
-  ret = vsnprintf (str, size, format, args);
-  gdb_assert (ret < size);
-  va_end (args);
-
-  return ret;
-}
-
 /* My replacement for the read system call.
    Used like `read' but keeps going if `read' returns too soon.  */
 
@@ -1385,7 +1245,7 @@ myread (int desc, char *addr, int len)
     }
   return orglen;
 }
-\f
+
 /* Make a copy of the string at PTR with SIZE characters
    (and add a null character at the end in the copy).
    Uses malloc to get the space.  Returns the address of the copy.  */
@@ -3741,7 +3601,7 @@ gdb_buildargv (const char *s)
   char **argv = buildargv (s);
 
   if (s != NULL && argv == NULL)
-    nomem (0);
+    malloc_failure (0);
   return argv;
 }
 
Index: gdb/xml-support.c
===================================================================
RCS file: /cvs/src/src/gdb/xml-support.c,v
retrieving revision 1.24
diff -u -p -r1.24 xml-support.c
--- gdb/xml-support.c	2 Feb 2011 16:12:59 -0000	1.24
+++ gdb/xml-support.c	12 Jul 2011 15:32:39 -0000
@@ -458,7 +458,7 @@ gdb_xml_create_parser_and_cleanup_1 (con
   if (parser->expat_parser == NULL)
     {
       xfree (parser);
-      nomem (0);
+      malloc_failure (0);
     }
 
   parser->name = name;
@@ -990,68 +990,6 @@ show_debug_xml (struct ui_file *file, in
   fprintf_filtered (file, _("XML debugging is %s.\n"), value);
 }
 
-/* Return a malloc allocated string with special characters from TEXT
-   replaced by entity references.  */
-
-char *
-xml_escape_text (const char *text)
-{
-  char *result;
-  int i, special;
-
-  /* Compute the length of the result.  */
-  for (i = 0, special = 0; text[i] != '\0'; i++)
-    switch (text[i])
-      {
-      case '\'':
-      case '\"':
-	special += 5;
-	break;
-      case '&':
-	special += 4;
-	break;
-      case '<':
-      case '>':
-	special += 3;
-	break;
-      default:
-	break;
-      }
-
-  /* Expand the result.  */
-  result = xmalloc (i + special + 1);
-  for (i = 0, special = 0; text[i] != '\0'; i++)
-    switch (text[i])
-      {
-      case '\'':
-	strcpy (result + i + special, "&apos;");
-	special += 5;
-	break;
-      case '\"':
-	strcpy (result + i + special, "&quot;");
-	special += 5;
-	break;
-      case '&':
-	strcpy (result + i + special, "&amp;");
-	special += 4;
-	break;
-      case '<':
-	strcpy (result + i + special, "&lt;");
-	special += 3;
-	break;
-      case '>':
-	strcpy (result + i + special, "&gt;");
-	special += 3;
-	break;
-      default:
-	result[i + special] = text[i];
-	break;
-      }
-  result[i + special] = '\0';
-
-  return result;
-}
-
 void
 obstack_xml_printf (struct obstack *obstack, const char *format, ...)
 {
@@ -1106,7 +1044,7 @@ xml_fetch_content_from_file (const char 
       char *fullname = concat (dirname, "/", filename, (char *) NULL);
 
       if (fullname == NULL)
-	nomem (0);
+	malloc_failure (0);
       file = fopen (fullname, FOPEN_RT);
       xfree (fullname);
     }
Index: gdb/xml-support.h
===================================================================
RCS file: /cvs/src/src/gdb/xml-support.h,v
retrieving revision 1.19
diff -u -p -r1.19 xml-support.h
--- gdb/xml-support.h	2 Feb 2011 16:12:59 -0000	1.19
+++ gdb/xml-support.h	12 Jul 2011 15:32:39 -0000
@@ -24,6 +24,7 @@
 
 #include "gdb_obstack.h"
 #include "vec.h"
+#include "xml-utils.h"
 
 struct gdb_xml_parser;
 struct gdb_xml_element;
@@ -48,11 +49,6 @@ LONGEST xml_builtin_xfer_partial (const 
 
 extern const char *xml_builtin[][2];
 
-/* Return a malloc allocated string with special characters from TEXT
-   replaced by entity references.  */
-
-char *xml_escape_text (const char *text);
-
 /* Support for XInclude.  */
 
 /* Callback to fetch a new XML file, based on the provided HREF.  */
Index: gdb/common/buffer.c
===================================================================
RCS file: gdb/common/buffer.c
diff -N gdb/common/buffer.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/buffer.c	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,144 @@
+/* A simple growing buffer for GDB.
+  
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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 GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#endif
+
+#include "xml-utils.h"
+#include "buffer.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+void
+buffer_grow (struct buffer *buffer, const char *data, size_t size)
+{
+  char *new_buffer;
+  size_t new_buffer_size;
+
+  if (size == 0)
+    return;
+
+  new_buffer_size = buffer->buffer_size;
+
+  if (new_buffer_size == 0)
+    new_buffer_size = 1;
+
+  while (buffer->used_size + size > new_buffer_size)
+    new_buffer_size *= 2;
+  new_buffer = xrealloc (buffer->buffer, new_buffer_size);
+  if (!new_buffer)
+    abort ();
+  memcpy (new_buffer + buffer->used_size, data, size);
+  buffer->buffer = new_buffer;
+  buffer->buffer_size = new_buffer_size;
+  buffer->used_size += size;
+}
+
+void
+buffer_free (struct buffer *buffer)
+{
+  if (!buffer)
+    return;
+
+  xfree (buffer->buffer);
+  buffer->buffer = NULL;
+  buffer->buffer_size = 0;
+  buffer->used_size = 0;
+}
+
+void
+buffer_init (struct buffer *buffer)
+{
+  memset (buffer, 0, sizeof (*buffer));
+}
+
+char*
+buffer_finish (struct buffer *buffer)
+{
+  char *ret = buffer->buffer;
+  buffer->buffer = NULL;
+  buffer->buffer_size = 0;
+  buffer->used_size = 0;
+  return ret;
+}
+
+void
+buffer_xml_printf (struct buffer *buffer, const char *format, ...)
+{
+  va_list ap;
+  const char *f;
+  const char *prev;
+  int percent = 0;
+
+  va_start (ap, format);
+
+  prev = format;
+  for (f = format; *f; f++)
+    {
+      if (percent)
+	{
+	  char buf[32];
+	  char *p;
+	  char *str = buf;
+	  
+	  switch (*f)
+	    {
+	    case 's':
+	      str = va_arg (ap, char *);
+	      break;
+	    case 'd':
+	      sprintf (str, "%d", va_arg (ap, int));
+	      break;
+	    case 'u':
+	      sprintf (str, "%u", va_arg (ap, unsigned int));
+	      break;
+	    case 'x':
+	      sprintf (str, "%x", va_arg (ap, unsigned int));
+	      break;
+	    case 'o':
+	      sprintf (str, "%o", va_arg (ap, unsigned int));
+	      break;
+	    default:
+	      str = 0;
+	      break;
+	    }
+	  
+	  if (str)
+	    {
+	      buffer_grow (buffer, prev, f - prev - 1);
+	      p = xml_escape_text (str);
+	      buffer_grow_str (buffer, p);
+	      xfree (p);
+	      prev = f + 1;
+	    }
+	  percent = 0;
+	}
+      else if (*f == '%')
+	percent = 1;
+    }
+
+  buffer_grow_str (buffer, prev);
+  va_end (ap);
+}
+
Index: gdb/common/buffer.h
===================================================================
RCS file: gdb/common/buffer.h
diff -N gdb/common/buffer.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/buffer.h	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,63 @@
+/* A simple growing buffer for GDB.
+  
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef BUFFER_H
+#define BUFFER_H
+
+#include <stddef.h>
+#include <string.h>
+#include "ansidecl.h"
+
+struct buffer
+{
+  char *buffer;
+  size_t buffer_size; /* allocated size */
+  size_t used_size; /* actually used size */
+};
+
+/* Append DATA of size SIZE to the end of BUFFER.  Grows the buffer to
+   accommodate the new data.  */
+void buffer_grow (struct buffer *buffer, const char *data, size_t size);
+
+/* Release any memory held by BUFFER.  */
+void buffer_free (struct buffer *buffer);
+
+/* Initialize BUFFER.  BUFFER holds no memory afterwards.  */
+void buffer_init (struct buffer *buffer);
+
+/* Return a pointer into BUFFER data, effectivelly transfering
+   ownership of the buffer memory to the caller.  Calling buffer_free
+   afterwards has no effect on the returned data.  */
+char* buffer_finish (struct buffer *buffer);
+
+/* Simple printf to buffer function.  Current implemented formatters:
+   %s - grow an xml escaped text in BUFFER.
+   %d - grow an signed integer in BUFFER.
+   %u - grow an unsigned integer in BUFFER.
+   %x - grow an unsigned integer formatted in hexadecimal in BUFFER.
+   %o - grow an unsigned integer formatted in octal in BUFFER.  */
+void buffer_xml_printf (struct buffer *buffer, const char *format, ...)
+  ATTRIBUTE_PRINTF (2, 3);
+
+#define buffer_grow_str(BUFFER,STRING)		\
+  buffer_grow (BUFFER, STRING, strlen (STRING))
+#define buffer_grow_str0(BUFFER,STRING)			\
+  buffer_grow (BUFFER, STRING, strlen (STRING) + 1)
+
+#endif
Index: gdb/common/common-utils.c
===================================================================
RCS file: gdb/common/common-utils.c
diff -N gdb/common/common-utils.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/common-utils.c	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,170 @@
+/* Shared general utility routines for GDB, the GNU debugger.
+
+   Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+   2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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 GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#endif
+
+#include "gdb_assert.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* The xmalloc() (libiberty.h) family of memory management routines.
+
+   These are like the ISO-C malloc() family except that they implement
+   consistent semantics and guard against typical memory management
+   problems.  */
+
+/* NOTE: These are declared using PTR to ensure consistency with
+   "libiberty.h".  xfree() is GDB local.  */
+
+PTR                            /* ARI: PTR */
+xmalloc (size_t size)
+{
+  void *val;
+
+  /* See libiberty/xmalloc.c.  This function need's to match that's
+     semantics.  It never returns NULL.  */
+  if (size == 0)
+    size = 1;
+
+  val = malloc (size);         /* ARI: malloc */
+  if (val == NULL)
+    malloc_failure (size);
+
+  return val;
+}
+
+PTR                              /* ARI: PTR */
+xrealloc (PTR ptr, size_t size)          /* ARI: PTR */
+{
+  void *val;
+
+  /* See libiberty/xmalloc.c.  This function need's to match that's
+     semantics.  It never returns NULL.  */
+  if (size == 0)
+    size = 1;
+
+  if (ptr != NULL)
+    val = realloc (ptr, size);	/* ARI: realloc */
+  else
+    val = malloc (size);	        /* ARI: malloc */
+  if (val == NULL)
+    malloc_failure (size);
+
+  return val;
+}
+
+PTR                            /* ARI: PTR */           
+xcalloc (size_t number, size_t size)
+{
+  void *mem;
+
+  /* See libiberty/xmalloc.c.  This function need's to match that's
+     semantics.  It never returns NULL.  */
+  if (number == 0 || size == 0)
+    {
+      number = 1;
+      size = 1;
+    }
+
+  mem = calloc (number, size);      /* ARI: xcalloc */
+  if (mem == NULL)
+    malloc_failure (number * size);
+
+  return mem;
+}
+
+void *
+xzalloc (size_t size)
+{
+  return xcalloc (1, size);
+}
+
+void
+xfree (void *ptr)
+{
+  if (ptr != NULL)
+    free (ptr);		/* ARI: free */
+}
+
+/* Like asprintf/vasprintf but get an internal_error if the call
+   fails. */
+
+char *
+xstrprintf (const char *format, ...)
+{
+  char *ret;
+  va_list args;
+
+  va_start (args, format);
+  ret = xstrvprintf (format, args);
+  va_end (args);
+  return ret;
+}
+
+char *
+xstrvprintf (const char *format, va_list ap)
+{
+  char *ret = NULL;
+  int status = vasprintf (&ret, format, ap);
+
+  /* NULL is returned when there was a memory allocation problem, or
+     any other error (for instance, a bad format string).  A negative
+     status (the printed length) with a non-NULL buffer should never
+     happen, but just to be sure.  */
+  if (ret == NULL || status < 0)
+    internal_error (__FILE__, __LINE__, _("vasprintf call failed"));
+  return ret;
+}
+
+void
+xasprintf (char **ret, const char *format, ...)
+{
+  va_list args;
+
+  va_start (args, format);
+  (*ret) = xstrvprintf (format, args);
+  va_end (args);
+}
+
+void
+xvasprintf (char **ret, const char *format, va_list ap)
+{
+  (*ret) = xstrvprintf (format, ap);
+}
+
+int
+xsnprintf (char *str, size_t size, const char *format, ...)
+{
+  va_list args;
+  int ret;
+
+  va_start (args, format);
+  ret = vsnprintf (str, size, format, args);
+  gdb_assert (ret < size);
+  va_end (args);
+
+  return ret;
+}
Index: gdb/common/common-utils.h
===================================================================
RCS file: gdb/common/common-utils.h
diff -N gdb/common/common-utils.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/common-utils.h	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,59 @@
+/* Shared general utility routines for GDB, the GNU debugger.
+
+   Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+   2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef COMMON_UTILS_H
+#define COMMON_UTILS_H
+
+#include "config.h"
+#include "ansidecl.h"
+#include <stddef.h>
+#include <stdarg.h>
+
+extern void malloc_failure (long size) ATTRIBUTE_NORETURN;
+extern void internal_error (const char *file, int line, const char *, ...)
+     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 4);
+
+/* xmalloc(), xrealloc() and xcalloc() have already been declared in
+   "libiberty.h". */
+
+/* Like xmalloc, but zero the memory.  */
+void *xzalloc (size_t);
+
+void xfree (void *);
+
+/* Like asprintf and vasprintf, but return the string, throw an error
+   if no memory.  */
+char *xstrprintf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
+char *xstrvprintf (const char *format, va_list ap)
+     ATTRIBUTE_PRINTF (1, 0);
+
+/* Like asprintf/vasprintf but get an internal_error if the call
+   fails.  */
+void xasprintf (char **ret, const char *format, ...)
+     ATTRIBUTE_PRINTF (2, 3);
+void xvasprintf (char **ret, const char *format, va_list ap)
+     ATTRIBUTE_PRINTF (2, 0);
+
+/* Like snprintf, but throw an error if the output buffer is too small.  */
+int xsnprintf (char *str, size_t size, const char *format, ...)
+     ATTRIBUTE_PRINTF (3, 4);
+
+#endif
Index: gdb/common/gdb_assert.h
===================================================================
RCS file: gdb/common/gdb_assert.h
diff -N gdb/common/gdb_assert.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/gdb_assert.h	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,68 @@
+/* GDB-friendly replacement for <assert.h>.
+   Copyright (C) 2000, 2001, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_ASSERT_H
+#define GDB_ASSERT_H
+
+/* PRAGMATICS: "gdb_assert.h":gdb_assert() is a lower case (rather
+   than upper case) macro since that provides the closest fit to the
+   existing lower case macro <assert.h>:assert() that it is
+   replacing.  */
+
+#define gdb_assert(expr)                                                      \
+  ((void) ((expr) ? 0 :                                                       \
+	   (gdb_assert_fail (#expr, __FILE__, __LINE__, ASSERT_FUNCTION), 0)))
+
+/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
+   which contains the name of the function currently being defined.
+   This is broken in G++ before version 2.6.
+   C9x has a similar variable called __func__, but prefer the GCC one since
+   it demangles C++ function names.  */
+#if (GCC_VERSION >= 2004)
+#define ASSERT_FUNCTION		__PRETTY_FUNCTION__
+#else
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#define ASSERT_FUNCTION		__func__
+#endif
+#endif
+
+/* This prints an "Assertion failed" message, asking the user if they
+   want to continue, dump core, or just exit.  */
+#if defined (ASSERT_FUNCTION)
+#define gdb_assert_fail(assertion, file, line, function)                      \
+  internal_error (file, line, _("%s: Assertion `%s' failed."),                \
+		  function, assertion)
+#else
+#define gdb_assert_fail(assertion, file, line, function)                      \
+  internal_error (file, line, _("Assertion `%s' failed."),                    \
+		  assertion)
+#endif
+
+/* The canonical form of gdb_assert (0).
+   MESSAGE is a string to include in the error message.  */
+
+#if defined (ASSERT_FUNCTION)
+#define gdb_assert_not_reached(message) \
+  internal_error (__FILE__, __LINE__, "%s: %s", ASSERT_FUNCTION, _(message))
+#else
+#define gdb_assert_not_reached(message) \
+  internal_error (__FILE__, __LINE__, _(message))
+#endif
+
+#endif /* gdb_assert.h */
Index: gdb/common/gdb_dirent.h
===================================================================
RCS file: gdb/common/gdb_dirent.h
diff -N gdb/common/gdb_dirent.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/gdb_dirent.h	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,41 @@
+/* Portable <dirent.h>.
+   Copyright (C) 2000, 2002, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_DIRENT_H
+#define GDB_DIRENT_H 1
+
+/* See description of `AC_HEADER_DIRENT' in the Autoconf manual.  */
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>		/* ARI: dirent.h */
+# define NAMELEN(dirent) strlen ((dirent)->d_name)    /* ARI: strlen d_name */
+#else
+# define dirent direct
+# define NAMELEN(dirent) (dirent)->d_namelen	/* ARI: d_namelen */
+# ifdef HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+#endif /* not GDB_DIRENT_H */
Index: gdb/common/gdb_locale.h
===================================================================
RCS file: gdb/common/gdb_locale.h
diff -N gdb/common/gdb_locale.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/gdb_locale.h	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,49 @@
+/* GDB-friendly replacement for <locale.h>.
+   Copyright (C) 2002, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_LOCALE_H
+#define GDB_LOCALE_H
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext (String)
+# ifdef gettext_noop
+#  define N_(String) gettext_noop (String)
+# else
+#  define N_(String) (String)
+# endif
+#else
+# define gettext(Msgid) (Msgid)
+# define dgettext(Domainname, Msgid) (Msgid)
+# define dcgettext(Domainname, Msgid, Category) (Msgid)
+# define textdomain(Domainname) while (0) /* nothing */
+# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */
+# define _(String) (String)
+# define N_(String) (String)
+#endif
+
+#ifdef HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
+#endif /* GDB_LOCALE_H */
Index: gdb/common/linux-osdata.c
===================================================================
RCS file: gdb/common/linux-osdata.c
diff -N gdb/common/linux-osdata.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/linux-osdata.c	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,586 @@
+/* Linux-specific functions to retrieve OS data.
+   
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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 GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#endif
+
+#include "linux-osdata.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+#include <time.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "xml-utils.h"
+#include "buffer.h"
+#include "gdb_assert.h"
+#include "gdb_dirent.h"
+
+int
+linux_common_core_of_thread (ptid_t ptid)
+{
+  char filename[sizeof ("/proc//task//stat")
+		 + 2 * 20 /* decimal digits for 2 numbers, max 2^64 bit each */
+		 + 1];
+  FILE *f;
+  char *content = NULL;
+  char *p;
+  char *ts = 0;
+  int content_read = 0;
+  int i;
+  int core;
+
+  sprintf (filename, "/proc/%d/task/%ld/stat",
+	   ptid_get_pid (ptid), ptid_get_lwp (ptid));
+  f = fopen (filename, "r");
+  if (!f)
+    return -1;
+
+  for (;;)
+    {
+      int n;
+      content = xrealloc (content, content_read + 1024);
+      n = fread (content + content_read, 1, 1024, f);
+      content_read += n;
+      if (n < 1024)
+	{
+	  content[content_read] = '\0';
+	  break;
+	}
+    }
+
+  p = strchr (content, '(');
+
+  /* Skip ")".  */
+  if (p != NULL)
+    p = strchr (p, ')');
+  if (p != NULL)
+    p++;
+
+  /* If the first field after program name has index 0, then core number is
+     the field with index 36.  There's no constant for that anywhere.  */
+  if (p != NULL)
+    p = strtok_r (p, " ", &ts);
+  for (i = 0; p != NULL && i != 36; ++i)
+    p = strtok_r (NULL, " ", &ts);
+
+  if (p == NULL || sscanf (p, "%d", &core) == 0)
+    core = -1;
+
+  xfree (content);
+  fclose (f);
+
+  return core;
+}
+
+static void
+command_from_pid (char *command, int maxlen, pid_t pid)
+{
+  char *stat_path = xstrprintf ("/proc/%d/stat", pid); 
+  FILE *fp = fopen (stat_path, "r");
+  
+  command[0] = '\0';
+ 
+  if (fp)
+    {
+      /* sizeof (cmd) should be greater or equal to TASK_COMM_LEN (in
+	 include/linux/sched.h in the Linux kernel sources) plus two
+	 (for the brackets).  */
+      char cmd[32]; 
+      pid_t stat_pid;
+      int items_read = fscanf (fp, "%d %32s", &stat_pid, cmd);
+	  
+      if (items_read == 2 && pid == stat_pid)
+	{
+	  cmd[strlen (cmd) - 1] = '\0'; /* Remove trailing parenthesis.  */
+	  strncpy (command, cmd + 1, maxlen); /* Ignore leading parenthesis.  */
+	}
+
+      fclose (fp);
+    }
+  else
+    {
+      /* Return the PID if a /proc entry for the process cannot be found.  */
+      snprintf (command, maxlen, "%d", pid);
+    }
+
+  command[maxlen - 1] = '\0'; /* Ensure string is null-terminated.  */
+	
+  xfree (stat_path);
+}
+
+/* Returns the command-line of the process with the given PID. The returned
+   string needs to be freed using xfree after use.  */
+
+static char *
+commandline_from_pid (pid_t pid)
+{
+  char *pathname = xstrprintf ("/proc/%d/cmdline", pid);
+  char *commandline = NULL;
+  FILE *f = fopen (pathname, "r");
+
+  if (f)
+    {
+      size_t len = 0;
+
+      while (!feof (f))
+	{
+	  char buf[1024];
+	  size_t read_bytes = fread (buf, 1, sizeof (buf), f);
+     
+	  if (read_bytes)
+	    {
+	      commandline = (char *) xrealloc (commandline, len + read_bytes + 1);
+	      memcpy (commandline + len, buf, read_bytes);
+	      len += read_bytes;
+	    }
+	}
+
+      fclose (f);
+
+      if (commandline)
+	{
+	  size_t i;
+
+	  /* Replace null characters with spaces.  */
+	  for (i = 0; i < len; ++i)
+	    if (commandline[i] == '\0')
+	      commandline[i] = ' ';
+
+	  commandline[len] = '\0';
+	}
+      else
+	{
+	  /* Return the command in square brackets if the command-line is empty.  */
+	  commandline = (char *) xmalloc (32);
+	  commandline[0] = '[';
+	  command_from_pid (commandline + 1, 31, pid);
+
+	  len = strlen (commandline);
+	  if (len < 31)
+	    strcat (commandline, "]");
+	}
+    }
+
+  xfree (pathname);
+
+  return commandline;
+}
+
+static void
+user_from_uid (char *user, int maxlen, uid_t uid)
+{
+  struct passwd *pwentry = getpwuid (uid);
+  
+  if (pwentry)
+    {
+      strncpy (user, pwentry->pw_name, maxlen);
+      user[maxlen - 1] = '\0'; /* Ensure that the user name is null-terminated.  */
+    }
+  else
+    user[0] = '\0';
+}
+
+static int
+get_process_owner (uid_t *owner, pid_t pid)
+{
+  struct stat statbuf;
+  char procentry[sizeof ("/proc/4294967295")];
+
+  sprintf (procentry, "/proc/%d", pid);
+  
+  if (stat (procentry, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
+    {
+      *owner = statbuf.st_uid;
+      return 0;
+    }
+  else
+    return -1;
+}
+
+static int
+get_number_of_cpu_cores (void)
+{
+  int cores = 0;
+  FILE *f = fopen ("/proc/cpuinfo", "r");
+
+  while (!feof (f))
+    {
+      char buf[512];
+      char *p = fgets (buf, sizeof (buf), f);
+
+      if (p && strncmp (buf, "processor", 9) == 0)
+	++cores;
+    }
+
+  fclose (f);
+
+  return cores;
+}
+
+/* CORES points to an array of at least get_number_of_cpu_cores () elements.  */
+
+static int
+get_cores_used_by_process (pid_t pid, int *cores)
+{
+  char taskdir[sizeof ("/proc/4294967295/task")];
+  DIR *dir;
+  struct dirent *dp;
+  int task_count = 0;
+
+  sprintf (taskdir, "/proc/%d/task", pid);
+  dir = opendir (taskdir);
+
+  while ((dp = readdir (dir)) != NULL)
+    {
+      pid_t tid;
+      int core;
+
+      if (!isdigit (dp->d_name[0])
+	  || NAMELEN (dp) > sizeof ("4294967295") - 1)
+	continue;
+
+      tid = atoi (dp->d_name);
+      core = linux_common_core_of_thread (ptid_build (pid, tid, 0));
+
+      if (core >= 0)
+	{
+	  ++cores[core];
+	  ++task_count;
+	}
+    }
+
+  closedir (dir);
+
+  return task_count;
+}
+
+static LONGEST
+linux_xfer_osdata_processes (gdb_byte *readbuf,
+			     ULONGEST offset, LONGEST len)
+{
+  /* We make the process list snapshot when the object starts to be read.  */
+  static const char *buf;
+  static LONGEST len_avail = -1;
+  static struct buffer buffer;
+
+  if (offset == 0)
+    {
+      DIR *dirp;
+
+      if (len_avail != -1 && len_avail != 0)
+	buffer_free (&buffer);
+      len_avail = 0;
+      buf = NULL;
+      buffer_init (&buffer);
+      buffer_grow_str (&buffer, "<osdata type=\"processes\">\n");
+
+      dirp = opendir ("/proc");
+      if (dirp)
+	{
+	  const int num_cores = get_number_of_cpu_cores ();
+	  struct dirent *dp;
+
+	  while ((dp = readdir (dirp)) != NULL)
+	    {
+	      pid_t pid;
+	      uid_t owner;
+	      char user[UT_NAMESIZE];
+	      char *command_line;
+	      int *cores;
+	      int task_count;
+	      char *cores_str;
+	      int i;
+
+	      if (!isdigit (dp->d_name[0])
+		  || NAMELEN (dp) > sizeof ("4294967295") - 1)
+		continue;
+
+	      sscanf (dp->d_name, "%d", &pid);
+	      command_line = commandline_from_pid (pid);
+
+	      if (get_process_owner (&owner, pid) == 0)
+		user_from_uid (user, sizeof (user), owner);
+	      else
+		strcpy (user, "?");
+
+	      /* Find CPU cores used by the process.  */
+	      cores = (int *) xcalloc (num_cores, sizeof (int));
+	      task_count = get_cores_used_by_process (pid, cores);
+	      cores_str = (char *) xcalloc (task_count, sizeof ("4294967295") + 1);
+
+	      for (i = 0; i < num_cores && task_count > 0; ++i)
+		if (cores[i])
+		  {
+		    char core_str[sizeof ("4294967205")];
+
+		    sprintf (core_str, "%d", i);
+		    strcat (cores_str, core_str);
+
+		    task_count -= cores[i];
+		    if (task_count > 0)
+		      strcat (cores_str, ",");
+		  }
+
+	      xfree (cores);
+	      
+	      buffer_xml_printf (
+		  &buffer,
+		  "<item>"
+		  "<column name=\"pid\">%d</column>"
+		  "<column name=\"user\">%s</column>"
+		  "<column name=\"command\">%s</column>"
+		  "<column name=\"cores\">%s</column>"
+		  "</item>",
+		  pid,
+		  user,
+		  command_line ? command_line : "",
+		  cores_str);
+
+	      xfree (command_line);     
+	      xfree (cores_str);
+	    }
+	  
+	  closedir (dirp);
+	}
+
+      buffer_grow_str0 (&buffer, "</osdata>\n");
+      buf = buffer_finish (&buffer);
+      len_avail = strlen (buf);
+    }
+
+  if (offset >= len_avail)
+    {
+      /* Done.  Get rid of the buffer.  */
+      buffer_free (&buffer);
+      buf = NULL;
+      len_avail = 0;
+      return 0;
+    }
+
+  if (len > len_avail - offset)
+    len = len_avail - offset;
+  memcpy (readbuf, buf + offset, len);
+
+  return len;
+}
+
+static LONGEST
+linux_xfer_osdata_threads (gdb_byte *readbuf,
+			   ULONGEST offset, LONGEST len)
+{
+  /* We make the process list snapshot when the object starts to be read.  */
+  static const char *buf;
+  static LONGEST len_avail = -1;
+  static struct buffer buffer;
+
+  if (offset == 0)
+    {
+      DIR *dirp;
+
+      if (len_avail != -1 && len_avail != 0)
+	buffer_free (&buffer);
+      len_avail = 0;
+      buf = NULL;
+      buffer_init (&buffer);
+      buffer_grow_str (&buffer, "<osdata type=\"threads\">\n");
+
+      dirp = opendir ("/proc");
+      if (dirp)
+	{
+	  struct dirent *dp;
+
+	  while ((dp = readdir (dirp)) != NULL)
+	    {
+	      struct stat statbuf;
+	      char procentry[sizeof ("/proc/4294967295")];
+
+	      if (!isdigit (dp->d_name[0])
+		  || NAMELEN (dp) > sizeof ("4294967295") - 1)
+		continue;
+
+	      sprintf (procentry, "/proc/%s", dp->d_name);
+	      if (stat (procentry, &statbuf) == 0
+		  && S_ISDIR (statbuf.st_mode))
+		{
+		  DIR *dirp2;
+		  char *pathname;
+		  pid_t pid;
+		  char command[32];
+
+		  pathname = xstrprintf ("/proc/%s/task", dp->d_name);
+		  
+		  pid = atoi (dp->d_name);
+		  command_from_pid (command, sizeof (command), pid);
+
+		  dirp2 = opendir (pathname);
+
+		  if (dirp2)
+		    {
+		      struct dirent *dp2;
+
+		      while ((dp2 = readdir (dirp2)) != NULL)
+			{
+			  pid_t tid;
+			  int core;
+
+			  if (!isdigit (dp2->d_name[0])
+			      || NAMELEN (dp2) > sizeof ("4294967295") - 1)
+			    continue;
+
+			  tid = atoi (dp2->d_name);
+			  core = linux_common_core_of_thread (ptid_build (pid, tid, 0));
+
+			  buffer_xml_printf (
+			    &buffer,
+			    "<item>"
+			    "<column name=\"pid\">%d</column>"
+			    "<column name=\"command\">%s</column>"
+			    "<column name=\"tid\">%d</column>"
+			    "<column name=\"core\">%d</column>"
+			    "</item>",
+			    pid,
+			    command,
+			    tid,
+			    core);
+			}
+
+		      closedir (dirp2);
+		    }
+
+		  xfree (pathname);
+		}
+	    }
+
+	  closedir (dirp);
+	}
+
+      buffer_grow_str0 (&buffer, "</osdata>\n");
+      buf = buffer_finish (&buffer);
+      len_avail = strlen (buf);
+    }
+
+  if (offset >= len_avail)
+    {
+      /* Done.  Get rid of the buffer.  */
+      buffer_free (&buffer);
+      buf = NULL;
+      len_avail = 0;
+      return 0;
+    }
+
+  if (len > len_avail - offset)
+    len = len_avail - offset;
+  memcpy (readbuf, buf + offset, len);
+
+  return len;
+}
+
+struct osdata_type {
+  char *type;
+  char *description;
+  LONGEST (*getter) (gdb_byte *readbuf, ULONGEST offset, LONGEST len);
+} osdata_table[] = {
+  { "processes", "Listing of all processes", linux_xfer_osdata_processes },
+  { "threads", "Listing of all threads", linux_xfer_osdata_threads },
+  { NULL, NULL, NULL }
+};
+
+LONGEST
+linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
+			  ULONGEST offset, LONGEST len)
+{
+  if (!annex || *annex == '\0')
+    {
+      static const char *buf;
+      static LONGEST len_avail = -1;
+      static struct buffer buffer;
+
+      if (offset == 0)
+	{
+	  int i;
+
+	  if (len_avail != -1 && len_avail != 0)
+	    buffer_free (&buffer);
+	  len_avail = 0;
+	  buf = NULL;
+	  buffer_init (&buffer);
+	  buffer_grow_str (&buffer, "<osdata type=\"types\">\n");
+
+	  for (i = 0; osdata_table[i].type; ++i)
+	    buffer_xml_printf (
+			       &buffer,
+			       "<item>"
+			       "<column name=\"Type\">%s</column>"
+			       "<column name=\"Description\">%s</column>"
+			       "</item>",
+			       osdata_table[i].type,
+			       osdata_table[i].description);
+
+	  buffer_grow_str0 (&buffer, "</osdata>\n");
+	  buf = buffer_finish (&buffer);
+	  len_avail = strlen (buf);
+	}
+
+      if (offset >= len_avail)
+	{
+	  /* Done.  Get rid of the buffer.  */
+	  buffer_free (&buffer);
+	  buf = NULL;
+	  len_avail = 0;
+	  return 0;
+	}
+
+      if (len > len_avail - offset)
+	len = len_avail - offset;
+      memcpy (readbuf, buf + offset, len);
+
+      return len;
+    }
+  else
+    {
+      int i;
+
+      for (i = 0; osdata_table[i].type; ++i)
+	{
+	  if (strcmp (annex, osdata_table[i].type) == 0)
+	    {
+	      gdb_assert (readbuf);
+	      
+	      return (osdata_table[i].getter) (readbuf, offset, len);
+	    }
+	}
+
+      return 0;
+    }
+}
+
Index: gdb/common/linux-osdata.h
===================================================================
RCS file: gdb/common/linux-osdata.h
diff -N gdb/common/linux-osdata.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/linux-osdata.h	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,29 @@
+/* Linux-specific functions to retrieve OS data.
+   
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef COMMON_LINUX_OSDATA_H
+#define COMMON_LINUX_OSDATA_H
+
+#include "ptid.h"
+
+extern int linux_common_core_of_thread (ptid_t ptid);
+extern LONGEST linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
+					 ULONGEST offset, LONGEST len);
+
+#endif
Index: gdb/common/ptid.c
===================================================================
RCS file: gdb/common/ptid.c
diff -N gdb/common/ptid.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/ptid.c	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,94 @@
+/* The ptid_t type and common functions operating on it.
+
+   Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+   2009, 2010 Free Software Foundation, Inc.
+   
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "ptid.h"
+
+/* Oft used ptids */
+ptid_t null_ptid = { 0, 0, 0 };
+ptid_t minus_one_ptid = { -1, 0, 0 };
+
+/* Create a ptid given the necessary PID, LWP, and TID components.  */
+
+ptid_t
+ptid_build (int pid, long lwp, long tid)
+{
+  ptid_t ptid;
+
+  ptid.pid = pid;
+  ptid.lwp = lwp;
+  ptid.tid = tid;
+  return ptid;
+}
+
+/* Create a ptid from just a pid.  */
+
+ptid_t
+pid_to_ptid (int pid)
+{
+  return ptid_build (pid, 0, 0);
+}
+
+/* Fetch the pid (process id) component from a ptid.  */
+
+int
+ptid_get_pid (ptid_t ptid)
+{
+  return ptid.pid;
+}
+
+/* Fetch the lwp (lightweight process) component from a ptid.  */
+
+long
+ptid_get_lwp (ptid_t ptid)
+{
+  return ptid.lwp;
+}
+
+/* Fetch the tid (thread id) component from a ptid.  */
+
+long
+ptid_get_tid (ptid_t ptid)
+{
+  return ptid.tid;
+}
+
+/* ptid_equal() is used to test equality of two ptids.  */
+
+int
+ptid_equal (ptid_t ptid1, ptid_t ptid2)
+{
+  return (ptid1.pid == ptid2.pid
+	  && ptid1.lwp == ptid2.lwp
+	  && ptid1.tid == ptid2.tid);
+}
+
+/* Returns true if PTID represents a process.  */
+
+int
+ptid_is_pid (ptid_t ptid)
+{
+  if (ptid_equal (minus_one_ptid, ptid))
+    return 0;
+  if (ptid_equal (null_ptid, ptid))
+    return 0;
+
+  return (ptid_get_lwp (ptid) == 0 && ptid_get_tid (ptid) == 0);
+}
Index: gdb/common/ptid.h
===================================================================
RCS file: gdb/common/ptid.h
diff -N gdb/common/ptid.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/ptid.h	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,87 @@
+/* The ptid_t type and common functions operating on it.
+
+   Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+   2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef PTID_H
+#define PTID_H
+
+/* The ptid struct is a collection of the various "ids" necessary
+   for identifying the inferior.  This consists of the process id
+   (pid), thread id (tid), and other fields necessary for uniquely
+   identifying the inferior process/thread being debugged.  When
+   manipulating ptids, the constructors, accessors, and predicate
+   declared in server.h should be used.  These are as follows:
+
+      ptid_build	- Make a new ptid from a pid, lwp, and tid.
+      pid_to_ptid	- Make a new ptid from just a pid.
+      ptid_get_pid	- Fetch the pid component of a ptid.
+      ptid_get_lwp	- Fetch the lwp component of a ptid.
+      ptid_get_tid	- Fetch the tid component of a ptid.
+      ptid_equal	- Test to see if two ptids are equal.
+
+   Please do NOT access the struct ptid members directly (except, of
+   course, in the implementation of the above ptid manipulation
+   functions).  */
+
+struct ptid
+  {
+    /* Process id */
+    int pid;
+
+    /* Lightweight process id */
+    long lwp;
+
+    /* Thread id */
+    long tid;
+  };
+
+typedef struct ptid ptid_t;
+
+/* The null or zero ptid, often used to indicate no process. */
+extern ptid_t null_ptid;
+
+/* The -1 ptid, often used to indicate either an error condition
+   or a "don't care" condition, i.e, "run all threads."  */
+extern ptid_t minus_one_ptid;
+
+/* Attempt to find and return an existing ptid with the given PID, LWP,
+   and TID components.  If none exists, create a new one and return
+   that.  */
+ptid_t ptid_build (int pid, long lwp, long tid);
+
+/* Find/Create a ptid from just a pid. */
+ptid_t pid_to_ptid (int pid);
+
+/* Fetch the pid (process id) component from a ptid. */
+int ptid_get_pid (ptid_t ptid);
+
+/* Fetch the lwp (lightweight process) component from a ptid. */
+long ptid_get_lwp (ptid_t ptid);
+
+/* Fetch the tid (thread id) component from a ptid. */
+long ptid_get_tid (ptid_t ptid);
+
+/* Compare two ptids to see if they are equal */
+int ptid_equal (ptid_t p1, ptid_t p2);
+
+/* Return true if PTID represents a process id.  */
+int ptid_is_pid (ptid_t ptid);
+
+#endif
Index: gdb/common/xml-utils.c
===================================================================
RCS file: gdb/common/xml-utils.c
diff -N gdb/common/xml-utils.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/xml-utils.c	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,90 @@
+/* Shared helper routines for manipulating XML using Expat.
+
+   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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 GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#endif
+
+#include "xml-utils.h"
+
+#include <string.h>
+
+/* Return a malloc allocated string with special characters from TEXT
+   replaced by entity references.  */
+
+char *
+xml_escape_text (const char *text)
+{
+  char *result;
+  int i, special;
+
+  /* Compute the length of the result.  */
+  for (i = 0, special = 0; text[i] != '\0'; i++)
+    switch (text[i])
+      {
+      case '\'':
+      case '\"':
+	special += 5;
+	break;
+      case '&':
+	special += 4;
+	break;
+      case '<':
+      case '>':
+	special += 3;
+	break;
+      default:
+	break;
+      }
+
+  /* Expand the result.  */
+  result = xmalloc (i + special + 1);
+  for (i = 0, special = 0; text[i] != '\0'; i++)
+    switch (text[i])
+      {
+      case '\'':
+	strcpy (result + i + special, "&apos;");
+	special += 5;
+	break;
+      case '\"':
+	strcpy (result + i + special, "&quot;");
+	special += 5;
+	break;
+      case '&':
+	strcpy (result + i + special, "&amp;");
+	special += 4;
+	break;
+      case '<':
+	strcpy (result + i + special, "&lt;");
+	special += 3;
+	break;
+      case '>':
+	strcpy (result + i + special, "&gt;");
+	special += 3;
+	break;
+      default:
+	result[i + special] = text[i];
+	break;
+      }
+  result[i + special] = '\0';
+
+  return result;
+}
Index: gdb/common/xml-utils.h
===================================================================
RCS file: gdb/common/xml-utils.h
diff -N gdb/common/xml-utils.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/common/xml-utils.h	12 Jul 2011 15:32:39 -0000
@@ -0,0 +1,28 @@
+/* Shared helper routines for manipulating XML using Expat.
+
+   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef XML_UTILS_H
+#define XML_UTILS_H
+
+/* Return a malloc allocated string with special characters from TEXT
+   replaced by entity references.  */
+
+extern char *xml_escape_text (const char *text);
+
+#endif
Index: gdb/config/alpha/alpha-linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/alpha/alpha-linux.mh,v
retrieving revision 1.22
diff -u -p -r1.22 alpha-linux.mh
--- gdb/config/alpha/alpha-linux.mh	28 May 2010 18:50:30 -0000	1.22
+++ gdb/config/alpha/alpha-linux.mh	12 Jul 2011 15:32:39 -0000
@@ -2,7 +2,7 @@
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o corelow.o alpha-linux-nat.o \
 	fork-child.o proc-service.o linux-thread-db.o \
-	linux-nat.o linux-fork.o
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 # The dynamically loaded libthread_db needs access to symbols in the
Index: gdb/config/arm/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/arm/linux.mh,v
retrieving revision 1.23
diff -u -p -r1.23 linux.mh
--- gdb/config/arm/linux.mh	28 May 2010 18:50:31 -0000	1.23
+++ gdb/config/arm/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -2,7 +2,8 @@
 
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o arm-linux-nat.o \
-	proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
+	proc-service.o linux-thread-db.o \
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 LOADLIBES= -ldl $(RDYNAMIC)
Index: gdb/config/i386/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/linux.mh,v
retrieving revision 1.24
diff -u -p -r1.24 linux.mh
--- gdb/config/i386/linux.mh	11 Jun 2010 12:08:51 -0000	1.24
+++ gdb/config/i386/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -4,7 +4,7 @@ NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o \
 	i386-nat.o i386-linux-nat.o \
 	proc-service.o linux-thread-db.o \
-	linux-nat.o linux-fork.o
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 # The dynamically loaded libthread_db needs access to symbols in the
Index: gdb/config/i386/linux64.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/linux64.mh,v
retrieving revision 1.10
diff -u -p -r1.10 linux64.mh
--- gdb/config/i386/linux64.mh	28 May 2010 18:50:31 -0000	1.10
+++ gdb/config/i386/linux64.mh	12 Jul 2011 15:32:39 -0000
@@ -1,6 +1,7 @@
 # Host: GNU/Linux x86-64
 NATDEPFILES= inf-ptrace.o fork-child.o \
-	i386-nat.o amd64-nat.o amd64-linux-nat.o linux-nat.o \
+	i386-nat.o amd64-nat.o amd64-linux-nat.o \
+	linux-nat.o linux-osdata.o \
 	proc-service.o linux-thread-db.o linux-fork.o
 NAT_FILE= config/nm-linux.h
 NAT_CDEPS = $(srcdir)/proc-service.list
Index: gdb/config/ia64/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/ia64/linux.mh,v
retrieving revision 1.24
diff -u -p -r1.24 linux.mh
--- gdb/config/ia64/linux.mh	28 May 2010 18:50:31 -0000	1.24
+++ gdb/config/ia64/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -3,7 +3,8 @@
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
 	core-regset.o ia64-linux-nat.o \
-	proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
+	proc-service.o linux-thread-db.o \
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 LOADLIBES = -ldl $(RDYNAMIC)
Index: gdb/config/m32r/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/m32r/linux.mh,v
retrieving revision 1.7
diff -u -p -r1.7 linux.mh
--- gdb/config/m32r/linux.mh	28 May 2010 18:50:32 -0000	1.7
+++ gdb/config/m32r/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -3,7 +3,7 @@
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o corelow.o	\
 	m32r-linux-nat.o proc-service.o linux-thread-db.o	\
-	linux-nat.o linux-fork.o
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 LOADLIBES= -ldl $(RDYNAMIC)
Index: gdb/config/m68k/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/m68k/linux.mh,v
retrieving revision 1.22
diff -u -p -r1.22 linux.mh
--- gdb/config/m68k/linux.mh	28 May 2010 18:50:32 -0000	1.22
+++ gdb/config/m68k/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -3,7 +3,8 @@
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o \
 	corelow.o m68klinux-nat.o \
-	proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
+	proc-service.o linux-thread-db.o \
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 # The dynamically loaded libthread_db needs access to symbols in the
Index: gdb/config/mips/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/linux.mh,v
retrieving revision 1.16
diff -u -p -r1.16 linux.mh
--- gdb/config/mips/linux.mh	28 May 2010 18:50:32 -0000	1.16
+++ gdb/config/mips/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -2,7 +2,7 @@
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o mips-linux-nat.o \
 	linux-thread-db.o proc-service.o \
-	linux-nat.o linux-fork.o
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 LOADLIBES = -ldl $(RDYNAMIC)
Index: gdb/config/pa/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/pa/linux.mh,v
retrieving revision 1.12
diff -u -p -r1.12 linux.mh
--- gdb/config/pa/linux.mh	28 May 2010 18:50:33 -0000	1.12
+++ gdb/config/pa/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -1,8 +1,8 @@
 # Host: Hewlett-Packard PA-RISC machine, running Linux
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
-	hppa-linux-nat.o proc-service.o linux-thread-db.o linux-nat.o \
-	linux-fork.o
+	hppa-linux-nat.o proc-service.o linux-thread-db.o \
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 LOADLIBES = -ldl $(RDYNAMIC)
Index: gdb/config/powerpc/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/powerpc/linux.mh,v
retrieving revision 1.23
diff -u -p -r1.23 linux.mh
--- gdb/config/powerpc/linux.mh	28 May 2010 18:50:33 -0000	1.23
+++ gdb/config/powerpc/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -5,7 +5,7 @@ XM_CLIBS=
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o \
 	ppc-linux-nat.o proc-service.o linux-thread-db.o \
-	linux-nat.o linux-fork.o
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 LOADLIBES = -ldl $(RDYNAMIC)
Index: gdb/config/powerpc/ppc64-linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/powerpc/ppc64-linux.mh,v
retrieving revision 1.13
diff -u -p -r1.13 ppc64-linux.mh
--- gdb/config/powerpc/ppc64-linux.mh	28 May 2010 18:50:33 -0000	1.13
+++ gdb/config/powerpc/ppc64-linux.mh	12 Jul 2011 15:32:39 -0000
@@ -5,7 +5,7 @@ XM_CLIBS=
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o \
 	ppc-linux-nat.o proc-service.o linux-thread-db.o \
-	linux-nat.o linux-fork.o
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 # The PowerPC has severe limitations on TOC size, and uses them even
Index: gdb/config/s390/s390.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/s390/s390.mh,v
retrieving revision 1.17
diff -u -p -r1.17 s390.mh
--- gdb/config/s390/s390.mh	28 May 2010 18:50:33 -0000	1.17
+++ gdb/config/s390/s390.mh	12 Jul 2011 15:32:39 -0000
@@ -1,6 +1,7 @@
 # Host: S390, running Linux
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o corelow.o s390-nat.o \
-	linux-thread-db.o proc-service.o linux-nat.o linux-fork.o
+	linux-thread-db.o proc-service.o \
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 LOADLIBES = -ldl $(RDYNAMIC)
Index: gdb/config/sparc/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/linux.mh,v
retrieving revision 1.21
diff -u -p -r1.21 linux.mh
--- gdb/config/sparc/linux.mh	28 May 2010 18:50:33 -0000	1.21
+++ gdb/config/sparc/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -3,7 +3,7 @@ NAT_FILE= config/nm-linux.h
 NATDEPFILES= sparc-nat.o sparc-linux-nat.o \
 	corelow.o core-regset.o fork-child.o inf-ptrace.o \
 	proc-service.o linux-thread-db.o \
-	linux-nat.o linux-fork.o
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 # The dynamically loaded libthread_db needs access to symbols in the
Index: gdb/config/sparc/linux64.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/linux64.mh,v
retrieving revision 1.12
diff -u -p -r1.12 linux64.mh
--- gdb/config/sparc/linux64.mh	28 May 2010 18:50:33 -0000	1.12
+++ gdb/config/sparc/linux64.mh	12 Jul 2011 15:32:39 -0000
@@ -4,7 +4,7 @@ NATDEPFILES= sparc-nat.o sparc64-nat.o s
 	corelow.o core-regset.o \
 	fork-child.o inf-ptrace.o \
 	proc-service.o linux-thread-db.o \
-	linux-nat.o linux-fork.o
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 # The dynamically loaded libthread_db needs access to symbols in the
Index: gdb/config/xtensa/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/xtensa/linux.mh,v
retrieving revision 1.3
diff -u -p -r1.3 linux.mh
--- gdb/config/xtensa/linux.mh	28 May 2010 18:50:34 -0000	1.3
+++ gdb/config/xtensa/linux.mh	12 Jul 2011 15:32:39 -0000
@@ -3,7 +3,8 @@
 NAT_FILE= config/nm-linux.h
 
 NATDEPFILES= inf-ptrace.o fork-child.o xtensa-linux-nat.o \
-	linux-thread-db.o proc-service.o linux-nat.o linux-fork.o
+	linux-thread-db.o proc-service.o \
+	linux-nat.o linux-osdata.o linux-fork.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 LOADLIBES = -ldl $(RDYNAMIC)
Index: gdb/gdbserver/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/Makefile.in,v
retrieving revision 1.110
diff -u -p -r1.110 Makefile.in
--- gdb/gdbserver/Makefile.in	26 May 2011 15:49:26 -0000	1.110
+++ gdb/gdbserver/Makefile.in	12 Jul 2011 15:32:40 -0000
@@ -124,7 +124,10 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/
 	$(srcdir)/linux-xtensa-low.c \
 	$(srcdir)/win32-arm-low.c $(srcdir)/win32-i386-low.c \
 	$(srcdir)/win32-low.c $(srcdir)/wincecompat.c \
-	$(srcdir)/hostio.c $(srcdir)/hostio-errno.c
+	$(srcdir)/hostio.c $(srcdir)/hostio-errno.c \
+	$(srcdir)/common/common-utils.c $(srcdir)/common/xml-utils.c \
+	$(srcdir)/common/linux-osdata.c $(srcdir)/common/ptid.c \
+	$(srcdir)/common/buffer.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -136,6 +139,7 @@ TAGFILES = $(SOURCES) ${HFILES} ${ALLPAR
 OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
 	utils.o version.o \
 	mem-break.o hostio.o event-loop.o tracepoint.o \
+	xml-utils.o common-utils.o ptid.o buffer.o \
 	$(XML_BUILTIN) \
 	$(DEPFILES) $(LIBOBJS)
 GDBREPLAY_OBS = gdbreplay.o version.o
@@ -234,7 +238,7 @@ gdbreplay$(EXEEXT): $(GDBREPLAY_OBS)
 	${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbreplay$(EXEEXT) $(GDBREPLAY_OBS) \
 	  $(XM_CLIBS)
 
-IPA_OBJS=tracepoint-ipa.o utils-ipa.o regcache-ipa.o remote-utils-ipa.o ${IPA_DEPFILES}
+IPA_OBJS=tracepoint-ipa.o utils-ipa.o regcache-ipa.o remote-utils-ipa.o common-utils-ipa.o ${IPA_DEPFILES}
 
 IPA_LIB=libinproctrace.so
 
@@ -331,8 +335,16 @@ regdef_h = $(srcdir)/../regformats/regde
 regcache_h = $(srcdir)/regcache.h
 signals_def = $(srcdir)/../../include/gdb/signals.def
 signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def)
+ptid_h = $(srcdir)/../common/ptid.h
+linux_osdata_h = $(srcdir)/../common/linux-osdata.h
 server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \
 		$(srcdir)/mem-break.h $(srcdir)/../common/gdb_signals.h \
+		$(srcdir)/../common/common-utils.h \
+		$(srcdir)/../common/xml-utils.h \
+		$(srcdir)/../common/buffer.h \
+		$(srcdir)/../common/gdb_assert.h \
+		$(srcdir)/../common/gdb_locale.h \
+		$(ptid_h) \
 		$(signals_h)
 
 linux_low_h = $(srcdir)/linux-low.h
@@ -358,6 +370,8 @@ tracepoint-ipa.o: tracepoint.c $(server_
 	$(CC) -c $(IPAGENT_CFLAGS) $< -o tracepoint-ipa.o
 utils-ipa.o: utils.c $(server_h)
 	$(CC) -c $(IPAGENT_CFLAGS) $< -o utils-ipa.o
+common-utils-ipa.o: ../common/common-utils.c $(server_h)
+	$(CC) -c $(IPAGENT_CFLAGS) $< -o common-utils-ipa.o
 remote-utils-ipa.o: remote-utils.c $(server_h)
 	$(CC) -c $(IPAGENT_CFLAGS) $< -o remote-utils-ipa.o
 regcache-ipa.o: regcache.c $(server_h)
@@ -390,6 +404,21 @@ gdbreplay.o: gdbreplay.c config.h
 signals.o: ../common/signals.c $(server_h) $(signals_def)
 	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
 
+common-utils.o: ../common/common-utils.c $(server_h)
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
+xml-utils.o: ../common/xml-utils.c $(server_h)
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
+linux-osdata.o: ../common/linux-osdata.c $(server_h) $(linux_osdata_h) ../common/gdb_dirent.h
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
+ptid.o: ../common/ptid.c $(ptid_h)
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
+buffer.o: ../common/buffer.c $(server_h)
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
 # We build memmem.c without -Werror because this file is not under
 # our control.  On LynxOS, the compiler generates some warnings
 # because str-two-way.h uses a constant (MAX_SIZE) whose definition
@@ -413,7 +442,7 @@ i386-low.o: i386-low.c $(i386_low_h) $(s
 
 i387-fp.o: i387-fp.c $(server_h)
 
-linux-low.o: linux-low.c $(linux_low_h) $(linux_ptrace_h) $(server_h)
+linux-low.o: linux-low.c $(linux_low_h) $(linux_ptrace_h) $(server_h) $(linux_osdata_h)
 	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< @USE_THREAD_DB@
 
 linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h) \
Index: gdb/gdbserver/config.in
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/config.in,v
retrieving revision 1.31
diff -u -p -r1.31 config.in
--- gdb/gdbserver/config.in	1 Sep 2010 18:56:45 -0000	1.31
+++ gdb/gdbserver/config.in	12 Jul 2011 15:32:40 -0000
@@ -38,6 +38,10 @@
    don't. */
 #undef HAVE_DECL_VSNPRINTF
 
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
+
 /* Define to 1 if you have the `dladdr' function. */
 #undef HAVE_DLADDR
 
@@ -80,6 +84,9 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
 /* Define to 1 if you have the <netdb.h> header file. */
 #undef HAVE_NETDB_H
 
@@ -138,12 +145,20 @@
 /* Define to 1 if the target supports __sync_*_compare_and_swap */
 #undef HAVE_SYNC_BUILTINS
 
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
 /* Define to 1 if you have the <sys/file.h> header file. */
 #undef HAVE_SYS_FILE_H
 
 /* Define to 1 if you have the <sys/ioctl.h> header file. */
 #undef HAVE_SYS_IOCTL_H
 
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
 /* Define to 1 if you have the <sys/procfs.h> header file. */
 #undef HAVE_SYS_PROCFS_H
 
Index: gdb/gdbserver/configure
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure,v
retrieving revision 1.59
diff -u -p -r1.59 configure
--- gdb/gdbserver/configure	9 Mar 2011 06:10:40 -0000	1.59
+++ gdb/gdbserver/configure	12 Jul 2011 15:32:41 -0000
@@ -3799,6 +3799,165 @@ $as_echo "#define STDC_HEADERS 1" >>conf
 
 fi
 
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_ac_Header=yes"
+else
+  eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
 
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
Index: gdb/gdbserver/configure.ac
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure.ac,v
retrieving revision 1.46
diff -u -p -r1.46 configure.ac
--- gdb/gdbserver/configure.ac	9 Mar 2011 06:10:40 -0000	1.46
+++ gdb/gdbserver/configure.ac	12 Jul 2011 15:32:41 -0000
@@ -35,6 +35,7 @@ AC_PROG_INSTALL
 AC_ARG_PROGRAM
 
 AC_HEADER_STDC
+AC_HEADER_DIRENT
 
 AC_FUNC_ALLOCA
 AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
Index: gdb/gdbserver/configure.srv
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure.srv,v
retrieving revision 1.60
diff -u -p -r1.60 configure.srv
--- gdb/gdbserver/configure.srv	4 May 2011 19:28:14 -0000	1.60
+++ gdb/gdbserver/configure.srv	12 Jul 2011 15:32:41 -0000
@@ -46,7 +46,7 @@ case "${target}" in
 			srv_regobj="${srv_regobj} arm-with-vfpv2.o"
 			srv_regobj="${srv_regobj} arm-with-vfpv3.o"
 			srv_regobj="${srv_regobj} arm-with-neon.o"
-			srv_tgtobj="linux-low.o linux-arm-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-arm-low.o"
 			srv_xmlfiles="arm-with-iwmmxt.xml"
 			srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv2.xml"
 			srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv3.xml"
@@ -68,17 +68,17 @@ case "${target}" in
 			srv_mingwce=yes
 			;;
   bfin-*-*linux*)	srv_regobj=reg-bfin.o
-			srv_tgtobj="linux-low.o linux-bfin-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-bfin-low.o"
 			srv_linux_usrregs=yes
 			srv_linux_thread_db=yes
 			;;
   crisv32-*-linux*)	srv_regobj=reg-crisv32.o
-			srv_tgtobj="linux-low.o linux-crisv32-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-crisv32-low.o"
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
   cris-*-linux*)	srv_regobj=reg-cris.o
-			srv_tgtobj="linux-low.o linux-cris-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-cris-low.o"
 			srv_linux_usrregs=yes
 			srv_linux_thread_db=yes
 			;;
@@ -92,7 +92,7 @@ case "${target}" in
 			    srv_regobj="$srv_regobj $srv_amd64_linux_regobj"
 			    srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
 			fi
-			srv_tgtobj="linux-low.o linux-x86-low.o i386-low.o i387-fp.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
@@ -123,11 +123,11 @@ case "${target}" in
 			srv_qnx="yes"
 			;;
   ia64-*-linux*)	srv_regobj=reg-ia64.o
-			srv_tgtobj="linux-low.o linux-ia64-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-ia64-low.o"
 			srv_linux_usrregs=yes
 			;;
   m32r*-*-linux*)	srv_regobj=reg-m32r.o
-			srv_tgtobj="linux-low.o linux-m32r-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-m32r-low.o"
 			srv_linux_usrregs=yes
  			srv_linux_thread_db=yes
 			;;
@@ -136,7 +136,7 @@ case "${target}" in
                         else
                           srv_regobj=reg-m68k.o
                         fi
-			srv_tgtobj="linux-low.o linux-m68k-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
@@ -146,13 +146,13 @@ case "${target}" in
                         else
                           srv_regobj=reg-m68k.o
                         fi
-			srv_tgtobj="linux-low.o linux-m68k-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
   mips*-*-linux*)	srv_regobj="mips-linux.o mips64-linux.o"
-			srv_tgtobj="linux-low.o linux-mips-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-mips-low.o"
 			srv_xmlfiles="mips-linux.xml"
 			srv_xmlfiles="${srv_xmlfiles} mips-cpu.xml"
 			srv_xmlfiles="${srv_xmlfiles} mips-cp0.xml"
@@ -180,7 +180,7 @@ case "${target}" in
 			srv_regobj="${srv_regobj} powerpc-isa205-64l.o"
 			srv_regobj="${srv_regobj} powerpc-isa205-altivec64l.o"
 			srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o"
-			srv_tgtobj="linux-low.o linux-ppc-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-ppc-low.o"
 			srv_xmlfiles="rs6000/powerpc-32l.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-altivec32l.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-cell32l.xml"
@@ -216,7 +216,7 @@ case "${target}" in
   s390*-*-linux*)	srv_regobj="s390-linux32.o"
 			srv_regobj="${srv_regobj} s390-linux64.o"
 			srv_regobj="${srv_regobj} s390x-linux64.o"
-			srv_tgtobj="linux-low.o linux-s390-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-s390-low.o"
 			srv_xmlfiles="s390-linux32.xml"
 			srv_xmlfiles="${srv_xmlfiles} s390-linux64.xml"
 			srv_xmlfiles="${srv_xmlfiles} s390x-linux64.xml"
@@ -230,13 +230,13 @@ case "${target}" in
 			srv_linux_thread_db=yes
 			;;
   sh*-*-linux*)		srv_regobj=reg-sh.o
-			srv_tgtobj="linux-low.o linux-sh-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-sh-low.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
   sparc*-*-linux*)	srv_regobj=reg-sparc64.o
-			srv_tgtobj="linux-low.o linux-sparc-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-sparc-low.o"
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
@@ -244,7 +244,7 @@ case "${target}" in
 			srv_tgtobj="spu-low.o"
 			;;
   x86_64-*-linux*)	srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
-			srv_tgtobj="linux-low.o linux-x86-low.o i386-low.o i387-fp.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o"
 			srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
 			srv_linux_usrregs=yes # This is for i386 progs.
 			srv_linux_regsets=yes
@@ -258,7 +258,7 @@ case "${target}" in
 			;;
 
   xtensa*-*-linux*)	srv_regobj=reg-xtensa.o
-			srv_tgtobj="linux-low.o linux-xtensa-low.o"
+			srv_tgtobj="linux-low.o linux-osdata.o linux-xtensa-low.o"
 			srv_linux_regsets=yes
 			;;
   *)			echo "Error: target not supported by gdbserver."
Index: gdb/gdbserver/inferiors.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/inferiors.c,v
retrieving revision 1.29
diff -u -p -r1.29 inferiors.c
--- gdb/gdbserver/inferiors.c	1 Jan 2011 15:33:24 -0000	1.29
+++ gdb/gdbserver/inferiors.c	12 Jul 2011 15:32:41 -0000
@@ -30,81 +30,6 @@ int dlls_changed;
 
 struct thread_info *current_inferior;
 
-
-/* Oft used ptids */
-ptid_t null_ptid;
-ptid_t minus_one_ptid;
-
-/* Create a ptid given the necessary PID, LWP, and TID components.  */
-
-ptid_t
-ptid_build (int pid, long lwp, long tid)
-{
-  ptid_t ptid;
-
-  ptid.pid = pid;
-  ptid.lwp = lwp;
-  ptid.tid = tid;
-  return ptid;
-}
-
-/* Create a ptid from just a pid.  */
-
-ptid_t
-pid_to_ptid (int pid)
-{
-  return ptid_build (pid, 0, 0);
-}
-
-/* Fetch the pid (process id) component from a ptid.  */
-
-int
-ptid_get_pid (ptid_t ptid)
-{
-  return ptid.pid;
-}
-
-/* Fetch the lwp (lightweight process) component from a ptid.  */
-
-long
-ptid_get_lwp (ptid_t ptid)
-{
-  return ptid.lwp;
-}
-
-/* Fetch the tid (thread id) component from a ptid.  */
-
-long
-ptid_get_tid (ptid_t ptid)
-{
-  return ptid.tid;
-}
-
-/* ptid_equal() is used to test equality of two ptids.  */
-
-int
-ptid_equal (ptid_t ptid1, ptid_t ptid2)
-{
-  return (ptid1.pid == ptid2.pid
-	  && ptid1.lwp == ptid2.lwp
-	  && ptid1.tid == ptid2.tid);
-}
-
-/* Return true if this ptid represents a process.  */
-
-int
-ptid_is_pid (ptid_t ptid)
-{
-  if (ptid_equal (minus_one_ptid, ptid))
-    return 0;
-  if (ptid_equal (null_ptid, ptid))
-    return 0;
-
-  return (ptid_get_pid (ptid) != 0
-	  && ptid_get_lwp (ptid) == 0
-	  && ptid_get_tid (ptid) == 0);
-}
-
 #define get_thread(inf) ((struct thread_info *)(inf))
 #define get_dll(inf) ((struct dll_info *)(inf))
 
@@ -518,10 +443,3 @@ current_process (void)
 
   return get_thread_process (current_inferior);
 }
-
-void
-initialize_inferiors (void)
-{
-  null_ptid = ptid_build (0, 0, 0);
-  minus_one_ptid = ptid_build (-1, 0, 0);
-}
Index: gdb/gdbserver/linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.172
diff -u -p -r1.172 linux-low.c
--- gdb/gdbserver/linux-low.c	4 May 2011 20:20:12 -0000	1.172
+++ gdb/gdbserver/linux-low.c	12 Jul 2011 15:32:42 -0000
@@ -19,6 +19,7 @@
 
 #include "server.h"
 #include "linux-low.h"
+#include "linux-osdata.h"
 
 #include <sys/wait.h>
 #include <stdio.h>
@@ -118,7 +119,6 @@ static int linux_wait_for_event (ptid_t 
 static void *add_lwp (ptid_t ptid);
 static int linux_stopped_by_watchpoint (void);
 static void mark_lwp_dead (struct lwp_info *lwp, int wstat);
-static int linux_core_of_thread (ptid_t ptid);
 static void proceed_all_lwps (void);
 static int finish_step_over (struct lwp_info *lwp);
 static CORE_ADDR get_stop_pc (struct lwp_info *lwp);
@@ -4387,264 +4387,11 @@ linux_read_offsets (CORE_ADDR *text_p, C
 #endif
 
 static int
-compare_ints (const void *xa, const void *xb)
-{
-  int a = *(const int *)xa;
-  int b = *(const int *)xb;
-
-  return a - b;
-}
-
-static int *
-unique (int *b, int *e)
-{
-  int *d = b;
-  while (++b != e)
-    if (*d != *b)
-      *++d = *b;
-  return ++d;
-}
-
-/* Given PID, iterates over all threads in that process.
-
-   Information about each thread, in a format suitable for qXfer:osdata:thread
-   is printed to BUFFER, if it's not NULL.  BUFFER is assumed to be already
-   initialized, and the caller is responsible for finishing and appending '\0'
-   to it.
-
-   The list of cores that threads are running on is assigned to *CORES, if it
-   is not NULL.  If no cores are found, *CORES will be set to NULL.  Caller
-   should free *CORES.  */
-
-static void
-list_threads (int pid, struct buffer *buffer, char **cores)
-{
-  int count = 0;
-  int allocated = 10;
-  int *core_numbers = xmalloc (sizeof (int) * allocated);
-  char pathname[128];
-  DIR *dir;
-  struct dirent *dp;
-  struct stat statbuf;
-
-  sprintf (pathname, "/proc/%d/task", pid);
-  if (stat (pathname, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
-    {
-      dir = opendir (pathname);
-      if (!dir)
-	{
-	  free (core_numbers);
-	  return;
-	}
-
-      while ((dp = readdir (dir)) != NULL)
-	{
-	  unsigned long lwp = strtoul (dp->d_name, NULL, 10);
-
-	  if (lwp != 0)
-	    {
-	      unsigned core = linux_core_of_thread (ptid_build (pid, lwp, 0));
-
-	      if (core != -1)
-		{
-		  char s[sizeof ("4294967295")];
-		  sprintf (s, "%u", core);
-
-		  if (count == allocated)
-		    {
-		      allocated *= 2;
-		      core_numbers = realloc (core_numbers,
-					      sizeof (int) * allocated);
-		    }
-		  core_numbers[count++] = core;
-		  if (buffer)
-		    buffer_xml_printf (buffer,
-				       "<item>"
-				       "<column name=\"pid\">%d</column>"
-				       "<column name=\"tid\">%s</column>"
-				       "<column name=\"core\">%s</column>"
-				       "</item>", pid, dp->d_name, s);
-		}
-	      else
-		{
-		  if (buffer)
-		    buffer_xml_printf (buffer,
-				       "<item>"
-				       "<column name=\"pid\">%d</column>"
-				       "<column name=\"tid\">%s</column>"
-				       "</item>", pid, dp->d_name);
-		}
-	    }
-	}
-      closedir (dir);
-    }
-
-  if (cores)
-    {
-      *cores = NULL;
-      if (count > 0)
-	{
-	  struct buffer buffer2;
-	  int *b;
-	  int *e;
-	  qsort (core_numbers, count, sizeof (int), compare_ints);
-
-	  /* Remove duplicates. */
-	  b = core_numbers;
-	  e = unique (b, core_numbers + count);
-
-	  buffer_init (&buffer2);
-
-	  for (b = core_numbers; b != e; ++b)
-	    {
-	      char number[sizeof ("4294967295")];
-	      sprintf (number, "%u", *b);
-	      buffer_xml_printf (&buffer2, "%s%s",
-				 (b == core_numbers) ? "" : ",", number);
-	    }
-	  buffer_grow_str0 (&buffer2, "");
-
-	  *cores = buffer_finish (&buffer2);
-	}
-    }
-  free (core_numbers);
-}
-
-static void
-show_process (int pid, const char *username, struct buffer *buffer)
-{
-  char pathname[128];
-  FILE *f;
-  char cmd[MAXPATHLEN + 1];
-
-  sprintf (pathname, "/proc/%d/cmdline", pid);
-
-  if ((f = fopen (pathname, "r")) != NULL)
-    {
-      size_t len = fread (cmd, 1, sizeof (cmd) - 1, f);
-      if (len > 0)
-	{
-	  char *cores = 0;
-	  int i;
-	  for (i = 0; i < len; i++)
-	    if (cmd[i] == '\0')
-	      cmd[i] = ' ';
-	  cmd[len] = '\0';
-
-	  buffer_xml_printf (buffer,
-			     "<item>"
-			     "<column name=\"pid\">%d</column>"
-			     "<column name=\"user\">%s</column>"
-			     "<column name=\"command\">%s</column>",
-			     pid,
-			     username,
-			     cmd);
-
-	  /* This only collects core numbers, and does not print threads.  */
-	  list_threads (pid, NULL, &cores);
-
-	  if (cores)
-	    {
-	      buffer_xml_printf (buffer,
-				 "<column name=\"cores\">%s</column>", cores);
-	      free (cores);
-	    }
-
-	  buffer_xml_printf (buffer, "</item>");
-	}
-      fclose (f);
-    }
-}
-
-static int
 linux_qxfer_osdata (const char *annex,
 		    unsigned char *readbuf, unsigned const char *writebuf,
 		    CORE_ADDR offset, int len)
 {
-  /* We make the process list snapshot when the object starts to be
-     read.  */
-  static const char *buf;
-  static long len_avail = -1;
-  static struct buffer buffer;
-  int processes = 0;
-  int threads = 0;
-
-  DIR *dirp;
-
-  if (strcmp (annex, "processes") == 0)
-    processes = 1;
-  else if (strcmp (annex, "threads") == 0)
-    threads = 1;
-  else
-    return 0;
-
-  if (!readbuf || writebuf)
-    return 0;
-
-  if (offset == 0)
-    {
-      if (len_avail != -1 && len_avail != 0)
-       buffer_free (&buffer);
-      len_avail = 0;
-      buf = NULL;
-      buffer_init (&buffer);
-      if (processes)
-	buffer_grow_str (&buffer, "<osdata type=\"processes\">");
-      else if (threads)
-	buffer_grow_str (&buffer, "<osdata type=\"threads\">");
-
-      dirp = opendir ("/proc");
-      if (dirp)
-       {
-	 struct dirent *dp;
-	 while ((dp = readdir (dirp)) != NULL)
-	   {
-	     struct stat statbuf;
-	     char procentry[sizeof ("/proc/4294967295")];
-
-	     if (!isdigit (dp->d_name[0])
-		 || strlen (dp->d_name) > sizeof ("4294967295") - 1)
-	       continue;
-
-	     sprintf (procentry, "/proc/%s", dp->d_name);
-	     if (stat (procentry, &statbuf) == 0
-		 && S_ISDIR (statbuf.st_mode))
-	       {
-		 int pid = (int) strtoul (dp->d_name, NULL, 10);
-
-		 if (processes)
-		   {
-		     struct passwd *entry = getpwuid (statbuf.st_uid);
-		     show_process (pid, entry ? entry->pw_name : "?", &buffer);
-		   }
-		 else if (threads)
-		   {
-		     list_threads (pid, &buffer, NULL);
-		   }
-	       }
-	   }
-
-	 closedir (dirp);
-       }
-      buffer_grow_str0 (&buffer, "</osdata>\n");
-      buf = buffer_finish (&buffer);
-      len_avail = strlen (buf);
-    }
-
-  if (offset >= len_avail)
-    {
-      /* Done.  Get rid of the data.  */
-      buffer_free (&buffer);
-      buf = NULL;
-      len_avail = 0;
-      return 0;
-    }
-
-  if (len > len_avail - offset)
-    len = len_avail - offset;
-  memcpy (readbuf, buf + offset, len);
-
-  return len;
+  return linux_common_xfer_osdata (annex, readbuf, offset, len);
 }
 
 /* Convert a native/host siginfo object, into/from the siginfo in the
@@ -4907,63 +4654,6 @@ linux_qxfer_spu (const char *annex, unsi
   return ret;
 }
 
-static int
-linux_core_of_thread (ptid_t ptid)
-{
-  char filename[sizeof ("/proc//task//stat")
-		 + 2 * 20 /* decimal digits for 2 numbers, max 2^64 bit each */
-		 + 1];
-  FILE *f;
-  char *content = NULL;
-  char *p;
-  char *ts = 0;
-  int content_read = 0;
-  int i;
-  int core;
-
-  sprintf (filename, "/proc/%d/task/%ld/stat",
-	   ptid_get_pid (ptid), ptid_get_lwp (ptid));
-  f = fopen (filename, "r");
-  if (!f)
-    return -1;
-
-  for (;;)
-    {
-      int n;
-      content = realloc (content, content_read + 1024);
-      n = fread (content + content_read, 1, 1024, f);
-      content_read += n;
-      if (n < 1024)
-	{
-	  content[content_read] = '\0';
-	  break;
-	}
-    }
-
-  p = strchr (content, '(');
-
-  /* Skip ")".  */
-  if (p != NULL)
-    p = strchr (p, ')');
-  if (p != NULL)
-    p++;
-
-  /* If the first field after program name has index 0, then core number is
-     the field with index 36.  There's no constant for that anywhere.  */
-  if (p != NULL)
-    p = strtok_r (p, " ", &ts);
-  for (i = 0; p != NULL && i != 36; ++i)
-    p = strtok_r (NULL, " ", &ts);
-
-  if (p == NULL || sscanf (p, "%d", &core) == 0)
-    core = -1;
-
-  free (content);
-  fclose (f);
-
-  return core;
-}
-
 static void
 linux_process_qsupported (const char *query)
 {
@@ -5111,7 +4801,7 @@ static struct target_ops linux_target_op
 #else
   NULL,
 #endif
-  linux_core_of_thread,
+  linux_common_core_of_thread,
   linux_process_qsupported,
   linux_supports_tracepoints,
   linux_read_pc,
Index: gdb/gdbserver/remote-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/remote-utils.c,v
retrieving revision 1.86
diff -u -p -r1.86 remote-utils.c
--- gdb/gdbserver/remote-utils.c	24 Apr 2011 08:02:20 -0000	1.86
+++ gdb/gdbserver/remote-utils.c	12 Jul 2011 15:32:42 -0000
@@ -1714,168 +1714,4 @@ monitor_output (const char *msg)
   free (buf);
 }
 
-/* Return a malloc allocated string with special characters from TEXT
-   replaced by entity references.  */
-
-char *
-xml_escape_text (const char *text)
-{
-  char *result;
-  int i, special;
-
-  /* Compute the length of the result.  */
-  for (i = 0, special = 0; text[i] != '\0'; i++)
-    switch (text[i])
-      {
-      case '\'':
-      case '\"':
-	special += 5;
-	break;
-      case '&':
-	special += 4;
-	break;
-      case '<':
-      case '>':
-	special += 3;
-	break;
-      default:
-	break;
-      }
-
-  /* Expand the result.  */
-  result = xmalloc (i + special + 1);
-  for (i = 0, special = 0; text[i] != '\0'; i++)
-    switch (text[i])
-      {
-      case '\'':
-	strcpy (result + i + special, "&apos;");
-	special += 5;
-	break;
-      case '\"':
-	strcpy (result + i + special, "&quot;");
-	special += 5;
-	break;
-      case '&':
-	strcpy (result + i + special, "&amp;");
-	special += 4;
-	break;
-      case '<':
-	strcpy (result + i + special, "&lt;");
-	special += 3;
-	break;
-      case '>':
-	strcpy (result + i + special, "&gt;");
-	special += 3;
-	break;
-      default:
-	result[i + special] = text[i];
-	break;
-      }
-  result[i + special] = '\0';
-
-  return result;
-}
-
-void
-buffer_grow (struct buffer *buffer, const char *data, size_t size)
-{
-  char *new_buffer;
-  size_t new_buffer_size;
-
-  if (size == 0)
-    return;
-
-  new_buffer_size = buffer->buffer_size;
-
-  if (new_buffer_size == 0)
-    new_buffer_size = 1;
-
-  while (buffer->used_size + size > new_buffer_size)
-    new_buffer_size *= 2;
-  new_buffer = realloc (buffer->buffer, new_buffer_size);
-  if (!new_buffer)
-    abort ();
-  memcpy (new_buffer + buffer->used_size, data, size);
-  buffer->buffer = new_buffer;
-  buffer->buffer_size = new_buffer_size;
-  buffer->used_size += size;
-}
-
-void
-buffer_free (struct buffer *buffer)
-{
-  if (!buffer)
-    return;
-
-  free (buffer->buffer);
-  buffer->buffer = NULL;
-  buffer->buffer_size = 0;
-  buffer->used_size = 0;
-}
-
-void
-buffer_init (struct buffer *buffer)
-{
-  memset (buffer, 0, sizeof (*buffer));
-}
-
-char*
-buffer_finish (struct buffer *buffer)
-{
-  char *ret = buffer->buffer;
-  buffer->buffer = NULL;
-  buffer->buffer_size = 0;
-  buffer->used_size = 0;
-  return ret;
-}
-
-void
-buffer_xml_printf (struct buffer *buffer, const char *format, ...)
-{
-  va_list ap;
-  const char *f;
-  const char *prev;
-  int percent = 0;
-
-  va_start (ap, format);
-
-  prev = format;
-  for (f = format; *f; f++)
-    {
-      if (percent)
-       {
-	 switch (*f)
-	   {
-	   case 's':
-	     {
-	       char *p;
-	       char *a = va_arg (ap, char *);
-	       buffer_grow (buffer, prev, f - prev - 1);
-	       p = xml_escape_text (a);
-	       buffer_grow_str (buffer, p);
-	       free (p);
-	       prev = f + 1;
-	     }
-	     break;
-	   case 'd':
-	     {
-	       int i = va_arg (ap, int);
-	       char b[sizeof ("4294967295")];
-
-	       buffer_grow (buffer, prev, f - prev - 1);
-	       sprintf (b, "%d", i);
-	       buffer_grow_str (buffer, b);
-	       prev = f + 1;
-	     }
-	   }
-	 percent = 0;
-       }
-      else if (*f == '%')
-       percent = 1;
-    }
-
-  buffer_grow_str (buffer, prev);
-  va_end (ap);
-}
-
 #endif
Index: gdb/gdbserver/server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.145
diff -u -p -r1.145 server.c
--- gdb/gdbserver/server.c	12 May 2011 12:09:17 -0000	1.145
+++ gdb/gdbserver/server.c	12 Jul 2011 15:32:42 -0000
@@ -2582,7 +2582,6 @@ main (int argc, char *argv[])
       exit (1);
     }
 
-  initialize_inferiors ();
   initialize_async_io ();
   initialize_low ();
   if (target_supports_tracepoints ())
Index: gdb/gdbserver/server.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.h,v
retrieving revision 1.83
diff -u -p -r1.83 server.h
--- gdb/gdbserver/server.h	24 Apr 2011 08:02:20 -0000	1.83
+++ gdb/gdbserver/server.h	12 Jul 2011 15:32:42 -0000
@@ -105,6 +105,11 @@ int vsnprintf(char *str, size_t size, co
 /* A type used for binary buffers.  */
 typedef unsigned char gdb_byte;
 
+#include "ptid.h"
+#include "buffer.h"
+#include "xml-utils.h"
+#include "gdb_locale.h"
+
 /* FIXME: This should probably be autoconf'd for.  It's an integer type at
    least the size of a (void *).  */
 typedef long long CORE_ADDR;
@@ -112,68 +117,6 @@ typedef long long CORE_ADDR;
 typedef long long LONGEST;
 typedef unsigned long long ULONGEST;
 
-/* The ptid struct is a collection of the various "ids" necessary
-   for identifying the inferior.  This consists of the process id
-   (pid), thread id (tid), and other fields necessary for uniquely
-   identifying the inferior process/thread being debugged.  When
-   manipulating ptids, the constructors, accessors, and predicate
-   declared in server.h should be used.  These are as follows:
-
-      ptid_build	- Make a new ptid from a pid, lwp, and tid.
-      pid_to_ptid	- Make a new ptid from just a pid.
-      ptid_get_pid	- Fetch the pid component of a ptid.
-      ptid_get_lwp	- Fetch the lwp component of a ptid.
-      ptid_get_tid	- Fetch the tid component of a ptid.
-      ptid_equal	- Test to see if two ptids are equal.
-
-   Please do NOT access the struct ptid members directly (except, of
-   course, in the implementation of the above ptid manipulation
-   functions).  */
-
-struct ptid
-  {
-    /* Process id */
-    int pid;
-
-    /* Lightweight process id */
-    long lwp;
-
-    /* Thread id */
-    long tid;
-  };
-
-typedef struct ptid ptid_t;
-
-/* The -1 ptid, often used to indicate either an error condition or a
-   "don't care" condition, i.e, "run all threads".  */
-extern ptid_t minus_one_ptid;
-
-/* The null or zero ptid, often used to indicate no process.  */
-extern ptid_t null_ptid;
-
-/* Attempt to find and return an existing ptid with the given PID,
-   LWP, and TID components.  If none exists, create a new one and
-   return that.  */
-ptid_t ptid_build (int pid, long lwp, long tid);
-
-/* Create a ptid from just a pid.  */
-ptid_t pid_to_ptid (int pid);
-
-/* Fetch the pid (process id) component from a ptid.  */
-int ptid_get_pid (ptid_t ptid);
-
-/* Fetch the lwp (lightweight process) component from a ptid.  */
-long ptid_get_lwp (ptid_t ptid);
-
-/* Fetch the tid (thread id) component from a ptid.  */
-long ptid_get_tid (ptid_t ptid);
-
-/* Compare two ptids to see if they are equal.  */
-extern int ptid_equal (ptid_t p1, ptid_t p2);
-
-/* Return true if this ptid represents a process id.  */
-extern int ptid_is_pid (ptid_t ptid);
-
 /* Generic information for tracking a list of ``inferiors'' - threads,
    processes, etc.  */
 struct inferior_list
@@ -294,8 +237,6 @@ extern struct inferior_list all_threads;
 extern struct inferior_list all_dlls;
 extern int dlls_changed;
 
-void initialize_inferiors (void);
-
 void add_inferior_to_list (struct inferior_list *list,
 			   struct inferior_list_entry *new_inferior);
 void for_each_inferior (struct inferior_list *list,
@@ -454,43 +395,8 @@ int relocate_instruction (CORE_ADDR *to,
 
 void monitor_output (const char *msg);
 
-char *xml_escape_text (const char *text);
-
-/* Simple growing buffer.  */
-
-struct buffer
-{
-  char *buffer;
-  size_t buffer_size; /* allocated size */
-  size_t used_size; /* actually used size */
-};
-
-/* Append DATA of size SIZE to the end of BUFFER.  Grows the buffer to
-   accommodate the new data.  */
-void buffer_grow (struct buffer *buffer, const char *data, size_t size);
-
-/* Release any memory held by BUFFER.  */
-void buffer_free (struct buffer *buffer);
-
-/* Initialize BUFFER.  BUFFER holds no memory afterwards.  */
-void buffer_init (struct buffer *buffer);
-
-/* Return a pointer into BUFFER data, effectivelly transfering
-   ownership of the buffer memory to the caller.  Calling buffer_free
-   afterwards has no effect on the returned data.  */
-char* buffer_finish (struct buffer *buffer);
-
-/* Simple printf to BUFFER function.  Current implemented formatters:
-   %s - grow an xml escaped text in OBSTACK.  */
-void buffer_xml_printf (struct buffer *buffer, const char *format, ...)
-  ATTR_FORMAT (printf, 2, 3);
-
-#define buffer_grow_str(BUFFER,STRING)         \
-  buffer_grow (BUFFER, STRING, strlen (STRING))
-#define buffer_grow_str0(BUFFER,STRING)                        \
-  buffer_grow (BUFFER, STRING, strlen (STRING) + 1)
-
 /* Functions from utils.c */
+#include "common-utils.h"
 
 void *xmalloc (size_t) ATTR_MALLOC;
 void *xrealloc (void *, size_t);
@@ -502,8 +408,6 @@ void freeargv (char **argv);
 void perror_with_name (const char *string);
 void error (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
 void fatal (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
-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);
 char *paddress (CORE_ADDR addr);
 char *pulongest (ULONGEST u);
@@ -511,33 +415,7 @@ char *plongest (LONGEST l);
 char *phex_nz (ULONGEST l, int sizeof_l);
 char *pfildes (gdb_fildes_t fd);
 
-#define gdb_assert(expr)                                                      \
-  ((void) ((expr) ? 0 :                                                       \
-	   (gdb_assert_fail (#expr, __FILE__, __LINE__, ASSERT_FUNCTION), 0)))
-
-/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
-   which contains the name of the function currently being defined.
-   This is broken in G++ before version 2.6.
-   C9x has a similar variable called __func__, but prefer the GCC one since
-   it demangles C++ function names.  */
-#if (GCC_VERSION >= 2004)
-#define ASSERT_FUNCTION		__PRETTY_FUNCTION__
-#else
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
-#define ASSERT_FUNCTION		__func__
-#endif
-#endif
-
-/* This prints an "Assertion failed" message, and exits.  */
-#if defined (ASSERT_FUNCTION)
-#define gdb_assert_fail(assertion, file, line, function)		\
-  internal_error (file, line, "%s: Assertion `%s' failed.",		\
-		  function, assertion)
-#else
-#define gdb_assert_fail(assertion, file, line, function)		\
-  internal_error (file, line, "Assertion `%s' failed.",			\
-		  assertion)
-#endif
+#include "gdb_assert.h"
 
 /* Maximum number of bytes to read/write at once.  The value here
    is chosen to fill up a packet (the headers account for the 32).  */
Index: gdb/gdbserver/utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/utils.c,v
retrieving revision 1.31
diff -u -p -r1.31 utils.c
--- gdb/gdbserver/utils.c	28 Feb 2011 22:00:45 -0000	1.31
+++ gdb/gdbserver/utils.c	12 Jul 2011 15:32:42 -0000
@@ -35,10 +35,8 @@
 
 /* Generally useful subroutines used throughout the program.  */
 
-static void malloc_failure (size_t size) ATTR_NORETURN;
-
-static void
-malloc_failure (size_t size)
+void
+malloc_failure (long size)
 {
   fprintf (stderr,
 	   PREFIX "ran out of memory while trying to allocate %lu bytes\n",
@@ -46,61 +44,6 @@ malloc_failure (size_t size)
   exit (1);
 }
 
-/* Allocate memory without fail.
-   If malloc fails, this will print a message to stderr and exit.  */
-
-void *
-xmalloc (size_t size)
-{
-  void *newmem;
-
-  if (size == 0)
-    size = 1;
-  newmem = malloc (size);
-  if (!newmem)
-    malloc_failure (size);
-
-  return newmem;
-}
-
-/* Reallocate memory without fail.  This works like xmalloc. */
-
-void *
-xrealloc (void *ptr, size_t size)
-{
-  void *val;
-
-  if (size == 0)
-    size = 1;
-
-  if (ptr != NULL)
-    val = realloc (ptr, size);	/* OK: realloc */
-  else
-    val = malloc (size);	/* OK: malloc */
-  if (val == NULL)
-    malloc_failure (size);
-
-  return val;
-}
-
-/* Allocate memory without fail and set it to zero.
-   If malloc fails, this will print a message to stderr and exit.  */
-
-void *
-xcalloc (size_t nelem, size_t elsize)
-{
-  void *newmem;
-
-  if (nelem == 0 || elsize == 0)
-    nelem = elsize = 1;
-
-  newmem = calloc (nelem, elsize);
-  if (!newmem)
-    malloc_failure (nelem * elsize);
-
-  return newmem;
-}
-
 /* Copy a string into a memory buffer.
    If malloc fails, this will print a message to stderr and exit.  */
 
@@ -239,22 +182,6 @@ get_cell (void)
   return buf[cell];
 }
 
-/* Stdarg wrapper around vsnprintf.
-   SIZE is the size of the buffer pointed to by STR.  */
-
-int
-xsnprintf (char *str, size_t size, const char *format, ...)
-{
-  va_list args;
-  int ret;
-
-  va_start (args, format);
-  ret = vsnprintf (str, size, format, args);
-  va_end (args);
-
-  return ret;
-}
-
 static char *
 decimal2str (char *sign, ULONGEST addr)
 {

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver
  2011-07-12 18:31 [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver Kwok Cheung Yeung
@ 2011-07-19 20:27 ` Tom Tromey
  2011-07-20 16:45   ` Pedro Alves
  2011-07-20 16:35 ` Pedro Alves
  2011-07-23 17:42 ` Mark Kettenis
  2 siblings, 1 reply; 6+ messages in thread
From: Tom Tromey @ 2011-07-19 20:27 UTC (permalink / raw)
  To: Kwok Cheung Yeung; +Cc: gdb-patches

>>>>> ">" == Kwok Cheung Yeung <kcy@codesourcery.com> writes:

>> Currently, the implementations of the 'info os' command in gdb and
>> gdbserver are maintained separately. This leads to a large amount of
>> code duplication, and discrepencies in the behaviour of the command
>> have already arisen between the two (gdb lists the available info
>> types if 'info os' is issued while gdbserver does not, and gdbserver
>> supports 'info os threads' while gdb does not). This patch attempts to
>> fix that by making the implementation of 'info os' for Linux systems
>> shared between gdb and gdbserver.

>> Auxilliary functions needed to implement 'info os' are moved into the
>> common/ subdirectory. gdb_assert.h, gdb_locale.h and gdb_dirent.h are
>> moved completely, while a subset of the following files are moved to
>> common/:
[...]

I like this patch.  I think it is generally a good direction for GDB to
go.

I read it and I did not see anything very objectionable.  However, as it
touches the ptid stuff, I would like Pedro to also sign off on it.

>> This necessitates various changes to the makefiles and config files to
>> make sure the right object files are built/linked in. Duplicated
>> functions in gdbserver are removed and the ones in common/ used
>> instead.

One thing I did notice is that you moved gdb_locale.h but gdbserver does
not include any of the configury that might enable the corresponding
functionality.

I am not sure this matters.

Tom

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver
  2011-07-12 18:31 [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver Kwok Cheung Yeung
  2011-07-19 20:27 ` Tom Tromey
@ 2011-07-20 16:35 ` Pedro Alves
  2011-07-23 17:42 ` Mark Kettenis
  2 siblings, 0 replies; 6+ messages in thread
From: Pedro Alves @ 2011-07-20 16:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kwok Cheung Yeung

Looks good to me.  A couple minor comments below.

On Tuesday 12 July 2011 18:46:56, Kwok Cheung Yeung wrote:

> 2011-07-12  Kwok Cheung Yeung  <kcy@codesourcery.com>
> 
>         * defs.h: Add guard against inclusion in gdbserver.
>         (struct ptid, ptid_t): Move to common/ptid.h.
>         (xfree, xzalloc, xasprintf, xvasprintf, xstrprintf, xstrvprintf,
>         xsnprintf, internal_error): Move to common/common-utils.h.
>         (nomem): Delete.
>         * gdb_assert.h: Move into common/ sub-directory.
>         * gdb_locale.h: Ditto.
>         * gdb_dirent.h: Ditto.
>         * inferior.h (minus_one_ptid, null_ptid, ptid_build, pid_to_ptid,
>         ptid_get_pid, ptid_get_lwp, ptid_get_tid, ptid_equal, ptid_is_pid):
>         Move into common/ptid.h.
>         * xml-support.c (xml_escape_text): Move into common/xml-utils.c.
>         (gdb_xml_create_parser_and_cleanup_1, xml_fetch_context_from_file):
>         Change nomem to malloc_failure.
>         * xml-support.h (xml_escape_text): Move into common/xml-utils.h.
>         * utils.c (nomem) Rename to malloc_failure.

Missing `:'.

>         (xmalloc, xzalloc, xrealloc, xcalloc, xfree, xstrprintf, xasprintf,
>         xvasprintf, xstrvprintf, xsnprintf) Move to common/common-utils.c.

Missing `:'.  Maybe more places.

> Index: gdb/common/buffer.c
> ===================================================================
> RCS file: gdb/common/buffer.c
> diff -N gdb/common/buffer.c
> --- /dev/null   1 Jan 1970 00:00:00 -0000
> +++ gdb/common/buffer.c 12 Jul 2011 15:32:39 -0000
> @@ -0,0 +1,144 @@
> +/* A simple growing buffer for GDB.
> +  
> +   Copyright (C) 2009, 2010 Free Software Foundation, Inc.

Needs 2011 as well.  There are other places with the same problem.

> Index: gdb/common/xml-utils.h
> ===================================================================
> RCS file: gdb/common/xml-utils.h
> diff -N gdb/common/xml-utils.h
> --- /dev/null   1 Jan 1970 00:00:00 -0000
> +++ gdb/common/xml-utils.h      12 Jul 2011 15:32:39 -0000
> @@ -0,0 +1,28 @@
> +/* Shared helper routines for manipulating XML using Expat.

The point of the file is exactly for XML routines independent of
Expat, as gdbserver doesn't like it in.  (gdb/xml-support.c is for
parsing, while gdb/common/xml-utils.c for XML output.)  Same comment
in xml-utils.c.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver
  2011-07-19 20:27 ` Tom Tromey
@ 2011-07-20 16:45   ` Pedro Alves
  0 siblings, 0 replies; 6+ messages in thread
From: Pedro Alves @ 2011-07-20 16:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey, Kwok Cheung Yeung

On Tuesday 19 July 2011 21:12:54, Tom Tromey wrote:

> However, as it touches the ptid stuff, I would like Pedro to also sign off on it.

Thanks, just did.

> One thing I did notice is that you moved gdb_locale.h but gdbserver does
> not include any of the configury that might enable the corresponding
> functionality.
> 
> I am not sure this matters.

It's not necessary; gdbserver doesn't bother with localization
at this point.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver
  2011-07-12 18:31 [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver Kwok Cheung Yeung
  2011-07-19 20:27 ` Tom Tromey
  2011-07-20 16:35 ` Pedro Alves
@ 2011-07-23 17:42 ` Mark Kettenis
  2011-08-10 22:07   ` Doug Evans
  2 siblings, 1 reply; 6+ messages in thread
From: Mark Kettenis @ 2011-07-23 17:42 UTC (permalink / raw)
  To: kcy; +Cc: gdb-patches

Sorry, but I still don't buy into the "let's share more stuff between
gdb and gsbserver" movement.  Especially when it results in massive
diffs like this one.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver
  2011-07-23 17:42 ` Mark Kettenis
@ 2011-08-10 22:07   ` Doug Evans
  0 siblings, 0 replies; 6+ messages in thread
From: Doug Evans @ 2011-08-10 22:07 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: kcy, gdb-patches

On Sat, Jul 23, 2011 at 9:55 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
> Sorry, but I still don't buy into the "let's share more stuff between
> gdb and gsbserver" movement.  Especially when it results in massive
> diffs like this one.

One thing to consider is that there are features that are only in gdb,
and features that are only in gdbserver.
We need to resolve that.

Another thing to consider is the perennial maintenance of ptrace issues in both.

The current situation is just not tenable IMO.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-08-10 22:07 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-12 18:31 [PATCH] Unify implementation of 'info os' commands between gdb and gdbserver Kwok Cheung Yeung
2011-07-19 20:27 ` Tom Tromey
2011-07-20 16:45   ` Pedro Alves
2011-07-20 16:35 ` Pedro Alves
2011-07-23 17:42 ` Mark Kettenis
2011-08-10 22:07   ` Doug Evans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).