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

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

gdbserver/
	* 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.
This commit is contained in:
Kwok Yeung 2011-07-21 23:46:12 +00:00
parent edc8499054
commit d26e3629bb
49 changed files with 1759 additions and 1321 deletions

View File

@ -1,3 +1,67 @@
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.

View File

@ -737,7 +737,9 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
jit.c \
xml-syscall.c \
annotate.c common/signals.c copying.c dfp.c gdb.c inf-child.c \
regset.c sol-thread.c windows-termcap.c
regset.c sol-thread.c windows-termcap.c \
common/common-utils.c common/xml-utils.c \
common/ptid.c common/buffer.c
LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
@ -816,7 +818,9 @@ osdata.h procfs.h python/py-event.h python/py-events.h python/py-stopevent.h \
python/python-internal.h python/python.h ravenscar-thread.h record.h \
solib-darwin.h solib-ia64-hpux.h solib-spu.h windows-nat.h xcoffread.h \
gnulib/extra/arg-nonnull.h gnulib/extra/c++defs.h gnulib/extra/warn-on-use.h \
gnulib/stddef.in.h inline-frame.h
gnulib/stddef.in.h inline-frame.h \
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
common/linux-osdata.h
# Header files that already have srcdir in them, or which are in objdir.
@ -898,10 +902,12 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
trad-frame.o \
tramp-frame.o \
solib.o solib-target.o \
prologue-value.o memory-map.o memrange.o xml-support.o xml-syscall.o \
prologue-value.o memory-map.o memrange.o \
xml-support.o xml-syscall.o xml-utils.o \
target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
jit.o progspace.o
jit.o progspace.o \
common-utils.o buffer.o ptid.o
TSOBS = inflow.o
@ -1933,6 +1939,26 @@ signals.o: $(srcdir)/common/signals.c
$(COMPILE) $(srcdir)/common/signals.c
$(POSTCOMPILE)
common-utils.o: ${srcdir}/common/common-utils.c
$(COMPILE) $(srcdir)/common/common-utils.c
$(POSTCOMPILE)
xml-utils.o: ${srcdir}/common/xml-utils.c
$(COMPILE) $(srcdir)/common/xml-utils.c
$(POSTCOMPILE)
ptid.o: ${srcdir}/common/ptid.c
$(COMPILE) $(srcdir)/common/ptid.c
$(POSTCOMPILE)
buffer.o: ${srcdir}/common/buffer.c
$(COMPILE) $(srcdir)/common/buffer.c
$(POSTCOMPILE)
linux-osdata.o: ${srcdir}/common/linux-osdata.c
$(COMPILE) $(srcdir)/common/linux-osdata.c
$(POSTCOMPILE)
#
# gdb/tui/ dependencies
#

144
gdb/common/buffer.c Normal file
View File

