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:
parent
edc8499054
commit
d26e3629bb
@ -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.
|
||||
|
@ -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
144
gdb/common/buffer.c
Normal 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
63
gdb/common/buffer.h
Normal 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
170
gdb/common/common-utils.c
Normal 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
59
gdb/common/common-utils.h
Normal 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
586
gdb/common/linux-osdata.c
Normal 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
29
gdb/common/linux-osdata.h
Normal 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
94
gdb/common/ptid.c
Normal 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
87
gdb/common/ptid.h
Normal 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
91
gdb/common/xml-utils.c
Normal 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, "'");
|
||||
special += 5;
|
||||
break;
|
||||
case '\"':
|
||||
strcpy (result + i + special, """);
|
||||
special += 5;
|
||||
break;
|
||||
case '&':
|
||||
strcpy (result + i + special, "&");
|
||||
special += 4;
|
||||
break;
|
||||
case '<':
|
||||
strcpy (result + i + special, "<");
|
||||
special += 3;
|
||||
break;
|
||||
case '>':
|
||||
strcpy (result + i + special, ">");
|
||||
special += 3;
|
||||
break;
|
||||
default:
|
||||
result[i + special] = text[i];
|
||||
break;
|
||||
}
|
||||
result[i + special] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
29
gdb/common/xml-utils.h
Normal file
29
gdb/common/xml-utils.h
Normal 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
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
70
gdb/defs.h
70
gdb/defs.h
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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
|
||||
|
||||
|
159
gdb/gdbserver/configure
vendored
159
gdb/gdbserver/configure
vendored
@ -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!
|
||||
|
@ -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
|
||||
|
@ -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."
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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, "'");
|
||||
special += 5;
|
||||
break;
|
||||
case '\"':
|
||||
strcpy (result + i + special, """);
|
||||
special += 5;
|
||||
break;
|
||||
case '&':
|
||||
strcpy (result + i + special, "&");
|
||||
special += 4;
|
||||
break;
|
||||
case '<':
|
||||
strcpy (result + i + special, "<");
|
||||
special += 3;
|
||||
break;
|
||||
case '>':
|
||||
strcpy (result + i + special, ">");
|
||||
special += 3;
|
||||
break;
|
||||
default:
|
||||
result[i + special] = text[i];
|
||||
break;
|
||||
}
|
||||
result[i + special] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_grow (struct buffer *buffer, const char *data, size_t size)
|
||||
{
|
||||
char *new_buffer;
|
||||
size_t new_buffer_size;
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
new_buffer_size = buffer->buffer_size;
|
||||
|
||||
if (new_buffer_size == 0)
|
||||
new_buffer_size = 1;
|
||||
|
||||
while (buffer->used_size + size > new_buffer_size)
|
||||
new_buffer_size *= 2;
|
||||
new_buffer = realloc (buffer->buffer, new_buffer_size);
|
||||
if (!new_buffer)
|
||||
abort ();
|
||||
memcpy (new_buffer + buffer->used_size, data, size);
|
||||
buffer->buffer = new_buffer;
|
||||
buffer->buffer_size = new_buffer_size;
|
||||
buffer->used_size += size;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_free (struct buffer *buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
free (buffer->buffer);
|
||||
buffer->buffer = NULL;
|
||||
buffer->buffer_size = 0;
|
||||
buffer->used_size = 0;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_init (struct buffer *buffer)
|
||||
{
|
||||
memset (buffer, 0, sizeof (*buffer));
|
||||
}
|
||||
|
||||
char*
|
||||
buffer_finish (struct buffer *buffer)
|
||||
{
|
||||
char *ret = buffer->buffer;
|
||||
buffer->buffer = NULL;
|
||||
buffer->buffer_size = 0;
|
||||
buffer->used_size = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_xml_printf (struct buffer *buffer, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *f;
|
||||
const char *prev;
|
||||
int percent = 0;
|
||||
|
||||
va_start (ap, format);
|
||||
|
||||
prev = format;
|
||||
for (f = format; *f; f++)
|
||||
{
|
||||
if (percent)
|
||||
{
|
||||
switch (*f)
|
||||
{
|
||||
case 's':
|
||||
{
|
||||
char *p;
|
||||
char *a = va_arg (ap, char *);
|
||||
buffer_grow (buffer, prev, f - prev - 1);
|
||||
p = xml_escape_text (a);
|
||||
buffer_grow_str (buffer, p);
|
||||
free (p);
|
||||
prev = f + 1;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
{
|
||||
int i = va_arg (ap, int);
|
||||
char b[sizeof ("4294967295")];
|
||||
|
||||
buffer_grow (buffer, prev, f - prev - 1);
|
||||
sprintf (b, "%d", i);
|
||||
buffer_grow_str (buffer, b);
|
||||
prev = f + 1;
|
||||
}
|
||||
}
|
||||
percent = 0;
|
||||
}
|
||||
else if (*f == '%')
|
||||
percent = 1;
|
||||
}
|
||||
|
||||
buffer_grow_str (buffer, prev);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2582,7 +2582,6 @@ main (int argc, char *argv[])
|
||||
exit (1);
|
||||
}
|
||||
|
||||
initialize_inferiors ();
|
||||
initialize_async_io ();
|
||||
initialize_low ();
|
||||
if (target_supports_tracepoints ())
|
||||
|
@ -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). */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
73
gdb/infrun.c
73
gdb/infrun.c
@ -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;
|
||||
|
||||
|
142
gdb/linux-nat.c
142
gdb/linux-nat.c
@ -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
|
||||
|
146
gdb/utils.c
146
gdb/utils.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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, "'");
|
||||
special += 5;
|
||||
break;
|
||||
case '\"':
|
||||
strcpy (result + i + special, """);
|
||||
special += 5;
|
||||
break;
|
||||
case '&':
|
||||
strcpy (result + i + special, "&");
|
||||
special += 4;
|
||||
break;
|
||||
case '<':
|
||||
strcpy (result + i + special, "<");
|
||||
special += 3;
|
||||
break;
|
||||
case '>':
|
||||
strcpy (result + i + special, ">");
|
||||
special += 3;
|
||||
break;
|
||||
default:
|
||||
result[i + special] = text[i];
|
||||
break;
|
||||
}
|
||||
result[i + special] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
obstack_xml_printf (struct obstack *obstack, const char *format, ...)
|
||||
{
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user