mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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:
1 parent
cb2b6edf55
commit
baa1aae9cf
9 files changed
-6678
No files matched your search
@@ -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
|
|
||||||
@@ -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
|
|
||||||