@ -0,0 +1,144 @@
/* 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);
}

63
gdb/common/buffer.h Normal file
View File

@ -0,0 +1,63 @@
/* 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

170
gdb/common/common-utils.c Normal file
View File

@ -0,0 +1,170 @@
/* Shared general utility routines for GDB, the GNU debugger.
Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 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;
}

59
gdb/common/common-utils.h Normal file
View File

@ -0,0 +1,59 @@
/* Shared general utility routines for GDB, the GNU debugger.
Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 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

586
gdb/common/linux-osdata.c Normal file
View File

@ -0,0 +1,586 @@
/* 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;
}
}

29
gdb/common/linux-osdata.h Normal file
View File

@ -0,0 +1,29 @@
/* 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

94
gdb/common/ptid.c Normal file
View File

@ -0,0 +1,94 @@
/* The ptid_t type and common functions operating on it.
Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 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);
}

87
gdb/common/ptid.h Normal file
View File

@ -0,0 +1,87 @@
/* The ptid_t type and common functions operating on it.
Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 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

91
gdb/common/xml-utils.c Normal file
View File

@ -0,0 +1,91 @@
/* 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, "&apos;");
special += 5;
break;
case '\"':
strcpy (result + i + special, "&quot;");
special += 5;
break;
case '&':
strcpy (result + i + special, "&amp;");
special += 4;
break;
case '<':
strcpy (result + i + special, "&lt;");
special += 3;
break;
case '>':
strcpy (result + i + special, "&gt;");
special += 3;
break;
default:
result[i + special] = text[i];
break;
}
result[i + special] = '\0';
return result;
}

29
gdb/common/xml-utils.h Normal file
View File

@ -0,0 +1,29 @@
/* 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

View File

@ -2,7 +2,7 @@
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o corelow.o alpha-linux-nat.o \
fork-child.o proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
# The dynamically loaded libthread_db needs access to symbols in the

View File

@ -2,7 +2,8 @@
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o arm-linux-nat.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
proc-service.o linux-thread-db.o \
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
LOADLIBES= -ldl $(RDYNAMIC)

View File

@ -4,7 +4,7 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
i386-nat.o i386-linux-nat.o \
proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
# The dynamically loaded libthread_db needs access to symbols in the

View File

@ -1,6 +1,7 @@
# Host: GNU/Linux x86-64
NATDEPFILES= inf-ptrace.o fork-child.o \
i386-nat.o amd64-nat.o amd64-linux-nat.o linux-nat.o \
i386-nat.o amd64-nat.o amd64-linux-nat.o \
linux-nat.o linux-osdata.o \
proc-service.o linux-thread-db.o linux-fork.o
NAT_FILE= config/nm-linux.h
NAT_CDEPS = $(srcdir)/proc-service.list

View File

@ -3,7 +3,8 @@
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
core-regset.o ia64-linux-nat.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
proc-service.o linux-thread-db.o \
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
LOADLIBES = -ldl $(RDYNAMIC)

View File

@ -3,7 +3,7 @@
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
m32r-linux-nat.o proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
LOADLIBES= -ldl $(RDYNAMIC)

View File

@ -3,7 +3,8 @@
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
corelow.o m68klinux-nat.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
proc-service.o linux-thread-db.o \
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
# The dynamically loaded libthread_db needs access to symbols in the

View File

@ -2,7 +2,7 @@
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o mips-linux-nat.o \
linux-thread-db.o proc-service.o \
linux-nat.o linux-fork.o
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
LOADLIBES = -ldl $(RDYNAMIC)

View File

@ -1,8 +1,8 @@
# Host: Hewlett-Packard PA-RISC machine, running Linux
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
hppa-linux-nat.o proc-service.o linux-thread-db.o linux-nat.o \
linux-fork.o
hppa-linux-nat.o proc-service.o linux-thread-db.o \
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
LOADLIBES = -ldl $(RDYNAMIC)

View File

@ -5,7 +5,7 @@ XM_CLIBS=
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
ppc-linux-nat.o proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
LOADLIBES = -ldl $(RDYNAMIC)

View File

@ -5,7 +5,7 @@ XM_CLIBS=
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
ppc-linux-nat.o proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
# The PowerPC has severe limitations on TOC size, and uses them even

View File

@ -1,6 +1,7 @@
# Host: S390, running Linux
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o s390-nat.o \
linux-thread-db.o proc-service.o linux-nat.o linux-fork.o
linux-thread-db.o proc-service.o \
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
LOADLIBES = -ldl $(RDYNAMIC)

View File

@ -3,7 +3,7 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= sparc-nat.o sparc-linux-nat.o \
corelow.o core-regset.o fork-child.o inf-ptrace.o \
proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
# The dynamically loaded libthread_db needs access to symbols in the

View File

@ -4,7 +4,7 @@ NATDEPFILES= sparc-nat.o sparc64-nat.o sparc64-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

View File

@ -3,7 +3,8 @@
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o xtensa-linux-nat.o \
linux-thread-db.o proc-service.o linux-nat.o linux-fork.o
linux-thread-db.o proc-service.o \
linux-nat.o linux-osdata.o linux-fork.o
NAT_CDEPS = $(srcdir)/proc-service.list
LOADLIBES = -ldl $(RDYNAMIC)

View File

@ -23,6 +23,10 @@
#ifndef DEFS_H
#define DEFS_H
#ifdef GDBSERVER
# error gdbserver should not include gdb/defs.h
#endif
#include "config.h" /* Generated by configure. */
#include <sys/types.h>
@ -142,6 +146,8 @@ typedef bfd_vma CORE_ADDR;
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
#include "ptid.h"
/* Check if a character is one of the commonly used C++ marker characters. */
extern int is_cplus_marker (int);
@ -753,41 +759,6 @@ enum val_prettyprint
Val_pretty_default
};
/* The ptid struct is a collection of the various "ids" necessary
for identifying the inferior. This consists of the process id
(pid), thread id (tid), and other fields necessary for uniquely
identifying the inferior process/thread being debugged. When
manipulating ptids, the constructors, accessors, and predicate
declared in inferior.h should be used. These are as follows:
ptid_build - Make a new ptid from a pid, lwp, and tid.
pid_to_ptid - Make a new ptid from just a pid.
ptid_get_pid - Fetch the pid component of a ptid.
ptid_get_lwp - Fetch the lwp component of a ptid.
ptid_get_tid - Fetch the tid component of a ptid.
ptid_equal - Test to see if two ptids are equal.
ptid_is_pid - Test to see if this ptid represents a process id.
Please do NOT access the struct ptid members directly (except, of
course, in the implementation of the above ptid manipulation
functions). */
struct ptid
{
/* Process id */
int pid;
/* Lightweight process id */
long lwp;
/* Thread id */
long tid;
};
typedef struct ptid ptid_t;
/* Optional native machine support. Non-native (and possibly pure
multi-arch) targets do not need a "nm.h" file. This will be a
symlink to one of the nm-*.h files, built by the `configure'
@ -851,13 +822,6 @@ extern int longest_to_int (LONGEST);
extern char *savestring (const char *, size_t);
/* xmalloc(), xrealloc() and xcalloc() have already been declared in
"libiberty.h". */
extern void xfree (void *);
/* Like xmalloc, but zero the memory. */
extern void *xzalloc (size_t);
/* Utility macros to allocate typed memory. Avoids errors like:
struct foo *foo = xmalloc (sizeof struct bar); and memset (foo,
sizeof (struct foo), 0). */
@ -865,22 +829,7 @@ extern void *xzalloc (size_t);
#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
#define XCALLOC(NMEMB, TYPE) ((TYPE*) xcalloc ((NMEMB), sizeof (TYPE)))
/* Like asprintf/vasprintf but get an internal_error if the call
fails. */
extern void xasprintf (char **ret, const char *format, ...)
ATTRIBUTE_PRINTF (2, 3);
extern void xvasprintf (char **ret, const char *format, va_list ap)
ATTRIBUTE_PRINTF (2, 0);
/* Like asprintf and vasprintf, but return the string, throw an error
if no memory. */
extern char *xstrprintf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
extern char *xstrvprintf (const char *format, va_list ap)
ATTRIBUTE_PRINTF (1, 0);
/* Like snprintf, but throw an error if the output buffer is too small. */
extern int xsnprintf (char *str, size_t size, const char *format, ...)
ATTRIBUTE_PRINTF (3, 4);
#include "common-utils.h"
extern int parse_escape (struct gdbarch *, char **);
@ -914,9 +863,6 @@ extern void internal_verror (const char *file, int line, const char *,
va_list ap)
ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0);
extern void internal_error (const char *file, int line, const char *, ...)
ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 4);
extern void internal_vwarning (const char *file, int line,
const char *, va_list ap)
ATTRIBUTE_PRINTF (3, 0);
@ -924,8 +870,6 @@ extern void internal_vwarning (const char *file, int line,
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);

View File

@ -1,3 +1,42 @@
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

View File

