+2011-07-22 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.
+
2011-07-21 Matt Rice <ratmice@gmail.com>
* NEWS: Add info macros and info definitions commands.
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
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.
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
$(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
#
--- /dev/null
+/* A simple growing buffer for GDB.
+
+ Copyright (C) 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/>. */
+
+#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);
+}
+
--- /dev/null
+/* A simple growing buffer for GDB.
+
+ Copyright (C) 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 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
--- /dev/null
+/* 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, 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/>. */
+
+#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;
+}
--- /dev/null
+/* 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, 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 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* Linux-specific functions to retrieve OS data.
+
+ Copyright (C) 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/>. */
+
+#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;
+ }
+}
+
--- /dev/null
+/* Linux-specific functions to retrieve OS data.
+
+ Copyright (C) 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 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
--- /dev/null
+/* 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, 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/>. */
+
+#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);
+}
--- /dev/null
+/* 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, 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 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
--- /dev/null
+/* Shared helper routines for manipulating XML.
+
+ Copyright (C) 2006, 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/>. */
+
+#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, "'");
+ special += 5;
+ break;
+ case '\"':
+ strcpy (result + i + special, """);
+ special += 5;
+ break;
+ case '&':
+ strcpy (result + i + special, "&");
+ special += 4;
+ break;
+ case '<':
+ strcpy (result + i + special, "<");
+ special += 3;
+ break;
+ case '>':
+ strcpy (result + i + special, ">");
+ special += 3;
+ break;
+ default:
+ result[i + special] = text[i];
+ break;
+ }
+ result[i + special] = '\0';
+
+ return result;
+}
--- /dev/null
+/* Shared helper routines for manipulating XML.
+
+ Copyright (C) 2006, 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 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
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
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)
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
# 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
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)
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)
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
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)
# 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)
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)
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
# 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)
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
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
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)
#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>
#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);
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'
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). */
#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 **);
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);
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);
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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 */
+2011-07-22 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.
+
2011-07-20 Pedro Alves <pedro@codesourcery.com>
* tracepoint.c (tracepoint_look_up_symbols): Return upon the first
$(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@
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
${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
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
$(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)
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
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) \
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
/* 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
/* 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
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!
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
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"
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
;;
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
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
;;
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
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"
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"
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"
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
;;
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
;;
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."
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))
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);
-}
#include "server.h"
#include "linux-low.h"
+#include "linux-osdata.h"
#include <sys/wait.h>
#include <stdio.h>
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);
}
#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
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)
{
#else
NULL,
#endif
- linux_core_of_thread,
+ linux_common_core_of_thread,
linux_process_qsupported,
linux_supports_tracepoints,
linux_read_pc,
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, "'");
- special += 5;
- break;
- case '\"':
- strcpy (result + i + special, """);
- special += 5;
- break;
- case '&':
- strcpy (result + i + special, "&");
- special += 4;
- break;
- case '<':
- strcpy (result + i + special, "<");
- special += 3;
- break;
- case '>':
- strcpy (result + i + special, ">");
- 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
exit (1);
}
- initialize_inferiors ();
initialize_async_io ();
initialize_low ();
if (target_supports_tracepoints ())
/* 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;
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
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,
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);
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);
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). */
/* 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",
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. */
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)
{
struct ui_out;
struct terminal_info;
+#include "ptid.h"
+
/* For bpstat. */
#include "breakpoint.h"
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
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)
{
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;
#include "terminal.h"
#include <sys/vfs.h>
#include "solib.h"
+#include "linux-osdata.h"
#ifndef SPUFS_MAGIC
#define SPUFS_MAGIC 0x23c9b64e
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
memory requested in SIZE. */
void
-nomem (long size)
+malloc_failure (long size)
{
if (size > 0)
{
}
}
-/* 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. */
}
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. */
char **argv = buildargv (s);
if (s != NULL && argv == NULL)
- nomem (0);
+ malloc_failure (0);
return argv;
}
if (parser->expat_parser == NULL)
{
xfree (parser);
- nomem (0);
+ malloc_failure (0);
}
parser->name = name;
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, "'");
- special += 5;
- break;
- case '\"':
- strcpy (result + i + special, """);
- special += 5;
- break;
- case '&':
- strcpy (result + i + special, "&");
- special += 4;
- break;
- case '<':
- strcpy (result + i + special, "<");
- special += 3;
- break;
- case '>':
- strcpy (result + i + special, ">");
- 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, ...)
{
char *fullname = concat (dirname, "/", filename, (char *) NULL);
if (fullname == NULL)
- nomem (0);
+ malloc_failure (0);
file = fopen (fullname, FOPEN_RT);
xfree (fullname);
}
#include "gdb_obstack.h"
#include "vec.h"
+#include "xml-utils.h"
struct gdb_xml_parser;
struct gdb_xml_element;
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. */