tools/debugger/gdb: Remove gdb

This code is not maintained, does not work properly, and no-one is
using it.  Delete it, following discussion on xen-devel.
This commit is contained in:
Ian Jackson committed 2010-07-02 17:46:01 +01:00
1 parent cb2b6edf55
commit baa1aae9cf
9 files changed
-6678

No files matched your search

-38
View File
@@ -1,38 +0,0 @@
DomU & HVM GDB server for 32-bit (PAE and non-PAE) and x86_64 systems
----------------------------------------------------
Lines marked below with [*] are optional, if you want full
source-level debugging of your kernel image.
To build the GDB server:
0. Build rest of the Xen first from the base directory
1. Run ./gdbbuild from within this directory.
2. Copy ./gdb-6.2.1-linux-i386-xen/gdb/gdbserver/gdbserver-xen
to your test machine.
To build a debuggable guest domU kernel image:
1. cd linux-2.6.xx-xenU
2. make menuconfig
3. From within the configurator, enable the following options:
# Kernel hacking -> Compile the kernel with debug info [*]
-> Compile the kernel with frame pointers
4. (Re)build and (re)install your xenU kernel image.
To debug a running guest:
1. Use 'xm list' to discover its domain id ($domid).
2. Run 'gdbserver-xen 127.0.0.1:9999 --attach $domid'.
3. Run 'gdb /path/to/vmlinux-syms-2.6.xx-xenU'.
4. From within the gdb client session:
# directory /path/to/linux-2.6.xx-xenU [*]
# target remote 127.0.0.1:9999
# bt
# disass
To debug a crashed domU guest:
1. Add '(enable-dump yes)' to /etc/xen/xend-config.sxp before
starting xend.
2. When the domain crashes, a core file is written to
'/var/xen/dump/<domain-name>.<domain-id>.core'.
3. Run 'gdbserver-xen 127.0.0.1:9999 --file <core-file>'.
4. Connect to the server as for a running guest.
@@ -1,308 +0,0 @@
# Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
# 1999, 2000, 2001, 2002, 2003, 2004 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 2 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
prefix = @prefix@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
target_alias = @target_alias@
program_transform_name = @program_transform_name@
bindir = @bindir@
libdir = @libdir@
tooldir = $(libdir)/$(target_alias)
datadir = @datadir@
mandir = @mandir@
man1dir = $(mandir)/man1
man2dir = $(mandir)/man2
man3dir = $(mandir)/man3
man4dir = $(mandir)/man4
man5dir = $(mandir)/man5
man6dir = $(mandir)/man6
man7dir = $(mandir)/man7
man8dir = $(mandir)/man8
man9dir = $(mandir)/man9
infodir = @infodir@
htmldir = $(prefix)/html
includedir = @includedir@
SHELL = /bin/sh
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
# Directory containing source files. Don't clean up the spacing,
# this exact string is matched for by the "configure" script.
srcdir = @srcdir@
VPATH = @srcdir@
# It is also possible that you will need to add -I/usr/include/sys to the
# CFLAGS section if your system doesn't have fcntl.h in /usr/include (which
# is where it should be according to Posix).
# Set this up with gcc if you have gnu ld and the loader will print out
# line numbers for undefinded refs.
#CC-LD=gcc -static
CC-LD=${CC}
# Where is the "include" directory? Traditionally ../include or ./include
INCLUDE_DIR = ${srcdir}/../../include
INCLUDE_DEP = $$(INCLUDE_DIR)
# Where are the BFD library?
BFD_DIR = ../../bfd
BFD = $(BFD_DIR)/libbfd.a
BFD_SRC = $(srcdir)/$(BFD_DIR)
BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC)
# Where is the source dir for the READLINE library? Traditionally in .. or .
# (For the binary library built from it, we use ${READLINE_DIR}${subdir}.)
READLINE_DIR = ${srcdir}/../readline
READLINE_DEP = $$(READLINE_DIR)
# All the includes used for CFLAGS and for lint.
# -I. for config files.
# -I${srcdir} for our headers.
# -I$(srcdir)/../regformats for regdef.h.
INCLUDE_CFLAGS = -I. -I${srcdir} -I$(srcdir)/../regformats -I$(INCLUDE_DIR) -I../../../../../libxc/ -I../../../../../include/
# M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS
# from the config/ directory.
GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS}
#PROFILE_CFLAGS = -pg
WARN_CFLAGS = -Wall
# CFLAGS is specifically reserved for setting from the command line
# when running make. I.E. "make CFLAGS=-Wmissing-prototypes".
CFLAGS = @CFLAGS@
# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
INTERNAL_CFLAGS = $(WARN_CFLAGS) ${CFLAGS} ${GLOBAL_CFLAGS} \
${PROFILE_CFLAGS} ${INCLUDE_CFLAGS} ${BFD_CFLAGS}
# LDFLAGS is specifically reserved for setting from the command line
# when running make.
LDFLAGS = @LDFLAGS@
# Perhaps should come from parent Makefile
VERSION = gdbserver-4.12.3
DIST=gdb
LINT=/usr/5bin/lint
LINTFLAGS= $(BFD_CFLAGS)
# All source files that go into linking GDB remote server.
SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c \
$(srcdir)/mem-break.c $(srcdir)/proc-service.c $(srcdir)/regcache.c \
$(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \
$(srcdir)/thread-db.c $(srcdir)/utils.c \
$(srcdir)/linux-arm-low.c $(srcdir)/linux-i386-low.c \
$(srcdir)/i387-fp.c \
$(srcdir)/linux-ia64-low.c $(srcdir)/linux-low.c \
$(srcdir)/linux-m68k-low.c $(srcdir)/linux-mips-low.c \
$(srcdir)/linux-ppc-low.c $(srcdir)/linux-s390-low.c \
$(srcdir)/linux-sh-low.c $(srcdir)/linux-x86-64-low.c
DEPFILES = @GDBSERVER_DEPFILES@
SOURCES = $(SFILES)
TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
utils.o \
mem-break.o \
$(DEPFILES)
GDBSERVER_LIBS = @GDBSERVER_LIBS@
# Prevent Sun make from putting in the machine type. Setting
# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
.c.o:
${CC} -c ${INTERNAL_CFLAGS} $<
all: gdbserver-xen gdbreplay
# Traditionally "install" depends on "all". But it may be useful
# not to; for example, if the user has made some trivial change to a
# source file and doesn't care about rebuilding or just wants to save the
# time it takes for make to check that all is up to date.
# install-only is intended to address that need.
install: all install-only
install-only:
n=`echo gdbserver-xen | sed '$(program_transform_name)'`; \
if [ x$$n = x ]; then n=gdbserver-xen; else true; fi; \
$(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(bindir); \
$(INSTALL_PROGRAM) gdbserver-xen $(DESTDIR)$(bindir)/$$n; \
$(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(man1dir); \
$(INSTALL_DATA) $(srcdir)/gdbserver.1 $(DESTDIR)$(man1dir)/$$n.1
uninstall: force
n=`echo gdbserver-xen | sed '$(program_transform_name)'`; \
if [ x$$n = x ]; then n=gdbserver-xen; else true; fi; \
rm -f $(bindir)/$$n $(DESTDIR)$(man1dir)/$$n.1
installcheck:
check:
info dvi:
install-info:
html:
install-html:
clean-info:
gdbserver-xen: $(OBS) ${ADD_DEPS} ${CDEPS}
rm -f gdbserver-xen
${CC-LD} $(GLOBAL_CFLAGS) $(LDFLAGS) -o gdbserver-xen $(OBS) \
$(GDBSERVER_LIBS) $(XM_CLIBS)
gdbreplay: gdbreplay.o
rm -f gdbreplay
${CC-LD} $(GLOBAL_CFLAGS) $(LDFLAGS) -o gdbreplay gdbreplay.o \
$(XM_CLIBS)
# Put the proper machine-specific files first, so M-. on a machine
# specific routine gets the one for the correct machine.
# The xyzzy stuff below deals with empty DEPFILES
TAGS: ${TAGFILES}
etags `find ${srcdir}/../config -name $(TM_FILE) -print` \
`find ${srcdir}/../config -name ${XM_FILE} -print` \
`find ${srcdir}/../config -name ${NAT_FILE} -print` \
`for i in yzzy ${DEPFILES}; do \
if [ x$$i != xyzzy ]; then \
echo ${srcdir}/$$i | sed -e 's/\.o$$/\.c/' ; \
fi; \
done` \
${TAGFILES}
tags: TAGS
clean:
rm -f *.o ${ADD_FILES} *~
rm -f gdbserver gdbreplay core make.log
rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m68k.c reg-mips.c
rm -f reg-ppc.c reg-sh.c reg-x86-64.c reg-i386-linux.c
maintainer-clean realclean distclean: clean
rm -f nm.h tm.h xm.h config.status config.h stamp-h config.log
rm -f Makefile
STAGESTUFF=${OBS} ${TSOBS} ${NTSOBS} ${ADD_FILES} init.c init.o version.c gdb
config.h: stamp-h ; @true
stamp-h: config.in config.status
CONFIG_FILES="" $(SHELL) ./config.status
Makefile: Makefile.in config.status
CONFIG_HEADERS="" $(SHELL) ./config.status
config.status: configure configure.srv
$(SHELL) ./config.status --recheck
force:
version.c: Makefile
echo 'char *version = "$(VERSION)";' >version.c
# GNU Make has an annoying habit of putting *all* the Makefile variables
# into the environment, unless you include this target as a circumvention.
# Rumor is that this will be fixed (and this target can be removed)
# in GNU Make 4.0.
.NOEXPORT:
# GNU Make 3.63 has a different problem: it keeps tacking command line
# overrides onto the definition of $(MAKE). This variable setting
# will remove them.
MAKEOVERRIDES=
gdb_proc_service_h = $(srcdir)/../gdb_proc_service.h $(srcdir)/../gregset.h
regdat_sh = $(srcdir)/../regformats/regdat.sh
regdef_h = $(srcdir)/../regformats/regdef.h
regcache_h = $(srcdir)/regcache.h
server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \
$(srcdir)/mem-break.h
inferiors.o: inferiors.c $(server_h)
mem-break.o: mem-break.c $(server_h)
proc-service.o: proc-service.c $(server_h) $(gdb_proc_service_h)
regcache.o: regcache.c $(server_h) $(regdef_h)
remote-utils.o: remote-utils.c terminal.h $(server_h)
server.o: server.c $(server_h)
target.o: target.c $(server_h)
thread-db.o: thread-db.c $(server_h) $(gdb_proc_service_h)
utils.o: utils.c $(server_h)
signals.o: ../signals/signals.c $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
i387-fp.o: i387-fp.c $(server_h)
linux_low_h = $(srcdir)/linux-low.h
linux-low.o: linux-low.c $(linux_low_h) $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< @USE_THREAD_DB@
linux-xen-low.o: linux-xen-low.c $(linux_low_h) $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< @USE_THREAD_DB@
linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h)
linux-i386-low.o: linux-i386-low.c $(linux_low_h) $(server_h)
linux-ia64-low.o: linux-ia64-low.c $(linux_low_h) $(server_h)
linux-mips-low.o: linux-mips-low.c $(linux_low_h) $(server_h)
linux-ppc-low.o: linux-ppc-low.c $(linux_low_h) $(server_h)
linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
linux-sh-low.o: linux-sh-low.c $(linux_low_h) $(server_h)
linux-x86-64-low.o: linux-x86-64-low.c $(linux_low_h) $(server_h)
reg-arm.o : reg-arm.c $(regdef_h)
reg-arm.c : $(srcdir)/../regformats/reg-arm.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-arm.dat reg-arm.c
reg-i386.o : reg-i386.c $(regdef_h)
reg-i386.c : $(srcdir)/../regformats/reg-i386.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-i386.dat reg-i386.c
reg-i386-linux.o : reg-i386-linux.c $(regdef_h)
reg-i386-linux.c : $(srcdir)/../regformats/reg-i386-linux.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-i386-linux.dat reg-i386-linux.c
reg-ia64.o : reg-ia64.c $(regdef_h)
reg-ia64.c : $(srcdir)/../regformats/reg-ia64.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-ia64.dat reg-ia64.c
reg-m68k.o : reg-m68k.c $(regdef_h)
reg-m68k.c : $(srcdir)/../regformats/reg-m68k.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-m68k.dat reg-m68k.c
reg-mips.o : reg-mips.c $(regdef_h)
reg-mips.c : $(srcdir)/../regformats/reg-mips.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-mips.dat reg-mips.c
reg-ppc.o : reg-ppc.c $(regdef_h)
reg-ppc.c : $(srcdir)/../regformats/reg-ppc.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-ppc.dat reg-ppc.c
reg-s390.o : reg-s390.c $(regdef_h)
reg-s390.c : $(srcdir)/../regformats/reg-s390.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-s390.dat reg-s390.c
reg-s390x.o : reg-s390x.c $(regdef_h)
reg-s390x.c : $(srcdir)/../regformats/reg-s390x.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-s390x.dat reg-s390x.c
reg-sh.o : reg-sh.c $(regdef_h)
reg-sh.c : $(srcdir)/../regformats/reg-sh.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-sh.dat reg-sh.c
reg-x86-64.o : reg-x86-64.c $(regdef_h)
reg-x86-64.c : $(srcdir)/../regformats/reg-x86-64.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-x86-64.dat reg-x86-64.c
# This is the end of "Makefile.in".
File diff suppressed because it is too large. Load diff
@@ -1,121 +0,0 @@
dnl Autoconf configure script for GDB server.
dnl Copyright 2000, 2002 Free Software Foundation, Inc.
dnl
dnl This file is part of GDB.
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
dnl Process this file with autoconf to produce a configure script.
AC_INIT(server.c)
AC_CONFIG_HEADER(config.h:config.in)
AC_PROG_CC
AC_CANONICAL_SYSTEM
AC_PROG_INSTALL
AC_HEADER_STDC
AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
proc_service.h sys/procfs.h thread_db.h linux/elf.h dnl
stdlib.h unistd.h)
BFD_NEED_DECLARATION(strerror)
. ${srcdir}/configure.srv
if test "${srv_linux_usrregs}" = "yes"; then
AC_DEFINE(HAVE_LINUX_USRREGS)
fi
if test "${srv_linux_regsets}" = "yes"; then
AC_MSG_CHECKING(for PTRACE_GETREGS)
AC_CACHE_VAL(gdbsrv_cv_have_ptrace_getregs,
[AC_TRY_COMPILE([#include <sys/ptrace.h>],
[PTRACE_GETREGS;],
[gdbsrv_cv_have_ptrace_getregs=yes],
[gdbsrv_cv_have_ptrace_getregs=no])])
AC_MSG_RESULT($gdbsrv_cv_have_ptrace_getregs)
if test "${gdbsrv_cv_have_ptrace_getregs}" = "yes"; then
AC_DEFINE(HAVE_LINUX_REGSETS)
fi
AC_MSG_CHECKING(for PTRACE_GETFPXREGS)
AC_CACHE_VAL(gdbsrv_cv_have_ptrace_getfpxregs,
[AC_TRY_COMPILE([#include <sys/ptrace.h>],
[PTRACE_GETFPXREGS;],
[gdbsrv_cv_have_ptrace_getfpxregs=yes],
[gdbsrv_cv_have_ptrace_getfpxregs=no])])
AC_MSG_RESULT($gdbsrv_cv_have_ptrace_getfpxregs)
if test "${gdbsrv_cv_have_ptrace_getfpxregs}" = "yes"; then
AC_DEFINE(HAVE_PTRACE_GETFPXREGS)
fi
fi
if test "$ac_cv_header_sys_procfs_h" = yes; then
BFD_HAVE_SYS_PROCFS_TYPE(lwpid_t)
BFD_HAVE_SYS_PROCFS_TYPE(psaddr_t)
BFD_HAVE_SYS_PROCFS_TYPE(prgregset_t)
BFD_HAVE_SYS_PROCFS_TYPE(prfpregset_t)
dnl Check for broken prfpregset_t type
dnl For Linux/i386, glibc 2.1.3 was released with a bogus
dnl prfpregset_t type (it's a typedef for the pointer to a struct
dnl instead of the struct itself). We detect this here, and work
dnl around it in gdb_proc_service.h.
if test $bfd_cv_have_sys_procfs_type_prfpregset_t = yes; then
AC_MSG_CHECKING(whether prfpregset_t type is broken)
AC_CACHE_VAL(gdb_cv_prfpregset_t_broken,
[AC_TRY_RUN([#include <sys/procfs.h>
int main ()
{
if (sizeof (prfpregset_t) == sizeof (void *))
return 1;
return 0;
}],
gdb_cv_prfpregset_t_broken=no,
gdb_cv_prfpregset_t_broken=yes,
gdb_cv_prfpregset_t_broken=yes)])
AC_MSG_RESULT($gdb_cv_prfpregset_t_broken)
if test $gdb_cv_prfpregset_t_broken = yes; then
AC_DEFINE(PRFPREGSET_T_BROKEN)
fi
fi
BFD_HAVE_SYS_PROCFS_TYPE(elf_fpregset_t)
fi
srv_thread_depfiles=
srv_libs=
USE_THREAD_DB=
GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj $srv_thread_depfiles"
GDBSERVER_LIBS="$srv_libs -L../../../../../libxc/ -lxenctrl"
AC_SUBST(GDBSERVER_DEPFILES)
AC_SUBST(GDBSERVER_LIBS)
AC_SUBST(USE_THREAD_DB)
AC_OUTPUT(Makefile,
[case x$CONFIG_HEADERS in
xconfig.h:config.in)
echo > stamp-h ;;
esac
])
@@ -1,75 +0,0 @@
# Mappings from configuration triplets to gdbserver build options.
# This is invoked from the autoconf-generated configure script, to
# produce the appropriate Makefile substitutions.
# This file sets the following shell variables:
# srv_regobj The register protocol appropriate for this target.
# srv_tgtobj Any other target-specific modules appropriate
# for this target.
#
# In addition, on GNU/Linux the following shell variables will be set:
# srv_linux_regsets Set to "yes" if ptrace(PTRACE_GETREGS) and friends
# may be available on this platform; unset otherwise.
# They will only be used if <sys/ptrace.h> defines
# PTRACE_GETREGS.
# srv_linux_usrregs Set to "yes" if we can get at registers via
# PTRACE_PEEKUSR / PTRACE_POKEUSR.
# Input is taken from the "${target}" variable.
case "${target}" in
arm*-*-linux*) srv_regobj=reg-arm.o
srv_tgtobj="linux-xen-low.o linux-arm-low.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
i[34567]86-*-linux*) srv_regobj=reg-i386-linux.o
srv_tgtobj="linux-xen-low.o linux-i386-low.o i387-fp.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
ia64-*-linux*) srv_regobj=reg-ia64.o
srv_tgtobj="linux-low.o linux-ia64-low.o"
srv_linux_usrregs=yes
;;
m68*-*-linux*) srv_regobj=reg-m68k.o
srv_tgtobj="linux-low.o linux-m68k-low.o"
srv_linux_usrregs=yes
;;
mips*-*-linux*) srv_regobj=reg-mips.o
srv_tgtobj="linux-low.o linux-mips-low.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
powerpc*-*-linux*) srv_regobj=reg-ppc.o
srv_tgtobj="linux-low.o linux-ppc-low.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
s390-*-linux*) srv_regobj=reg-s390.o
srv_tgtobj="linux-low.o linux-s390-low.o"
srv_linux_usrregs=yes
;;
s390x-*-linux*) srv_regobj=reg-s390x.o
srv_tgtobj="linux-low.o linux-s390-low.o"
srv_linux_usrregs=yes
;;
sh*-*-linux*) srv_regobj=reg-sh.o
srv_tgtobj="linux-low.o linux-sh-low.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
x86_64-*-linux*) srv_regobj=reg-x86-64.o
srv_tgtobj="linux-xen-low.o linux-x86-64-low.o i387-fp.o"
srv_linux_regsets=yes
;;
xscale*-*-linux*) srv_regobj=reg-arm.o
srv_tgtobj="linux-low.o linux-arm-low.o"
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
*) echo "Error: target not supported by gdbserver."
exit 1
;;
esac
@@ -1,667 +0,0 @@
/* Low level interface to ptrace, for the remote server for GDB.
Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "server.h"
#include "linux-low.h"
#include <sys/wait.h>
#include <stdio.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <xenctrl.h>
#define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
static xc_interface *xc_handle;
static inline int
curvcpuid()
{
struct process_info *process;
if (current_inferior == NULL)
return 0;
process = get_thread_process(current_inferior);
return (process->thread_known ? process->tid : 0);
}
struct inferior_list all_processes;
static int current_domid;
static int expect_signal = 0;
static int signal_to_send = 0;
static void linux_resume (struct thread_resume *resume_info);
static void linux_set_inferior (void);
int debug_threads;
int using_threads;
extern int isfile;
struct pending_signals
{
int signal;
struct pending_signals *prev;
};
#define PTRACE_ARG3_TYPE long
#define PTRACE_XFER_TYPE long
static int use_regsets_p = 1;
#define pid_of(proc) ((proc)->head.id)
/* FIXME: Delete eventually. */
#define inferior_pid (pid_of (get_thread_process (current_inferior)))
/* This function should only be called if the process got a SIGTRAP.
The SIGTRAP could mean several things.
On i386, where decr_pc_after_break is non-zero:
If we were single-stepping this process using PTRACE_SINGLESTEP,
we will get only the one SIGTRAP (even if the instruction we
stepped over was a breakpoint). The value of $eip will be the
next instruction.
If we continue the process using PTRACE_CONT, we will get a
SIGTRAP when we hit a breakpoint. The value of $eip will be
the instruction after the breakpoint (i.e. needs to be
decremented). If we report the SIGTRAP to GDB, we must also
report the undecremented PC. If we cancel the SIGTRAP, we
must resume at the decremented PC.
(Presumably, not yet tested) On a non-decr_pc_after_break machine
with hardware or kernel single-step:
If we single-step over a breakpoint instruction, our PC will
point at the following instruction. If we continue and hit a
breakpoint instruction, our PC will point at the breakpoint
instruction. */
static CORE_ADDR
get_stop_pc (void)
{
CORE_ADDR stop_pc = (*the_low_target.get_pc) ();
if (get_thread_process (current_inferior)->stepping)
return stop_pc;
else
return stop_pc - the_low_target.decr_pc_after_break;
}
static void *
add_process (int pid, long tid)
{
struct process_info *process;
process = (struct process_info *) malloc (sizeof (*process));
memset (process, 0, sizeof (*process));
process->head.id = pid;
process->tid = tid;
process->lwpid = tid;
add_inferior_to_list (&all_processes, &process->head);
return process;
}
/* Start an inferior process and returns its pid.
ALLARGS is a vector of program-name and args. */
static int
linux_create_inferior (char *program, char **allargs)
{
fprintf (stderr, "Cannot exec %s: %s.\n", program,
strerror (errno));
fflush (stderr);
_exit (0177);
/* NOT REACHED */
return -1;
}
int
linux_attach (int domid)
{
struct process_info *new_process;
current_domid = domid;
/* this is handled for all active vcpus in PTRACE_ATTACH via the thread_create_callback */
new_process = (struct process_info *) add_process (domid, curvcpuid());
/* Don't ignore the initial SIGSTOP if we just attached to this process. */
/* vcpuid == 0 */
add_thread (0, new_process);
new_process->stop_expected = 0;
if (xc_ptrace (xc_handle, PTRACE_ATTACH, domid, 0, isfile) != 0) {
fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domid,
strerror (errno), errno);
fflush (stderr);
if (!using_threads)
_exit (0177);
}
return 0;
}
/* Kill the inferior process. Make us have no inferior. */
static void
linux_kill_one_process (struct inferior_list_entry *entry)
{
struct thread_info *thread = (struct thread_info *) entry;
struct process_info *process = get_thread_process (thread);
xc_ptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
}
static void
linux_kill (void)
{
for_each_inferior (&all_threads, linux_kill_one_process);
}
static void
linux_detach_one_process (struct inferior_list_entry *entry)
{
xc_ptrace (xc_handle, PTRACE_DETACH, current_domid, 0, 0);
}
static void
linux_detach (void)
{
for_each_inferior (&all_threads, linux_detach_one_process);
}
/* Return nonzero if the given thread is still alive. */
static int
linux_thread_alive (int tid)
{
if (find_inferior_id (&all_threads, tid) != NULL)
return 1;
else
return 0;
}
/* Wait for process, returns status. */
static unsigned char
linux_wait (char *status)
{
int w;
if (xc_waitdomain(xc_handle, current_domid, &w, 0))
return -1;
*status = 'T';
if (expect_signal)
return expect_signal;
else
return SIGTRAP;
}
static void
linux_resume (struct thread_resume *resume_info)
{
int step = resume_info->step;
TRACE_ENTER;
expect_signal = resume_info->sig;
for_each_inferior(&all_threads, regcache_invalidate_one);
if (debug_threads)
fprintf(stderr, "step: %d\n", step);
xc_ptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT,
resume_info->thread, 0, 0);
}
static int
regsets_fetch_inferior_registers ()
{
struct regset_info *regset;
TRACE_ENTER;
regset = target_regsets;
while (regset->size >= 0)
{
void *buf;
int res;
if (regset->size == 0)
{
regset ++;
continue;
}
buf = malloc (regset->size);
res = xc_ptrace (xc_handle, regset->get_request,
curvcpuid(),
0, (PTRACE_XFER_TYPE)buf);
if (res < 0)
{
if (errno == EIO)
{
/* If we get EIO on the first regset, do not try regsets again.
If we get EIO on a later regset, disable that regset. */
if (regset == target_regsets)
{
use_regsets_p = 0;
return -1;
}
else
{
regset->size = 0;
continue;
}
}
else
{
char s[256];
sprintf (s, "ptrace(regsets_fetch_inferior_registers) PID=%d",
inferior_pid);
perror (s);
}
}
regset->store_function (buf);
regset ++;
}
return 0;
}
static int
regsets_store_inferior_registers ()
{
struct regset_info *regset;
TRACE_ENTER;
regset = target_regsets;
while (regset->size >= 0)
{
void *buf;
int res;
if (regset->size == 0)
{
regset ++;
continue;
}
buf = malloc (regset->size);
regset->fill_function (buf);
res = xc_ptrace (xc_handle, regset->set_request, curvcpuid(), 0, (PTRACE_XFER_TYPE)buf);
if (res < 0)
{
if (errno == EIO)
{
/* If we get EIO on the first regset, do not try regsets again.
If we get EIO on a later regset, disable that regset. */
if (regset == target_regsets)
{
use_regsets_p = 0;
return -1;
}
else
{
regset->size = 0;
continue;
}
}
else
{
#ifdef DEBUG
perror ("Warning: ptrace(regsets_store_inferior_registers)");
#endif
}
}
regset ++;
free (buf);
}
return 0;
}
void
linux_fetch_registers (int regno)
{
if (use_regsets_p)
{
if (regsets_fetch_inferior_registers () == 0)
return;
}
}
void
linux_store_registers (int regno)
{
if (use_regsets_p)
{
if (regsets_store_inferior_registers () == 0)
return;
}
}
/* Copy LEN bytes from inferior's memory starting at MEMADDR
to debugger memory starting at MYADDR. */
static int
linux_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
{
register int i;
/* Round starting address down to longword boundary. */
register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
/* Round ending address up; get number of longwords that makes. */
register int count
= (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
/ sizeof (PTRACE_XFER_TYPE);
/* Allocate buffer of that many longwords. */
register PTRACE_XFER_TYPE *buffer
= (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
TRACE_ENTER;
/* Read all the longwords */
for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
buffer[i] = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(), (PTRACE_ARG3_TYPE) addr, 0);
if (errno)
return errno;
}
/* Copy appropriate bytes out of the buffer. */
memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
return 0;
}
/* Copy LEN bytes of data from debugger memory at MYADDR
to inferior's memory at MEMADDR.
On failure (cannot write the inferior)
returns the value of errno. */
static int
linux_write_memory (CORE_ADDR memaddr, const char *myaddr, int len)
{
register int i;
/* Round starting address down to longword boundary. */
register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
/* Round ending address up; get number of longwords that makes. */
register int count
= (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE);
/* Allocate buffer of that many longwords. */
register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
extern int errno;
TRACE_ENTER;
/* Fill start and end extra bytes of buffer with existing memory data. */
buffer[0] = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
(PTRACE_ARG3_TYPE) addr, 0);
if (count > 1)
{
buffer[count - 1]
= xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
(PTRACE_ARG3_TYPE) (addr + (count - 1)
* sizeof (PTRACE_XFER_TYPE)),
0);
}
/* Copy data to be written over corresponding part of buffer */
memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
/* Write the entire buffer. */
for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
xc_ptrace (xc_handle, PTRACE_POKETEXT, curvcpuid(),
(PTRACE_ARG3_TYPE) addr, buffer[i]);
if (errno)
return errno;
}
return 0;
}
static void
linux_look_up_symbols (void)
{
if (using_threads)
return;
using_threads = thread_db_init ();
}
static void
linux_send_signal (int signum)
{
extern int signal_pid;
TRACE_ENTER;
signal_to_send = signum;
psignal(signum, "need to send ");
if (cont_thread > 0)
{
struct process_info *process;
process = get_thread_process (current_inferior);
kill (process->lwpid, signum);
}
else
kill (signal_pid, signum);
}
/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
to debugger memory starting at MYADDR. */
static int
linux_read_auxv (CORE_ADDR offset, char *myaddr, unsigned int len)
{
char filename[PATH_MAX];
int fd, n;
TRACE_ENTER;
snprintf (filename, sizeof filename, "/proc/%d/auxv", inferior_pid);
fd = open (filename, O_RDONLY);
if (fd < 0)
return -1;
if (offset != (CORE_ADDR) 0
&& lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
n = -1;
else
n = read (fd, myaddr, len);
close (fd);
return n;
}
static struct target_ops linux_xen_target_ops = {
linux_create_inferior,
linux_attach,
linux_kill,
linux_detach,
linux_thread_alive,
linux_resume,
linux_wait,
linux_fetch_registers,
linux_store_registers,
linux_read_memory,
linux_write_memory,
linux_look_up_symbols,
linux_send_signal,
linux_read_auxv,
};
static void
linux_init_signals ()
{
/* FIXME drow/2002-06-09: As above, we should check with LinuxThreads
to find what the cancel signal actually is. */
signal (__SIGRTMIN+1, SIG_IGN);
}
void
initialize_low (void)
{
using_threads = 0;
xc_handle = xc_interface_open();
set_target_ops (&linux_xen_target_ops);
set_breakpoint_data (the_low_target.breakpoint,
the_low_target.breakpoint_len);
init_registers ();
linux_init_signals ();
using_threads = thread_db_init ();
}
static void
thread_create_callback(long vcpuid)
{
struct thread_info *inferior;
struct process_info *process;
/* If we are attaching to our first thread, things are a little
* different.
*/
if (all_threads.head == all_threads.tail)
{
inferior = (struct thread_info *) all_threads.head;
process = get_thread_process (inferior);
if (process->thread_known == 0)
{
/* Switch to indexing the threads list by TID. */
change_inferior_id (&all_threads, vcpuid);
goto found;
}
}
if (debug_threads)
fprintf (stderr, "looking up thread %ld\n",
vcpuid);
inferior = (struct thread_info *) find_inferior_id (&all_threads,
vcpuid);
/* if vcpu alread registered - do nothing */
if (inferior != NULL)
return;
if (debug_threads)
fprintf (stderr, "Attaching to thread %ld\n",
vcpuid);
process = add_process(current_domid, vcpuid);
add_thread(vcpuid, process);
inferior = (struct thread_info *) find_inferior_id (&all_threads,
vcpuid);
if (inferior == NULL)
{
warning ("Could not attach to thread %ld\n",
vcpuid);
return;
}
found:
if (debug_threads)
fprintf (stderr, "notifying of new thread %ld\n",
vcpuid);
new_thread_notify (vcpuid);
process->tid = vcpuid;
process->lwpid = vcpuid;
process->thread_known = 1;
}
static void
thread_death_callback(long vcpuid)
{
if (debug_threads)
fprintf (stderr, "Buuurp...! CPU down event.\n");
}
int
thread_db_init(void)
{
debug_threads = 0;
xc_register_event_handler(thread_create_callback, TD_CREATE);
xc_register_event_handler(thread_death_callback, TD_DEATH);
return 1;
}
/* XXX GAG ME */
static int breakpoint_found;
static void
set_breakpoint_inferior (struct inferior_list_entry *entry)
{
struct thread_info *thread = (struct thread_info *) entry;
struct thread_info *saved_inferior = current_inferior;
CORE_ADDR eip;
unsigned char buf[2] = {0, 0};
current_inferior = thread;
if (!breakpoint_found) {
eip = get_stop_pc();
linux_read_memory(eip, buf, 1);
if (buf[0] == 0xcc) {
breakpoint_found = 1;
return;
}
} else if (breakpoint_found == 2) {
if (get_thread_process (current_inferior)->stepping) {
printf("stepping\n");
breakpoint_found = 1;
return;
}
}
current_inferior = saved_inferior;
}
static void
linux_set_inferior (void)
{
breakpoint_found = 0;
for_each_inferior (&all_threads, set_breakpoint_inferior);
if (!breakpoint_found) {
breakpoint_found = 2;
for_each_inferior (&all_threads, set_breakpoint_inferior);
}
}
@@ -1,676 +0,0 @@
/* Main code for remote server for GDB.
Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "server.h"
#include "linux-low.h"
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int cont_thread;
int general_thread;
int step_thread;
int thread_from_wait;
int old_thread_from_wait;
int extended_protocol;
int server_waiting;
int isfile = 0;
jmp_buf toplevel;
/* The PID of the originally created or attached inferior. Used to
send signals to the process when GDB sends us an asynchronous interrupt
(user hitting Control-C in the client), and to wait for the child to exit
when no longer debugging it. */
int signal_pid;
static unsigned char
start_inferior (char *argv[], char *statusptr)
{
signal (SIGTTOU, SIG_DFL);
signal (SIGTTIN, SIG_DFL);
signal_pid = create_inferior (argv[0], argv);
fprintf (stderr, "Process %s created; pid = %d\n", argv[0],
signal_pid);
signal (SIGTTOU, SIG_IGN);
signal (SIGTTIN, SIG_IGN);
tcsetpgrp (fileno (stderr), signal_pid);
/* Wait till we are at 1st instruction in program, return signal number. */
return mywait (statusptr, 0);
}
static int
attach_inferior (int pid, char *statusptr, unsigned char *sigptr)
{
/* myattach should return -1 if attaching is unsupported,
0 if it succeeded, and call error() otherwise. */
if (myattach (pid) != 0)
return -1;
fprintf (stderr, "Attached; pid = %d\n", pid);
/* FIXME - It may be that we should get the SIGNAL_PID from the
attach function, so that it can be the main thread instead of
whichever we were told to attach to. */
signal_pid = pid;
*sigptr = mywait (statusptr, 0);
return 0;
}
extern int remote_debug;
/* Handle all of the extended 'q' packets. */
void
handle_query (char *own_buf)
{
static struct inferior_list_entry *thread_ptr;
if (strcmp ("qSymbol::", own_buf) == 0)
{
if (the_target->look_up_symbols != NULL)
(*the_target->look_up_symbols) ();
strcpy (own_buf, "OK");
return;
}
if (strcmp ("qC", own_buf) == 0)
{
struct process_info *process;
if (current_inferior == NULL)
return;
process = get_thread_process(current_inferior);
sprintf(own_buf, "QC%x", process->thread_known ? process->tid : 0);
}
if (strcmp ("qfThreadInfo", own_buf) == 0)
{
thread_ptr = all_threads.head;
sprintf (own_buf, "m%x", thread_ptr->id);
thread_ptr = thread_ptr->next;
return;
}
if (strcmp ("qsThreadInfo", own_buf) == 0)
{
if (thread_ptr != NULL)
{
sprintf (own_buf, "m%x", thread_ptr->id);
thread_ptr = thread_ptr->next;
return;
}
else
{
sprintf (own_buf, "l");
return;
}
}
if (the_target->read_auxv != NULL
&& strncmp ("qPart:auxv:read::", own_buf, 17) == 0)
{
char data[(PBUFSIZ - 1) / 2];
CORE_ADDR ofs;
unsigned int len;
int n;
decode_m_packet (&own_buf[17], &ofs, &len); /* "OFS,LEN" */
if (len > sizeof data)
len = sizeof data;
n = (*the_target->read_auxv) (ofs, data, len);
if (n == 0)
write_ok (own_buf);
else if (n < 0)
write_enn (own_buf);
else
convert_int_to_ascii (data, own_buf, n);
return;
}
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
}
/* Parse vCont packets. */
void
handle_v_cont (char *own_buf, char *status, unsigned char *signal)
{
char *p, *q;
int n = 0, i = 0;
struct thread_resume *resume_info, default_action;
/* Count the number of semicolons in the packet. There should be one
for every action. */
p = &own_buf[5];
while (p)
{
n++;
p++;
p = strchr (p, ';');
}
/* Allocate room for one extra action, for the default remain-stopped
behavior; if no default action is in the list, we'll need the extra
slot. */
resume_info = malloc ((n + 1) * sizeof (resume_info[0]));
default_action.thread = -1;
default_action.leave_stopped = 1;
default_action.step = 0;
default_action.sig = 0;
p = &own_buf[5];
i = 0;
while (*p)
{
p++;
resume_info[i].leave_stopped = 0;
if (p[0] == 's' || p[0] == 'S')
resume_info[i].step = 1;
else if (p[0] == 'c' || p[0] == 'C')
resume_info[i].step = 0;
else
goto err;
if (p[0] == 'S' || p[0] == 'C')
{
int sig;
sig = strtol (p + 1, &q, 16);
if (p == q)
goto err;
p = q;
if (!target_signal_to_host_p (sig))
goto err;
resume_info[i].sig = target_signal_to_host (sig);
}
else
{
resume_info[i].sig = 0;
p = p + 1;
}
if (p[0] == 0)
{
resume_info[i].thread = -1;
default_action = resume_info[i];
/* Note: we don't increment i here, we'll overwrite this entry
the next time through. */
}
else if (p[0] == ':')
{
resume_info[i].thread = strtol (p + 1, &q, 16);
if (p == q)
goto err;
p = q;
if (p[0] != ';' && p[0] != 0)
goto err;
i++;
}
}
resume_info[i] = default_action;
/* Still used in occasional places in the backend. */
if (n == 1 && resume_info[0].thread != -1)
cont_thread = resume_info[0].thread;
else
cont_thread = -1;
set_desired_inferior (0);
(*the_target->resume) (resume_info);
free (resume_info);
*signal = mywait (status, 1);
prepare_resume_reply (own_buf, *status, *signal);
return;
err:
/* No other way to report an error... */
strcpy (own_buf, "");
free (resume_info);
return;
}
/* Handle all of the extended 'v' packets. */
void
handle_v_requests (char *own_buf, char *status, unsigned char *signal)
{
if (strncmp (own_buf, "vCont;", 6) == 0)
{
handle_v_cont (own_buf, status, signal);
return;
}
if (strncmp (own_buf, "vCont?", 6) == 0)
{
strcpy (own_buf, "vCont;c;C;s;S");
return;
}
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
return;
}
void
handle_breakpoint_requests (char *own_buf, char *status, unsigned char *signal)
{
/* Currently we only support software breakpoints */
switch (own_buf[1]) {
case '0': /* software breakpoint, int3 based */
own_buf[0] = '\0';
break;
case '1': /* hardware breakpoint */
default:
write_enn (own_buf);
break;
}
}
void
myresume (int step, int sig)
{
struct thread_resume resume_info[2];
int n = 0;
if (step || sig || cont_thread > 0)
{
resume_info[0].thread
= ((struct inferior_list_entry *) current_inferior)->id;
resume_info[0].step = step;
resume_info[0].sig = sig;
resume_info[0].leave_stopped = 0;
n++;
}
resume_info[n].thread = -1;
resume_info[n].step = 0;
resume_info[n].sig = 0;
resume_info[n].leave_stopped = (cont_thread > 0);
(*the_target->resume) (resume_info);
}
static int attached;
static void
gdbserver_usage (void)
{
error ("Usage:\tgdbserver COMM PROG [ARGS ...]\n"
"\tgdbserver COMM --attach PID\n"
"\tgdbserver COMM --file COREFILE\n"
"\n"
"COMM may either be a tty device (for serial debugging), or \n"
"HOST:PORT to listen for a TCP connection.\n");
}
extern control_c_pressed_flag;
#include <signal.h>
void ctrl_c_handler(int signo)
{
printf("Ctrl-C pressed: Quit from the attached gdb first\n");
control_c_pressed_flag = 1;
}
struct sigaction ctrl_c_sigaction = { .sa_handler = ctrl_c_handler };
struct sigaction old_sigaction;
int
main (int argc, char *argv[])
{
char ch, status, *own_buf, mem_buf[2000];
int i = 0;
unsigned char signal;
unsigned int len;
CORE_ADDR mem_addr;
int bad_attach;
int pid;
char *arg_end;
if (setjmp (toplevel))
{
fprintf (stderr, "Exiting\n");
exit (1);
}
bad_attach = 0;
pid = 0;
attached = 0;
if (argc >= 3 && strcmp (argv[2], "--attach") == 0)
{
if (argc == 4
&& argv[3] != '\0'
&& (pid = strtoul (argv[3], &arg_end, 10)) != 0
&& *arg_end == '\0')
{
;
}
else
bad_attach = 1;
}
else if (argc >= 3 && strcmp (argv[2], "--file") == 0)
{
if (argc == 4
&& argv[3] != '\0')
{
if ((pid = open(argv[3], O_RDONLY)) <= 0)
bad_attach = 1;
else
isfile = 1;
}
else
bad_attach = 1;
}
if (argc < 3 || bad_attach)
gdbserver_usage();
initialize_low ();
own_buf = malloc (PBUFSIZ);
if (pid == 0)
{
/* Wait till we are at first instruction in program. */
signal = start_inferior (&argv[2], &status);
/* We are now stopped at the first instruction of the target process */
}
else
{
switch (attach_inferior (pid, &status, &signal))
{
case -1:
error ("Attaching not supported on this target");
break;
default:
attached = 1;
break;
}
}
while (1)
{
remote_open (argv[1]);
sigaction(SIGINT, &ctrl_c_sigaction, &old_sigaction);
restart:
setjmp (toplevel);
while (getpkt (own_buf) > 0)
{
unsigned char sig;
i = 0;
ch = own_buf[i++];
switch (ch)
{
case 'q':
handle_query (own_buf);
break;
case 'd':
remote_debug = !remote_debug;
break;
case 'D':
fprintf (stderr, "Detaching from inferior\n");
detach_inferior ();
write_ok (own_buf);
putpkt (own_buf);
remote_close ();
/* If we are attached, then we can exit. Otherwise, we need to
hang around doing nothing, until the child is gone. */
if (!attached)
{
int status, ret;
do {
ret = waitpid (signal_pid, &status, 0);
if (WIFEXITED (status) || WIFSIGNALED (status))
break;
} while (ret != -1 || errno != ECHILD);
}
exit (0);
case '!':
if (attached == 0)
{
extended_protocol = 1;
prepare_resume_reply (own_buf, status, signal);
}
else
{
/* We can not use the extended protocol if we are
attached, because we can not restart the running
program. So return unrecognized. */
own_buf[0] = '\0';
}
break;
case '?':
prepare_resume_reply (own_buf, status, signal);
break;
case 'H':
switch (own_buf[1])
{
case 'g':
general_thread = strtol (&own_buf[2], NULL, 16);
write_ok (own_buf);
set_desired_inferior (1);
break;
case 'c':
cont_thread = strtol (&own_buf[2], NULL, 16);
write_ok (own_buf);
break;
case 's':
step_thread = strtol (&own_buf[2], NULL, 16);
write_ok (own_buf);
break;
default:
/* Silently ignore it so that gdb can extend the protocol
without compatibility headaches. */
own_buf[0] = '\0';
break;
}
break;
case 'g':
set_desired_inferior (1);
registers_to_string (own_buf);
break;
case 'G':
set_desired_inferior (1);
registers_from_string (&own_buf[1]);
write_ok (own_buf);
break;
case 'm':
decode_m_packet (&own_buf[1], &mem_addr, &len);
if (read_inferior_memory (mem_addr, mem_buf, len) == 0)
convert_int_to_ascii (mem_buf, own_buf, len);
else
write_enn (own_buf);
break;
case 'M':
decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
write_ok (own_buf);
else
write_enn (own_buf);
break;
case 'C':
convert_ascii_to_int (own_buf + 1, &sig, 1);
if (target_signal_to_host_p (sig))
signal = target_signal_to_host (sig);
else
signal = 0;
set_desired_inferior (0);
myresume (0, signal);
signal = mywait (&status, 1);
prepare_resume_reply (own_buf, status, signal);
break;
case 'S':
convert_ascii_to_int (own_buf + 1, &sig, 1);
if (target_signal_to_host_p (sig))
signal = target_signal_to_host (sig);
else
signal = 0;
set_desired_inferior (0);
myresume (1, signal);
signal = mywait (&status, 1);
prepare_resume_reply (own_buf, status, signal);
break;
case 'c':
set_desired_inferior (0);
myresume (0, 0);
signal = mywait (&status, 1);
prepare_resume_reply (own_buf, status, signal);
break;
case 's':
set_desired_inferior (0);
myresume (1, 0);
signal = mywait (&status, 1);
prepare_resume_reply (own_buf, status, signal);
break;
case 'k':
fprintf (stderr, "Killing inferior\n");
kill_inferior ();
/* When using the extended protocol, we start up a new
debugging session. The traditional protocol will
exit instead. */
if (extended_protocol)
{
write_ok (own_buf);
fprintf (stderr, "GDBserver restarting\n");
/* Wait till we are at 1st instruction in prog. */
signal = start_inferior (&argv[2], &status);
goto restart;
break;
}
else
{
exit (0);
break;
}
case 'T':
if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
write_ok (own_buf);
else
write_enn (own_buf);
break;
case 'R':
/* Restarting the inferior is only supported in the
extended protocol. */
if (extended_protocol)
{
kill_inferior ();
write_ok (own_buf);
fprintf (stderr, "GDBserver restarting\n");
/* Wait till we are at 1st instruction in prog. */
signal = start_inferior (&argv[2], &status);
goto restart;
break;
}
else
{
/* It is a request we don't understand. Respond with an
empty packet so that gdb knows that we don't support this
request. */
own_buf[0] = '\0';
break;
}
case 'v':
/* Extended (long) request. */
handle_v_requests (own_buf, &status, &signal);
break;
case 'Z':
handle_breakpoint_requests (own_buf, &status, &signal);
break;
default:
/* It is a request we don't understand. Respond with an
empty packet so that gdb knows that we don't support this
request. */
own_buf[0] = '\0';
break;
}
putpkt (own_buf);
if (status == 'W')
fprintf (stderr,
"\nChild exited with status %d\n", signal);
if (status == 'X')
fprintf (stderr, "\nChild terminated with signal = 0x%x\n",
signal);
if (status == 'W' || status == 'X')
{
if (extended_protocol)
{
fprintf (stderr, "Killing inferior\n");
kill_inferior ();
write_ok (own_buf);
fprintf (stderr, "GDBserver restarting\n");
/* Wait till we are at 1st instruction in prog. */
signal = start_inferior (&argv[2], &status);
goto restart;
break;
}
else
{
fprintf (stderr, "GDBserver exiting\n");
exit (0);
}
}
}
/* We come here when getpkt fails.
For the extended remote protocol we exit (and this is the only
way we gracefully exit!).
For the traditional remote protocol close the connection,
and re-open it at the top of the loop. */
detach_inferior ();
remote_close ();
if (extended_protocol)
exit (0);
else
fprintf (stderr, "Remote side has terminated connection. "
"GDBserver will reopen the connection.\n");
sigaction(SIGINT, &old_sigaction, NULL);
}
}
@@ -1,115 +0,0 @@
#!/bin/bash
# mkbuildtree <build tree>
#
# Creates symbolic links in <build tree> for the sparse tree
# in the current directory.
# Script to determine the relative path between two directories.
# Copyright (c) D. J. Hawkey Jr. 2002
# Fixed for Xen project by K. Fraser in 2003.
abs_to_rel ()
{
local CWD SRCPATH
if [ "$1" != "/" -a "${1##*[^/]}" = "/" ]; then
SRCPATH=${1%?}
else
SRCPATH=$1
fi
if [ "$2" != "/" -a "${2##*[^/]}" = "/" ]; then
DESTPATH=${2%?}
else
DESTPATH=$2
fi
CWD=$PWD
[ "${1%%[^/]*}" != "/" ] && cd $1 && SRCPATH=$PWD
[ "${2%%[^/]*}" != "/" ] && cd $2 && DESTPATH=$PWD
[ "$CWD" != "$PWD" ] && cd $CWD
BASEPATH=$SRCPATH
[ "$SRCPATH" = "$DESTPATH" ] && DESTPATH="." && return
[ "$SRCPATH" = "/" ] && DESTPATH=${DESTPATH#?} && return
while [ "$BASEPATH/" != "${DESTPATH%${DESTPATH#$BASEPATH/}}" ]; do
BASEPATH=${BASEPATH%/*}
done
SRCPATH=${SRCPATH#$BASEPATH}
DESTPATH=${DESTPATH#$BASEPATH}
DESTPATH=${DESTPATH#?}
while [ -n "$SRCPATH" ]; do
SRCPATH=${SRCPATH%/*}
DESTPATH="../$DESTPATH"
done
[ -z "$BASEPATH" ] && BASEPATH="/"
[ "${DESTPATH##*[^/]}" = "/" ] && DESTPATH=${DESTPATH%?}
}
# relative_lndir <target_dir>
# Creates a tree of symlinks in the current working directory that mirror
# real files in <target_dir>. <target_dir> should be relative to the current
# working directory. Symlinks in <target_dir> are ignored. Source-control files
# are ignored.
relative_lndir ()
{
local SYMLINK_DIR REAL_DIR pref i j
SYMLINK_DIR=$PWD
REAL_DIR=$1
(
cd $REAL_DIR
for i in `find . -type d | grep -v SCCS`; do
[ -d $SYMLINK_DIR/$i ] || mkdir -p $SYMLINK_DIR/$i
(
cd $i
pref=`echo $i | sed -e 's#/[^/]*#../#g' -e 's#^\.##'`
for j in `find . -type f -o -type l -maxdepth 1`; do
ln -sf ${pref}${REAL_DIR}/$i/$j ${SYMLINK_DIR}/$i/$j
done
)
done
)
}
[ "$1" == "" ] && { echo "Syntax: $0 <linux tree to xenify>"; exit 1; }
# Get absolute path to the destination directory
pushd . >/dev/null
cd ${1}
AD=$PWD
popd >/dev/null
# Get absolute path to the source directory
AS=`pwd`
# Get name of sparse directory
SDN=$(basename $AS)
# Get path to source, relative to destination
abs_to_rel ${AD} ${AS}
RS=$DESTPATH
# We now work from the destination directory
cd ${AD}
# Remove old symlinks
find sys -type l | while read f
do
case $(readlink $f) in
*/$SDN/*)
rm -f $f
;;
esac
done
if [ -f ${AD}/BUILDING ]; then
# Create symlinks of files and directories which exist in the sparse source
(cd sys && relative_lndir ../${RS}/sys)
else
# Create symlinks of files and directories which exist in the sparse source
relative_lndir ${RS}
rm -f mkbuildtree
fi
-28
View File
@@ -1,28 +0,0 @@
#!/bin/sh
set -e
GDB_VERSION=6.2.1
[ "$GDB_MIRROR" ] || GDB_MIRROR="ftp://ftp.gnu.org/gnu/gdb/"
rm -rf gdb-$GDB_VERSION gdb-$GDB_VERSION-linux-i386-xen
[ -a gdb-$GDB_VERSION.tar.bz2 ] || wget -c "$GDB_MIRROR/gdb-$GDB_VERSION.tar.bz2"
tar xjf gdb-$GDB_VERSION.tar.bz2
cd gdb-$GDB_VERSION-xen-sparse
bash ./mkbuildtree ../gdb-$GDB_VERSION
cd ..
mkdir gdb-$GDB_VERSION-linux-i386-xen
cd gdb-$GDB_VERSION-linux-i386-xen
../gdb-$GDB_VERSION/configure
# Use $MAKE if set, else use gmake if present, otherwise use make
if [ "$MAKE" ]; then
$MAKE
elif which gmake ; then
gmake -j4
else
make -j4
fi
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.