@ -124,7 +124,10 @@ SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c \
$(srcdir)/linux-xtensa-low.c \
$(srcdir)/win32-arm-low.c $(srcdir)/win32-i386-low.c \
$(srcdir)/win32-low.c $(srcdir)/wincecompat.c \
$(srcdir)/hostio.c $(srcdir)/hostio-errno.c
$(srcdir)/hostio.c $(srcdir)/hostio-errno.c \
$(srcdir)/common/common-utils.c $(srcdir)/common/xml-utils.c \
$(srcdir)/common/linux-osdata.c $(srcdir)/common/ptid.c \
$(srcdir)/common/buffer.c
DEPFILES = @GDBSERVER_DEPFILES@
@ -136,6 +139,7 @@ TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
utils.o version.o \
mem-break.o hostio.o event-loop.o tracepoint.o \
xml-utils.o common-utils.o ptid.o buffer.o \
$(XML_BUILTIN) \
$(DEPFILES) $(LIBOBJS)
GDBREPLAY_OBS = gdbreplay.o version.o
@ -234,7 +238,7 @@ gdbreplay$(EXEEXT): $(GDBREPLAY_OBS)
${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbreplay$(EXEEXT) $(GDBREPLAY_OBS) \
$(XM_CLIBS)
IPA_OBJS=tracepoint-ipa.o utils-ipa.o regcache-ipa.o remote-utils-ipa.o ${IPA_DEPFILES}
IPA_OBJS=tracepoint-ipa.o utils-ipa.o regcache-ipa.o remote-utils-ipa.o common-utils-ipa.o ${IPA_DEPFILES}
IPA_LIB=libinproctrace.so
@ -331,8 +335,16 @@ regdef_h = $(srcdir)/../regformats/regdef.h
regcache_h = $(srcdir)/regcache.h
signals_def = $(srcdir)/../../include/gdb/signals.def
signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def)
ptid_h = $(srcdir)/../common/ptid.h
linux_osdata_h = $(srcdir)/../common/linux-osdata.h
server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \
$(srcdir)/mem-break.h $(srcdir)/../common/gdb_signals.h \
$(srcdir)/../common/common-utils.h \
$(srcdir)/../common/xml-utils.h \
$(srcdir)/../common/buffer.h \
$(srcdir)/../common/gdb_assert.h \
$(srcdir)/../common/gdb_locale.h \
$(ptid_h) \
$(signals_h)
linux_low_h = $(srcdir)/linux-low.h
@ -358,6 +370,8 @@ tracepoint-ipa.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def
$(CC) -c $(IPAGENT_CFLAGS) $< -o tracepoint-ipa.o
utils-ipa.o: utils.c $(server_h)
$(CC) -c $(IPAGENT_CFLAGS) $< -o utils-ipa.o
common-utils-ipa.o: ../common/common-utils.c $(server_h)
$(CC) -c $(IPAGENT_CFLAGS) $< -o common-utils-ipa.o
remote-utils-ipa.o: remote-utils.c $(server_h)
$(CC) -c $(IPAGENT_CFLAGS) $< -o remote-utils-ipa.o
regcache-ipa.o: regcache.c $(server_h)
@ -390,6 +404,21 @@ gdbreplay.o: gdbreplay.c config.h
signals.o: ../common/signals.c $(server_h) $(signals_def)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
common-utils.o: ../common/common-utils.c $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
xml-utils.o: ../common/xml-utils.c $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
linux-osdata.o: ../common/linux-osdata.c $(server_h) $(linux_osdata_h) ../common/gdb_dirent.h
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
ptid.o: ../common/ptid.c $(ptid_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
buffer.o: ../common/buffer.c $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
# We build memmem.c without -Werror because this file is not under
# our control. On LynxOS, the compiler generates some warnings
# because str-two-way.h uses a constant (MAX_SIZE) whose definition
@ -413,7 +442,7 @@ i386-low.o: i386-low.c $(i386_low_h) $(server_h) $(target_h)
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) \

View File

@ -38,6 +38,10 @@
don't. */
#undef HAVE_DECL_VSNPRINTF
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
/* Define to 1 if you have the `dladdr' function. */
#undef HAVE_DLADDR
@ -80,6 +84,9 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
@ -138,12 +145,20 @@
/* Define to 1 if the target supports __sync_*_compare_and_swap */
#undef HAVE_SYNC_BUILTINS
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_DIR_H
/* Define to 1 if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_NDIR_H
/* Define to 1 if you have the <sys/procfs.h> header file. */
#undef HAVE_SYS_PROCFS_H

View File

@ -3799,6 +3799,165 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.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!

View File

@ -35,6 +35,7 @@ AC_PROG_INSTALL
AC_ARG_PROGRAM
AC_HEADER_STDC
AC_HEADER_DIRENT
AC_FUNC_ALLOCA
AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl

View File

@ -46,7 +46,7 @@ case "${target}" in
srv_regobj="${srv_regobj} arm-with-vfpv2.o"
srv_regobj="${srv_regobj} arm-with-vfpv3.o"
srv_regobj="${srv_regobj} arm-with-neon.o"
srv_tgtobj="linux-low.o linux-arm-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-arm-low.o"
srv_xmlfiles="arm-with-iwmmxt.xml"
srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv2.xml"
srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv3.xml"
@ -68,17 +68,17 @@ case "${target}" in
srv_mingwce=yes
;;
bfin-*-*linux*) srv_regobj=reg-bfin.o
srv_tgtobj="linux-low.o linux-bfin-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-bfin-low.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
crisv32-*-linux*) srv_regobj=reg-crisv32.o
srv_tgtobj="linux-low.o linux-crisv32-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-crisv32-low.o"
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
cris-*-linux*) srv_regobj=reg-cris.o
srv_tgtobj="linux-low.o linux-cris-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-cris-low.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
@ -92,7 +92,7 @@ case "${target}" in
srv_regobj="$srv_regobj $srv_amd64_linux_regobj"
srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
fi
srv_tgtobj="linux-low.o linux-x86-low.o i386-low.o i387-fp.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
@ -123,11 +123,11 @@ case "${target}" in
srv_qnx="yes"
;;
ia64-*-linux*) srv_regobj=reg-ia64.o
srv_tgtobj="linux-low.o linux-ia64-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-ia64-low.o"
srv_linux_usrregs=yes
;;
m32r*-*-linux*) srv_regobj=reg-m32r.o
srv_tgtobj="linux-low.o linux-m32r-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-m32r-low.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
@ -136,7 +136,7 @@ case "${target}" in
else
srv_regobj=reg-m68k.o
fi
srv_tgtobj="linux-low.o linux-m68k-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
@ -146,13 +146,13 @@ case "${target}" in
else
srv_regobj=reg-m68k.o
fi
srv_tgtobj="linux-low.o linux-m68k-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
mips*-*-linux*) srv_regobj="mips-linux.o mips64-linux.o"
srv_tgtobj="linux-low.o linux-mips-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-mips-low.o"
srv_xmlfiles="mips-linux.xml"
srv_xmlfiles="${srv_xmlfiles} mips-cpu.xml"
srv_xmlfiles="${srv_xmlfiles} mips-cp0.xml"
@ -180,7 +180,7 @@ case "${target}" in
srv_regobj="${srv_regobj} powerpc-isa205-64l.o"
srv_regobj="${srv_regobj} powerpc-isa205-altivec64l.o"
srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o"
srv_tgtobj="linux-low.o linux-ppc-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-ppc-low.o"
srv_xmlfiles="rs6000/powerpc-32l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-altivec32l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-cell32l.xml"
@ -216,7 +216,7 @@ case "${target}" in
s390*-*-linux*) srv_regobj="s390-linux32.o"
srv_regobj="${srv_regobj} s390-linux64.o"
srv_regobj="${srv_regobj} s390x-linux64.o"
srv_tgtobj="linux-low.o linux-s390-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-s390-low.o"
srv_xmlfiles="s390-linux32.xml"
srv_xmlfiles="${srv_xmlfiles} s390-linux64.xml"
srv_xmlfiles="${srv_xmlfiles} s390x-linux64.xml"
@ -230,13 +230,13 @@ case "${target}" in
srv_linux_thread_db=yes
;;
sh*-*-linux*) srv_regobj=reg-sh.o
srv_tgtobj="linux-low.o linux-sh-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-sh-low.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
sparc*-*-linux*) srv_regobj=reg-sparc64.o
srv_tgtobj="linux-low.o linux-sparc-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-sparc-low.o"
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
@ -244,7 +244,7 @@ case "${target}" in
srv_tgtobj="spu-low.o"
;;
x86_64-*-linux*) srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
srv_tgtobj="linux-low.o linux-x86-low.o i386-low.o i387-fp.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o"
srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
srv_linux_usrregs=yes # This is for i386 progs.
srv_linux_regsets=yes
@ -258,7 +258,7 @@ case "${target}" in
;;
xtensa*-*-linux*) srv_regobj=reg-xtensa.o
srv_tgtobj="linux-low.o linux-xtensa-low.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-xtensa-low.o"
srv_linux_regsets=yes
;;
*) echo "Error: target not supported by gdbserver."

View File

@ -30,81 +30,6 @@ int dlls_changed;
struct thread_info *current_inferior;
/* Oft used ptids */
ptid_t null_ptid;
ptid_t minus_one_ptid;
/* Create a ptid given the necessary PID, LWP, and TID components. */
ptid_t
ptid_build (int pid, long lwp, long tid)
{
ptid_t ptid;
ptid.pid = pid;
ptid.lwp = lwp;
ptid.tid = tid;
return ptid;
}
/* Create a ptid from just a pid. */
ptid_t
pid_to_ptid (int pid)
{
return ptid_build (pid, 0, 0);
}
/* Fetch the pid (process id) component from a ptid. */
int
ptid_get_pid (ptid_t ptid)
{
return ptid.pid;
}
/* Fetch the lwp (lightweight process) component from a ptid. */
long
ptid_get_lwp (ptid_t ptid)
{
return ptid.lwp;
}
/* Fetch the tid (thread id) component from a ptid. */
long
ptid_get_tid (ptid_t ptid)
{
return ptid.tid;
}
/* ptid_equal() is used to test equality of two ptids. */
int
ptid_equal (ptid_t ptid1, ptid_t ptid2)
{
return (ptid1.pid == ptid2.pid
&& ptid1.lwp == ptid2.lwp
&& ptid1.tid == ptid2.tid);
}
/* Return true if this ptid represents a process. */
int
ptid_is_pid (ptid_t ptid)
{
if (ptid_equal (minus_one_ptid, ptid))
return 0;
if (ptid_equal (null_ptid, ptid))
return 0;
return (ptid_get_pid (ptid) != 0
&& ptid_get_lwp (ptid) == 0
&& ptid_get_tid (ptid) == 0);
}
#define get_thread(inf) ((struct thread_info *)(inf))
#define get_dll(inf) ((struct dll_info *)(inf))
@ -518,10 +443,3 @@ current_process (void)
return get_thread_process (current_inferior);
}
void
initialize_inferiors (void)
{
null_ptid = ptid_build (0, 0, 0);
minus_one_ptid = ptid_build (-1, 0, 0);
}

View File

@ -19,6 +19,7 @@
#include "server.h"
#include "linux-low.h"
#include "linux-osdata.h"
#include <sys/wait.h>
#include <stdio.h>
@ -118,7 +119,6 @@ static int linux_wait_for_event (ptid_t ptid, int *wstat, int options);
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);
@ -4386,265 +4386,12 @@ linux_read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p)
}
#endif
static int
compare_ints (const void *xa, const void *xb)
{
int a = *(const int *)xa;
int b = *(const int *)xb;
return a - b;
}
static int *
unique (int *b, int *e)
{
int *d = b;
while (++b != e)
if (*d != *b)
*++d = *b;
return ++d;
}
/* Given PID, iterates over all threads in that process.
Information about each thread, in a format suitable for qXfer:osdata:thread
is printed to BUFFER, if it's not NULL. BUFFER is assumed to be already
initialized, and the caller is responsible for finishing and appending '\0'
to it.
The list of cores that threads are running on is assigned to *CORES, if it
is not NULL. If no cores are found, *CORES will be set to NULL. Caller
should free *CORES. */
static void
list_threads (int pid, struct buffer *buffer, char **cores)
{
int count = 0;
int allocated = 10;
int *core_numbers = xmalloc (sizeof (int) * allocated);
char pathname[128];
DIR *dir;
struct dirent *dp;
struct stat statbuf;
sprintf (pathname, "/proc/%d/task", pid);
if (stat (pathname, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
{
dir = opendir (pathname);
if (!dir)
{
free (core_numbers);
return;
}
while ((dp = readdir (dir)) != NULL)
{
unsigned long lwp = strtoul (dp->d_name, NULL, 10);
if (lwp != 0)
{
unsigned core = linux_core_of_thread (ptid_build (pid, lwp, 0));
if (core != -1)
{
char s[sizeof ("4294967295")];
sprintf (s, "%u", core);
if (count == allocated)
{
allocated *= 2;
core_numbers = realloc (core_numbers,
sizeof (int) * allocated);
}
core_numbers[count++] = core;
if (buffer)
buffer_xml_printf (buffer,
"<item>"
"<column name=\"pid\">%d</column>"
"<column name=\"tid\">%s</column>"
"<column name=\"core\">%s</column>"
"</item>", pid, dp->d_name, s);
}
else
{
if (buffer)
buffer_xml_printf (buffer,
"<item>"
"<column name=\"pid\">%d</column>"
"<column name=\"tid\">%s</column>"
"</item>", pid, dp->d_name);
}
}
}
closedir (dir);
}
if (cores)
{
*cores = NULL;
if (count > 0)
{
struct buffer buffer2;
int *b;
int *e;
qsort (core_numbers, count, sizeof (int), compare_ints);
/* Remove duplicates. */
b = core_numbers;
e = unique (b, core_numbers + count);
buffer_init (&buffer2);
for (b = core_numbers; b != e; ++b)
{
char number[sizeof ("4294967295")];
sprintf (number, "%u", *b);
buffer_xml_printf (&buffer2, "%s%s",
(b == core_numbers) ? "" : ",", number);
}
buffer_grow_str0 (&buffer2, "");
*cores = buffer_finish (&buffer2);
}
}
free (core_numbers);
}
static void
show_process (int pid, const char *username, struct buffer *buffer)
{
char pathname[128];
FILE *f;
char cmd[MAXPATHLEN + 1];
sprintf (pathname, "/proc/%d/cmdline", pid);
if ((f = fopen (pathname, "r")) != NULL)
{
size_t len = fread (cmd, 1, sizeof (cmd) - 1, f);
if (len > 0)
{
char *cores = 0;
int i;
for (i = 0; i < len; i++)
if (cmd[i] == '\0')
cmd[i] = ' ';
cmd[len] = '\0';
buffer_xml_printf (buffer,
"<item>"
"<column name=\"pid\">%d</column>"
"<column name=\"user\">%s</column>"
"<column name=\"command\">%s</column>",
pid,
username,
cmd);
/* This only collects core numbers, and does not print threads. */
list_threads (pid, NULL, &cores);
if (cores)
{
buffer_xml_printf (buffer,
"<column name=\"cores\">%s</column>", cores);
free (cores);
}
buffer_xml_printf (buffer, "</item>");
}
fclose (f);
}
}
static int
linux_qxfer_osdata (const char *annex,
unsigned char *readbuf, unsigned const char *writebuf,
CORE_ADDR offset, int len)
{
/* We make the process list snapshot when the object starts to be
read. */
static const char *buf;
static long len_avail = -1;
static struct buffer buffer;
int processes = 0;
int threads = 0;
DIR *dirp;
if (strcmp (annex, "processes") == 0)
processes = 1;
else if (strcmp (annex, "threads") == 0)
threads = 1;
else
return 0;
if (!readbuf || writebuf)
return 0;
if (offset == 0)
{
if (len_avail != -1 && len_avail != 0)
buffer_free (&buffer);
len_avail = 0;
buf = NULL;
buffer_init (&buffer);
if (processes)
buffer_grow_str (&buffer, "<osdata type=\"processes\">");
else if (threads)
buffer_grow_str (&buffer, "<osdata type=\"threads\">");
dirp = opendir ("/proc");
if (dirp)
{
struct dirent *dp;
while ((dp = readdir (dirp)) != NULL)
{
struct stat statbuf;
char procentry[sizeof ("/proc/4294967295")];
if (!isdigit (dp->d_name[0])
|| strlen (dp->d_name) > sizeof ("4294967295") - 1)
continue;
sprintf (procentry, "/proc/%s", dp->d_name);
if (stat (procentry, &statbuf) == 0
&& S_ISDIR (statbuf.st_mode))
{
int pid = (int) strtoul (dp->d_name, NULL, 10);
if (processes)
{
struct passwd *entry = getpwuid (statbuf.st_uid);
show_process (pid, entry ? entry->pw_name : "?", &buffer);
}
else if (threads)
{
list_threads (pid, &buffer, NULL);
}
}
}
closedir (dirp);
}
buffer_grow_str0 (&buffer, "</osdata>\n");
buf = buffer_finish (&buffer);
len_avail = strlen (buf);
}
if (offset >= len_avail)
{
/* Done. Get rid of the data. */
buffer_free (&buffer);
buf = NULL;
len_avail = 0;
return 0;
}
if (len > len_avail - offset)
len = len_avail - offset;
memcpy (readbuf, buf + offset, len);
return len;
return linux_common_xfer_osdata (annex, readbuf, offset, len);
}
/* Convert a native/host siginfo object, into/from the siginfo in the
@ -4907,63 +4654,6 @@ linux_qxfer_spu (const char *annex, unsigned char *readbuf,
return ret;
}
static int
linux_core_of_thread (ptid_t ptid)
{
char filename[sizeof ("/proc//task//stat")
+ 2 * 20 /* decimal digits for 2 numbers, max 2^64 bit each */
+ 1];
FILE *f;
char *content = NULL;
char *p;
char *ts = 0;
int content_read = 0;
int i;
int core;
sprintf (filename, "/proc/%d/task/%ld/stat",
ptid_get_pid (ptid), ptid_get_lwp (ptid));
f = fopen (filename, "r");
if (!f)
return -1;
for (;;)
{
int n;
content = realloc (content, content_read + 1024);
n = fread (content + content_read, 1, 1024, f);
content_read += n;
if (n < 1024)
{
content[content_read] = '\0';
break;
}
}
p = strchr (content, '(');
/* Skip ")". */
if (p != NULL)
p = strchr (p, ')');
if (p != NULL)
p++;
/* If the first field after program name has index 0, then core number is
the field with index 36. There's no constant for that anywhere. */
if (p != NULL)
p = strtok_r (p, " ", &ts);
for (i = 0; p != NULL && i != 36; ++i)
p = strtok_r (NULL, " ", &ts);
if (p == NULL || sscanf (p, "%d", &core) == 0)
core = -1;
free (content);
fclose (f);
return core;
}
static void
linux_process_qsupported (const char *query)
{
@ -5111,7 +4801,7 @@ static struct target_ops linux_target_ops = {
#else
NULL,
#endif
linux_core_of_thread,
linux_common_core_of_thread,
linux_process_qsupported,
linux_supports_tracepoints,
linux_read_pc,

View File

@ -1714,168 +1714,4 @@ monitor_output (const char *msg)
free (buf);
}
/* Return a malloc allocated string with special characters from TEXT
replaced by entity references. */
char *
xml_escape_text (const char *text)
{
char *result;
int i, special;
/* Compute the length of the result. */
for (i = 0, special = 0; text[i] != '\0'; i++)
switch (text[i])
{
case '\'':
case '\"':
special += 5;
break;
case '&':
special += 4;
break;
case '<':
case '>':
special += 3;
break;
default:
break;
}
/* Expand the result. */
result = xmalloc (i + special + 1);
for (i = 0, special = 0; text[i] != '\0'; i++)
switch (text[i])
{
case '\'':
strcpy (result + i + special, "&apos;");
special += 5;
break;
case '\"':
strcpy (result + i + special, "&quot;");
special += 5;
break;
case '&':
strcpy (result + i + special, "&amp;");
special += 4;
break;
case '<':
strcpy (result + i + special, "&lt;");
special += 3;
break;
case '>':
strcpy (result + i + special, "&gt;");
special += 3;
break;
default:
result[i + special] = text[i];
break;
}
result[i + special] = '\0';
return result;
}
void
buffer_grow (struct buffer *buffer, const char *data, size_t size)
{
char *new_buffer;
size_t new_buffer_size;
if (size == 0)
return;
new_buffer_size = buffer->buffer_size;
if (new_buffer_size == 0)
new_buffer_size = 1;
while (buffer->used_size + size > new_buffer_size)
new_buffer_size *= 2;
new_buffer = realloc (buffer->buffer, new_buffer_size);
if (!new_buffer)
abort ();
memcpy (new_buffer + buffer->used_size, data, size);
buffer->buffer = new_buffer;
buffer->buffer_size = new_buffer_size;
buffer->used_size += size;
}
void
buffer_free (struct buffer *buffer)
{
if (!buffer)
return;
free (buffer->buffer);
buffer->buffer = NULL;
buffer->buffer_size = 0;
buffer->used_size = 0;
}
void
buffer_init (struct buffer *buffer)
{
memset (buffer, 0, sizeof (*buffer));
}
char*
buffer_finish (struct buffer *buffer)
{
char *ret = buffer->buffer;
buffer->buffer = NULL;
buffer->buffer_size = 0;
buffer->used_size = 0;
return ret;
}
void
buffer_xml_printf (struct buffer *buffer, const char *format, ...)
{
va_list ap;
const char *f;
const char *prev;
int percent = 0;
va_start (ap, format);
prev = format;
for (f = format; *f; f++)
{
if (percent)
{
switch (*f)
{
case 's':
{
char *p;
char *a = va_arg (ap, char *);
buffer_grow (buffer, prev, f - prev - 1);
p = xml_escape_text (a);
buffer_grow_str (buffer, p);
free (p);
prev = f + 1;
}
break;
case 'd':
{
int i = va_arg (ap, int);
char b[sizeof ("4294967295")];
buffer_grow (buffer, prev, f - prev - 1);
sprintf (b, "%d", i);
buffer_grow_str (buffer, b);
prev = f + 1;
}
}
percent = 0;
}
else if (*f == '%')
percent = 1;
}
buffer_grow_str (buffer, prev);
va_end (ap);
}
#endif

View File

@ -2582,7 +2582,6 @@ main (int argc, char *argv[])
exit (1);
}
initialize_inferiors ();
initialize_async_io ();
initialize_low ();
if (target_supports_tracepoints ())

View File

@ -105,6 +105,11 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap);
/* A type used for binary buffers. */
typedef unsigned char gdb_byte;
#include "ptid.h"
#include "buffer.h"
#include "xml-utils.h"
#include "gdb_locale.h"
/* FIXME: This should probably be autoconf'd for. It's an integer type at
least the size of a (void *). */
typedef long long CORE_ADDR;
@ -112,68 +117,6 @@ typedef long long CORE_ADDR;
typedef long long LONGEST;
typedef unsigned long long ULONGEST;
/* The ptid struct is a collection of the various "ids" necessary
for identifying the inferior. This consists of the process id
(pid), thread id (tid), and other fields necessary for uniquely
identifying the inferior process/thread being debugged. When
manipulating ptids, the constructors, accessors, and predicate
declared in server.h should be used. These are as follows:
ptid_build - Make a new ptid from a pid, lwp, and tid.
pid_to_ptid - Make a new ptid from just a pid.
ptid_get_pid - Fetch the pid component of a ptid.
ptid_get_lwp - Fetch the lwp component of a ptid.
ptid_get_tid - Fetch the tid component of a ptid.
ptid_equal - Test to see if two ptids are equal.
Please do NOT access the struct ptid members directly (except, of
course, in the implementation of the above ptid manipulation
functions). */
struct ptid
{
/* Process id */
int pid;
/* Lightweight process id */
long lwp;
/* Thread id */
long tid;
};
typedef struct ptid ptid_t;
/* The -1 ptid, often used to indicate either an error condition or a
"don't care" condition, i.e, "run all threads". */
extern ptid_t minus_one_ptid;
/* The null or zero ptid, often used to indicate no process. */
extern ptid_t null_ptid;
/* Attempt to find and return an existing ptid with the given PID,
LWP, and TID components. If none exists, create a new one and
return that. */
ptid_t ptid_build (int pid, long lwp, long tid);
/* Create a ptid from just a pid. */
ptid_t pid_to_ptid (int pid);
/* Fetch the pid (process id) component from a ptid. */
int ptid_get_pid (ptid_t ptid);
/* Fetch the lwp (lightweight process) component from a ptid. */
long ptid_get_lwp (ptid_t ptid);
/* Fetch the tid (thread id) component from a ptid. */
long ptid_get_tid (ptid_t ptid);
/* Compare two ptids to see if they are equal. */
extern int ptid_equal (ptid_t p1, ptid_t p2);
/* Return true if this ptid represents a process id. */
extern int ptid_is_pid (ptid_t ptid);
/* Generic information for tracking a list of ``inferiors'' - threads,
processes, etc. */
struct inferior_list
@ -294,8 +237,6 @@ extern struct inferior_list all_threads;
extern struct inferior_list all_dlls;
extern int dlls_changed;
void initialize_inferiors (void);
void add_inferior_to_list (struct inferior_list *list,
struct inferior_list_entry *new_inferior);
void for_each_inferior (struct inferior_list *list,
@ -454,43 +395,8 @@ int relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc);
void monitor_output (const char *msg);
char *xml_escape_text (const char *text);
/* Simple growing buffer. */
struct buffer
{
char *buffer;
size_t buffer_size; /* allocated size */
size_t used_size; /* actually used size */
};
/* Append DATA of size SIZE to the end of BUFFER. Grows the buffer to
accommodate the new data. */
void buffer_grow (struct buffer *buffer, const char *data, size_t size);
/* Release any memory held by BUFFER. */
void buffer_free (struct buffer *buffer);
/* Initialize BUFFER. BUFFER holds no memory afterwards. */
void buffer_init (struct buffer *buffer);
/* Return a pointer into BUFFER data, effectivelly transfering
ownership of the buffer memory to the caller. Calling buffer_free
afterwards has no effect on the returned data. */
char* buffer_finish (struct buffer *buffer);
/* Simple printf to BUFFER function. Current implemented formatters:
%s - grow an xml escaped text in OBSTACK. */
void buffer_xml_printf (struct buffer *buffer, const char *format, ...)
ATTR_FORMAT (printf, 2, 3);
#define buffer_grow_str(BUFFER,STRING) \
buffer_grow (BUFFER, STRING, strlen (STRING))
#define buffer_grow_str0(BUFFER,STRING) \
buffer_grow (BUFFER, STRING, strlen (STRING) + 1)
/* Functions from utils.c */
#include "common-utils.h"
void *xmalloc (size_t) ATTR_MALLOC;
void *xrealloc (void *, size_t);
@ -502,8 +408,6 @@ void freeargv (char **argv);
void perror_with_name (const char *string);
void error (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
void fatal (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
void internal_error (const char *file, int line, const char *, ...)
ATTR_NORETURN ATTR_FORMAT (printf, 3, 4);
void warning (const char *string,...) ATTR_FORMAT (printf, 1, 2);
char *paddress (CORE_ADDR addr);
char *pulongest (ULONGEST u);
@ -511,33 +415,7 @@ char *plongest (LONGEST l);
char *phex_nz (ULONGEST l, int sizeof_l);
char *pfildes (gdb_fildes_t fd);
#define gdb_assert(expr) \
((void) ((expr) ? 0 : \
(gdb_assert_fail (#expr, __FILE__, __LINE__, ASSERT_FUNCTION), 0)))
/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
which contains the name of the function currently being defined.
This is broken in G++ before version 2.6.
C9x has a similar variable called __func__, but prefer the GCC one since
it demangles C++ function names. */
#if (GCC_VERSION >= 2004)
#define ASSERT_FUNCTION __PRETTY_FUNCTION__
#else
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#define ASSERT_FUNCTION __func__
#endif
#endif
/* This prints an "Assertion failed" message, and exits. */
#if defined (ASSERT_FUNCTION)
#define gdb_assert_fail(assertion, file, line, function) \
internal_error (file, line, "%s: Assertion `%s' failed.", \
function, assertion)
#else
#define gdb_assert_fail(assertion, file, line, function) \
internal_error (file, line, "Assertion `%s' failed.", \
assertion)
#endif
#include "gdb_assert.h"
/* Maximum number of bytes to read/write at once. The value here
is chosen to fill up a packet (the headers account for the 32). */

View File

@ -35,10 +35,8 @@
/* Generally useful subroutines used throughout the program. */
static void malloc_failure (size_t size) ATTR_NORETURN;
static void
malloc_failure (size_t size)
void
malloc_failure (long size)
{
fprintf (stderr,
PREFIX "ran out of memory while trying to allocate %lu bytes\n",
@ -46,61 +44,6 @@ malloc_failure (size_t size)
exit (1);
}
/* Allocate memory without fail.
If malloc fails, this will print a message to stderr and exit. */
void *
xmalloc (size_t size)
{
void *newmem;
if (size == 0)
size = 1;
newmem = malloc (size);
if (!newmem)
malloc_failure (size);
return newmem;
}
/* Reallocate memory without fail. This works like xmalloc. */
void *
xrealloc (void *ptr, size_t size)
{
void *val;
if (size == 0)
size = 1;
if (ptr != NULL)
val = realloc (ptr, size); /* OK: realloc */
else
val = malloc (size); /* OK: malloc */
if (val == NULL)
malloc_failure (size);
return val;
}
/* Allocate memory without fail and set it to zero.
If malloc fails, this will print a message to stderr and exit. */
void *
xcalloc (size_t nelem, size_t elsize)
{
void *newmem;
if (nelem == 0 || elsize == 0)
nelem = elsize = 1;
newmem = calloc (nelem, elsize);
if (!newmem)
malloc_failure (nelem * elsize);
return newmem;
}
/* Copy a string into a memory buffer.
If malloc fails, this will print a message to stderr and exit. */
@ -239,22 +182,6 @@ get_cell (void)
return buf[cell];
}
/* Stdarg wrapper around vsnprintf.
SIZE is the size of the buffer pointed to by STR. */
int
xsnprintf (char *str, size_t size, const char *format, ...)
{
va_list args;
int ret;
va_start (args, format);
ret = vsnprintf (str, size, format, args);
va_end (args);
return ret;
}
static char *
decimal2str (char *sign, ULONGEST addr)
{

View File

@ -32,6 +32,8 @@ struct regcache;
struct ui_out;
struct terminal_info;
#include "ptid.h"
/* For bpstat. */
#include "breakpoint.h"
@ -63,36 +65,6 @@ extern void discard_infcall_control_state (struct infcall_control_state *);
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

View File

@ -6803,77 +6803,6 @@ inferior_has_called_syscall (ptid_t pid, int *syscall_number)
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)
{
@ -7263,8 +7192,6 @@ Tells gdb whether to detach the child of a fork."),
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;

View File

@ -57,6 +57,7 @@
#include "terminal.h"
#include <sys/vfs.h>
#include "solib.h"
#include "linux-osdata.h"
#ifndef SPUFS_MAGIC
#define SPUFS_MAGIC 0x23c9b64e
@ -5114,148 +5115,9 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
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

View File

@ -1210,7 +1210,7 @@ quit (void)
memory requested in SIZE. */
void
nomem (long size)
malloc_failure (long size)
{
if (size > 0)
{
@ -1224,146 +1224,6 @@ nomem (long size)
}
}
/* The xmalloc() (libiberty.h) family of memory management routines.
These are like the ISO-C malloc() family except that they implement
consistent semantics and guard against typical memory management
problems. */
/* NOTE: These are declared using PTR to ensure consistency with
"libiberty.h". xfree() is GDB local. */
PTR /* ARI: PTR */
xmalloc (size_t size)
{
void *val;
/* See libiberty/xmalloc.c. This function need's to match that's
semantics. It never returns NULL. */
if (size == 0)
size = 1;
val = malloc (size); /* ARI: malloc */
if (val == NULL)
nomem (size);
return (val);
}
void *
xzalloc (size_t size)
{
return xcalloc (1, size);
}
PTR /* ARI: PTR */
xrealloc (PTR ptr, size_t size) /* ARI: PTR */
{
void *val;
/* See libiberty/xmalloc.c. This function need's to match that's
semantics. It never returns NULL. */
if (size == 0)
size = 1;
if (ptr != NULL)
val = realloc (ptr, size); /* ARI: realloc */
else
val = malloc (size); /* ARI: malloc */
if (val == NULL)
nomem (size);
return (val);
}
PTR /* ARI: PTR */
xcalloc (size_t number, size_t size)
{
void *mem;
/* See libiberty/xmalloc.c. This function need's to match that's
semantics. It never returns NULL. */
if (number == 0 || size == 0)
{
number = 1;
size = 1;
}
mem = calloc (number, size); /* ARI: xcalloc */
if (mem == NULL)
nomem (number * size);
return mem;
}
void
xfree (void *ptr)
{
if (ptr != NULL)
free (ptr); /* ARI: free */
}
/* Like asprintf/vasprintf but get an internal_error if the call
fails. */
char *
xstrprintf (const char *format, ...)
{
char *ret;
va_list args;
va_start (args, format);
ret = xstrvprintf (format, args);
va_end (args);
return ret;
}
void
xasprintf (char **ret, const char *format, ...)
{
va_list args;
va_start (args, format);
(*ret) = xstrvprintf (format, args);
va_end (args);
}
void
xvasprintf (char **ret, const char *format, va_list ap)
{
(*ret) = xstrvprintf (format, ap);
}
char *
xstrvprintf (const char *format, va_list ap)
{
char *ret = NULL;
int status = vasprintf (&ret, format, ap);
/* NULL is returned when there was a memory allocation problem, or
any other error (for instance, a bad format string). A negative
status (the printed length) with a non-NULL buffer should never
happen, but just to be sure. */
if (ret == NULL || status < 0)
internal_error (__FILE__, __LINE__, _("vasprintf call failed"));
return ret;
}
int
xsnprintf (char *str, size_t size, const char *format, ...)
{
va_list args;
int ret;
va_start (args, format);
ret = vsnprintf (str, size, format, args);
gdb_assert (ret < size);
va_end (args);
return ret;
}
/* My replacement for the read system call.
Used like `read' but keeps going if `read' returns too soon. */
@ -1385,7 +1245,7 @@ myread (int desc, char *addr, int len)
}
return orglen;
}
/* Make a copy of the string at PTR with SIZE characters
(and add a null character at the end in the copy).
Uses malloc to get the space. Returns the address of the copy. */
@ -3741,7 +3601,7 @@ gdb_buildargv (const char *s)
char **argv = buildargv (s);
if (s != NULL && argv == NULL)
nomem (0);
malloc_failure (0);
return argv;
}

View File

@ -458,7 +458,7 @@ gdb_xml_create_parser_and_cleanup_1 (const char *name,
if (parser->expat_parser == NULL)
{
xfree (parser);
nomem (0);
malloc_failure (0);
}
parser->name = name;
@ -990,68 +990,6 @@ show_debug_xml (struct ui_file *file, int from_tty,
fprintf_filtered (file, _("XML debugging is %s.\n"), value);
}
/* Return a malloc allocated string with special characters from TEXT
replaced by entity references. */
char *
xml_escape_text (const char *text)
{
char *result;
int i, special;
/* Compute the length of the result. */
for (i = 0, special = 0; text[i] != '\0'; i++)
switch (text[i])
{
case '\'':
case '\"':
special += 5;
break;
case '&':
special += 4;
break;
case '<':
case '>':
special += 3;
break;
default:
break;
}
/* Expand the result. */
result = xmalloc (i + special + 1);
for (i = 0, special = 0; text[i] != '\0'; i++)
switch (text[i])
{
case '\'':
strcpy (result + i + special, "&apos;");
special += 5;
break;
case '\"':
strcpy (result + i + special, "&quot;");
special += 5;
break;
case '&':
strcpy (result + i + special, "&amp;");
special += 4;
break;
case '<':
strcpy (result + i + special, "&lt;");
special += 3;
break;
case '>':
strcpy (result + i + special, "&gt;");
special += 3;
break;
default:
result[i + special] = text[i];
break;
}
result[i + special] = '\0';
return result;
}
void
obstack_xml_printf (struct obstack *obstack, const char *format, ...)
{
@ -1106,7 +1044,7 @@ xml_fetch_content_from_file (const char *filename, void *baton)
char *fullname = concat (dirname, "/", filename, (char *) NULL);
if (fullname == NULL)
nomem (0);
malloc_failure (0);
file = fopen (fullname, FOPEN_RT);
xfree (fullname);
}

View File

@ -24,6 +24,7 @@
#include "gdb_obstack.h"
#include "vec.h"
#include "xml-utils.h"
struct gdb_xml_parser;
struct gdb_xml_element;
@ -48,11 +49,6 @@ LONGEST xml_builtin_xfer_partial (const char *filename,
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. */