forked from Imagelibrary/rtems
2007-08-02 Joel Sherrill <joel.sherrill@OARcorp.com>
* configure.ac, wrapup/Makefile.am: Remove RDBG. * aclocal/check-rdbg.m4, aclocal/enable-rdbg.m4, librdbg/.cvsignore, librdbg/Makefile.am, librdbg/preinstall.am, librdbg/include/rdbg/rdbg.h, librdbg/include/rdbg/servrpc.h, librdbg/include/rdbg/i386/rdbg_f.h, librdbg/include/rdbg/i386/reg.h, librdbg/include/rdbg/m68k/rdbg_f.h, librdbg/include/rdbg/m68k/reg.h, librdbg/include/rdbg/powerpc/rdbg_f.h, librdbg/include/rdbg/powerpc/reg.h, librdbg/src/_servtgt.c, librdbg/src/awk.svc, librdbg/src/excep.c, librdbg/src/ptrace.c, librdbg/src/rdbg.c, librdbg/src/remdeb.x, librdbg/src/servbkpt.c, librdbg/src/servcon.c, librdbg/src/servrpc.c, librdbg/src/servtgt.c, librdbg/src/servtsp.c, librdbg/src/servutil.c, librdbg/src/i386/excep_f.c, librdbg/src/i386/rdbg_cpu_asm.S, librdbg/src/i386/rdbg_f.c, librdbg/src/i386/any/remdeb.h, librdbg/src/i386/any/remdeb_f.x, librdbg/src/i386/any/remdeb_svc.c, librdbg/src/i386/any/remdeb_xdr.c, librdbg/src/m68k/excep_f.c, librdbg/src/m68k/rdbg_cpu_asm.S, librdbg/src/m68k/rdbg_f.c, librdbg/src/m68k/any/remdeb.h, librdbg/src/m68k/any/remdeb_f.x, librdbg/src/m68k/any/remdeb_svc.c, librdbg/src/m68k/any/remdeb_xdr.c, librdbg/src/powerpc/excep_f.c, librdbg/src/powerpc/rdbg_cpu_asm.S, librdbg/src/powerpc/rdbg_f.c, librdbg/src/powerpc/new_exception_processing/remdeb.h, librdbg/src/powerpc/new_exception_processing/remdeb_f.x, librdbg/src/powerpc/new_exception_processing/remdeb_svc.c, librdbg/src/powerpc/new_exception_processing/remdeb_xdr.c: Removed.
This commit is contained in:
@@ -1,3 +1,31 @@
|
||||
2007-08-02 Joel Sherrill <joel.sherrill@OARcorp.com>
|
||||
|
||||
* configure.ac, wrapup/Makefile.am: Remove RDBG.
|
||||
* aclocal/check-rdbg.m4, aclocal/enable-rdbg.m4, librdbg/.cvsignore,
|
||||
librdbg/Makefile.am, librdbg/preinstall.am,
|
||||
librdbg/include/rdbg/rdbg.h, librdbg/include/rdbg/servrpc.h,
|
||||
librdbg/include/rdbg/i386/rdbg_f.h, librdbg/include/rdbg/i386/reg.h,
|
||||
librdbg/include/rdbg/m68k/rdbg_f.h, librdbg/include/rdbg/m68k/reg.h,
|
||||
librdbg/include/rdbg/powerpc/rdbg_f.h,
|
||||
librdbg/include/rdbg/powerpc/reg.h, librdbg/src/_servtgt.c,
|
||||
librdbg/src/awk.svc, librdbg/src/excep.c, librdbg/src/ptrace.c,
|
||||
librdbg/src/rdbg.c, librdbg/src/remdeb.x, librdbg/src/servbkpt.c,
|
||||
librdbg/src/servcon.c, librdbg/src/servrpc.c, librdbg/src/servtgt.c,
|
||||
librdbg/src/servtsp.c, librdbg/src/servutil.c,
|
||||
librdbg/src/i386/excep_f.c, librdbg/src/i386/rdbg_cpu_asm.S,
|
||||
librdbg/src/i386/rdbg_f.c, librdbg/src/i386/any/remdeb.h,
|
||||
librdbg/src/i386/any/remdeb_f.x, librdbg/src/i386/any/remdeb_svc.c,
|
||||
librdbg/src/i386/any/remdeb_xdr.c, librdbg/src/m68k/excep_f.c,
|
||||
librdbg/src/m68k/rdbg_cpu_asm.S, librdbg/src/m68k/rdbg_f.c,
|
||||
librdbg/src/m68k/any/remdeb.h, librdbg/src/m68k/any/remdeb_f.x,
|
||||
librdbg/src/m68k/any/remdeb_svc.c, librdbg/src/m68k/any/remdeb_xdr.c,
|
||||
librdbg/src/powerpc/excep_f.c, librdbg/src/powerpc/rdbg_cpu_asm.S,
|
||||
librdbg/src/powerpc/rdbg_f.c,
|
||||
librdbg/src/powerpc/new_exception_processing/remdeb.h,
|
||||
librdbg/src/powerpc/new_exception_processing/remdeb_f.x,
|
||||
librdbg/src/powerpc/new_exception_processing/remdeb_svc.c,
|
||||
librdbg/src/powerpc/new_exception_processing/remdeb_xdr.c: Removed.
|
||||
|
||||
2007-07-27 Ralf Corsépius <ralf.corsepius@rtems.org>
|
||||
|
||||
* nfsclient/src/dirutils.c: Use PATH_MAX instead of MAXPATHLEN.
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl
|
||||
AC_DEFUN([RTEMS_CHECK_RDBG],
|
||||
[dnl
|
||||
AC_REQUIRE([RTEMS_TOP])dnl
|
||||
AC_REQUIRE([RTEMS_CANONICAL_TARGET_CPU])dnl
|
||||
AC_REQUIRE([RTEMS_CHECK_NETWORKING])dnl
|
||||
AC_REQUIRE([RTEMS_ENABLE_RDBG])dnl
|
||||
AC_CACHE_CHECK([whether BSP supports librdbg],
|
||||
rtems_cv_HAS_RDBG,
|
||||
[
|
||||
if test -d "$srcdir/${RTEMS_TOPdir}/c/src/librdbg/src/${RTEMS_CPU}/${$1}";
|
||||
then
|
||||
rtems_cv_HAS_RDBG="yes" ;
|
||||
elif test -d "$srcdir/${RTEMS_TOPdir}/c/src/librdbg/src/${RTEMS_CPU}/any";
|
||||
then
|
||||
rtems_cv_HAS_RDBG="yes" ;
|
||||
elif test "${RTEMS_CPU}" = "powerpc";
|
||||
then
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[],
|
||||
[#if defined(_OLD_EXCEPTIONS)
|
||||
choke me
|
||||
#endif])],
|
||||
[rtems_cv_HAS_RDBG=yes],
|
||||
[rtems_cv_HAS_RDBG=no])
|
||||
else
|
||||
rtems_cv_HAS_RDBG="no";
|
||||
fi
|
||||
])
|
||||
HAS_RDBG="$rtems_cv_HAS_RDBG"
|
||||
])
|
||||
@@ -1,15 +0,0 @@
|
||||
dnl $Id$
|
||||
|
||||
AC_DEFUN([RTEMS_ENABLE_RDBG],
|
||||
[
|
||||
AC_BEFORE([$0], [RTEMS_CHECK_RDBG])dnl
|
||||
|
||||
AC_ARG_ENABLE(rdbg,
|
||||
[AS_HELP_STRING(--enable-rdbg,enable remote debugger)],
|
||||
[case "${enableval}" in
|
||||
yes) RTEMS_HAS_RDBG=yes ;;
|
||||
no) RTEMS_HAS_RDBG=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for enable-rdbg option) ;;
|
||||
esac],[RTEMS_HAS_RDBG=no])
|
||||
AC_SUBST(RTEMS_HAS_RDBG)dnl
|
||||
])
|
||||
@@ -9,7 +9,6 @@ RTEMS_TOP(../..)
|
||||
|
||||
RTEMS_ENABLE_CXX
|
||||
RTEMS_ENABLE_NETWORKING
|
||||
RTEMS_ENABLE_RDBG
|
||||
|
||||
RTEMS_CANONICAL_TARGET_CPU
|
||||
|
||||
@@ -105,12 +104,6 @@ AM_PROG_CC_C_O
|
||||
RTEMS_PROG_CCAS
|
||||
RTEMS_CANONICALIZE_TOOLS
|
||||
|
||||
AS_IF([test "$HAS_NETWORKING" = "yes"],[
|
||||
AS_IF([test "$RTEMS_HAS_RDBG" = "yes"],[
|
||||
RTEMS_CHECK_RDBG(RTEMS_BSP)
|
||||
])
|
||||
])
|
||||
|
||||
RTEMS_CHECK_GCC_WEAK
|
||||
|
||||
AC_SUBST(CUSTOM_CFG_FILES)
|
||||
@@ -152,7 +145,6 @@ fi
|
||||
|
||||
BSP_SUBDIRS="$BSP_SUBDIRS lib"
|
||||
BSP_SUBDIRS="$BSP_SUBDIRS libchip"
|
||||
BSP_SUBDIRS="$BSP_SUBDIRS librdbg"
|
||||
BSP_SUBDIRS="$BSP_SUBDIRS nfsclient"
|
||||
|
||||
AS_IF([test "$RTEMS_HAS_CPLUSPLUS" = "yes"],[
|
||||
@@ -220,15 +212,6 @@ AS_IF([test "$host_cpu" = sparc],[
|
||||
|
||||
AM_CONDITIONAL([HAS_NETWORKING],[test "$HAS_NETWORKING" = "yes"])
|
||||
|
||||
# FIXME: This is sick
|
||||
AM_CONDITIONAL([HAS_RDBG],[test "$HAS_RDBG" = "yes"])
|
||||
AM_CONDITIONAL([HAS_RDBG_i386],[test "$HAS_RDBG" = "yes" \
|
||||
&& test $RTEMS_CPU = "i386"])
|
||||
AM_CONDITIONAL([HAS_RDBG_m68k],[test "$HAS_RDBG" = "yes" \
|
||||
&& test $RTEMS_CPU = "m68k"])
|
||||
AM_CONDITIONAL([HAS_RDBG_powerpc],[test "$HAS_RDBG" = "yes" \
|
||||
&& test $RTEMS_CPU = "powerpc"])
|
||||
|
||||
AM_CONDITIONAL(HAS_POSIX,test "$HAS_POSIX_API" = "yes")
|
||||
|
||||
# The posix bsp doesn't support libchip
|
||||
@@ -259,8 +242,6 @@ AC_CONFIG_FILES([Makefile],
|
||||
AC_CONFIG_FILES([
|
||||
support/Makefile
|
||||
|
||||
librdbg/Makefile
|
||||
|
||||
libchip/Makefile
|
||||
|
||||
optman/Makefile
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
aclocal.m4
|
||||
autom4te*.cache
|
||||
config.cache
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
Makefile
|
||||
Makefile.in
|
||||
missing
|
||||
mkinstalldirs
|
||||
@@ -1,174 +0,0 @@
|
||||
##
|
||||
## $Id$
|
||||
##
|
||||
|
||||
include $(top_srcdir)/automake/compile.am
|
||||
|
||||
DISTCLEANFILES =
|
||||
CLEANFILES =
|
||||
BUILT_SOURCES =
|
||||
MAINTAINERCLEANFILES =
|
||||
|
||||
## FIXME: This Makefile.am is one blatant ugly HACK
|
||||
## May-be this should be put into libcpu?
|
||||
|
||||
if HAS_RDBG
|
||||
include_rdbgdir = $(includedir)/rdbg
|
||||
|
||||
include_rdbg_HEADERS = include/rdbg/rdbg.h include/rdbg/servrpc.h
|
||||
|
||||
noinst_LIBRARIES = librdbg.a
|
||||
librdbg_a_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
librdbg_a_SOURCES = src/rdbg.c src/servcon.c src/servbkpt.c src/servrpc.c \
|
||||
src/excep.c src/servtgt.c src/servtsp.c src/servutil.c src/_servtgt.c \
|
||||
src/ptrace.c
|
||||
endif
|
||||
|
||||
X_FILES = src/remdeb.x
|
||||
EXTRA_DIST = src/remdeb.x
|
||||
|
||||
if HAS_RDBG
|
||||
if HAS_RDBG_powerpc
|
||||
librdbg_a_SOURCES += src/powerpc/excep_f.c src/powerpc/rdbg_f.c \
|
||||
src/powerpc/rdbg_cpu_asm.S
|
||||
|
||||
# Generated sources
|
||||
librdbg_a_SOURCES += src/powerpc/new_exception_processing/remdeb_xdr.c
|
||||
librdbg_a_SOURCES += src/powerpc/new_exception_processing/remdeb_svc.c
|
||||
librdbg_a_SOURCES += src/powerpc/new_exception_processing/remdeb.h
|
||||
include_rdbg_HEADERS += src/powerpc/new_exception_processing/remdeb.h
|
||||
include_rdbg_HEADERS += include/rdbg/powerpc/rdbg_f.h \
|
||||
include/rdbg/powerpc/reg.h
|
||||
endif
|
||||
endif
|
||||
|
||||
# X source names
|
||||
EXTRA_DIST += src/powerpc/new_exception_processing/remdeb_f.x
|
||||
|
||||
BUILT_SOURCES += src/powerpc/new_exception_processing/remdeb.h
|
||||
BUILT_SOURCES += src/powerpc/new_exception_processing/remdeb_xdr.c
|
||||
BUILT_SOURCES += src/powerpc/new_exception_processing/remdeb_svc.c
|
||||
MAINTAINERCLEANFILES += src/powerpc/new_exception_processing/remdeb_xdr.c
|
||||
MAINTAINERCLEANFILES += src/powerpc/new_exception_processing/remdeb_svc.c
|
||||
MAINTAINERCLEANFILES += src/powerpc/new_exception_processing/remdeb.h
|
||||
|
||||
if RPCTOOLS
|
||||
$(srcdir)/src/powerpc/new_exception_processing/remdeb.h: $(X_FILES) \
|
||||
src/powerpc/new_exception_processing/remdeb_f.x
|
||||
rm -f $@; ( cd $(srcdir) && \
|
||||
$(RPCGEN) -h -DFRONTEND=\"powerpc/new_exception_processing/remdeb_f.x\" \
|
||||
-o src/powerpc/new_exception_processing/remdeb.h src/remdeb.x )
|
||||
|
||||
$(srcdir)/src/powerpc/new_exception_processing/remdeb_xdr.c: $(X_FILES) \
|
||||
src/powerpc/new_exception_processing/remdeb_f.x
|
||||
rm -f $@; ( cd $(srcdir) && \
|
||||
$(RPCGEN) -c -DFRONTEND=\"powerpc/new_exception_processing/remdeb_f.x\" src/remdeb.x \
|
||||
| sed "s,^#include.*remdeb\.h.*,#include \"src/powerpc/new_exception_processing/remdeb.h\"," \
|
||||
> src/powerpc/new_exception_processing/remdeb_xdr.c )
|
||||
|
||||
$(srcdir)/src/powerpc/new_exception_processing/remdeb_svc.c: $(X_FILES) \
|
||||
src/powerpc/new_exception_processing/remdeb_f.x
|
||||
rm -f $@; ( cd $(srcdir) && \
|
||||
$(RPCGEN) -m -DFRONTEND=\"powerpc/new_exception_processing/remdeb_f.x\" \
|
||||
-o src/powerpc/new_exception_processing/tmpSvc.c src/remdeb.x; \
|
||||
$(AWK) -f src/awk.svc THEPROG="remdeb.h" src/powerpc/new_exception_processing/tmpSvc.c \
|
||||
> src/powerpc/new_exception_processing/remdeb_svc.c; \
|
||||
sed -e 's/fprintf.*,/printf(/' src/powerpc/new_exception_processing/remdeb_svc.c > src/powerpc/new_exception_processing/remdeb_svc.tmp; \
|
||||
mv src/powerpc/new_exception_processing/remdeb_svc.tmp src/powerpc/new_exception_processing/remdeb_svc.c; \
|
||||
rm -f src/powerpc/new_exception_processing/tmpSvc.c )
|
||||
endif
|
||||
|
||||
if HAS_RDBG
|
||||
if HAS_RDBG_i386
|
||||
librdbg_a_SOURCES += src/i386/excep_f.c src/i386/rdbg_f.c \
|
||||
src/i386/rdbg_cpu_asm.S
|
||||
|
||||
# Generated sources
|
||||
librdbg_a_SOURCES += src/i386/any/remdeb_xdr.c
|
||||
librdbg_a_SOURCES += src/i386/any/remdeb_svc.c
|
||||
librdbg_a_SOURCES += src/i386/any/remdeb.h
|
||||
include_rdbg_HEADERS += src/i386/any/remdeb.h
|
||||
include_rdbg_HEADERS += include/rdbg/i386/rdbg_f.h include/rdbg/i386/reg.h
|
||||
endif
|
||||
endif
|
||||
|
||||
# X source names
|
||||
EXTRA_DIST += src/i386/any/remdeb_f.x
|
||||
BUILT_SOURCES += src/i386/any/remdeb.h
|
||||
BUILT_SOURCES += src/i386/any/remdeb_xdr.c
|
||||
BUILT_SOURCES += src/i386/any/remdeb_svc.c
|
||||
MAINTAINERCLEANFILES += src/i386/any/remdeb_xdr.c
|
||||
MAINTAINERCLEANFILES += src/i386/any/remdeb_svc.c
|
||||
MAINTAINERCLEANFILES += src/i386/any/remdeb.h
|
||||
|
||||
if RPCTOOLS
|
||||
$(srcdir)/src/i386/any/remdeb.h: $(X_FILES) src/i386/any/remdeb_f.x
|
||||
rm -f $@; ( cd $(srcdir) && \
|
||||
$(RPCGEN) -h -DFRONTEND=\"i386/any/remdeb_f.x\" \
|
||||
-o src/i386/any/remdeb.h src/remdeb.x )
|
||||
|
||||
$(srcdir)/src/i386/any/remdeb_xdr.c: $(X_FILES) src/i386/any/remdeb_f.x
|
||||
rm -f $@; ( cd $(srcdir) && \
|
||||
$(RPCGEN) -c -DFRONTEND=\"i386/any/remdeb_f.x\" src/remdeb.x \
|
||||
| sed "s,^#include.*remdeb\.h.*,#include \"src/i386/any/remdeb.h\"," \
|
||||
> src/i386/any/remdeb_xdr.c )
|
||||
|
||||
$(srcdir)/src/i386/any/remdeb_svc.c: $(X_FILES) src/i386/any/remdeb_f.x
|
||||
rm -f $@; ( cd $(srcdir) && \
|
||||
$(RPCGEN) -m -DFRONTEND=\"i386/any/remdeb_f.x\" \
|
||||
-o src/i386/any/tmpSvc.c src/remdeb.x; \
|
||||
$(AWK) -f src/awk.svc THEPROG="remdeb.h" src/i386/any/tmpSvc.c \
|
||||
> src/i386/any/remdeb_svc.c; \
|
||||
sed -e 's/fprintf.*,/printf(/' src/i386/any/remdeb_svc.c > src/i386/any/remdeb_svc.tmp; \
|
||||
mv src/i386/any/remdeb_svc.tmp src/i386/any/remdeb_svc.c; \
|
||||
rm -f src/i386/any/tmpSvc.c )
|
||||
endif
|
||||
|
||||
if HAS_RDBG
|
||||
if HAS_RDBG_m68k
|
||||
librdbg_a_SOURCES += src/m68k/excep_f.c src/m68k/rdbg_f.c \
|
||||
src/m68k/rdbg_cpu_asm.S
|
||||
|
||||
# Generated sources
|
||||
librdbg_a_SOURCES += src/m68k/any/remdeb_xdr.c
|
||||
librdbg_a_SOURCES += src/m68k/any/remdeb_svc.c
|
||||
librdbg_a_SOURCES += src/m68k/any/remdeb.h
|
||||
include_rdbg_HEADERS += src/m68k/any/remdeb.h
|
||||
include_rdbg_HEADERS += include/rdbg/m68k/rdbg_f.h include/rdbg/m68k/reg.h
|
||||
endif
|
||||
endif
|
||||
|
||||
# X source names
|
||||
EXTRA_DIST += src/m68k/any/remdeb_f.x
|
||||
BUILT_SOURCES += src/m68k/any/remdeb.h
|
||||
BUILT_SOURCES += src/m68k/any/remdeb_xdr.c
|
||||
BUILT_SOURCES += src/m68k/any/remdeb_svc.c
|
||||
MAINTAINERCLEANFILES += src/m68k/any/remdeb_xdr.c
|
||||
MAINTAINERCLEANFILES += src/m68k/any/remdeb_svc.c
|
||||
MAINTAINERCLEANFILES += src/m68k/any/remdeb.h
|
||||
|
||||
if RPCTOOLS
|
||||
$(srcdir)/src/m68k/any/remdeb.h: $(X_FILES) src/m68k/any/remdeb_f.x
|
||||
rm -f $@; ( cd $(srcdir) && \
|
||||
$(RPCGEN) -h -DFRONTEND=\"m68k/any/remdeb_f.x\" \
|
||||
-o src/m68k/any/remdeb.h src/remdeb.x )
|
||||
$(srcdir)/src/m68k/any/remdeb_xdr.c: $(X_FILES) src/m68k/any/remdeb_f.x
|
||||
rm -f $@; ( cd $(srcdir) && \
|
||||
$(RPCGEN) -c -DFRONTEND=\"m68k/any/remdeb_f.x\" src/remdeb.x \
|
||||
| sed "s,^#include.*remdeb\.h.*,#include \"src/m68k/any/remdeb.h\"," \
|
||||
> src/m68k/any/remdeb_xdr.c )
|
||||
$(srcdir)/src/m68k/any/remdeb_svc.c: $(X_FILES) src/m68k/any/remdeb_f.x
|
||||
rm -f $@; ( cd $(srcdir) && \
|
||||
$(RPCGEN) -m -DFRONTEND=\"m68k/any/remdeb_f.x\" \
|
||||
-o src/m68k/any/tmpSvc.c src/remdeb.x; \
|
||||
$(AWK) -f src/awk.svc THEPROG="remdeb.h" src/m68k/any/tmpSvc.c \
|
||||
> src/m68k/any/remdeb_svc.c; \
|
||||
sed -e 's/fprintf.*,/printf(/' src/m68k/any/remdeb_svc.c > src/m68k/any/remdeb_svc.tmp; \
|
||||
mv src/m68k/any/remdeb_svc.tmp src/m68k/any/remdeb_svc.c; \
|
||||
rm -f src/m68k/any/tmpSvc.c )
|
||||
endif
|
||||
|
||||
EXTRA_DIST += src/awk.svc
|
||||
|
||||
include $(srcdir)/preinstall.am
|
||||
include $(top_srcdir)/automake/local.am
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component = RDBG
|
||||
* Module = rdbg_f.h
|
||||
*
|
||||
* Synopsis = Machine-dependent header file
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef RDBG_F_H
|
||||
#define RDBG_F_H
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
|
||||
#define EFLAGS_TF 0x00100
|
||||
|
||||
static inline int isRdbgException(Exception_context *ctx)
|
||||
{
|
||||
if (
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG
|
||||
) return 0;
|
||||
else return 1;
|
||||
}
|
||||
static inline int getExcNum(Exception_context *ctx)
|
||||
{
|
||||
return ctx->ctx->idtIndex;
|
||||
}
|
||||
|
||||
extern void connect_rdbg_exception();
|
||||
extern void disconnect_rdbg_exception();
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Registers Offset in frame definition
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define NBREGS 19
|
||||
|
||||
#define SS 18
|
||||
#define UESP 17
|
||||
#define EFL 16
|
||||
#define CS 15
|
||||
#define EIP 14
|
||||
#define ERR 13
|
||||
#define TRAPNO 12
|
||||
#define EAX 11
|
||||
#define ECX 10
|
||||
#define EDX 9
|
||||
#define EBX 8
|
||||
#define ESP 7
|
||||
#define EBP 6
|
||||
#define ESI 5
|
||||
#define EDI 4
|
||||
#define DS 3
|
||||
#define ES 2
|
||||
#define FS 1
|
||||
#define GS 0
|
||||
|
||||
typedef unsigned int regs[NBREGS];
|
||||
|
||||
/* To be used in common code */
|
||||
typedef regs REGS;
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component = RDBG
|
||||
* Module = rdbg_f.h
|
||||
*
|
||||
* Synopsis = Machine-dependent header file
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef RDBG_F_H
|
||||
#define RDBG_F_H
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
|
||||
static inline int isRdbgException(Exception_context *ctx)
|
||||
{
|
||||
if (
|
||||
ctx->ctx->vecnum != 9 /* trace - singlestep */
|
||||
&& ctx->ctx->vecnum != 47 /* trap #15 - breakpoint */
|
||||
&& ctx->ctx->vecnum != 36 /* trap #4 - enter RDBG */
|
||||
) return 0;
|
||||
else return 1;
|
||||
}
|
||||
static inline int getExcNum(Exception_context *ctx)
|
||||
{
|
||||
return ctx->ctx->vecnum;
|
||||
}
|
||||
|
||||
extern void connect_rdbg_exception();
|
||||
extern void disconnect_rdbg_exception();
|
||||
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Registers frame offset definition
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define NBREGS 18
|
||||
|
||||
typedef unsigned int regs[NBREGS];
|
||||
|
||||
/* To be used in common code */
|
||||
typedef regs REGS;
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component = RDBG
|
||||
* Module = rdbg_f.h
|
||||
*
|
||||
* Synopsis = Machine-dependent header file
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef RDBG_F_H
|
||||
#define RDBG_F_H
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
|
||||
static inline int isRdbgException(Exception_context *ctx)
|
||||
{
|
||||
if (
|
||||
ctx->ctx->_EXC_number != ASM_SYS_VECTOR &&
|
||||
ctx->ctx->_EXC_number != ASM_PROG_VECTOR &&
|
||||
ctx->ctx->_EXC_number != ASM_TRACE_VECTOR
|
||||
) return 0;
|
||||
else return 1;
|
||||
}
|
||||
static inline int getExcNum(Exception_context *ctx)
|
||||
{
|
||||
return ctx->ctx->_EXC_number;
|
||||
}
|
||||
|
||||
extern void connect_rdbg_exception();
|
||||
extern void disconnect_rdbg_exception();
|
||||
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Registers frame offset definition
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define NBREGS 43
|
||||
|
||||
typedef unsigned int regs[NBREGS];
|
||||
|
||||
/* To be used in common code */
|
||||
typedef regs REGS;
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component = RDBG
|
||||
*
|
||||
* Synopsis = rdbg.h
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef RDBG_H
|
||||
#define RDBG_H
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdlib.h> /* For malloc() and free() prototypes */
|
||||
#include <bsp.h>
|
||||
#include <rtems.h>
|
||||
|
||||
#define Malloc(size) malloc (size)
|
||||
#define Free(block) free (block)
|
||||
#define Realloc(block,size) realloc (block, size)
|
||||
#define StrDup(str) strdup(str)
|
||||
|
||||
#define LIST_PID 16 /* dynamic list of processes/tasks */
|
||||
#define LIST_PID_DEB 17 /* list of processes under debug now */
|
||||
#define LIST_PID_THREAD 18 /* list of threads for specific process */
|
||||
#define LIST_CONN 19 /* dynamic list of connections */
|
||||
|
||||
/* RTEMS internals */
|
||||
extern void remotedeb_2 (struct svc_req* rqstp, SVCXPRT* transp);
|
||||
extern void setErrno (int error);
|
||||
extern int getErrno ();
|
||||
extern int ptrace (int request, int pid, char* addr,
|
||||
int data, char* addr2);
|
||||
|
||||
extern int TSP_RETRIES;
|
||||
extern volatile int ExitForSingleStep;
|
||||
extern volatile int justSaveContext;
|
||||
extern volatile Objects_Id currentTargetThread;
|
||||
extern volatile int CannotRestart;
|
||||
extern volatile int TotalReboot;
|
||||
|
||||
/* Missing RPC prototypes */
|
||||
SVCXPRT* svcudp_create (int fd);
|
||||
void svc_processrequest (SVCXPRT* xprt,
|
||||
u_long prog, u_long vers,
|
||||
void (*dispatch)());
|
||||
int svcudp_enablecache (SVCXPRT *transp, u_long size);
|
||||
|
||||
typedef struct Exception_context_struct {
|
||||
struct Exception_context_struct *next;
|
||||
struct Exception_context_struct *previous;
|
||||
Objects_Id id;
|
||||
Objects_Id semaphoreId;
|
||||
CPU_Exception_frame *ctx;
|
||||
} Exception_context;
|
||||
|
||||
struct xdr_regs;
|
||||
|
||||
extern int PushExceptCtx (Objects_Id Id,
|
||||
Objects_Id semId,
|
||||
CPU_Exception_frame *ctx);
|
||||
extern int PopExceptCtx (Objects_Id Id);
|
||||
extern Exception_context *GetExceptCtx (Objects_Id Id);
|
||||
extern int Single_Step (CPU_Exception_frame* ctx);
|
||||
extern int CheckForSingleStep (CPU_Exception_frame* ctx);
|
||||
extern void BreakPointExcHdl (CPU_Exception_frame *ctx);
|
||||
extern void CtxToRegs (const CPU_Exception_frame*,struct xdr_regs*);
|
||||
extern void RegsToCtx (const struct xdr_regs*,CPU_Exception_frame*);
|
||||
|
||||
extern void enterRdbg ();
|
||||
extern void get_ctx_thread (Thread_Control *thread,
|
||||
CPU_Exception_frame* ctx);
|
||||
extern void set_ctx_thread (Thread_Control *thread,
|
||||
CPU_Exception_frame* ctx);
|
||||
extern int PushSavedExceptCtx ( Objects_Id Id,
|
||||
CPU_Exception_frame *ctx );
|
||||
extern int ExcepToSig (Exception_context *ctx);
|
||||
|
||||
extern rtems_id serializeSemId;
|
||||
extern rtems_id wakeupEventSemId;
|
||||
extern volatile unsigned int NbSerializedCtx;
|
||||
|
||||
void copyback_data_cache_and_invalidate_instr_cache(unsigned char* addr, int size);
|
||||
|
||||
#include <rdbg/rdbg_f.h>
|
||||
|
||||
#endif /* !RDBG_H */
|
||||
@@ -1,279 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef SERVRPC_H
|
||||
#define SERVRPC_H
|
||||
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rpc/types.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/svc.h>
|
||||
|
||||
extern int CONN_LIST_INC;
|
||||
extern int PID_LIST_INC;
|
||||
extern int TSP_RETRIES;
|
||||
extern int BackPort;
|
||||
extern char taskName[];
|
||||
extern int getId();
|
||||
|
||||
|
||||
#ifdef DDEBUG
|
||||
int rdb_debug; /* True if env var RDB_DEBUG defined */
|
||||
extern const char* PtraceNames[]; /* list of ptrace requests for debug out */
|
||||
extern const char* BmsgNames[]; /* list of BMSG_xxx names */
|
||||
extern const char* PtraceName(int req);
|
||||
|
||||
#ifdef i386 /* low-high machine such as 386 */
|
||||
#define HL_W(w) (((UINT16)(w)>>8)+((((w)&0xFF)<<8)))
|
||||
#define HL_D(d) (((UINT32)(d)>>24)+(((d)&0x00FF0000)>>8) \
|
||||
+(((d)&0xFF00)<<8)+(((d)&0xFF)<<24))
|
||||
#else
|
||||
#define HL_W(w) w
|
||||
#define HL_D(d) d
|
||||
#endif
|
||||
|
||||
# define DPRINTF(a) (rdb_debug ? printk ("%d >>> ", getId()), printk a : 0)
|
||||
#else
|
||||
# define DPRINTF(a) /* suppress */
|
||||
#endif
|
||||
|
||||
/* Macros for analyzing/creating process status values. Presently do
|
||||
not need to be separated per target. Could even use WIF... */
|
||||
|
||||
#define STS_SIGNALLED(status) (((status) & 0xFF) == 0x7F)
|
||||
#define STS_TERMONSIG(status) (((status) & 0xFF) && !STS_SIGNALLED(status))
|
||||
#define STS_TERMGETSIG(status) ((status) & 0x7F)
|
||||
#define STS_MAKESIG(sig) (((sig) << 8) | 0x7f)
|
||||
#define STS_GETSIG(status) ((status) >> 8)
|
||||
#define STS_GETCODE(status) ((status) >> 8)
|
||||
|
||||
|
||||
/* now define base types */
|
||||
#ifndef UCHAR_DEFINED
|
||||
#define UCHAR_DEFINED /* to handle duplicate typedes */
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char UINT8;
|
||||
typedef char INT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef short INT16;
|
||||
typedef unsigned long UINT32;
|
||||
typedef long INT32;
|
||||
#endif /* UCHAR_DEFINED */
|
||||
|
||||
typedef long PID; /* generalized process id */
|
||||
|
||||
#ifndef True
|
||||
# define True 1
|
||||
# define False 0
|
||||
typedef char Boolean;
|
||||
#endif
|
||||
|
||||
#define MAX_FILENAME 1024 /* largest filename with path */
|
||||
#define MAX_SEND 5 /* up to 5 pended outbound messages */
|
||||
|
||||
#define SERVER_VERS 1
|
||||
|
||||
typedef enum
|
||||
{ /* message types */
|
||||
BMSG_WARM=1, /* warm test for network connection */
|
||||
BMSG_WAIT, /* wait change (stopped/started) */
|
||||
BMSG_BREAK, /* breakpoint changed */
|
||||
BMSG_EXEC_FAIL, /* exec failed from spawn */
|
||||
BMSG_DETACH, /* process detached from server */
|
||||
BMSG_KILLED, /* killed by server */
|
||||
BMSG_NOT_PRIM, /* no longer the primary owner */
|
||||
BMSG_NEW_PID /* the process was restart with new pid (in
|
||||
context). Same ownership rules. */
|
||||
} BACK_MSG;
|
||||
|
||||
typedef struct
|
||||
{ /* this is the break_list[0] entry of pid */
|
||||
UCHAR clr_step; /* true if step off break in last_break */
|
||||
UCHAR pad1; /* Set if STEPEMUL breakpoints exist */
|
||||
UINT16 last_break; /* last breakpoint we stopped on (if break) */
|
||||
UINT32 range_start; /* start address of range */
|
||||
UINT32 range_end; /* end address inclusive */
|
||||
} BASE_BREAK;
|
||||
|
||||
enum
|
||||
{ /* last start values */
|
||||
LAST_NONE, /* stopped already */
|
||||
LAST_STEP, /* did a step last - do not send to prim */
|
||||
LAST_CONT, /* did a continue last */
|
||||
LAST_RANGE, /* in the middle of step-in-range */
|
||||
LAST_STEPOFF, /* stepped off break, now need to cont */
|
||||
LAST_KILLED, /* was killed by ptrace */
|
||||
LAST_DETACHED /* was detached by ptrace */
|
||||
};
|
||||
#define LAST_START 0x80 /* first execed. This is to handle MiX
|
||||
bug where we need to start again */
|
||||
|
||||
typedef struct
|
||||
{ /* one per open process */
|
||||
PID pid; /* process id (or 0 if free) */
|
||||
int state; /* status from last wait if stopped */
|
||||
UCHAR running; /* True if running, else stopped/term */
|
||||
/* now connection control over process */
|
||||
UCHAR owners; /* count of owners for notify and term release */
|
||||
UCHAR primary_conn; /* primary owner connection or 255=none */
|
||||
|
||||
UCHAR filler; /* Preserve alignment */
|
||||
|
||||
/* now break control and support */
|
||||
UINT8 last_start; /* LAST_xx start info for wait() */
|
||||
UINT8 flags; /* PIDFLG_xxx flags */
|
||||
UINT16 break_alloc; /* number of entries in break_list */
|
||||
xdr_break *break_list; /* list of breakpoints ([0] is BASE_BREAK) */
|
||||
/* now registers and other save information */
|
||||
xdr_regs regs; /* saved registers when stopped */
|
||||
int is_step; /* Was break or step (regs ambiguous often) */
|
||||
int stop_wanted; /* Don't ignore next stop */
|
||||
UINT32 thread; /* current stopped thread or -1 if none */
|
||||
char *name; /* full pathname or NULL if not known */
|
||||
INT32 child; /* child pid that manages the pid */
|
||||
UINT32 textStart; /* for relocating breakpoints at restart */
|
||||
} PID_LIST;
|
||||
PID_LIST *pid_list; /* array of processes being managed */
|
||||
int pid_list_cnt; /* number of entries allocated */
|
||||
UINT16 last_break; /* unique handle generator for breaks */
|
||||
#define NO_PRIMARY ((UCHAR)-1)
|
||||
|
||||
typedef union
|
||||
{ /* an opaque net address */
|
||||
unsigned long l[4];
|
||||
unsigned char c[16]; /* corresponds to IP, enough for ChIPC */
|
||||
} NET_OPAQUE;
|
||||
|
||||
typedef struct
|
||||
{ /* one per connection */
|
||||
UCHAR in_use; /* True if in use */
|
||||
UCHAR debug_type; /* type of connection */
|
||||
UINT16 flags; /* flags for connection (CFLG_xxx) */
|
||||
NET_OPAQUE sender; /* opaque address for transport compare */
|
||||
NET_OPAQUE back_port; /* opaque address for transport event msgs */
|
||||
NET_OPAQUE route; /* optional route address */
|
||||
UINT32 pid_map[10]; /* map of pids owned relative to pid list */
|
||||
/* this allows up to 320 pids to be managed */
|
||||
UCHAR last_msg_num; /* msg number used last to handle multi-send */
|
||||
/* next field associated with UDP send messages */
|
||||
UCHAR retry; /* count of retries. If 0, ok. If not 0, we
|
||||
are in active wait for reply to an event */
|
||||
UCHAR send_idx; /* current number of send's pended */
|
||||
struct SEND_LIST
|
||||
{ /* holds pending msgs */
|
||||
UCHAR send_type; /* BMSG_xxx type of message */
|
||||
UCHAR retry; /* number of times to retry */
|
||||
UINT16 spec; /* spec field */
|
||||
PID pid; /* pid if applies */
|
||||
UINT32 context; /* additional context if needed */
|
||||
} send_list[MAX_SEND]; /* pended list of messages being sent */
|
||||
char user_name[NAMEMAX]; /* name of user connecting in */
|
||||
/* next fields are managed at runtime to handle lists, command upload, and
|
||||
command download. */
|
||||
enum {LST_NONE, LST_SPAWN, LST_INFO, LST_CMD_DOWN} list_type;
|
||||
char *list; /* curr list we are sending/getting (malloced) */
|
||||
UINT16 list_sz; /* size of current list (string len) */
|
||||
UINT16 list_num; /* number of current list or position */
|
||||
UINT16 list_alloc; /* amount allocated so far */
|
||||
UINT16 list_save; /* used internally */
|
||||
} CONN_LIST;
|
||||
CONN_LIST *conn_list; /* an array of connections */
|
||||
int conn_list_cnt; /* number allocated */
|
||||
|
||||
/* Operations over the PID map. Each indexes into long and then bit */
|
||||
/* 5 is log2 of 32, the number of bits in an int */
|
||||
#define PIDMAP_TEST(conn,idx) \
|
||||
(conn_list [conn].pid_map [(idx) >> 5] & (1 << ((idx) & 31)))
|
||||
|
||||
#define PIDMAP_SET(conn,idx) \
|
||||
(conn_list [conn].pid_map [(idx) >> 5] |= 1 << ((idx) & 31))
|
||||
|
||||
#define PIDMAP_CLEAR(conn,idx) \
|
||||
(conn_list [conn].pid_map [(idx) >> 5] &= ~(1 << ((idx) &31)))
|
||||
|
||||
#define PROC_TERMINATED(plst) \
|
||||
(!(plst)->running && !STS_SIGNALLED ((plst)->state))
|
||||
|
||||
|
||||
/* first define the Connection routines exported from servcon.c */
|
||||
|
||||
int ConnCreate (struct svc_req *rqstp, open_in *in);
|
||||
void ConnDelete (int conn_idx, struct svc_req *rqstp, close_control control);
|
||||
|
||||
void TspInit (int rpc_io_channel);
|
||||
Boolean TspTranslateRpcAddr (struct svc_req *rqstp, NET_OPAQUE *opaque);
|
||||
Boolean TspValidateAddr (NET_OPAQUE *opaque, NET_OPAQUE *sender);
|
||||
int TspConnGetIndex (struct svc_req *rqstp);
|
||||
|
||||
void TspSendWaitChange (int conn_idx, BACK_MSG msg, UINT16 spec, PID pid,
|
||||
UINT32 context, Boolean force);
|
||||
void TspSendMessage (int conn_idx, Boolean resend);
|
||||
void TspMessageReceive (int conn_idx, PID pid);
|
||||
char* TspGetHostName (int conn_idx);
|
||||
void TgtCreateNew (PID pid, int conn_idx, INT32 child,
|
||||
char *name, Boolean spawn);
|
||||
Boolean TgtAttach (int conn_idx, PID pid);
|
||||
void TgtNotifyWaitChange(PID pid, int status, Boolean exclude);
|
||||
void TgtNotifyAll (int pid_idx, BACK_MSG msg, UINT16 spec,
|
||||
UINT32 context, int exclude_conn, Boolean force);
|
||||
void TgtDelete (PID_LIST*, int conn_idx, BACK_MSG notify);
|
||||
int TgtKillAndDelete (PID_LIST *plst, struct svc_req *rqstp, Boolean term);
|
||||
void TgtDetachCon (int conn_idx, int pid_idx, Boolean delete);
|
||||
int TgtThreadList (PID_LIST*, unsigned* buf, unsigned int size);
|
||||
int TgtGetThreadName (PID_LIST*, unsigned thLi, char* name);
|
||||
int TgtPtrace (int req, PID pid, char *addr, int data, void *addr2);
|
||||
int TgtRealPtrace (int req, PID pid, char *addr, int data, void *addr2);
|
||||
Boolean TgtHandleChildChange(PID pid, int* status, int* unexp,
|
||||
CPU_Exception_frame *ctx);
|
||||
#ifdef DDEBUG
|
||||
/* TgtDbgPtrace is a wrapper for RealPtrace() doing traces */
|
||||
int TgtDbgPtrace (int req, PID pid, char *addr, int data, void *addr2);
|
||||
#endif
|
||||
|
||||
|
||||
/* Information stored in "handle" */
|
||||
#define BKPT_INACTIVE 1 /* bkpt inactive for this execution */
|
||||
#define BKPT_ACTIVE 0 /* bkpt active for this execution */
|
||||
|
||||
int BreakOverwrite (const PID_LIST* plst,const char* addr,
|
||||
unsigned int size);
|
||||
int BreakSet (PID_LIST*, int conn_idx, xdr_break*);
|
||||
int BreakSetAt (PID_LIST*, int conn_idx, unsigned long addr,break_type);
|
||||
int BreakClear (PID_LIST*, int conn_idx, int handle);
|
||||
int BreakGetIndex (PID_LIST*, void* addr);
|
||||
int BreakGet (const PID_LIST*, int data, xdr_break*);
|
||||
void BreakHide (const PID_LIST*, void*, int, void*);
|
||||
int BreakStepOff (const PID_LIST*, void** paddr2);
|
||||
void BreakSteppedOff (PID_LIST*);
|
||||
int BreakRespawn (PID_LIST*);
|
||||
int BreakIdentify (PID_LIST*, int adjust, int thread);
|
||||
void BreakPcChanged (PID_LIST*);
|
||||
int BreakStepRange (PID_LIST*, void* addr, int len);
|
||||
void BreaksDisable (int pid);
|
||||
void BreaksEnable (int pid);
|
||||
|
||||
int TgtBreakRestoreOrig (int pid, void* addr, void* addr2);
|
||||
void TgtBreakCancelStep (PID_LIST* plst);
|
||||
|
||||
Boolean ListAlloc (char *buff, CONN_LIST *clst);
|
||||
int FindPidEntry (int pid);
|
||||
|
||||
open_out* RPCGENSRVNAME(open_connex_2_svc) (open_in *in,
|
||||
struct svc_req *rqstp);
|
||||
signal_out* RPCGENSRVNAME(send_signal_2_svc) (signal_in *in,
|
||||
struct svc_req *rqstp);
|
||||
ptrace_out* RPCGENSRVNAME(ptrace_2_svc) (ptrace_in *in,
|
||||
struct svc_req *rqstp);
|
||||
wait_out* RPCGENSRVNAME(wait_info_2_svc) (wait_in *in,
|
||||
struct svc_req *rqstp);
|
||||
#endif /* !SERVRPC_H */
|
||||
@@ -1,74 +0,0 @@
|
||||
## Automatically generated by ampolish3 - Do not edit
|
||||
|
||||
if AMPOLISH3
|
||||
$(srcdir)/preinstall.am: Makefile.am
|
||||
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
|
||||
endif
|
||||
|
||||
PREINSTALL_DIRS =
|
||||
DISTCLEANFILES += $(PREINSTALL_DIRS)
|
||||
|
||||
all-am: $(PREINSTALL_FILES)
|
||||
|
||||
PREINSTALL_FILES =
|
||||
CLEANFILES += $(PREINSTALL_FILES)
|
||||
|
||||
if HAS_RDBG
|
||||
$(PROJECT_INCLUDE)/rdbg/$(dirstamp):
|
||||
@$(MKDIR_P) $(PROJECT_INCLUDE)/rdbg
|
||||
@: > $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
|
||||
$(PROJECT_INCLUDE)/rdbg/rdbg.h: include/rdbg/rdbg.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/rdbg.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/rdbg.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rdbg/servrpc.h: include/rdbg/servrpc.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/servrpc.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/servrpc.h
|
||||
endif
|
||||
if HAS_RDBG
|
||||
if HAS_RDBG_powerpc
|
||||
$(PROJECT_INCLUDE)/rdbg/remdeb.h: src/powerpc/new_exception_processing/remdeb.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/remdeb.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/remdeb.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rdbg/rdbg_f.h: include/rdbg/powerpc/rdbg_f.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/rdbg_f.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/rdbg_f.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rdbg/reg.h: include/rdbg/powerpc/reg.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/reg.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/reg.h
|
||||
endif
|
||||
endif
|
||||
if HAS_RDBG
|
||||
if HAS_RDBG_i386
|
||||
$(PROJECT_INCLUDE)/rdbg/remdeb.h: src/i386/any/remdeb.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/remdeb.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/remdeb.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rdbg/rdbg_f.h: include/rdbg/i386/rdbg_f.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/rdbg_f.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/rdbg_f.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rdbg/reg.h: include/rdbg/i386/reg.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/reg.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/reg.h
|
||||
endif
|
||||
endif
|
||||
if HAS_RDBG
|
||||
if HAS_RDBG_m68k
|
||||
$(PROJECT_INCLUDE)/rdbg/remdeb.h: src/m68k/any/remdeb.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/remdeb.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/remdeb.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rdbg/rdbg_f.h: include/rdbg/m68k/rdbg_f.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/rdbg_f.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/rdbg_f.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rdbg/reg.h: include/rdbg/m68k/reg.h $(PROJECT_INCLUDE)/rdbg/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rdbg/reg.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rdbg/reg.h
|
||||
endif
|
||||
endif
|
||||
@@ -1,308 +0,0 @@
|
||||
/*
|
||||
============================================================================
|
||||
_SERVTGT
|
||||
$Id$
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/rdbg_f.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <assert.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
#ifdef DDEBUG
|
||||
#define Ptrace TgtDbgPtrace
|
||||
#else
|
||||
#define Ptrace TgtRealPtrace
|
||||
#endif
|
||||
|
||||
extern int errno;
|
||||
|
||||
rtems_id eventTaskId;
|
||||
rtems_id serializeSemId;
|
||||
rtems_id wakeupEventSemId;
|
||||
rtems_id debugId;
|
||||
|
||||
CPU_Exception_frame Idle_frame;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
TgtRealPtrace - lowest level ptrace() wrapper
|
||||
----------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
TgtRealPtrace (int req, PID aid, char *addr, int d, void *addr2)
|
||||
{
|
||||
return ptrace (req, aid, addr, d, addr2);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
TgtChange() is called when the system stops.
|
||||
It informs the generic layers must be informed of
|
||||
that fact.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
TgtChange (PID pid, CPU_Exception_frame * ctx, int status)
|
||||
{
|
||||
|
||||
if (TgtHandleChildChange (pid, &status, NULL, ctx)) {
|
||||
TgtNotifyWaitChange (pid, status, -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
eventTask
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
rtems_task
|
||||
eventTask (rtems_task_argument pid)
|
||||
{
|
||||
Exception_context *ctx;
|
||||
|
||||
DPRINTF (("event task: pid %d\n", pid));
|
||||
|
||||
/*
|
||||
* we spend all our time waiting for a semaphore.
|
||||
* If wait change, we send info
|
||||
*/
|
||||
|
||||
for (;;) {
|
||||
DPRINTF (("Event Task: wait event\n"));
|
||||
rtems_semaphore_obtain (wakeupEventSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
DPRINTF (("Event Task: wake up !!!!!!!!!!!!!\n"));
|
||||
|
||||
errno = 0;
|
||||
ctx = GetExceptCtx (currentTargetThread);
|
||||
|
||||
CheckForSingleStep (ctx->ctx);
|
||||
|
||||
TgtChange (pid, ctx->ctx, STS_MAKESIG (ExcepToSig (ctx)));
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
MyThreadIdle -
|
||||
|
||||
This task is used to initiate the exception mechanism:
|
||||
It calls the enterDebug function with justSaveContext=1
|
||||
only to push a first valid context in the list
|
||||
---------------------------------------------------------------------*/
|
||||
|
||||
rtems_task
|
||||
MyThreadIdle (rtems_task_argument argument)
|
||||
{
|
||||
enterRdbg ();
|
||||
rtems_task_delete (RTEMS_SELF);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
TgtAttach - attach to a process that is running without control.
|
||||
|
||||
Notes:
|
||||
- this function performs a ptrace ATTACH equivalent (attaching to a
|
||||
process that we do not control now).
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
Boolean
|
||||
TgtAttach (int conn_idx, /* client that is requesting */
|
||||
PID pid)
|
||||
{ /* process to attach to */
|
||||
rtems_name task_name;
|
||||
rtems_status_code status;
|
||||
|
||||
errno = 0;
|
||||
|
||||
DPRINTF (("TgtAttach pid=%d\n", pid));
|
||||
|
||||
Ptrace (RPT_ATTACH, pid, NULL, 0, NULL);
|
||||
if (errno)
|
||||
return (False); /* failed */
|
||||
|
||||
TgtCreateNew (pid, conn_idx, 0, NULL, False);
|
||||
|
||||
connect_rdbg_exception ();
|
||||
|
||||
/*
|
||||
* Search for and remove debugging tasks / semaphores left over from
|
||||
* a previous attach without a detach.
|
||||
*/
|
||||
|
||||
if (rtems_task_ident (rtems_build_name ('E', 'v', 'n', 't'),
|
||||
RTEMS_SEARCH_ALL_NODES,
|
||||
&eventTaskId) == RTEMS_SUCCESSFUL)
|
||||
rtems_task_delete (eventTaskId);
|
||||
|
||||
if (rtems_semaphore_ident (rtems_build_name ('D', 'B', 'G', 's'),
|
||||
RTEMS_SEARCH_ALL_NODES,
|
||||
&serializeSemId) == RTEMS_SUCCESSFUL)
|
||||
rtems_semaphore_delete (serializeSemId);
|
||||
|
||||
if (rtems_semaphore_ident (rtems_build_name ('D', 'B', 'G', 'w'),
|
||||
RTEMS_SEARCH_ALL_NODES,
|
||||
&wakeupEventSemId) == RTEMS_SUCCESSFUL)
|
||||
rtems_semaphore_delete (wakeupEventSemId);
|
||||
|
||||
/*
|
||||
* Create the attach debugger task
|
||||
*/
|
||||
task_name = rtems_build_name ('E', 'v', 'n', 't');
|
||||
if ((status = rtems_task_create (task_name, 10, 24576,
|
||||
RTEMS_INTERRUPT_LEVEL (0),
|
||||
RTEMS_DEFAULT_ATTRIBUTES |
|
||||
RTEMS_SYSTEM_TASK, &eventTaskId))
|
||||
!= RTEMS_SUCCESSFUL) {
|
||||
printf ("status = %d\n", status);
|
||||
rtems_panic ("Can't create task.\n");
|
||||
}
|
||||
|
||||
status = rtems_task_start (eventTaskId, eventTask, pid);
|
||||
|
||||
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 's'),
|
||||
1,
|
||||
RTEMS_FIFO |
|
||||
RTEMS_COUNTING_SEMAPHORE |
|
||||
RTEMS_NO_INHERIT_PRIORITY |
|
||||
RTEMS_NO_PRIORITY_CEILING |
|
||||
RTEMS_LOCAL, 0, &serializeSemId);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_panic ("Can't create serialize semaphore: `%s'\n",
|
||||
rtems_status_text (status));
|
||||
|
||||
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 'w'),
|
||||
0,
|
||||
RTEMS_FIFO |
|
||||
RTEMS_COUNTING_SEMAPHORE |
|
||||
RTEMS_NO_INHERIT_PRIORITY |
|
||||
RTEMS_NO_PRIORITY_CEILING |
|
||||
RTEMS_LOCAL, 0, &wakeupEventSemId);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_panic ("Can't create wakeup semaphore: `%s'\n",
|
||||
rtems_status_text (status));
|
||||
|
||||
/*
|
||||
* Create the MyThreadIdle task to init Exception mechanism
|
||||
*/
|
||||
task_name = rtems_build_name ('R', 'i', 'n', 'i');
|
||||
if ((status = rtems_task_create (task_name, 10, 24576,
|
||||
RTEMS_INTERRUPT_LEVEL (0),
|
||||
RTEMS_DEFAULT_ATTRIBUTES, &debugId))
|
||||
!= RTEMS_SUCCESSFUL) {
|
||||
printf ("status = %d (%s)\n", status, rtems_status_text (status));
|
||||
rtems_panic ("Can't create task.\n");
|
||||
}
|
||||
|
||||
status = rtems_task_start (debugId, MyThreadIdle, pid);
|
||||
|
||||
return (True);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
TgtPtrace - handle ptrace requests for server.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
TgtPtrace (int req, PID pid, char *addr, int data, void *addr2)
|
||||
{
|
||||
if ((req == RPT_SINGLESTEP || req == RPT_CONT)
|
||||
&& addr2) { /* clear then step */ /* addr2 is the old value */
|
||||
|
||||
int ret;
|
||||
|
||||
errno = 0;
|
||||
TgtBreakRestoreOrig (pid, addr, addr2);
|
||||
ret = Ptrace (RPT_SINGLESTEP, pid, addr, data, NULL); /* step over */
|
||||
if (ret) { /* error, cannot single-step */
|
||||
int pid_idx = FindPidEntry (pid);
|
||||
TgtBreakCancelStep (&pid_list[pid_idx]);
|
||||
}
|
||||
return (ret); /* failed or done */
|
||||
} else
|
||||
return (Ptrace (req, pid, addr, data, addr2)); /* normal call */
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
TgtGetThreadName - get thread name
|
||||
--------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
TgtGetThreadName (PID_LIST * plst, /* Process entry */
|
||||
unsigned Id, /* Thread ID */
|
||||
char *ThrName)
|
||||
{ /* Thread name */
|
||||
int index;
|
||||
unsigned name;
|
||||
|
||||
if (Id < _Objects_Information_table[OBJECTS_CLASSIC_API][1]->maximum_id &&
|
||||
Id > _Objects_Information_table[OBJECTS_CLASSIC_API][1]->minimum_id) {
|
||||
|
||||
index = Id - _Objects_Information_table[OBJECTS_CLASSIC_API][1]->minimum_id;
|
||||
name =
|
||||
*(unsigned *) (_Objects_Information_table[OBJECTS_CLASSIC_API][1]->
|
||||
local_table[1 + index]->name);
|
||||
ThrName[0] = (char) ((name >> 24) & 0xFF);
|
||||
ThrName[1] = (char) ((name >> 16) & 0xFF);
|
||||
ThrName[2] = (char) ((name >> 8) & 0xFF);
|
||||
ThrName[3] = (char) (name & 0xFF);
|
||||
ThrName[4] = 0x0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Id < _Objects_Information_table[OBJECTS_POSIX_API][1]->maximum_id &&
|
||||
Id > _Objects_Information_table[OBJECTS_POSIX_API][1]->minimum_id) {
|
||||
|
||||
index =
|
||||
Id - _Objects_Information_table[OBJECTS_POSIX_API][1]->minimum_id;
|
||||
name =
|
||||
*(unsigned *) (_Objects_Information_table[OBJECTS_POSIX_API][1]->
|
||||
local_table[1 + index]->name);
|
||||
ThrName[0] = (char) ((name >> 24) & 0xFF);
|
||||
ThrName[1] = (char) ((name >> 16) & 0xFF);
|
||||
ThrName[2] = (char) ((name >> 8) & 0xFF);
|
||||
ThrName[3] = (char) (name & 0xFF);
|
||||
ThrName[4] = 0x0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
TgtThreadList - return all the threads in the system
|
||||
----------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
TgtThreadList (PID_LIST * plst, /* Process entry */
|
||||
unsigned *threads, /* Output buffer */
|
||||
unsigned size)
|
||||
{ /* Output buffer size */
|
||||
int curr = 0;
|
||||
int api;
|
||||
Objects_Id id, min_id, max_id;
|
||||
unsigned index;
|
||||
|
||||
for ( api=OBJECTS_CLASSIC_API ; api <= OBJECTS_ITRON_API ; api++ ) {
|
||||
min_id = _Objects_Information_table[api][1]->minimum_id;
|
||||
max_id = _Objects_Information_table[api][1]->maximum_id;
|
||||
id = min_id;
|
||||
|
||||
while (id < max_id) {
|
||||
index = id - min_id;
|
||||
if (_Objects_Information_table[api][1]->local_table[1 + index] != NULL) {
|
||||
threads[curr] = (unsigned) id;
|
||||
curr++;
|
||||
}
|
||||
id++;
|
||||
}
|
||||
}
|
||||
|
||||
return curr;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#########################################################################
|
||||
#
|
||||
# Component: RDBG
|
||||
# Module: awk.svc
|
||||
#
|
||||
# Synopsis: AWK script which transforms the server skeleton produced
|
||||
# by rpcgen(1) into something suitable for RDB servers.
|
||||
#
|
||||
#########################################################################
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
BEGIN {
|
||||
headerstarted = 0
|
||||
withinproc = 0
|
||||
brack = 0
|
||||
}
|
||||
|
||||
$1 ~ /^\/\*HEADER_START\*\/$/ {
|
||||
headerstarted = 1
|
||||
printf("#include <rpc/types.h>\n");
|
||||
printf("#include <rpc/rpc.h>\n");
|
||||
printf("#include <stdio.h>\n");
|
||||
printf("#include <stdlib.h>\n");
|
||||
printf("#include <string.h>\n");
|
||||
printf("#include <bsp.h>\n");
|
||||
printf("#include <rdbg/servrpc.h>\n");
|
||||
printf("#include <rdbg/%s>\n", THEPROG);
|
||||
printf("#define fprintf(a,b,c) printf(b,c)\n");
|
||||
}
|
||||
|
||||
$1 ~ /^\/\*HEADER_END\*\/$/ {
|
||||
headerstarted = 0
|
||||
}
|
||||
|
||||
{
|
||||
if (headerstarted == 1) {
|
||||
print $0
|
||||
} else if ($1 ~ /.*_2.*/) {
|
||||
withinproc = 1
|
||||
printf("void\n");
|
||||
print $0
|
||||
} else if (withinproc == 1) {
|
||||
if ($1 == "switch") {
|
||||
print "\tDPRINTF ((\"remotedeb_2: %s (%d)\\n\", "
|
||||
print "\t\t(unsigned) rqstp->rq_proc < "
|
||||
print "\t\t(unsigned) (sizeof names / sizeof names[0]) ?"
|
||||
print "\t\tnames [rqstp->rq_proc] : \"???\", "
|
||||
print "\t\t(int) rqstp->rq_proc));\n"
|
||||
}
|
||||
for (i = 1; i <= NF; i++) {
|
||||
if ($i == "{") {
|
||||
brack++;
|
||||
} else if ($i == "}") {
|
||||
brack--;
|
||||
if (brack == 0) {
|
||||
withinproc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($1 != "_rpcsvcdirty" ) {
|
||||
print $0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component =
|
||||
*
|
||||
* Synopsis = rdbgexcep.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
|
||||
unsigned int NbExceptCtx;
|
||||
volatile unsigned int NbSerializedCtx;
|
||||
Exception_context *FirstCtx = NULL;
|
||||
Exception_context *LastCtx = NULL;
|
||||
|
||||
CPU_Exception_frame SavedContext;
|
||||
|
||||
/*
|
||||
* Save an exception context at the end of a list
|
||||
*/
|
||||
|
||||
int
|
||||
PushExceptCtx (Objects_Id Id, Objects_Id semId, CPU_Exception_frame * ctx)
|
||||
{
|
||||
|
||||
Exception_context *SaveCtx;
|
||||
|
||||
SaveCtx = (Exception_context *) malloc (sizeof (Exception_context));
|
||||
if (SaveCtx == NULL)
|
||||
rtems_panic ("Can't allocate memory to save Exception context");
|
||||
|
||||
SaveCtx->id = Id;
|
||||
SaveCtx->ctx = ctx;
|
||||
SaveCtx->semaphoreId = semId;
|
||||
SaveCtx->previous = NULL;
|
||||
SaveCtx->next = NULL;
|
||||
|
||||
if (FirstCtx == NULL) { /* initialization */
|
||||
FirstCtx = SaveCtx;
|
||||
LastCtx = SaveCtx;
|
||||
NbExceptCtx = 1;
|
||||
} else {
|
||||
NbExceptCtx++;
|
||||
LastCtx->next = SaveCtx;
|
||||
SaveCtx->previous = LastCtx;
|
||||
LastCtx = SaveCtx;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save an temporary exception context in a global variable
|
||||
*/
|
||||
|
||||
int
|
||||
PushSavedExceptCtx (Objects_Id Id, CPU_Exception_frame * ctx)
|
||||
{
|
||||
memcpy (&(SavedContext), ctx, sizeof (CPU_Exception_frame));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the context of the specified Id thread.
|
||||
* If Id = -1, then return the first context
|
||||
*/
|
||||
|
||||
int
|
||||
PopExceptCtx (Objects_Id Id)
|
||||
{
|
||||
|
||||
Exception_context *ExtractCtx;
|
||||
|
||||
if (FirstCtx == NULL)
|
||||
return -1;
|
||||
|
||||
if (Id == -1) {
|
||||
ExtractCtx = LastCtx;
|
||||
LastCtx = LastCtx->previous;
|
||||
free (ExtractCtx);
|
||||
NbExceptCtx--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ExtractCtx = LastCtx;
|
||||
|
||||
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
|
||||
ExtractCtx = ExtractCtx->previous;
|
||||
}
|
||||
|
||||
if (ExtractCtx == NULL)
|
||||
return -1;
|
||||
|
||||
if (ExtractCtx->previous != NULL)
|
||||
(ExtractCtx->previous)->next = ExtractCtx->next;
|
||||
|
||||
if (ExtractCtx->next != NULL)
|
||||
(ExtractCtx->next)->previous = ExtractCtx->previous;
|
||||
|
||||
if (ExtractCtx == FirstCtx)
|
||||
FirstCtx = FirstCtx->next;
|
||||
else if (ExtractCtx == LastCtx)
|
||||
LastCtx = LastCtx->previous;
|
||||
|
||||
free (ExtractCtx);
|
||||
NbExceptCtx--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the context of the specified Id thread.
|
||||
* If Id = -1, then return the first context.
|
||||
*/
|
||||
|
||||
Exception_context *
|
||||
GetExceptCtx (Objects_Id Id)
|
||||
{
|
||||
|
||||
Exception_context *ExtractCtx;
|
||||
|
||||
if (FirstCtx == NULL)
|
||||
return NULL;
|
||||
|
||||
if (Id == -1) {
|
||||
return LastCtx;
|
||||
}
|
||||
|
||||
ExtractCtx = LastCtx;
|
||||
|
||||
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
|
||||
ExtractCtx = ExtractCtx->previous;
|
||||
}
|
||||
|
||||
if (ExtractCtx == NULL)
|
||||
return NULL;
|
||||
|
||||
return ExtractCtx;
|
||||
}
|
||||
@@ -1,522 +0,0 @@
|
||||
/*
|
||||
* Please do not edit this file.
|
||||
* It was generated using rpcgen.
|
||||
*/
|
||||
|
||||
#ifndef _REMDEB_H_RPCGEN
|
||||
#define _REMDEB_H_RPCGEN
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RTEMS_PORT 2071
|
||||
#define RTEMS_BACK_PORT 2073
|
||||
#ifndef REMDEB_H
|
||||
#define RPCGENSRVNAME(a) a
|
||||
|
||||
enum rpc_type {
|
||||
SUNRPC = 0,
|
||||
BADRPCTYPE = 25,
|
||||
};
|
||||
typedef enum rpc_type rpc_type;
|
||||
#define NET_SAFE 1400
|
||||
|
||||
struct UDP_MSG {
|
||||
u_char type;
|
||||
u_char msg_num;
|
||||
u_short spec;
|
||||
long pid;
|
||||
u_long context;
|
||||
};
|
||||
typedef struct UDP_MSG UDP_MSG;
|
||||
/*
|
||||
* Sun request values for the remote ptrace system call
|
||||
*/
|
||||
|
||||
|
||||
enum ptracereq {
|
||||
RPT_TRACEME = 0,
|
||||
RPT_CHILDDONE = 0,
|
||||
RPT_PEEKTEXT = 0 + 1,
|
||||
RPT_PEEKDATA = 0 + 2,
|
||||
RPT_PEEKUSER = 0 + 3,
|
||||
RPT_POKETEXT = 0 + 4,
|
||||
RPT_POKEDATA = 0 + 5,
|
||||
RPT_POKEUSER = 0 + 6,
|
||||
RPT_CONT = 0 + 7,
|
||||
RPT_KILL = 0 + 8,
|
||||
RPT_SINGLESTEP = 0 + 9,
|
||||
RPT_ATTACH = 0 + 10,
|
||||
RPT_DETACH = 0 + 11,
|
||||
RPT_GETREGS = 0 + 12,
|
||||
RPT_SETREGS = 0 + 13,
|
||||
RPT_GETFPREGS = 0 + 14,
|
||||
RPT_SETFPREGS = 0 + 15,
|
||||
RPT_READDATA = 0 + 16,
|
||||
RPT_WRITEDATA = 0 + 17,
|
||||
RPT_READTEXT = 0 + 18,
|
||||
RPT_WRITETEXT = 0 + 19,
|
||||
RPT_GETFPAREGS = 0 + 20,
|
||||
RPT_SETFPAREGS = 0 + 21,
|
||||
RPT_22 = 0 + 22,
|
||||
RPT_23 = 0 + 23,
|
||||
RPT_SYSCALL = 0 + 24,
|
||||
RPT_DUMPCORE = 0 + 25,
|
||||
RPT_26 = 0 + 26,
|
||||
RPT_27 = 0 + 27,
|
||||
RPT_28 = 0 + 28,
|
||||
RPT_GETUCODE = 0 + 29,
|
||||
RPT_GETTARGETTHREAD = 50,
|
||||
RPT_SETTARGETTHREAD = 51,
|
||||
RPT_THREADSUSPEND = 52,
|
||||
RPT_THREADRESUME = 53,
|
||||
RPT_THREADLIST = 54,
|
||||
RPT_GETTHREADNAME = 55,
|
||||
RPT_SETTHREADNAME = 56,
|
||||
RPT_SETTHREADREGS = 57,
|
||||
RPT_GETTHREADREGS = 58,
|
||||
RPT_STEPRANGE = 75,
|
||||
RPT_CONTTO = 76,
|
||||
RPT_SETBREAK = 77,
|
||||
RPT_CLRBREAK = 78,
|
||||
RPT_GETBREAK = 79,
|
||||
RPT_GETNAME = 80,
|
||||
RPT_STOP = 81,
|
||||
RPT_PGETREGS = 82,
|
||||
RPT_PSETREGS = 83,
|
||||
RPT_PSETTHREADREGS = 84,
|
||||
RPT_PGETTHREADREGS = 85,
|
||||
};
|
||||
typedef enum ptracereq ptracereq;
|
||||
|
||||
struct xdr_regs {
|
||||
u_int tabreg[19];
|
||||
};
|
||||
typedef struct xdr_regs xdr_regs;
|
||||
/* now define register macros to apply to xdr_reg struct */
|
||||
|
||||
#define GS 0
|
||||
#define FS 1
|
||||
#define ES 2
|
||||
#define DS 3
|
||||
#define EDI 4
|
||||
#define ESI 5
|
||||
#define EBP 6
|
||||
#define ESP 7
|
||||
#define EBX 8
|
||||
#define EDX 9
|
||||
#define ECX 10
|
||||
#define EAX 11
|
||||
#define TRAPNO 12
|
||||
#define ERR 13
|
||||
#define EIP 14
|
||||
#define CS 15
|
||||
#define EFL 16
|
||||
#define UESP 17
|
||||
#define SS 18
|
||||
|
||||
#define REG_PC tabreg[EIP] /* PC (eip) register offset */
|
||||
#define REG_SP tabreg[UESP] /* SP (uesp) register offset */
|
||||
#define REG_FP tabreg[EBP] /* FP (ebp) register offset */
|
||||
/* now define the BREAKPOINT mask technique to a long word */
|
||||
#define SET_BREAK(l) ((l&0xFFFFFF00) | 0xCC)
|
||||
#define IS_BREAK(l) (((l) & 0xFF) == 0xCC)
|
||||
#define ORG_BREAK(c,p) (((c) & 0xFFFFFF00) | ((p) & 0xFF))
|
||||
#define IS_STEP(regs) (regs.tabreg[TRAPNO] == 1) /* was step and not break */
|
||||
#define BREAK_ADJ 1 /* must subtract one from address after bp */
|
||||
#define BREAK_SIZE 1 /* Breakpoint occupies one byte */
|
||||
#define TARGET_PROC_TYPE 0
|
||||
#define MAXDEBUGGEE 150
|
||||
#define NAMEMAX 17
|
||||
/*
|
||||
* Memory data for read/write text or data. The size is in data. The target
|
||||
* addr is in the addr field.
|
||||
* Be careful before modifying because this value goes into internal
|
||||
* pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
* become too small if this value gets incremented.
|
||||
*/
|
||||
#define MEM_DATA_MAX 256
|
||||
|
||||
struct xdr_mem {
|
||||
u_long addr;
|
||||
u_int dataNb;
|
||||
u_char data[MEM_DATA_MAX];
|
||||
};
|
||||
typedef struct xdr_mem xdr_mem;
|
||||
|
||||
enum break_type {
|
||||
BRKT_NONE = 0,
|
||||
BRKT_INSTR = 1,
|
||||
BRKT_READ = 2,
|
||||
BRKT_WRITE = 3,
|
||||
BRKT_ACCESS = 4,
|
||||
BRKT_EXEC = 5,
|
||||
BRKT_OS_CALL = 6,
|
||||
BRKT_OS_SWITCH = 7,
|
||||
BRKT_STEPEMUL = 8,
|
||||
};
|
||||
typedef enum break_type break_type;
|
||||
#define MAX_THRD_BRK 4
|
||||
|
||||
struct xdr_break {
|
||||
u_char type;
|
||||
u_char thread_spec;
|
||||
u_short handle;
|
||||
u_long ee_loc;
|
||||
u_long ee_type;
|
||||
u_short length;
|
||||
u_char pass_count;
|
||||
u_char curr_pass;
|
||||
u_long thread_list[MAX_THRD_BRK];
|
||||
};
|
||||
typedef struct xdr_break xdr_break;
|
||||
#define UTHREAD_MAX 64
|
||||
#define THREADNAMEMAX 16
|
||||
|
||||
typedef char *thread_name;
|
||||
|
||||
struct KernThread {
|
||||
u_int threadLi;
|
||||
};
|
||||
typedef struct KernThread KernThread;
|
||||
typedef KernThread *ptThreadList;
|
||||
|
||||
struct thread_list {
|
||||
u_int nbThread;
|
||||
ptThreadList threads;
|
||||
};
|
||||
typedef struct thread_list thread_list;
|
||||
|
||||
struct ptrace_addr_data_in {
|
||||
ptracereq req;
|
||||
union {
|
||||
xdr_regs regs;
|
||||
struct {
|
||||
u_int pregs_len;
|
||||
u_int *pregs_val;
|
||||
} pregs;
|
||||
thread_name name;
|
||||
xdr_mem mem;
|
||||
xdr_break breakp;
|
||||
u_int address;
|
||||
} ptrace_addr_data_in_u;
|
||||
};
|
||||
typedef struct ptrace_addr_data_in ptrace_addr_data_in;
|
||||
|
||||
struct ptrace_addr_data_out {
|
||||
ptracereq req;
|
||||
union {
|
||||
xdr_regs regs;
|
||||
struct {
|
||||
u_int pregs_len;
|
||||
u_int *pregs_val;
|
||||
} pregs;
|
||||
thread_list threads;
|
||||
thread_name name;
|
||||
xdr_mem mem;
|
||||
xdr_break breakp;
|
||||
u_int addr;
|
||||
} ptrace_addr_data_out_u;
|
||||
};
|
||||
typedef struct ptrace_addr_data_out ptrace_addr_data_out;
|
||||
|
||||
typedef struct {
|
||||
u_int CHAR_DATA_len;
|
||||
char *CHAR_DATA_val;
|
||||
} CHAR_DATA;
|
||||
|
||||
typedef char *one_arg;
|
||||
/* now open_connex() routine which establishes a connection to server */
|
||||
|
||||
enum debug_type {
|
||||
DEBTYP_PROCESS = 0,
|
||||
DEBTYP_C_ACTOR = 1,
|
||||
DEBTYP_KERNEL = 2,
|
||||
DEBTYP_OTHER = 3,
|
||||
};
|
||||
typedef enum debug_type debug_type;
|
||||
#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
|
||||
struct open_in {
|
||||
u_char back_port[16];
|
||||
u_short debug_type;
|
||||
u_short flags;
|
||||
u_char destination[16];
|
||||
one_arg user_name;
|
||||
};
|
||||
typedef struct open_in open_in;
|
||||
|
||||
struct open_out {
|
||||
u_long port;
|
||||
u_int pad[4];
|
||||
u_int fp;
|
||||
u_char cmd_table_num;
|
||||
u_char cmd_table_vers;
|
||||
u_short server_vers;
|
||||
};
|
||||
typedef struct open_out open_out;
|
||||
/* now close_connex() routine which detaches from server */
|
||||
|
||||
enum close_control {
|
||||
CLOSE_IGNORE = 0,
|
||||
CLOSE_KILL = 1,
|
||||
CLOSE_DETACH = 2,
|
||||
};
|
||||
typedef enum close_control close_control;
|
||||
|
||||
struct close_in {
|
||||
close_control control;
|
||||
};
|
||||
typedef struct close_in close_in;
|
||||
/* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
|
||||
struct signal_in {
|
||||
int pid;
|
||||
int sig;
|
||||
};
|
||||
typedef struct signal_in signal_in;
|
||||
|
||||
struct signal_out {
|
||||
int kill_return;
|
||||
int errNo;
|
||||
};
|
||||
typedef struct signal_out signal_out;
|
||||
/* now wait_info() routine which returns results of polling the wait status
|
||||
of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
|
||||
enum stop_code {
|
||||
STOP_ERROR = 0,
|
||||
STOP_NONE = 1,
|
||||
STOP_UNKNOWN = 2,
|
||||
STOP_BREAK = 3,
|
||||
STOP_STEP = 4,
|
||||
STOP_SIGNAL = 5,
|
||||
STOP_TERM_EXIT = 6,
|
||||
STOP_TERM_SIG = 7,
|
||||
STOP_DETACHED = 8,
|
||||
STOP_KILLED = 9,
|
||||
STOP_SPAWN_FAILED = 10,
|
||||
};
|
||||
typedef enum stop_code stop_code;
|
||||
|
||||
struct wait_in {
|
||||
int pid;
|
||||
};
|
||||
typedef struct wait_in wait_in;
|
||||
|
||||
struct wait_out {
|
||||
int wait_return;
|
||||
int errNo;
|
||||
int status;
|
||||
stop_code reason;
|
||||
int handle;
|
||||
u_long PC;
|
||||
u_long SP;
|
||||
u_long FP;
|
||||
u_long thread;
|
||||
};
|
||||
typedef struct wait_out wait_out;
|
||||
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
some additions */
|
||||
#define PTRFLG_FORCE 1
|
||||
#define PTRFLG_NON_OWNER 2
|
||||
#define PTRFLG_FREE 4
|
||||
#define PTRDET_UNOWN 0x100
|
||||
|
||||
struct ptrace_in {
|
||||
int pid;
|
||||
ptrace_addr_data_in addr;
|
||||
u_int data;
|
||||
u_int flags;
|
||||
};
|
||||
typedef struct ptrace_in ptrace_in;
|
||||
|
||||
struct ptrace_out {
|
||||
ptrace_addr_data_out addr;
|
||||
int result;
|
||||
int errNo;
|
||||
};
|
||||
typedef struct ptrace_out ptrace_out;
|
||||
|
||||
struct one_symbol {
|
||||
char *symbolName;
|
||||
long symbolValue;
|
||||
};
|
||||
typedef struct one_symbol one_symbol;
|
||||
|
||||
typedef struct {
|
||||
u_int all_symbols_len;
|
||||
one_symbol *all_symbols_val;
|
||||
} all_symbols;
|
||||
|
||||
struct get_global_symbols_out {
|
||||
all_symbols symbols;
|
||||
};
|
||||
typedef struct get_global_symbols_out get_global_symbols_out;
|
||||
|
||||
struct get_text_data_in {
|
||||
int pid;
|
||||
char *actorName;
|
||||
};
|
||||
typedef struct get_text_data_in get_text_data_in;
|
||||
|
||||
struct get_text_data_out {
|
||||
int result;
|
||||
int errNo;
|
||||
u_long textStart;
|
||||
u_long textSize;
|
||||
u_long dataStart;
|
||||
u_long dataSize;
|
||||
};
|
||||
typedef struct get_text_data_out get_text_data_out;
|
||||
|
||||
struct one_signal {
|
||||
u_int number;
|
||||
char *name;
|
||||
};
|
||||
typedef struct one_signal one_signal;
|
||||
|
||||
typedef struct {
|
||||
u_int all_signals_len;
|
||||
one_signal *all_signals_val;
|
||||
} all_signals;
|
||||
|
||||
struct get_signal_names_out {
|
||||
all_signals signals;
|
||||
};
|
||||
typedef struct get_signal_names_out get_signal_names_out;
|
||||
/* now define the actual calls we support */
|
||||
#define REMDEB_H
|
||||
#endif
|
||||
|
||||
#define REMOTEDEB 0x20000fff
|
||||
#define REMOTEVERS 2
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
#define OPEN_CONNEX 1
|
||||
extern open_out * open_connex_2(open_in *, CLIENT *);
|
||||
extern open_out * open_connex_2_svc(open_in *, struct svc_req *);
|
||||
#define SEND_SIGNAL 2
|
||||
extern signal_out * send_signal_2(signal_in *, CLIENT *);
|
||||
extern signal_out * send_signal_2_svc(signal_in *, struct svc_req *);
|
||||
#define CLOSE_CONNEX 10
|
||||
extern void * close_connex_2(close_in *, CLIENT *);
|
||||
extern void * close_connex_2_svc(close_in *, struct svc_req *);
|
||||
#define PTRACE 11
|
||||
extern ptrace_out * ptrace_2(ptrace_in *, CLIENT *);
|
||||
extern ptrace_out * ptrace_2_svc(ptrace_in *, struct svc_req *);
|
||||
#define WAIT_INFO 13
|
||||
extern wait_out * wait_info_2(wait_in *, CLIENT *);
|
||||
extern wait_out * wait_info_2_svc(wait_in *, struct svc_req *);
|
||||
#define GET_SIGNAL_NAMES 17
|
||||
extern get_signal_names_out * get_signal_names_2(void *, CLIENT *);
|
||||
extern get_signal_names_out * get_signal_names_2_svc(void *, struct svc_req *);
|
||||
extern int remotedeb_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
|
||||
|
||||
#else /* K&R C */
|
||||
#define OPEN_CONNEX 1
|
||||
extern open_out * open_connex_2();
|
||||
extern open_out * open_connex_2_svc();
|
||||
#define SEND_SIGNAL 2
|
||||
extern signal_out * send_signal_2();
|
||||
extern signal_out * send_signal_2_svc();
|
||||
#define CLOSE_CONNEX 10
|
||||
extern void * close_connex_2();
|
||||
extern void * close_connex_2_svc();
|
||||
#define PTRACE 11
|
||||
extern ptrace_out * ptrace_2();
|
||||
extern ptrace_out * ptrace_2_svc();
|
||||
#define WAIT_INFO 13
|
||||
extern wait_out * wait_info_2();
|
||||
extern wait_out * wait_info_2_svc();
|
||||
#define GET_SIGNAL_NAMES 17
|
||||
extern get_signal_names_out * get_signal_names_2();
|
||||
extern get_signal_names_out * get_signal_names_2_svc();
|
||||
extern int remotedeb_2_freeresult ();
|
||||
#endif /* K&R C */
|
||||
|
||||
/* the xdr functions */
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
extern bool_t xdr_rpc_type (XDR *, rpc_type*);
|
||||
extern bool_t xdr_UDP_MSG (XDR *, UDP_MSG*);
|
||||
extern bool_t xdr_ptracereq (XDR *, ptracereq*);
|
||||
extern bool_t xdr_xdr_regs (XDR *, xdr_regs*);
|
||||
extern bool_t xdr_xdr_mem (XDR *, xdr_mem*);
|
||||
extern bool_t xdr_break_type (XDR *, break_type*);
|
||||
extern bool_t xdr_xdr_break (XDR *, xdr_break*);
|
||||
extern bool_t xdr_thread_name (XDR *, thread_name*);
|
||||
extern bool_t xdr_KernThread (XDR *, KernThread*);
|
||||
extern bool_t xdr_thread_list (XDR *, thread_list*);
|
||||
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in*);
|
||||
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out*);
|
||||
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA*);
|
||||
extern bool_t xdr_one_arg (XDR *, one_arg*);
|
||||
extern bool_t xdr_debug_type (XDR *, debug_type*);
|
||||
extern bool_t xdr_open_in (XDR *, open_in*);
|
||||
extern bool_t xdr_open_out (XDR *, open_out*);
|
||||
extern bool_t xdr_close_control (XDR *, close_control*);
|
||||
extern bool_t xdr_close_in (XDR *, close_in*);
|
||||
extern bool_t xdr_signal_in (XDR *, signal_in*);
|
||||
extern bool_t xdr_signal_out (XDR *, signal_out*);
|
||||
extern bool_t xdr_stop_code (XDR *, stop_code*);
|
||||
extern bool_t xdr_wait_in (XDR *, wait_in*);
|
||||
extern bool_t xdr_wait_out (XDR *, wait_out*);
|
||||
extern bool_t xdr_ptrace_in (XDR *, ptrace_in*);
|
||||
extern bool_t xdr_ptrace_out (XDR *, ptrace_out*);
|
||||
extern bool_t xdr_one_symbol (XDR *, one_symbol*);
|
||||
extern bool_t xdr_all_symbols (XDR *, all_symbols*);
|
||||
extern bool_t xdr_get_global_symbols_out (XDR *, get_global_symbols_out*);
|
||||
extern bool_t xdr_get_text_data_in (XDR *, get_text_data_in*);
|
||||
extern bool_t xdr_get_text_data_out (XDR *, get_text_data_out*);
|
||||
extern bool_t xdr_one_signal (XDR *, one_signal*);
|
||||
extern bool_t xdr_all_signals (XDR *, all_signals*);
|
||||
extern bool_t xdr_get_signal_names_out (XDR *, get_signal_names_out*);
|
||||
|
||||
#else /* K&R C */
|
||||
extern bool_t xdr_rpc_type ();
|
||||
extern bool_t xdr_UDP_MSG ();
|
||||
extern bool_t xdr_ptracereq ();
|
||||
extern bool_t xdr_xdr_regs ();
|
||||
extern bool_t xdr_xdr_mem ();
|
||||
extern bool_t xdr_break_type ();
|
||||
extern bool_t xdr_xdr_break ();
|
||||
extern bool_t xdr_thread_name ();
|
||||
extern bool_t xdr_KernThread ();
|
||||
extern bool_t xdr_thread_list ();
|
||||
extern bool_t xdr_ptrace_addr_data_in ();
|
||||
extern bool_t xdr_ptrace_addr_data_out ();
|
||||
extern bool_t xdr_CHAR_DATA ();
|
||||
extern bool_t xdr_one_arg ();
|
||||
extern bool_t xdr_debug_type ();
|
||||
extern bool_t xdr_open_in ();
|
||||
extern bool_t xdr_open_out ();
|
||||
extern bool_t xdr_close_control ();
|
||||
extern bool_t xdr_close_in ();
|
||||
extern bool_t xdr_signal_in ();
|
||||
extern bool_t xdr_signal_out ();
|
||||
extern bool_t xdr_stop_code ();
|
||||
extern bool_t xdr_wait_in ();
|
||||
extern bool_t xdr_wait_out ();
|
||||
extern bool_t xdr_ptrace_in ();
|
||||
extern bool_t xdr_ptrace_out ();
|
||||
extern bool_t xdr_one_symbol ();
|
||||
extern bool_t xdr_all_symbols ();
|
||||
extern bool_t xdr_get_global_symbols_out ();
|
||||
extern bool_t xdr_get_text_data_in ();
|
||||
extern bool_t xdr_get_text_data_out ();
|
||||
extern bool_t xdr_one_signal ();
|
||||
extern bool_t xdr_all_signals ();
|
||||
extern bool_t xdr_get_signal_names_out ();
|
||||
|
||||
#endif /* K&R C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_REMDEB_H_RPCGEN */
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component = rdblib
|
||||
*
|
||||
* Synopsis = remdeb_f.x
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
struct xdr_regs
|
||||
{
|
||||
unsigned int tabreg[19];
|
||||
};
|
||||
|
||||
#ifdef RPC_HDR
|
||||
|
||||
%/* now define register macros to apply to xdr_reg struct */
|
||||
%
|
||||
%#define GS 0
|
||||
%#define FS 1
|
||||
%#define ES 2
|
||||
%#define DS 3
|
||||
%#define EDI 4
|
||||
%#define ESI 5
|
||||
%#define EBP 6
|
||||
%#define ESP 7
|
||||
%#define EBX 8
|
||||
%#define EDX 9
|
||||
%#define ECX 10
|
||||
%#define EAX 11
|
||||
%#define TRAPNO 12
|
||||
%#define ERR 13
|
||||
%#define EIP 14
|
||||
%#define CS 15
|
||||
%#define EFL 16
|
||||
%#define UESP 17
|
||||
%#define SS 18
|
||||
%
|
||||
%#define REG_PC tabreg[EIP] /* PC (eip) register offset */
|
||||
%#define REG_SP tabreg[UESP] /* SP (uesp) register offset */
|
||||
%#define REG_FP tabreg[EBP] /* FP (ebp) register offset */
|
||||
|
||||
%/* now define the BREAKPOINT mask technique to a long word */
|
||||
%#define SET_BREAK(l) ((l&0xFFFFFF00) | 0xCC)
|
||||
%#define IS_BREAK(l) (((l) & 0xFF) == 0xCC)
|
||||
%#define ORG_BREAK(c,p) (((c) & 0xFFFFFF00) | ((p) & 0xFF))
|
||||
%#define IS_STEP(regs) (regs.tabreg[TRAPNO] == 1) /* was step and not break */
|
||||
%#define BREAK_ADJ 1 /* must subtract one from address after bp */
|
||||
%#define BREAK_SIZE 1 /* Breakpoint occupies one byte */
|
||||
|
||||
%#define TARGET_PROC_TYPE 0
|
||||
|
||||
#endif
|
||||
@@ -1,120 +0,0 @@
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <bsp.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
#define printf(c)
|
||||
/*HEADER_START*/
|
||||
#define RTEMS_PORT 2071
|
||||
#define RTEMS_BACK_PORT 2073
|
||||
/*
|
||||
* Sun request values for the remote ptrace system call
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory data for read/write text or data. The size is in data. The target
|
||||
* addr is in the addr field.
|
||||
* Be careful before modifying because this value goes into internal
|
||||
* pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
* become too small if this value gets incremented.
|
||||
*/
|
||||
/* now open_connex() routine which establishes a connection to server */
|
||||
#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
/* now close_connex() routine which detaches from server */
|
||||
/* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
/* now wait_info() routine which returns results of polling the wait status
|
||||
of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
some additions */
|
||||
/* now define the actual calls we support */
|
||||
const char* names [] = {
|
||||
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
|
||||
"name4", "name5", "name6", "name7",
|
||||
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
|
||||
"name12", "WAIT_INFO", "name14", "name15",
|
||||
"name16", "GET_SIGNAL_NAMES", "name18"
|
||||
};
|
||||
|
||||
void
|
||||
remotedeb_2(struct svc_req *rqstp, register SVCXPRT *transp)
|
||||
{
|
||||
union {
|
||||
open_in open_connex_2_arg;
|
||||
signal_in send_signal_2_arg;
|
||||
close_in close_connex_2_arg;
|
||||
ptrace_in ptrace_2_arg;
|
||||
wait_in wait_info_2_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
xdrproc_t _xdr_argument, _xdr_result;
|
||||
char *(*local)(char *, struct svc_req *);
|
||||
|
||||
DPRINTF (("remotedeb_2: %s (%d)\n",
|
||||
(unsigned) rqstp->rq_proc <
|
||||
(unsigned) (sizeof names / sizeof names[0]) ?
|
||||
names [rqstp->rq_proc] : "???",
|
||||
(int) rqstp->rq_proc));
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
case NULLPROC:
|
||||
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
|
||||
return;
|
||||
|
||||
case OPEN_CONNEX:
|
||||
_xdr_argument = (xdrproc_t) xdr_open_in;
|
||||
_xdr_result = (xdrproc_t) xdr_open_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) open_connex_2_svc;
|
||||
break;
|
||||
|
||||
case SEND_SIGNAL:
|
||||
_xdr_argument = (xdrproc_t) xdr_signal_in;
|
||||
_xdr_result = (xdrproc_t) xdr_signal_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) send_signal_2_svc;
|
||||
break;
|
||||
|
||||
case CLOSE_CONNEX:
|
||||
_xdr_argument = (xdrproc_t) xdr_close_in;
|
||||
_xdr_result = (xdrproc_t) xdr_void;
|
||||
local = (char *(*)(char *, struct svc_req *)) close_connex_2_svc;
|
||||
break;
|
||||
|
||||
case PTRACE:
|
||||
_xdr_argument = (xdrproc_t) xdr_ptrace_in;
|
||||
_xdr_result = (xdrproc_t) xdr_ptrace_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) ptrace_2_svc;
|
||||
break;
|
||||
|
||||
case WAIT_INFO:
|
||||
_xdr_argument = (xdrproc_t) xdr_wait_in;
|
||||
_xdr_result = (xdrproc_t) xdr_wait_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) wait_info_2_svc;
|
||||
break;
|
||||
|
||||
case GET_SIGNAL_NAMES:
|
||||
_xdr_argument = (xdrproc_t) xdr_void;
|
||||
_xdr_result = (xdrproc_t) xdr_get_signal_names_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) get_signal_names_2_svc;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc (transp);
|
||||
return;
|
||||
}
|
||||
memset ((char *)&argument, 0, sizeof (argument));
|
||||
if (!svc_getargs (transp, _xdr_argument, (caddr_t) &argument)) {
|
||||
svcerr_decode (transp);
|
||||
return;
|
||||
}
|
||||
result = (*local)((char *)&argument, rqstp);
|
||||
if (result != NULL && !svc_sendreply(transp, _xdr_result, result)) {
|
||||
svcerr_systemerr (transp);
|
||||
}
|
||||
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument)) {
|
||||
printf( "unable to free arguments");
|
||||
exit (1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,841 +0,0 @@
|
||||
/*
|
||||
* Please do not edit this file.
|
||||
* It was generated using rpcgen.
|
||||
*/
|
||||
|
||||
#include "src/i386/any/remdeb.h"
|
||||
#define RTEMS_PORT 2071
|
||||
#define RTEMS_BACK_PORT 2073
|
||||
|
||||
bool_t
|
||||
xdr_rpc_type (XDR *xdrs, rpc_type *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_UDP_MSG (XDR *xdrs, UDP_MSG *objp)
|
||||
{
|
||||
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->msg_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->spec))
|
||||
return FALSE;
|
||||
if (!xdr_long (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->context))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* Sun request values for the remote ptrace system call
|
||||
*/
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_ptracereq (XDR *xdrs, ptracereq *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_xdr_regs (XDR *xdrs, xdr_regs *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, ( 19 ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->tabreg, 19,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->tabreg;
|
||||
i < 19; ++i) {
|
||||
IXDR_PUT_U_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, ( 19 ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->tabreg, 19,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->tabreg;
|
||||
i < 19; ++i) {
|
||||
*genp++ = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_vector (xdrs, (char *)objp->tabreg, 19,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* Memory data for read/write text or data. The size is in data. The target
|
||||
* addr is in the addr field.
|
||||
* Be careful before modifying because this value goes into internal
|
||||
* pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
* become too small if this value gets incremented.
|
||||
*/
|
||||
bool_t xdr_xdr_mem(xdrs, objp)
|
||||
XDR *xdrs;
|
||||
struct xdr_mem *objp;
|
||||
{
|
||||
if (!xdr_u_long(xdrs, &objp->addr)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_u_int(xdrs, &objp->dataNb)) {
|
||||
return(FALSE);
|
||||
}
|
||||
return (xdr_opaque(xdrs, objp->data, objp->dataNb));
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_break_type (XDR *xdrs, break_type *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_xdr_break (XDR *xdrs, xdr_break *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->thread_spec))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_short (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_loc))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->length))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
IXDR_PUT_U_SHORT(buf, objp->handle);
|
||||
IXDR_PUT_U_LONG(buf, objp->ee_loc);
|
||||
IXDR_PUT_U_LONG(buf, objp->ee_type);
|
||||
IXDR_PUT_U_SHORT(buf, objp->length);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->pass_count))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->curr_pass))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, ( MAX_THRD_BRK ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
|
||||
sizeof (u_long), (xdrproc_t) xdr_u_long))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_long *genp;
|
||||
|
||||
for (i = 0, genp = objp->thread_list;
|
||||
i < MAX_THRD_BRK; ++i) {
|
||||
IXDR_PUT_U_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->thread_spec))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_short (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_loc))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->length))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
objp->handle = IXDR_GET_U_SHORT(buf);
|
||||
objp->ee_loc = IXDR_GET_U_LONG(buf);
|
||||
objp->ee_type = IXDR_GET_U_LONG(buf);
|
||||
objp->length = IXDR_GET_U_SHORT(buf);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->pass_count))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->curr_pass))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, ( MAX_THRD_BRK ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
|
||||
sizeof (u_long), (xdrproc_t) xdr_u_long))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_long *genp;
|
||||
|
||||
for (i = 0, genp = objp->thread_list;
|
||||
i < MAX_THRD_BRK; ++i) {
|
||||
*genp++ = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->thread_spec))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_loc))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->length))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->pass_count))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->curr_pass))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
|
||||
sizeof (u_long), (xdrproc_t) xdr_u_long))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_thread_name (XDR *xdrs, thread_name *objp)
|
||||
{
|
||||
|
||||
if (!xdr_string (xdrs, objp, THREADNAMEMAX))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_KernThread (XDR *xdrs, KernThread *objp)
|
||||
{
|
||||
|
||||
if (!xdr_u_int (xdrs, &objp->threadLi))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
bool_t xdr_thread_list(xdrs, objp)
|
||||
XDR *xdrs;
|
||||
struct thread_list *objp;
|
||||
{
|
||||
return (xdr_array(xdrs, (char**)&objp->threads, &objp->nbThread,
|
||||
UTHREAD_MAX, sizeof(KernThread), xdr_KernThread));
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_addr_data_in (XDR *xdrs, ptrace_addr_data_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_ptracereq (xdrs, &objp->req))
|
||||
return FALSE;
|
||||
switch (objp->req) {
|
||||
case RPT_SETTHREADREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_SETREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PSETTHREADREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PSETREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_SETTHREADNAME:
|
||||
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_in_u.name))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_WRITETEXT:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_WRITEDATA:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_SETBREAK:
|
||||
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_in_u.breakp))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_in_u.address))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_addr_data_out (XDR *xdrs, ptrace_addr_data_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_ptracereq (xdrs, &objp->req))
|
||||
return FALSE;
|
||||
switch (objp->req) {
|
||||
case RPT_GETREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETTHREADREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PGETREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PGETTHREADREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_THREADLIST:
|
||||
if (!xdr_thread_list (xdrs, &objp->ptrace_addr_data_out_u.threads))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETTHREADNAME:
|
||||
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_out_u.name))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_READTEXT:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETNAME:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_READDATA:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETBREAK:
|
||||
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_out_u.breakp))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_out_u.addr))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_CHAR_DATA (XDR *xdrs, CHAR_DATA *objp)
|
||||
{
|
||||
|
||||
if (!xdr_bytes (xdrs, (char **)&objp->CHAR_DATA_val, (u_int *) &objp->CHAR_DATA_len, NET_SAFE))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_one_arg (XDR *xdrs, one_arg *objp)
|
||||
{
|
||||
|
||||
if (!xdr_string (xdrs, objp, NET_SAFE))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now open_connex() routine which establishes a connection to server */
|
||||
|
||||
bool_t
|
||||
xdr_debug_type (XDR *xdrs, debug_type *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
|
||||
bool_t
|
||||
xdr_open_in (XDR *xdrs, open_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_vector (xdrs, (char *)objp->back_port, 16,
|
||||
sizeof (u_char), (xdrproc_t) xdr_u_char))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->debug_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->flags))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->destination, 16,
|
||||
sizeof (u_char), (xdrproc_t) xdr_u_char))
|
||||
return FALSE;
|
||||
if (!xdr_one_arg (xdrs, &objp->user_name))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_open_out (XDR *xdrs, open_out *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_long (xdrs, &objp->port))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->fp))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
IXDR_PUT_U_LONG(buf, objp->port);
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->pad;
|
||||
i < 4; ++i) {
|
||||
IXDR_PUT_U_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
IXDR_PUT_U_LONG(buf, objp->fp);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->server_vers))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_long (xdrs, &objp->port))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->fp))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
objp->port = IXDR_GET_U_LONG(buf);
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->pad;
|
||||
i < 4; ++i) {
|
||||
*genp++ = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
}
|
||||
objp->fp = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->server_vers))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_u_long (xdrs, &objp->port))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->fp))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->server_vers))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now close_connex() routine which detaches from server */
|
||||
|
||||
bool_t
|
||||
xdr_close_control (XDR *xdrs, close_control *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_close_in (XDR *xdrs, close_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_close_control (xdrs, &objp->control))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
|
||||
bool_t
|
||||
xdr_signal_in (XDR *xdrs, signal_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->sig))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_signal_out (XDR *xdrs, signal_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->kill_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now wait_info() routine which returns results of polling the wait status
|
||||
of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
|
||||
bool_t
|
||||
xdr_stop_code (XDR *xdrs, stop_code *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_wait_in (XDR *xdrs, wait_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_wait_out (XDR *xdrs, wait_out *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->wait_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
IXDR_PUT_LONG(buf, objp->wait_return);
|
||||
IXDR_PUT_LONG(buf, objp->errNo);
|
||||
IXDR_PUT_LONG(buf, objp->status);
|
||||
}
|
||||
if (!xdr_stop_code (xdrs, &objp->reason))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->PC))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->SP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->FP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->thread))
|
||||
return FALSE;
|
||||
} else {
|
||||
IXDR_PUT_LONG(buf, objp->handle);
|
||||
IXDR_PUT_U_LONG(buf, objp->PC);
|
||||
IXDR_PUT_U_LONG(buf, objp->SP);
|
||||
IXDR_PUT_U_LONG(buf, objp->FP);
|
||||
IXDR_PUT_U_LONG(buf, objp->thread);
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->wait_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
objp->wait_return = IXDR_GET_LONG(buf);
|
||||
objp->errNo = IXDR_GET_LONG(buf);
|
||||
objp->status = IXDR_GET_LONG(buf);
|
||||
}
|
||||
if (!xdr_stop_code (xdrs, &objp->reason))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->PC))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->SP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->FP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->thread))
|
||||
return FALSE;
|
||||
} else {
|
||||
objp->handle = IXDR_GET_LONG(buf);
|
||||
objp->PC = IXDR_GET_U_LONG(buf);
|
||||
objp->SP = IXDR_GET_U_LONG(buf);
|
||||
objp->FP = IXDR_GET_U_LONG(buf);
|
||||
objp->thread = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_int (xdrs, &objp->wait_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
if (!xdr_stop_code (xdrs, &objp->reason))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->PC))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->SP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->FP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->thread))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
some additions */
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_in (XDR *xdrs, ptrace_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_ptrace_addr_data_in (xdrs, &objp->addr))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->data))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->flags))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_out (XDR *xdrs, ptrace_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_ptrace_addr_data_out (xdrs, &objp->addr))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_one_symbol (XDR *xdrs, one_symbol *objp)
|
||||
{
|
||||
|
||||
if (!xdr_string (xdrs, &objp->symbolName, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_long (xdrs, &objp->symbolValue))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_all_symbols (XDR *xdrs, all_symbols *objp)
|
||||
{
|
||||
|
||||
if (!xdr_array (xdrs, (char **)&objp->all_symbols_val, (u_int *) &objp->all_symbols_len, ~0,
|
||||
sizeof (one_symbol), (xdrproc_t) xdr_one_symbol))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_global_symbols_out (XDR *xdrs, get_global_symbols_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_all_symbols (xdrs, &objp->symbols))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_text_data_in (XDR *xdrs, get_text_data_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->actorName, 16))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_text_data_out (XDR *xdrs, get_text_data_out *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textSize))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataSize))
|
||||
return FALSE;
|
||||
} else {
|
||||
IXDR_PUT_LONG(buf, objp->result);
|
||||
IXDR_PUT_LONG(buf, objp->errNo);
|
||||
IXDR_PUT_U_LONG(buf, objp->textStart);
|
||||
IXDR_PUT_U_LONG(buf, objp->textSize);
|
||||
IXDR_PUT_U_LONG(buf, objp->dataStart);
|
||||
IXDR_PUT_U_LONG(buf, objp->dataSize);
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textSize))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataSize))
|
||||
return FALSE;
|
||||
} else {
|
||||
objp->result = IXDR_GET_LONG(buf);
|
||||
objp->errNo = IXDR_GET_LONG(buf);
|
||||
objp->textStart = IXDR_GET_U_LONG(buf);
|
||||
objp->textSize = IXDR_GET_U_LONG(buf);
|
||||
objp->dataStart = IXDR_GET_U_LONG(buf);
|
||||
objp->dataSize = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textSize))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataSize))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_one_signal (XDR *xdrs, one_signal *objp)
|
||||
{
|
||||
|
||||
if (!xdr_u_int (xdrs, &objp->number))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->name, ~0))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_all_signals (XDR *xdrs, all_signals *objp)
|
||||
{
|
||||
|
||||
if (!xdr_array (xdrs, (char **)&objp->all_signals_val, (u_int *) &objp->all_signals_len, ~0,
|
||||
sizeof (one_signal), (xdrproc_t) xdr_one_signal))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_signal_names_out (XDR *xdrs, get_signal_names_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_all_signals (xdrs, &objp->signals))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now define the actual calls we support */
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component =
|
||||
*
|
||||
* Synopsis = rdbg/i386/excep.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
Maping of hardware exceptions into Unix-like signal numbers.
|
||||
It is identical to the one used by the PM and the AM.
|
||||
----------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
ExcepToSig (Exception_context * ctx)
|
||||
{
|
||||
int excep = getExcNum (ctx);
|
||||
|
||||
switch (excep) {
|
||||
|
||||
case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
|
||||
case I386_EXCEPTION_I386_COPROC_SEG_ERR:
|
||||
case I386_EXCEPTION_FLOAT_ERROR:
|
||||
case I386_EXCEPTION_BOUND:
|
||||
return SIGFPE;
|
||||
|
||||
case I386_EXCEPTION_DEBUG:
|
||||
case I386_EXCEPTION_BREAKPOINT:
|
||||
case I386_EXCEPTION_ENTER_RDBG:
|
||||
return SIGTRAP;
|
||||
|
||||
case I386_EXCEPTION_OVERFLOW:
|
||||
case I386_EXCEPTION_DIVIDE_BY_ZERO:
|
||||
case I386_EXCEPTION_ILLEGAL_INSTR:
|
||||
return SIGILL;
|
||||
|
||||
case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
|
||||
case I386_EXCEPTION_STACK_SEGMENT_FAULT:
|
||||
case I386_EXCEPTION_GENERAL_PROT_ERR:
|
||||
case I386_EXCEPTION_PAGE_FAULT:
|
||||
return SIGSEGV;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SIGKILL;
|
||||
}
|
||||
|
||||
/*----- Breakpoint Exception management -----*/
|
||||
|
||||
/*
|
||||
* Handler for Breakpoint Exceptions :
|
||||
* software breakpoints.
|
||||
*/
|
||||
|
||||
void
|
||||
BreakPointExcHdl (CPU_Exception_frame * ctx)
|
||||
{
|
||||
rtems_status_code status;
|
||||
rtems_id continueSemId;
|
||||
|
||||
if ((justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG)) {
|
||||
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
|
||||
justSaveContext = 0;
|
||||
} else {
|
||||
if (ctx->idtIndex != I386_EXCEPTION_DEBUG) {
|
||||
NbSerializedCtx++;
|
||||
rtems_semaphore_obtain (serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
NbSerializedCtx--;
|
||||
}
|
||||
|
||||
currentTargetThread = _Thread_Executing->Object.id;
|
||||
|
||||
#ifdef DDEBUG
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk ("Exception %d caught at PC %x by thread %d\n",
|
||||
ctx->idtIndex, ctx->eip, _Thread_Executing->Object.id);
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk ("Processor execution context at time of the fault was :\n");
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk (" EAX = %x EBX = %x ECX = %x EDX = %x\n",
|
||||
ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
|
||||
printk (" ESI = %x EDI = %x EBP = %x ESP = %x\n",
|
||||
ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk ("Error code pushed by processor itself (if not 0) = %x\n",
|
||||
ctx->faultCode);
|
||||
printk ("----------------------------------------------------------\n\n");
|
||||
#endif
|
||||
|
||||
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 'c'),
|
||||
0,
|
||||
RTEMS_FIFO |
|
||||
RTEMS_COUNTING_SEMAPHORE |
|
||||
RTEMS_NO_INHERIT_PRIORITY |
|
||||
RTEMS_NO_PRIORITY_CEILING |
|
||||
RTEMS_LOCAL, 0, &continueSemId);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_panic ("Can't create continue semaphore: `%s'\n",
|
||||
rtems_status_text (status));
|
||||
|
||||
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
|
||||
|
||||
switch (ctx->idtIndex) {
|
||||
case I386_EXCEPTION_DEBUG:
|
||||
DPRINTF ((" DEBUG EXCEPTION !!!\n"));
|
||||
ctx->eflags &= ~EFLAGS_TF;
|
||||
ExitForSingleStep--;
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
|
||||
case I386_EXCEPTION_BREAKPOINT:
|
||||
DPRINTF ((" BREAKPOINT EXCEPTION !!!\n"));
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
|
||||
case I386_EXCEPTION_ENTER_RDBG:
|
||||
DPRINTF ((" ENTER RDBG !!!\n"));
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTF ((" OTHER EXCEPTION !!!\n"));
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
}
|
||||
|
||||
rtems_semaphore_obtain (continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
|
||||
PopExceptCtx (_Thread_Executing->Object.id);
|
||||
rtems_semaphore_delete (continueSemId);
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/* cpu_asm.s
|
||||
*
|
||||
* This file contains all assembly code for the Intel i386 implementation
|
||||
* of RDBG.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
|
||||
BEGIN_CODE
|
||||
|
||||
/*
|
||||
* void copyback_data_cache_and_invalidate_instr_cache(addr, size)
|
||||
*
|
||||
* This routine performs a copy of the data cache
|
||||
* and invalidate the instruction cache
|
||||
*/
|
||||
|
||||
.p2align 1
|
||||
PUBLIC (copyback_data_cache_and_invalidate_instr_cache)
|
||||
|
||||
SYM (copyback_data_cache_and_invalidate_instr_cache):
|
||||
wbinvd
|
||||
ret
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void enterRdbg(void)
|
||||
*
|
||||
* This function perform a call to the exception 19
|
||||
* It is used :
|
||||
* 1 - in the user code, to simulate a Breakpoint.
|
||||
* (with justSaveContext = 0)
|
||||
* 2 - in the RDBG code, to push a ctx in the list.
|
||||
* (with justSaveContext = 1)
|
||||
*
|
||||
* In most of case, it will be use as described in 1.
|
||||
* The 2nd possibility will be used by RDBG to obtain
|
||||
* its own ctx
|
||||
*/
|
||||
|
||||
PUBLIC (enterRdbg)
|
||||
|
||||
SYM (enterRdbg):
|
||||
int $50
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* void rtems_exception_prologue_50(void)
|
||||
*
|
||||
* Exception 50 is used to enter Rdbg
|
||||
*
|
||||
*/
|
||||
|
||||
.p2align 4
|
||||
|
||||
PUBLIC (rtems_exception_prologue_50)
|
||||
PUBLIC (_Exception_Handler)
|
||||
|
||||
SYM (rtems_exception_prologue_50):
|
||||
pushl $ 0
|
||||
pushl $ 50
|
||||
jmp SYM(_Exception_Handler) ;
|
||||
|
||||
|
||||
END_CODE
|
||||
|
||||
END
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component =
|
||||
*
|
||||
* Synopsis = rdbg/i386/rdbg_f.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/reg.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <rtems/score/thread.h>
|
||||
|
||||
void
|
||||
CtxToRegs (const CPU_Exception_frame * ctx, xdr_regs * regs)
|
||||
{
|
||||
regs->tabreg[GS] = 0;
|
||||
regs->tabreg[FS] = 0;
|
||||
regs->tabreg[ES] = 0;
|
||||
regs->tabreg[DS] = 0;
|
||||
regs->tabreg[EDI] = ctx->edi;
|
||||
regs->tabreg[ESI] = ctx->esi;
|
||||
regs->tabreg[EBP] = ctx->ebp;
|
||||
regs->tabreg[ESP] = ctx->esp0;
|
||||
regs->tabreg[EBX] = ctx->ebx;
|
||||
regs->tabreg[EDX] = ctx->edx;
|
||||
regs->tabreg[ECX] = ctx->ecx;
|
||||
regs->tabreg[EAX] = ctx->eax;
|
||||
regs->tabreg[TRAPNO] = ctx->idtIndex;
|
||||
regs->tabreg[ERR] = ctx->faultCode;
|
||||
regs->tabreg[EIP] = ctx->eip;
|
||||
regs->tabreg[CS] = ctx->cs & 0xFFFF;
|
||||
regs->tabreg[EFL] = ctx->eflags;
|
||||
}
|
||||
|
||||
void
|
||||
RegsToCtx (const xdr_regs * regs, CPU_Exception_frame * ctx)
|
||||
{
|
||||
ctx->edi = regs->tabreg[EDI];
|
||||
ctx->esi = regs->tabreg[ESI];
|
||||
ctx->ebp = regs->tabreg[EBP];
|
||||
ctx->esp0 = regs->tabreg[ESP];
|
||||
ctx->ebx = regs->tabreg[EBX];
|
||||
ctx->edx = regs->tabreg[EDX];
|
||||
ctx->ecx = regs->tabreg[ECX];
|
||||
ctx->eax = regs->tabreg[EAX];
|
||||
ctx->idtIndex = regs->tabreg[TRAPNO];
|
||||
ctx->faultCode = regs->tabreg[ERR];
|
||||
ctx->eip = regs->tabreg[EIP];
|
||||
ctx->cs = regs->tabreg[CS];
|
||||
ctx->eflags = regs->tabreg[EFL];
|
||||
}
|
||||
|
||||
void
|
||||
get_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
|
||||
{
|
||||
ctx->edi = thread->Registers.edi;
|
||||
ctx->esi = thread->Registers.esi;
|
||||
ctx->ebp = (uint32_t) (thread->Registers.ebp);
|
||||
ctx->esp0 = (uint32_t) (thread->Registers.esp);
|
||||
ctx->ebx = thread->Registers.ebx;
|
||||
ctx->edx = 0;
|
||||
ctx->ecx = 0;
|
||||
ctx->eax = 0;
|
||||
ctx->idtIndex = 0;
|
||||
ctx->faultCode = 0;
|
||||
ctx->eip = *(unsigned int *) (thread->Registers.esp);
|
||||
ctx->cs = 0;
|
||||
ctx->eflags = thread->Registers.eflags;
|
||||
}
|
||||
|
||||
void
|
||||
set_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
|
||||
{
|
||||
thread->Registers.edi = ctx->edi;
|
||||
thread->Registers.esi = ctx->esi;
|
||||
thread->Registers.ebp = (void *) (ctx->ebp);
|
||||
thread->Registers.esp = (void *) (ctx->esp0);
|
||||
thread->Registers.ebx = ctx->ebx;
|
||||
thread->Registers.eflags = ctx->eflags;
|
||||
}
|
||||
|
||||
int
|
||||
Single_Step (CPU_Exception_frame * ctx)
|
||||
{
|
||||
/*
|
||||
* Check if not already set
|
||||
*/
|
||||
if ((ctx->eflags & EFLAGS_TF) != 0 || ExitForSingleStep != 0) {
|
||||
/*
|
||||
* Check coherency
|
||||
*/
|
||||
assert ((ctx->eflags & EFLAGS_TF) != 0);
|
||||
assert (ExitForSingleStep != 0);
|
||||
return 0;
|
||||
}
|
||||
ctx->eflags |= EFLAGS_TF; /* eflags */
|
||||
++ExitForSingleStep;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CheckForSingleStep (CPU_Exception_frame * ctx)
|
||||
{
|
||||
if (ExitForSingleStep) {
|
||||
/*
|
||||
* This functions can be called both from
|
||||
* INT1 and INT3 handlers. In case it is
|
||||
* called from INT3, need to clear TF.
|
||||
*/
|
||||
ctx->eflags &= ~EFLAGS_TF;
|
||||
ExitForSingleStep = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CancelSingleStep (CPU_Exception_frame * ctx)
|
||||
{
|
||||
/*
|
||||
* Cancel scheduled SS
|
||||
*/
|
||||
ctx->eflags &= ~EFLAGS_TF;
|
||||
ExitForSingleStep--;
|
||||
}
|
||||
|
||||
static cpuExcHandlerType old_currentExcHandler;
|
||||
extern void rtems_exception_prologue_50 ();
|
||||
|
||||
void
|
||||
connect_rdbg_exception ()
|
||||
{
|
||||
interrupt_gate_descriptor *currentIdtEntry;
|
||||
unsigned limit;
|
||||
unsigned level;
|
||||
|
||||
/*
|
||||
* Connect the Exception used to debug
|
||||
*/
|
||||
i386_get_info_from_IDTR (¤tIdtEntry, &limit);
|
||||
|
||||
_CPU_ISR_Disable (level);
|
||||
create_interrupt_gate_descriptor (¤tIdtEntry[50],
|
||||
rtems_exception_prologue_50);
|
||||
_CPU_ISR_Enable (level);
|
||||
|
||||
if (_currentExcHandler != BreakPointExcHdl) {
|
||||
old_currentExcHandler = _currentExcHandler;
|
||||
_currentExcHandler = BreakPointExcHdl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
disconnect_rdbg_exception ()
|
||||
{
|
||||
if (_currentExcHandler == BreakPointExcHdl) {
|
||||
_currentExcHandler = old_currentExcHandler;
|
||||
}
|
||||
}
|
||||
@@ -1,509 +0,0 @@
|
||||
/*
|
||||
* Please do not edit this file.
|
||||
* It was generated using rpcgen.
|
||||
*/
|
||||
|
||||
#ifndef _REMDEB_H_RPCGEN
|
||||
#define _REMDEB_H_RPCGEN
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RTEMS_PORT 2071
|
||||
#define RTEMS_BACK_PORT 2073
|
||||
#ifndef REMDEB_H
|
||||
#define RPCGENSRVNAME(a) a
|
||||
|
||||
enum rpc_type {
|
||||
SUNRPC = 0,
|
||||
BADRPCTYPE = 25,
|
||||
};
|
||||
typedef enum rpc_type rpc_type;
|
||||
#define NET_SAFE 1400
|
||||
|
||||
struct UDP_MSG {
|
||||
u_char type;
|
||||
u_char msg_num;
|
||||
u_short spec;
|
||||
long pid;
|
||||
u_long context;
|
||||
};
|
||||
typedef struct UDP_MSG UDP_MSG;
|
||||
/*
|
||||
* Sun request values for the remote ptrace system call
|
||||
*/
|
||||
|
||||
|
||||
enum ptracereq {
|
||||
RPT_TRACEME = 0,
|
||||
RPT_CHILDDONE = 0,
|
||||
RPT_PEEKTEXT = 0 + 1,
|
||||
RPT_PEEKDATA = 0 + 2,
|
||||
RPT_PEEKUSER = 0 + 3,
|
||||
RPT_POKETEXT = 0 + 4,
|
||||
RPT_POKEDATA = 0 + 5,
|
||||
RPT_POKEUSER = 0 + 6,
|
||||
RPT_CONT = 0 + 7,
|
||||
RPT_KILL = 0 + 8,
|
||||
RPT_SINGLESTEP = 0 + 9,
|
||||
RPT_ATTACH = 0 + 10,
|
||||
RPT_DETACH = 0 + 11,
|
||||
RPT_GETREGS = 0 + 12,
|
||||
RPT_SETREGS = 0 + 13,
|
||||
RPT_GETFPREGS = 0 + 14,
|
||||
RPT_SETFPREGS = 0 + 15,
|
||||
RPT_READDATA = 0 + 16,
|
||||
RPT_WRITEDATA = 0 + 17,
|
||||
RPT_READTEXT = 0 + 18,
|
||||
RPT_WRITETEXT = 0 + 19,
|
||||
RPT_GETFPAREGS = 0 + 20,
|
||||
RPT_SETFPAREGS = 0 + 21,
|
||||
RPT_22 = 0 + 22,
|
||||
RPT_23 = 0 + 23,
|
||||
RPT_SYSCALL = 0 + 24,
|
||||
RPT_DUMPCORE = 0 + 25,
|
||||
RPT_26 = 0 + 26,
|
||||
RPT_27 = 0 + 27,
|
||||
RPT_28 = 0 + 28,
|
||||
RPT_GETUCODE = 0 + 29,
|
||||
RPT_GETTARGETTHREAD = 50,
|
||||
RPT_SETTARGETTHREAD = 51,
|
||||
RPT_THREADSUSPEND = 52,
|
||||
RPT_THREADRESUME = 53,
|
||||
RPT_THREADLIST = 54,
|
||||
RPT_GETTHREADNAME = 55,
|
||||
RPT_SETTHREADNAME = 56,
|
||||
RPT_SETTHREADREGS = 57,
|
||||
RPT_GETTHREADREGS = 58,
|
||||
RPT_STEPRANGE = 75,
|
||||
RPT_CONTTO = 76,
|
||||
RPT_SETBREAK = 77,
|
||||
RPT_CLRBREAK = 78,
|
||||
RPT_GETBREAK = 79,
|
||||
RPT_GETNAME = 80,
|
||||
RPT_STOP = 81,
|
||||
RPT_PGETREGS = 82,
|
||||
RPT_PSETREGS = 83,
|
||||
RPT_PSETTHREADREGS = 84,
|
||||
RPT_PGETTHREADREGS = 85,
|
||||
};
|
||||
typedef enum ptracereq ptracereq;
|
||||
|
||||
struct xdr_regs {
|
||||
int r_dreg[8];
|
||||
int r_areg[8];
|
||||
int r_sr;
|
||||
int r_pc;
|
||||
int r_vec;
|
||||
};
|
||||
typedef struct xdr_regs xdr_regs;
|
||||
/* now define register macros to apply to xdr_reg struct */
|
||||
|
||||
#define r_r0 r_dreg[0] /* r0 for portability */
|
||||
#define r_sp r_areg[7] /* user stack pointer */
|
||||
#define r_ps r_sr
|
||||
#define REG_PC r_pc /* PC register offset */
|
||||
#define REG_SP r_areg[7] /* SP register offset */
|
||||
#define REG_FP r_areg[6] /* FP register offset */
|
||||
/* now define the BREAKPOINT mask technique to a long word */
|
||||
#define SET_BREAK(l) ((l&0x0000FFFF) | 0x4E4F0000) /* TRAP 15 */
|
||||
#define IS_BREAK(l) (((l) & 0xFFFF0000) == 0x4E4F0000)
|
||||
#define ORG_BREAK(c,p) (((c) & 0x0000FFFF) | ((p) & 0xFFFF0000))
|
||||
#define IS_STEP(regs) ((regs).r_vec == 9)
|
||||
#define BREAK_ADJ 0
|
||||
#define BREAK_SIZE 2
|
||||
#define TARGET_PROC_TYPE 2
|
||||
#define MAXDEBUGGEE 150
|
||||
#define NAMEMAX 17
|
||||
/*
|
||||
* Memory data for read/write text or data. The size is in data. The target
|
||||
* addr is in the addr field.
|
||||
* Be careful before modifying because this value goes into internal
|
||||
* pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
* become too small if this value gets incremented.
|
||||
*/
|
||||
#define MEM_DATA_MAX 256
|
||||
|
||||
struct xdr_mem {
|
||||
u_long addr;
|
||||
u_int dataNb;
|
||||
u_char data[MEM_DATA_MAX];
|
||||
};
|
||||
typedef struct xdr_mem xdr_mem;
|
||||
|
||||
enum break_type {
|
||||
BRKT_NONE = 0,
|
||||
BRKT_INSTR = 1,
|
||||
BRKT_READ = 2,
|
||||
BRKT_WRITE = 3,
|
||||
BRKT_ACCESS = 4,
|
||||
BRKT_EXEC = 5,
|
||||
BRKT_OS_CALL = 6,
|
||||
BRKT_OS_SWITCH = 7,
|
||||
BRKT_STEPEMUL = 8,
|
||||
};
|
||||
typedef enum break_type break_type;
|
||||
#define MAX_THRD_BRK 4
|
||||
|
||||
struct xdr_break {
|
||||
u_char type;
|
||||
u_char thread_spec;
|
||||
u_short handle;
|
||||
u_long ee_loc;
|
||||
u_long ee_type;
|
||||
u_short length;
|
||||
u_char pass_count;
|
||||
u_char curr_pass;
|
||||
u_long thread_list[MAX_THRD_BRK];
|
||||
};
|
||||
typedef struct xdr_break xdr_break;
|
||||
#define UTHREAD_MAX 64
|
||||
#define THREADNAMEMAX 16
|
||||
|
||||
typedef char *thread_name;
|
||||
|
||||
struct KernThread {
|
||||
u_int threadLi;
|
||||
};
|
||||
typedef struct KernThread KernThread;
|
||||
typedef KernThread *ptThreadList;
|
||||
|
||||
struct thread_list {
|
||||
u_int nbThread;
|
||||
ptThreadList threads;
|
||||
};
|
||||
typedef struct thread_list thread_list;
|
||||
|
||||
struct ptrace_addr_data_in {
|
||||
ptracereq req;
|
||||
union {
|
||||
xdr_regs regs;
|
||||
struct {
|
||||
u_int pregs_len;
|
||||
u_int *pregs_val;
|
||||
} pregs;
|
||||
thread_name name;
|
||||
xdr_mem mem;
|
||||
xdr_break breakp;
|
||||
u_int address;
|
||||
} ptrace_addr_data_in_u;
|
||||
};
|
||||
typedef struct ptrace_addr_data_in ptrace_addr_data_in;
|
||||
|
||||
struct ptrace_addr_data_out {
|
||||
ptracereq req;
|
||||
union {
|
||||
xdr_regs regs;
|
||||
struct {
|
||||
u_int pregs_len;
|
||||
u_int *pregs_val;
|
||||
} pregs;
|
||||
thread_list threads;
|
||||
thread_name name;
|
||||
xdr_mem mem;
|
||||
xdr_break breakp;
|
||||
u_int addr;
|
||||
} ptrace_addr_data_out_u;
|
||||
};
|
||||
typedef struct ptrace_addr_data_out ptrace_addr_data_out;
|
||||
|
||||
typedef struct {
|
||||
u_int CHAR_DATA_len;
|
||||
char *CHAR_DATA_val;
|
||||
} CHAR_DATA;
|
||||
|
||||
typedef char *one_arg;
|
||||
/* now open_connex() routine which establishes a connection to server */
|
||||
|
||||
enum debug_type {
|
||||
DEBTYP_PROCESS = 0,
|
||||
DEBTYP_C_ACTOR = 1,
|
||||
DEBTYP_KERNEL = 2,
|
||||
DEBTYP_OTHER = 3,
|
||||
};
|
||||
typedef enum debug_type debug_type;
|
||||
#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
|
||||
struct open_in {
|
||||
u_char back_port[16];
|
||||
u_short debug_type;
|
||||
u_short flags;
|
||||
u_char destination[16];
|
||||
one_arg user_name;
|
||||
};
|
||||
typedef struct open_in open_in;
|
||||
|
||||
struct open_out {
|
||||
u_long port;
|
||||
u_int pad[4];
|
||||
u_int fp;
|
||||
u_char cmd_table_num;
|
||||
u_char cmd_table_vers;
|
||||
u_short server_vers;
|
||||
};
|
||||
typedef struct open_out open_out;
|
||||
/* now close_connex() routine which detaches from server */
|
||||
|
||||
enum close_control {
|
||||
CLOSE_IGNORE = 0,
|
||||
CLOSE_KILL = 1,
|
||||
CLOSE_DETACH = 2,
|
||||
};
|
||||
typedef enum close_control close_control;
|
||||
|
||||
struct close_in {
|
||||
close_control control;
|
||||
};
|
||||
typedef struct close_in close_in;
|
||||
/* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
|
||||
struct signal_in {
|
||||
int pid;
|
||||
int sig;
|
||||
};
|
||||
typedef struct signal_in signal_in;
|
||||
|
||||
struct signal_out {
|
||||
int kill_return;
|
||||
int errNo;
|
||||
};
|
||||
typedef struct signal_out signal_out;
|
||||
/* now wait_info() routine which returns results of polling the wait status
|
||||
of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
|
||||
enum stop_code {
|
||||
STOP_ERROR = 0,
|
||||
STOP_NONE = 1,
|
||||
STOP_UNKNOWN = 2,
|
||||
STOP_BREAK = 3,
|
||||
STOP_STEP = 4,
|
||||
STOP_SIGNAL = 5,
|
||||
STOP_TERM_EXIT = 6,
|
||||
STOP_TERM_SIG = 7,
|
||||
STOP_DETACHED = 8,
|
||||
STOP_KILLED = 9,
|
||||
STOP_SPAWN_FAILED = 10,
|
||||
};
|
||||
typedef enum stop_code stop_code;
|
||||
|
||||
struct wait_in {
|
||||
int pid;
|
||||
};
|
||||
typedef struct wait_in wait_in;
|
||||
|
||||
struct wait_out {
|
||||
int wait_return;
|
||||
int errNo;
|
||||
int status;
|
||||
stop_code reason;
|
||||
int handle;
|
||||
u_long PC;
|
||||
u_long SP;
|
||||
u_long FP;
|
||||
u_long thread;
|
||||
};
|
||||
typedef struct wait_out wait_out;
|
||||
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
some additions */
|
||||
#define PTRFLG_FORCE 1
|
||||
#define PTRFLG_NON_OWNER 2
|
||||
#define PTRFLG_FREE 4
|
||||
#define PTRDET_UNOWN 0x100
|
||||
|
||||
struct ptrace_in {
|
||||
int pid;
|
||||
ptrace_addr_data_in addr;
|
||||
u_int data;
|
||||
u_int flags;
|
||||
};
|
||||
typedef struct ptrace_in ptrace_in;
|
||||
|
||||
struct ptrace_out {
|
||||
ptrace_addr_data_out addr;
|
||||
int result;
|
||||
int errNo;
|
||||
};
|
||||
typedef struct ptrace_out ptrace_out;
|
||||
|
||||
struct one_symbol {
|
||||
char *symbolName;
|
||||
long symbolValue;
|
||||
};
|
||||
typedef struct one_symbol one_symbol;
|
||||
|
||||
typedef struct {
|
||||
u_int all_symbols_len;
|
||||
one_symbol *all_symbols_val;
|
||||
} all_symbols;
|
||||
|
||||
struct get_global_symbols_out {
|
||||
all_symbols symbols;
|
||||
};
|
||||
typedef struct get_global_symbols_out get_global_symbols_out;
|
||||
|
||||
struct get_text_data_in {
|
||||
int pid;
|
||||
char *actorName;
|
||||
};
|
||||
typedef struct get_text_data_in get_text_data_in;
|
||||
|
||||
struct get_text_data_out {
|
||||
int result;
|
||||
int errNo;
|
||||
u_long textStart;
|
||||
u_long textSize;
|
||||
u_long dataStart;
|
||||
u_long dataSize;
|
||||
};
|
||||
typedef struct get_text_data_out get_text_data_out;
|
||||
|
||||
struct one_signal {
|
||||
u_int number;
|
||||
char *name;
|
||||
};
|
||||
typedef struct one_signal one_signal;
|
||||
|
||||
typedef struct {
|
||||
u_int all_signals_len;
|
||||
one_signal *all_signals_val;
|
||||
} all_signals;
|
||||
|
||||
struct get_signal_names_out {
|
||||
all_signals signals;
|
||||
};
|
||||
typedef struct get_signal_names_out get_signal_names_out;
|
||||
/* now define the actual calls we support */
|
||||
#define REMDEB_H
|
||||
#endif
|
||||
|
||||
#define REMOTEDEB 0x20000fff
|
||||
#define REMOTEVERS 2
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
#define OPEN_CONNEX 1
|
||||
extern open_out * open_connex_2(open_in *, CLIENT *);
|
||||
extern open_out * open_connex_2_svc(open_in *, struct svc_req *);
|
||||
#define SEND_SIGNAL 2
|
||||
extern signal_out * send_signal_2(signal_in *, CLIENT *);
|
||||
extern signal_out * send_signal_2_svc(signal_in *, struct svc_req *);
|
||||
#define CLOSE_CONNEX 10
|
||||
extern void * close_connex_2(close_in *, CLIENT *);
|
||||
extern void * close_connex_2_svc(close_in *, struct svc_req *);
|
||||
#define PTRACE 11
|
||||
extern ptrace_out * ptrace_2(ptrace_in *, CLIENT *);
|
||||
extern ptrace_out * ptrace_2_svc(ptrace_in *, struct svc_req *);
|
||||
#define WAIT_INFO 13
|
||||
extern wait_out * wait_info_2(wait_in *, CLIENT *);
|
||||
extern wait_out * wait_info_2_svc(wait_in *, struct svc_req *);
|
||||
#define GET_SIGNAL_NAMES 17
|
||||
extern get_signal_names_out * get_signal_names_2(void *, CLIENT *);
|
||||
extern get_signal_names_out * get_signal_names_2_svc(void *, struct svc_req *);
|
||||
extern int remotedeb_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
|
||||
|
||||
#else /* K&R C */
|
||||
#define OPEN_CONNEX 1
|
||||
extern open_out * open_connex_2();
|
||||
extern open_out * open_connex_2_svc();
|
||||
#define SEND_SIGNAL 2
|
||||
extern signal_out * send_signal_2();
|
||||
extern signal_out * send_signal_2_svc();
|
||||
#define CLOSE_CONNEX 10
|
||||
extern void * close_connex_2();
|
||||
extern void * close_connex_2_svc();
|
||||
#define PTRACE 11
|
||||
extern ptrace_out * ptrace_2();
|
||||
extern ptrace_out * ptrace_2_svc();
|
||||
#define WAIT_INFO 13
|
||||
extern wait_out * wait_info_2();
|
||||
extern wait_out * wait_info_2_svc();
|
||||
#define GET_SIGNAL_NAMES 17
|
||||
extern get_signal_names_out * get_signal_names_2();
|
||||
extern get_signal_names_out * get_signal_names_2_svc();
|
||||
extern int remotedeb_2_freeresult ();
|
||||
#endif /* K&R C */
|
||||
|
||||
/* the xdr functions */
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
extern bool_t xdr_rpc_type (XDR *, rpc_type*);
|
||||
extern bool_t xdr_UDP_MSG (XDR *, UDP_MSG*);
|
||||
extern bool_t xdr_ptracereq (XDR *, ptracereq*);
|
||||
extern bool_t xdr_xdr_regs (XDR *, xdr_regs*);
|
||||
extern bool_t xdr_xdr_mem (XDR *, xdr_mem*);
|
||||
extern bool_t xdr_break_type (XDR *, break_type*);
|
||||
extern bool_t xdr_xdr_break (XDR *, xdr_break*);
|
||||
extern bool_t xdr_thread_name (XDR *, thread_name*);
|
||||
extern bool_t xdr_KernThread (XDR *, KernThread*);
|
||||
extern bool_t xdr_thread_list (XDR *, thread_list*);
|
||||
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in*);
|
||||
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out*);
|
||||
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA*);
|
||||
extern bool_t xdr_one_arg (XDR *, one_arg*);
|
||||
extern bool_t xdr_debug_type (XDR *, debug_type*);
|
||||
extern bool_t xdr_open_in (XDR *, open_in*);
|
||||
extern bool_t xdr_open_out (XDR *, open_out*);
|
||||
extern bool_t xdr_close_control (XDR *, close_control*);
|
||||
extern bool_t xdr_close_in (XDR *, close_in*);
|
||||
extern bool_t xdr_signal_in (XDR *, signal_in*);
|
||||
extern bool_t xdr_signal_out (XDR *, signal_out*);
|
||||
extern bool_t xdr_stop_code (XDR *, stop_code*);
|
||||
extern bool_t xdr_wait_in (XDR *, wait_in*);
|
||||
extern bool_t xdr_wait_out (XDR *, wait_out*);
|
||||
extern bool_t xdr_ptrace_in (XDR *, ptrace_in*);
|
||||
extern bool_t xdr_ptrace_out (XDR *, ptrace_out*);
|
||||
extern bool_t xdr_one_symbol (XDR *, one_symbol*);
|
||||
extern bool_t xdr_all_symbols (XDR *, all_symbols*);
|
||||
extern bool_t xdr_get_global_symbols_out (XDR *, get_global_symbols_out*);
|
||||
extern bool_t xdr_get_text_data_in (XDR *, get_text_data_in*);
|
||||
extern bool_t xdr_get_text_data_out (XDR *, get_text_data_out*);
|
||||
extern bool_t xdr_one_signal (XDR *, one_signal*);
|
||||
extern bool_t xdr_all_signals (XDR *, all_signals*);
|
||||
extern bool_t xdr_get_signal_names_out (XDR *, get_signal_names_out*);
|
||||
|
||||
#else /* K&R C */
|
||||
extern bool_t xdr_rpc_type ();
|
||||
extern bool_t xdr_UDP_MSG ();
|
||||
extern bool_t xdr_ptracereq ();
|
||||
extern bool_t xdr_xdr_regs ();
|
||||
extern bool_t xdr_xdr_mem ();
|
||||
extern bool_t xdr_break_type ();
|
||||
extern bool_t xdr_xdr_break ();
|
||||
extern bool_t xdr_thread_name ();
|
||||
extern bool_t xdr_KernThread ();
|
||||
extern bool_t xdr_thread_list ();
|
||||
extern bool_t xdr_ptrace_addr_data_in ();
|
||||
extern bool_t xdr_ptrace_addr_data_out ();
|
||||
extern bool_t xdr_CHAR_DATA ();
|
||||
extern bool_t xdr_one_arg ();
|
||||
extern bool_t xdr_debug_type ();
|
||||
extern bool_t xdr_open_in ();
|
||||
extern bool_t xdr_open_out ();
|
||||
extern bool_t xdr_close_control ();
|
||||
extern bool_t xdr_close_in ();
|
||||
extern bool_t xdr_signal_in ();
|
||||
extern bool_t xdr_signal_out ();
|
||||
extern bool_t xdr_stop_code ();
|
||||
extern bool_t xdr_wait_in ();
|
||||
extern bool_t xdr_wait_out ();
|
||||
extern bool_t xdr_ptrace_in ();
|
||||
extern bool_t xdr_ptrace_out ();
|
||||
extern bool_t xdr_one_symbol ();
|
||||
extern bool_t xdr_all_symbols ();
|
||||
extern bool_t xdr_get_global_symbols_out ();
|
||||
extern bool_t xdr_get_text_data_in ();
|
||||
extern bool_t xdr_get_text_data_out ();
|
||||
extern bool_t xdr_one_signal ();
|
||||
extern bool_t xdr_all_signals ();
|
||||
extern bool_t xdr_get_signal_names_out ();
|
||||
|
||||
#endif /* K&R C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_REMDEB_H_RPCGEN */
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component = rdblib
|
||||
*
|
||||
* Synopsis = remdeb_f.x
|
||||
*
|
||||
*
|
||||
* Copyright(C) 2000 Canon Research Center France SA.
|
||||
*
|
||||
* Developped by :
|
||||
* Eric Valette, mail to : valette@crf.canon.fr
|
||||
* Emmanuel Raguet, mail to : raguet@crf.canon.fr
|
||||
*
|
||||
* $Header$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
/* Basic, host-specific, and target-specific definitions for GDB.
|
||||
Copyright (C) 1986, 1989, 1991, 1992, 1993, 1994, 1995
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
struct xdr_regs {
|
||||
int r_dreg[8]; /* data registers */
|
||||
int r_areg[8]; /* address registers */
|
||||
int r_sr; /* status register (actually a short) */
|
||||
int r_pc; /* program counter */
|
||||
int r_vec; /* last vector */
|
||||
};
|
||||
|
||||
#ifdef RPC_HDR
|
||||
|
||||
%/* now define register macros to apply to xdr_reg struct */
|
||||
%
|
||||
|
||||
%#define r_r0 r_dreg[0] /* r0 for portability */
|
||||
%#define r_sp r_areg[7] /* user stack pointer */
|
||||
%#define r_ps r_sr
|
||||
|
||||
%#define REG_PC r_pc /* PC register offset */
|
||||
%#define REG_SP r_areg[7] /* SP register offset */
|
||||
%#define REG_FP r_areg[6] /* FP register offset */
|
||||
|
||||
%/* now define the BREAKPOINT mask technique to a long word */
|
||||
%#define SET_BREAK(l) ((l&0x0000FFFF) | 0x4E4F0000) /* TRAP 15 */
|
||||
%#define IS_BREAK(l) (((l) & 0xFFFF0000) == 0x4E4F0000)
|
||||
%#define ORG_BREAK(c,p) (((c) & 0x0000FFFF) | ((p) & 0xFFFF0000))
|
||||
%#define IS_STEP(regs) ((regs).r_vec == 9)
|
||||
%#define BREAK_ADJ 0
|
||||
%#define BREAK_SIZE 2
|
||||
|
||||
%#define TARGET_PROC_TYPE 2
|
||||
|
||||
#endif
|
||||
@@ -1,120 +0,0 @@
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <bsp.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
#define printf(c)
|
||||
/*HEADER_START*/
|
||||
#define RTEMS_PORT 2071
|
||||
#define RTEMS_BACK_PORT 2073
|
||||
/*
|
||||
* Sun request values for the remote ptrace system call
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory data for read/write text or data. The size is in data. The target
|
||||
* addr is in the addr field.
|
||||
* Be careful before modifying because this value goes into internal
|
||||
* pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
* become too small if this value gets incremented.
|
||||
*/
|
||||
/* now open_connex() routine which establishes a connection to server */
|
||||
#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
/* now close_connex() routine which detaches from server */
|
||||
/* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
/* now wait_info() routine which returns results of polling the wait status
|
||||
of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
some additions */
|
||||
/* now define the actual calls we support */
|
||||
const char* names [] = {
|
||||
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
|
||||
"name4", "name5", "name6", "name7",
|
||||
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
|
||||
"name12", "WAIT_INFO", "name14", "name15",
|
||||
"name16", "GET_SIGNAL_NAMES", "name18"
|
||||
};
|
||||
|
||||
void
|
||||
remotedeb_2(struct svc_req *rqstp, register SVCXPRT *transp)
|
||||
{
|
||||
union {
|
||||
open_in open_connex_2_arg;
|
||||
signal_in send_signal_2_arg;
|
||||
close_in close_connex_2_arg;
|
||||
ptrace_in ptrace_2_arg;
|
||||
wait_in wait_info_2_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
xdrproc_t _xdr_argument, _xdr_result;
|
||||
char *(*local)(char *, struct svc_req *);
|
||||
|
||||
DPRINTF (("remotedeb_2: %s (%d)\n",
|
||||
(unsigned) rqstp->rq_proc <
|
||||
(unsigned) (sizeof names / sizeof names[0]) ?
|
||||
names [rqstp->rq_proc] : "???",
|
||||
(int) rqstp->rq_proc));
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
case NULLPROC:
|
||||
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
|
||||
return;
|
||||
|
||||
case OPEN_CONNEX:
|
||||
_xdr_argument = (xdrproc_t) xdr_open_in;
|
||||
_xdr_result = (xdrproc_t) xdr_open_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) open_connex_2_svc;
|
||||
break;
|
||||
|
||||
case SEND_SIGNAL:
|
||||
_xdr_argument = (xdrproc_t) xdr_signal_in;
|
||||
_xdr_result = (xdrproc_t) xdr_signal_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) send_signal_2_svc;
|
||||
break;
|
||||
|
||||
case CLOSE_CONNEX:
|
||||
_xdr_argument = (xdrproc_t) xdr_close_in;
|
||||
_xdr_result = (xdrproc_t) xdr_void;
|
||||
local = (char *(*)(char *, struct svc_req *)) close_connex_2_svc;
|
||||
break;
|
||||
|
||||
case PTRACE:
|
||||
_xdr_argument = (xdrproc_t) xdr_ptrace_in;
|
||||
_xdr_result = (xdrproc_t) xdr_ptrace_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) ptrace_2_svc;
|
||||
break;
|
||||
|
||||
case WAIT_INFO:
|
||||
_xdr_argument = (xdrproc_t) xdr_wait_in;
|
||||
_xdr_result = (xdrproc_t) xdr_wait_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) wait_info_2_svc;
|
||||
break;
|
||||
|
||||
case GET_SIGNAL_NAMES:
|
||||
_xdr_argument = (xdrproc_t) xdr_void;
|
||||
_xdr_result = (xdrproc_t) xdr_get_signal_names_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) get_signal_names_2_svc;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc (transp);
|
||||
return;
|
||||
}
|
||||
memset ((char *)&argument, 0, sizeof (argument));
|
||||
if (!svc_getargs (transp, _xdr_argument, (caddr_t) &argument)) {
|
||||
svcerr_decode (transp);
|
||||
return;
|
||||
}
|
||||
result = (*local)((char *)&argument, rqstp);
|
||||
if (result != NULL && !svc_sendreply(transp, _xdr_result, result)) {
|
||||
svcerr_systemerr (transp);
|
||||
}
|
||||
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument)) {
|
||||
printf( "unable to free arguments");
|
||||
exit (1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,890 +0,0 @@
|
||||
/*
|
||||
* Please do not edit this file.
|
||||
* It was generated using rpcgen.
|
||||
*/
|
||||
|
||||
#include "src/m68k/any/remdeb.h"
|
||||
#define RTEMS_PORT 2071
|
||||
#define RTEMS_BACK_PORT 2073
|
||||
|
||||
bool_t
|
||||
xdr_rpc_type (XDR *xdrs, rpc_type *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_UDP_MSG (XDR *xdrs, UDP_MSG *objp)
|
||||
{
|
||||
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->msg_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->spec))
|
||||
return FALSE;
|
||||
if (!xdr_long (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->context))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* Sun request values for the remote ptrace system call
|
||||
*/
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_ptracereq (XDR *xdrs, ptracereq *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_xdr_regs (XDR *xdrs, xdr_regs *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, (3 + 8 + 8 )* BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->r_dreg, 8,
|
||||
sizeof (int), (xdrproc_t) xdr_int))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->r_areg, 8,
|
||||
sizeof (int), (xdrproc_t) xdr_int))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->r_sr))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->r_pc))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->r_vec))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register int *genp;
|
||||
|
||||
for (i = 0, genp = objp->r_dreg;
|
||||
i < 8; ++i) {
|
||||
IXDR_PUT_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
{
|
||||
register int *genp;
|
||||
|
||||
for (i = 0, genp = objp->r_areg;
|
||||
i < 8; ++i) {
|
||||
IXDR_PUT_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
IXDR_PUT_LONG(buf, objp->r_sr);
|
||||
IXDR_PUT_LONG(buf, objp->r_pc);
|
||||
IXDR_PUT_LONG(buf, objp->r_vec);
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, (3 + 8 + 8 )* BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->r_dreg, 8,
|
||||
sizeof (int), (xdrproc_t) xdr_int))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->r_areg, 8,
|
||||
sizeof (int), (xdrproc_t) xdr_int))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->r_sr))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->r_pc))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->r_vec))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register int *genp;
|
||||
|
||||
for (i = 0, genp = objp->r_dreg;
|
||||
i < 8; ++i) {
|
||||
*genp++ = IXDR_GET_LONG(buf);
|
||||
}
|
||||
}
|
||||
{
|
||||
register int *genp;
|
||||
|
||||
for (i = 0, genp = objp->r_areg;
|
||||
i < 8; ++i) {
|
||||
*genp++ = IXDR_GET_LONG(buf);
|
||||
}
|
||||
}
|
||||
objp->r_sr = IXDR_GET_LONG(buf);
|
||||
objp->r_pc = IXDR_GET_LONG(buf);
|
||||
objp->r_vec = IXDR_GET_LONG(buf);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_vector (xdrs, (char *)objp->r_dreg, 8,
|
||||
sizeof (int), (xdrproc_t) xdr_int))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->r_areg, 8,
|
||||
sizeof (int), (xdrproc_t) xdr_int))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->r_sr))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->r_pc))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->r_vec))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* Memory data for read/write text or data. The size is in data. The target
|
||||
* addr is in the addr field.
|
||||
* Be careful before modifying because this value goes into internal
|
||||
* pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
* become too small if this value gets incremented.
|
||||
*/
|
||||
bool_t xdr_xdr_mem(xdrs, objp)
|
||||
XDR *xdrs;
|
||||
struct xdr_mem *objp;
|
||||
{
|
||||
if (!xdr_u_long(xdrs, &objp->addr)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_u_int(xdrs, &objp->dataNb)) {
|
||||
return(FALSE);
|
||||
}
|
||||
return (xdr_opaque(xdrs, objp->data, objp->dataNb));
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_break_type (XDR *xdrs, break_type *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_xdr_break (XDR *xdrs, xdr_break *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->thread_spec))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_short (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_loc))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->length))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
IXDR_PUT_U_SHORT(buf, objp->handle);
|
||||
IXDR_PUT_U_LONG(buf, objp->ee_loc);
|
||||
IXDR_PUT_U_LONG(buf, objp->ee_type);
|
||||
IXDR_PUT_U_SHORT(buf, objp->length);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->pass_count))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->curr_pass))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, ( MAX_THRD_BRK ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
|
||||
sizeof (u_long), (xdrproc_t) xdr_u_long))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_long *genp;
|
||||
|
||||
for (i = 0, genp = objp->thread_list;
|
||||
i < MAX_THRD_BRK; ++i) {
|
||||
IXDR_PUT_U_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->thread_spec))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_short (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_loc))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->length))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
objp->handle = IXDR_GET_U_SHORT(buf);
|
||||
objp->ee_loc = IXDR_GET_U_LONG(buf);
|
||||
objp->ee_type = IXDR_GET_U_LONG(buf);
|
||||
objp->length = IXDR_GET_U_SHORT(buf);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->pass_count))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->curr_pass))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, ( MAX_THRD_BRK ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
|
||||
sizeof (u_long), (xdrproc_t) xdr_u_long))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_long *genp;
|
||||
|
||||
for (i = 0, genp = objp->thread_list;
|
||||
i < MAX_THRD_BRK; ++i) {
|
||||
*genp++ = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->thread_spec))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_loc))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->length))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->pass_count))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->curr_pass))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
|
||||
sizeof (u_long), (xdrproc_t) xdr_u_long))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_thread_name (XDR *xdrs, thread_name *objp)
|
||||
{
|
||||
|
||||
if (!xdr_string (xdrs, objp, THREADNAMEMAX))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_KernThread (XDR *xdrs, KernThread *objp)
|
||||
{
|
||||
|
||||
if (!xdr_u_int (xdrs, &objp->threadLi))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
bool_t xdr_thread_list(xdrs, objp)
|
||||
XDR *xdrs;
|
||||
struct thread_list *objp;
|
||||
{
|
||||
return (xdr_array(xdrs, (char**)&objp->threads, &objp->nbThread,
|
||||
UTHREAD_MAX, sizeof(KernThread), xdr_KernThread));
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_addr_data_in (XDR *xdrs, ptrace_addr_data_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_ptracereq (xdrs, &objp->req))
|
||||
return FALSE;
|
||||
switch (objp->req) {
|
||||
case RPT_SETTHREADREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_SETREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PSETTHREADREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PSETREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_SETTHREADNAME:
|
||||
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_in_u.name))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_WRITETEXT:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_WRITEDATA:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_SETBREAK:
|
||||
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_in_u.breakp))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_in_u.address))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_addr_data_out (XDR *xdrs, ptrace_addr_data_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_ptracereq (xdrs, &objp->req))
|
||||
return FALSE;
|
||||
switch (objp->req) {
|
||||
case RPT_GETREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETTHREADREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PGETREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PGETTHREADREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_THREADLIST:
|
||||
if (!xdr_thread_list (xdrs, &objp->ptrace_addr_data_out_u.threads))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETTHREADNAME:
|
||||
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_out_u.name))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_READTEXT:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETNAME:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_READDATA:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETBREAK:
|
||||
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_out_u.breakp))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_out_u.addr))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_CHAR_DATA (XDR *xdrs, CHAR_DATA *objp)
|
||||
{
|
||||
|
||||
if (!xdr_bytes (xdrs, (char **)&objp->CHAR_DATA_val, (u_int *) &objp->CHAR_DATA_len, NET_SAFE))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_one_arg (XDR *xdrs, one_arg *objp)
|
||||
{
|
||||
|
||||
if (!xdr_string (xdrs, objp, NET_SAFE))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now open_connex() routine which establishes a connection to server */
|
||||
|
||||
bool_t
|
||||
xdr_debug_type (XDR *xdrs, debug_type *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
|
||||
bool_t
|
||||
xdr_open_in (XDR *xdrs, open_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_vector (xdrs, (char *)objp->back_port, 16,
|
||||
sizeof (u_char), (xdrproc_t) xdr_u_char))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->debug_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->flags))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->destination, 16,
|
||||
sizeof (u_char), (xdrproc_t) xdr_u_char))
|
||||
return FALSE;
|
||||
if (!xdr_one_arg (xdrs, &objp->user_name))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_open_out (XDR *xdrs, open_out *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_long (xdrs, &objp->port))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->fp))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
IXDR_PUT_U_LONG(buf, objp->port);
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->pad;
|
||||
i < 4; ++i) {
|
||||
IXDR_PUT_U_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
IXDR_PUT_U_LONG(buf, objp->fp);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->server_vers))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_long (xdrs, &objp->port))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->fp))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
objp->port = IXDR_GET_U_LONG(buf);
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->pad;
|
||||
i < 4; ++i) {
|
||||
*genp++ = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
}
|
||||
objp->fp = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->server_vers))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_u_long (xdrs, &objp->port))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->fp))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->server_vers))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now close_connex() routine which detaches from server */
|
||||
|
||||
bool_t
|
||||
xdr_close_control (XDR *xdrs, close_control *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_close_in (XDR *xdrs, close_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_close_control (xdrs, &objp->control))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
|
||||
bool_t
|
||||
xdr_signal_in (XDR *xdrs, signal_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->sig))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_signal_out (XDR *xdrs, signal_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->kill_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now wait_info() routine which returns results of polling the wait status
|
||||
of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
|
||||
bool_t
|
||||
xdr_stop_code (XDR *xdrs, stop_code *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_wait_in (XDR *xdrs, wait_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_wait_out (XDR *xdrs, wait_out *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->wait_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
IXDR_PUT_LONG(buf, objp->wait_return);
|
||||
IXDR_PUT_LONG(buf, objp->errNo);
|
||||
IXDR_PUT_LONG(buf, objp->status);
|
||||
}
|
||||
if (!xdr_stop_code (xdrs, &objp->reason))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->PC))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->SP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->FP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->thread))
|
||||
return FALSE;
|
||||
} else {
|
||||
IXDR_PUT_LONG(buf, objp->handle);
|
||||
IXDR_PUT_U_LONG(buf, objp->PC);
|
||||
IXDR_PUT_U_LONG(buf, objp->SP);
|
||||
IXDR_PUT_U_LONG(buf, objp->FP);
|
||||
IXDR_PUT_U_LONG(buf, objp->thread);
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->wait_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
objp->wait_return = IXDR_GET_LONG(buf);
|
||||
objp->errNo = IXDR_GET_LONG(buf);
|
||||
objp->status = IXDR_GET_LONG(buf);
|
||||
}
|
||||
if (!xdr_stop_code (xdrs, &objp->reason))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->PC))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->SP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->FP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->thread))
|
||||
return FALSE;
|
||||
} else {
|
||||
objp->handle = IXDR_GET_LONG(buf);
|
||||
objp->PC = IXDR_GET_U_LONG(buf);
|
||||
objp->SP = IXDR_GET_U_LONG(buf);
|
||||
objp->FP = IXDR_GET_U_LONG(buf);
|
||||
objp->thread = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_int (xdrs, &objp->wait_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
if (!xdr_stop_code (xdrs, &objp->reason))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->PC))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->SP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->FP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->thread))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
some additions */
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_in (XDR *xdrs, ptrace_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_ptrace_addr_data_in (xdrs, &objp->addr))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->data))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->flags))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_out (XDR *xdrs, ptrace_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_ptrace_addr_data_out (xdrs, &objp->addr))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_one_symbol (XDR *xdrs, one_symbol *objp)
|
||||
{
|
||||
|
||||
if (!xdr_string (xdrs, &objp->symbolName, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_long (xdrs, &objp->symbolValue))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_all_symbols (XDR *xdrs, all_symbols *objp)
|
||||
{
|
||||
|
||||
if (!xdr_array (xdrs, (char **)&objp->all_symbols_val, (u_int *) &objp->all_symbols_len, ~0,
|
||||
sizeof (one_symbol), (xdrproc_t) xdr_one_symbol))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_global_symbols_out (XDR *xdrs, get_global_symbols_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_all_symbols (xdrs, &objp->symbols))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_text_data_in (XDR *xdrs, get_text_data_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->actorName, 16))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_text_data_out (XDR *xdrs, get_text_data_out *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textSize))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataSize))
|
||||
return FALSE;
|
||||
} else {
|
||||
IXDR_PUT_LONG(buf, objp->result);
|
||||
IXDR_PUT_LONG(buf, objp->errNo);
|
||||
IXDR_PUT_U_LONG(buf, objp->textStart);
|
||||
IXDR_PUT_U_LONG(buf, objp->textSize);
|
||||
IXDR_PUT_U_LONG(buf, objp->dataStart);
|
||||
IXDR_PUT_U_LONG(buf, objp->dataSize);
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textSize))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataSize))
|
||||
return FALSE;
|
||||
} else {
|
||||
objp->result = IXDR_GET_LONG(buf);
|
||||
objp->errNo = IXDR_GET_LONG(buf);
|
||||
objp->textStart = IXDR_GET_U_LONG(buf);
|
||||
objp->textSize = IXDR_GET_U_LONG(buf);
|
||||
objp->dataStart = IXDR_GET_U_LONG(buf);
|
||||
objp->dataSize = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textSize))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataSize))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_one_signal (XDR *xdrs, one_signal *objp)
|
||||
{
|
||||
|
||||
if (!xdr_u_int (xdrs, &objp->number))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->name, ~0))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_all_signals (XDR *xdrs, all_signals *objp)
|
||||
{
|
||||
|
||||
if (!xdr_array (xdrs, (char **)&objp->all_signals_val, (u_int *) &objp->all_signals_len, ~0,
|
||||
sizeof (one_signal), (xdrproc_t) xdr_one_signal))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_signal_names_out (XDR *xdrs, get_signal_names_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_all_signals (xdrs, &objp->signals))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now define the actual calls we support */
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component =
|
||||
*
|
||||
* Synopsis = rdbg/m68k/excep_f.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
|
||||
int
|
||||
ExcepToSig (Exception_context * ctx)
|
||||
{
|
||||
int excep = getExcNum (ctx);
|
||||
|
||||
switch (excep) {
|
||||
case 2:
|
||||
return 10;
|
||||
break; /* bus error */
|
||||
case 3:
|
||||
return 10;
|
||||
break; /* address error */
|
||||
case 4:
|
||||
return 4;
|
||||
break; /* illegal instruction */
|
||||
case 5:
|
||||
return 8;
|
||||
break; /* zero divide */
|
||||
case 6:
|
||||
return 8;
|
||||
break; /* chk instruction */
|
||||
case 7:
|
||||
return 8;
|
||||
break; /* trapv instruction */
|
||||
case 8:
|
||||
return 11;
|
||||
break; /* privilege violation */
|
||||
case 9:
|
||||
return 5;
|
||||
break; /* trace trap */
|
||||
case 10:
|
||||
return 4;
|
||||
break; /* line 1010 emulator */
|
||||
case 11:
|
||||
return 4;
|
||||
break; /* line 1111 emulator */
|
||||
|
||||
/*
|
||||
* Coprocessor protocol violation. Using a standard MMU or FPU
|
||||
* this cannot be triggered by software. Call it a SIGBUS.
|
||||
*/
|
||||
case 13:
|
||||
return 10;
|
||||
break;
|
||||
|
||||
case 31:
|
||||
return 2;
|
||||
break; /* interrupt */
|
||||
case 33:
|
||||
return 5;
|
||||
break; /* monitor breakpoint */
|
||||
case 34:
|
||||
return 2;
|
||||
break; /* lets use this for SCC1 interrupt */
|
||||
case 35:
|
||||
return 5;
|
||||
break; /* rdbg breakpoint */
|
||||
case 36:
|
||||
return 2;
|
||||
break; /* enter RDBG */
|
||||
/*
|
||||
* This is a trap #8 instruction. Apparently it is someone's software
|
||||
* convention for some sort of SIGFPE condition. Whose? How many
|
||||
* people are being screwed by having this code the way it is?
|
||||
* Is there a clean solution?
|
||||
*/
|
||||
case 40:
|
||||
return 8;
|
||||
break; /* floating point err */
|
||||
|
||||
case 47:
|
||||
return 5;
|
||||
break; /* rdbg breakpoint */
|
||||
|
||||
case 48:
|
||||
return 8;
|
||||
break; /* floating point err */
|
||||
case 49:
|
||||
return 8;
|
||||
break; /* floating point err */
|
||||
case 50:
|
||||
return 8;
|
||||
break; /* zero divide */
|
||||
case 51:
|
||||
return 8;
|
||||
break; /* underflow */
|
||||
case 52:
|
||||
return 8;
|
||||
break; /* operand error */
|
||||
case 53:
|
||||
return 8;
|
||||
break; /* overflow */
|
||||
case 54:
|
||||
return 8;
|
||||
break; /* NAN */
|
||||
default:
|
||||
return 7; /* "software generated" */
|
||||
}
|
||||
return SIGKILL;
|
||||
}
|
||||
|
||||
/*----- Breakpoint Exception management -----*/
|
||||
|
||||
/*
|
||||
* Handler for Breakpoint Exceptions :
|
||||
* software breakpoints.
|
||||
*/
|
||||
|
||||
void
|
||||
BreakPointExcHdl (CPU_Exception_frame * ctx)
|
||||
{
|
||||
rtems_status_code status;
|
||||
rtems_id continueSemId;
|
||||
|
||||
connect_rdbg_exception (); /* monitor stub changes trace vector */
|
||||
if ((justSaveContext) && (ctx->vecnum == 47)) { /* break */
|
||||
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
|
||||
justSaveContext = 0;
|
||||
} else {
|
||||
if (ctx->vecnum != 9) { /* trace */
|
||||
NbSerializedCtx++;
|
||||
rtems_semaphore_obtain (serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
NbSerializedCtx--;
|
||||
}
|
||||
|
||||
currentTargetThread = _Thread_Executing->Object.id;
|
||||
|
||||
#ifdef DDEBUG
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk ("Exception %d caught at PC %x by thread %d\n",
|
||||
ctx->vecnum, ctx->pc, _Thread_Executing->Object.id);
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk ("Processor execution context at time of the fault was :\n");
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk ("\t A0 = %x\n", ctx->a0);
|
||||
printk ("\t A1 = %x\n", ctx->a1);
|
||||
printk ("\t A2 = %x\n", ctx->a2);
|
||||
printk ("\t A3 = %x\n", ctx->a3);
|
||||
printk ("\t A4 = %x\n", ctx->a4);
|
||||
printk ("\t A5 = %x\n", ctx->a5);
|
||||
printk ("\t A6 = %x\n", ctx->a6);
|
||||
printk ("\t A7 = %x\n", ctx->a7);
|
||||
printk ("\t D0 = %x\n", ctx->d0);
|
||||
printk ("\t D1 = %x\n", ctx->d1);
|
||||
printk ("\t D2 = %x\n", ctx->d2);
|
||||
printk ("\t D3 = %x\n", ctx->d3);
|
||||
printk ("\t D4 = %x\n", ctx->d4);
|
||||
printk ("\t D5 = %x\n", ctx->d5);
|
||||
printk ("\t D6 = %x\n", ctx->d6);
|
||||
printk ("\t D7 = %x\n", ctx->d7);
|
||||
printk ("\t SR = %x\n", ctx->sr);
|
||||
#endif
|
||||
|
||||
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 'c'),
|
||||
0,
|
||||
RTEMS_FIFO |
|
||||
RTEMS_COUNTING_SEMAPHORE |
|
||||
RTEMS_NO_INHERIT_PRIORITY |
|
||||
RTEMS_NO_PRIORITY_CEILING |
|
||||
RTEMS_LOCAL, 0, &continueSemId);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_panic ("Can't create continue semaphore: `%s'\n",
|
||||
rtems_status_text (status));
|
||||
|
||||
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
|
||||
|
||||
switch (ctx->vecnum) {
|
||||
case 9: /* trace */
|
||||
DPRINTF ((" TRACE EXCEPTION !!!\n"));
|
||||
ctx->sr &= ~(1 << 15);
|
||||
ExitForSingleStep--;
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
|
||||
case 47: /* trap #15 */
|
||||
DPRINTF ((" BREAKPOINT EXCEPTION !!!\n"));
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
|
||||
case 36: /* trap #4 */
|
||||
DPRINTF ((" ENTER RDBG !!!\n"));
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTF ((" OTHER EXCEPTION !!!\n"));
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
}
|
||||
|
||||
rtems_semaphore_obtain (continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
|
||||
PopExceptCtx (_Thread_Executing->Object.id);
|
||||
rtems_semaphore_delete (continueSemId);
|
||||
}
|
||||
|
||||
connect_rdbg_exception (); /* monitor stub changes trace vector */
|
||||
}
|
||||
@@ -1,244 +0,0 @@
|
||||
/* rdbg_cpu_asm.s
|
||||
*
|
||||
* This file contains all assembly code for the Motorola m68k implementation
|
||||
* of RDBG.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
BEGIN_CODE
|
||||
|
||||
/*
|
||||
* void copyback_data_cache_and_invalidate_instr_cache(addr, size)
|
||||
*
|
||||
* This routine performs a copy of the data cache
|
||||
* and invalidate the instruction cache
|
||||
*/
|
||||
|
||||
.align 2
|
||||
PUBLIC (copyback_data_cache_and_invalidate_instr_cache)
|
||||
|
||||
SYM (copyback_data_cache_and_invalidate_instr_cache):
|
||||
nop | how?
|
||||
rts
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void enterRdbg(void)
|
||||
*
|
||||
* This function performs trap #4
|
||||
* It is used :
|
||||
* 1 - in the user code, to simulate a Breakpoint.
|
||||
* (with justSaveContext = 0)
|
||||
* 2 - in the RDBG code, to push a ctx in the list.
|
||||
* (with justSaveContext = 1)
|
||||
*
|
||||
* In most of case, it will be use as described in 1.
|
||||
* The 2nd possibility will be used by RDBG to obtain
|
||||
* its own ctx
|
||||
*/
|
||||
|
||||
PUBLIC (enterRdbg)
|
||||
|
||||
SYM (enterRdbg):
|
||||
trap #4
|
||||
rts
|
||||
|
||||
|
||||
/*
|
||||
* void excHandler(void)
|
||||
*
|
||||
* lotsa copypaste from cpu_asm.S
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The RTEMS jump table pushes vector
|
||||
*
|
||||
* The two types of exception frames on m68000 are
|
||||
*
|
||||
* uint16_t sr <- sp
|
||||
* uint32_t pc
|
||||
*
|
||||
* uint16_t fc <- sp
|
||||
* uint32_t addr
|
||||
* uint16_t instr
|
||||
* uint16_t sr
|
||||
* uint32_t pc
|
||||
*
|
||||
* after real frame we push d0-d1/a0-a1
|
||||
*
|
||||
* after that we push CPU_Exception_frame
|
||||
*
|
||||
* exframe <- sp
|
||||
* d0-d1/a0-a1
|
||||
* frame
|
||||
*/
|
||||
#if ( M68K_COLDFIRE_ARCH == 1 )
|
||||
.set SR_OFFSET, 2 | Status register offset
|
||||
.set PC_OFFSET, 4 | Program Counter offset
|
||||
.set FVO_OFFSET, 0 | Format/vector offset
|
||||
#elif ( M68K_HAS_VBR == 1 )
|
||||
.set SR_OFFSET, 0 | Status register offset
|
||||
.set PC_OFFSET, 2 | Program Counter offset
|
||||
.set FVO_OFFSET, 6 | Format/vector offset
|
||||
#else
|
||||
.set SR_OFFSET, 2 | Status register offset
|
||||
.set PC_OFFSET, 4 | Program Counter offset
|
||||
.set FVO_OFFSET, 0 | Format/vector offset placed in the stack
|
||||
#endif /* M68K_HAS_VBR */
|
||||
|
||||
.align 4
|
||||
|
||||
PUBLIC (excHandler)
|
||||
PUBLIC (BreakPointExcHdl)
|
||||
|
||||
SYM (excFormatLength):
|
||||
/*
|
||||
* size of exception stack frame depending on format type
|
||||
* This is valid for m68k with VBR (68020/030/040/CPU32/CPU32+)
|
||||
* size | format/name
|
||||
*/
|
||||
dc.w 4*2 | $0 standard
|
||||
dc.w 4*2 | $1 throwaway stackframe
|
||||
dc.w 6*2 | $2 CHK/CHK2/TRAPcc/TRAPV/DIV0/TRACE
|
||||
dc.w 6*2 | $3 Coprocessor Post-Instruction (040)
|
||||
dc.w 4*2 | $4 reserved
|
||||
dc.w 4*2 | $5 reserved
|
||||
dc.w 4*2 | $6 reserved
|
||||
dc.w 30*2 | $7 Access Error (040)
|
||||
dc.w 29*2 | $8 Bus Error (020)
|
||||
dc.w 10*2 | $9 Coprocessor Mid-Instruction (020)
|
||||
dc.w 16*2 | $A Short Bus-Error (020)
|
||||
dc.w 46*2 | $B Long Bus-Error (020)
|
||||
dc.w 12*2 | $C Bus Error/Address Error (CPU32)
|
||||
dc.w 4*2 | $D reserved
|
||||
dc.w 4*2 | $E reserved
|
||||
dc.w 4*2 | $F reserved
|
||||
|
||||
SYM (excHandler):
|
||||
#if ( M68K_COLDFIRE_ARCH == 1 )
|
||||
lea a7@(-16),a7
|
||||
movm.l d0-d1/a0-a1,a7@ | save d0-d1,a0-a1
|
||||
movew a7@(16+FVO_OFFSET),d0 | d0 = F/VO
|
||||
andl #0x0ffc,d0 | d0 = vector offset in vbr
|
||||
lsrl #2,d0 | d0 = vector number
|
||||
lea a7@(16),a1 | address of orig frame
|
||||
lea a7@(16),a0 | address of orig frame
|
||||
lea a0@(8),a0 | skip exception frame
|
||||
#else
|
||||
moveml d0-d1/a0-a1,a7@- | save d0-d1,a0-a1
|
||||
movew a7@(16+FVO_OFFSET),d0 | d0 = F/VO
|
||||
#if ( M68K_HAS_VBR == 1 )
|
||||
movew d0,d1 | d1 is copy of F/VO
|
||||
andl #0x0ffc,d0 | d0 = vector offset in vbr
|
||||
lsrl #2,d0 | d0 = vector number
|
||||
lsrl #8,d1
|
||||
lsrl #3,d1
|
||||
andl #0x001f,d1 | d1 is format number
|
||||
lea SYM (excFormatLength),a1
|
||||
movew a1@(d1),d1 | d1 = size of exc frame
|
||||
lea a7@(16,d1),a0
|
||||
lea a7@(16),a1 | address of orig frame
|
||||
|
||||
#else /* (M68k_HAS_VBR == 0) */
|
||||
lea a7@(16),a1 | address of orig frame
|
||||
lea a1@(6),a0 | skip stack frame
|
||||
/*
|
||||
* skip bus error stack frame...
|
||||
*/
|
||||
cmpi.l #3,d0
|
||||
bgt 1f | if >3 then normal exc
|
||||
lea a1@(8),a0 | skip extra stuff
|
||||
lea a0@(6),a0 | a0 = orig sp
|
||||
1:
|
||||
#endif /* M68K_HAS_VBR */
|
||||
#endif /* ( M68K_COLDFIRE_ARCH == 0 ) */
|
||||
|
||||
/*
|
||||
* at this point:
|
||||
* a0 points to stack above exception stack frame
|
||||
* a1 points to start of exception stack frame
|
||||
*/
|
||||
|
||||
movew a1@(SR_OFFSET),d1 | d1 = sr
|
||||
andl #0xffff,d1
|
||||
lea a7@(-76),a7 | reserve room for exception frame
|
||||
| build CPU_Exception_frame
|
||||
movel d0,a7@ | vecnum
|
||||
movel d1,a7@(4) | sr
|
||||
movel a1@(PC_OFFSET),d1 | d1 = pc
|
||||
#if ( M68K_COLDFIRE_ARCH == 0 )
|
||||
cmpiw #47,d0 | trap #15, breakpoint?
|
||||
#else
|
||||
cmpil #47,d0 | trap #15, breakpoint?
|
||||
#endif
|
||||
bne 2f
|
||||
subql #2,d1 | real PC is at trap insn
|
||||
2: movel d1,a7@(8) | store pc to exframe struct
|
||||
movel a7@(76),a7@(12) | the orig d0 pushed at beginning
|
||||
movel a7@(76+4),a7@(16) | the orig d1 pushed at beginning
|
||||
movel d2,a7@(20)
|
||||
movel d3,a7@(24)
|
||||
movel d4,a7@(28)
|
||||
movel d5,a7@(32)
|
||||
movel d6,a7@(36)
|
||||
movel d7,a7@(40)
|
||||
movel a7@(76+8),a7@(44) | the orig a0 pushed at beginning
|
||||
movel a7@(76+12),a7@(48) | the orig a1 pushed at beginning
|
||||
movel a2,a7@(52)
|
||||
movel a3,a7@(56)
|
||||
movel a4,a7@(60)
|
||||
movel a5,a7@(64)
|
||||
movel a6,a7@(68)
|
||||
movel a0,a7@(72) | stack pointer before exception
|
||||
lea a7@,a0 | exframe address
|
||||
movel a1,a7@- | save top of orig frame
|
||||
movel a0,a7@- | push exframe address
|
||||
jsr SYM(BreakPointExcHdl)
|
||||
addql #4,a7 | pop exframe address
|
||||
movel a7@+,a1 | restore orig frame address
|
||||
| XXX what should be restored from exframe??
|
||||
movel a7@(4),d1 | sr
|
||||
movew d1,a1@(SR_OFFSET) | store sr to frame XXX ???
|
||||
movel a7@(8),a1@(PC_OFFSET) | store pc to frame XXX ???
|
||||
movel a7@(12),a7@(76) | d0 to be restored from stack
|
||||
movel a7@(16),a7@(76+4) | d1 to be restored from stack
|
||||
movel a7@(20),d2
|
||||
movel a7@(24),d3
|
||||
movel a7@(28),d4
|
||||
movel a7@(32),d5
|
||||
movel a7@(36),d6
|
||||
movel a7@(40),d7
|
||||
movel a7@(44),a7@(76+8) | a0 to be restored from stack
|
||||
movel a7@(48),a7@(76+12) | a1 to be restored from stack
|
||||
movel a7@(52),a2
|
||||
movel a7@(56),a3
|
||||
movel a7@(60),a4
|
||||
movel a7@(64),a5
|
||||
movel a7@(68),a6
|
||||
addl #76,a7 | pop exframe
|
||||
|
||||
#if ( M68K_COLDFIRE_ARCH == 0 )
|
||||
moveml a7@+,d0-d1/a0-a1 | restore d0-d1,a0-a1
|
||||
#else
|
||||
moveml a7@,d0-d1/a0-a1 | restore d0-d1,a0-a1
|
||||
lea a7@(16),a7
|
||||
#endif
|
||||
|
||||
#if ( M68K_HAS_VBR == 0 )
|
||||
addql #2,a7 | pop format/id
|
||||
#endif /* M68K_HAS_VBR */
|
||||
|
||||
| XXX bus err cleanup
|
||||
|
||||
rte
|
||||
|
||||
END_CODE
|
||||
|
||||
END
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component =
|
||||
*
|
||||
* Synopsis = rdbg/m68k/rdbg_f.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/reg.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <rtems/score/thread.h>
|
||||
|
||||
m68k_isr_entry set_vector(
|
||||
rtems_isr_entry handler,
|
||||
rtems_vector_number vector,
|
||||
int type
|
||||
);
|
||||
|
||||
void CtxToRegs (const CPU_Exception_frame * ctx, xdr_regs * regs)
|
||||
{
|
||||
regs->r_dreg[0] = ctx->d0;
|
||||
regs->r_dreg[1] = ctx->d1;
|
||||
regs->r_dreg[2] = ctx->d2;
|
||||
regs->r_dreg[3] = ctx->d3;
|
||||
regs->r_dreg[4] = ctx->d4;
|
||||
regs->r_dreg[5] = ctx->d5;
|
||||
regs->r_dreg[6] = ctx->d6;
|
||||
regs->r_dreg[7] = ctx->d7;
|
||||
|
||||
regs->r_areg[0] = ctx->a0;
|
||||
regs->r_areg[1] = ctx->a1;
|
||||
regs->r_areg[2] = ctx->a2;
|
||||
regs->r_areg[3] = ctx->a3;
|
||||
regs->r_areg[4] = ctx->a4;
|
||||
regs->r_areg[5] = ctx->a5;
|
||||
regs->r_areg[6] = ctx->a6;
|
||||
regs->r_areg[7] = ctx->a7;
|
||||
|
||||
regs->r_sr = ctx->sr;
|
||||
regs->r_pc = ctx->pc;
|
||||
regs->r_vec = ctx->vecnum;
|
||||
}
|
||||
|
||||
void
|
||||
RegsToCtx (const xdr_regs * regs, CPU_Exception_frame * ctx)
|
||||
{
|
||||
ctx->d0 = regs->r_dreg[0];
|
||||
ctx->d1 = regs->r_dreg[1];
|
||||
ctx->d2 = regs->r_dreg[2];
|
||||
ctx->d3 = regs->r_dreg[3];
|
||||
ctx->d4 = regs->r_dreg[4];
|
||||
ctx->d5 = regs->r_dreg[5];
|
||||
ctx->d6 = regs->r_dreg[6];
|
||||
ctx->d7 = regs->r_dreg[7];
|
||||
|
||||
ctx->a0 = regs->r_areg[0];
|
||||
ctx->a1 = regs->r_areg[1];
|
||||
ctx->a2 = regs->r_areg[2];
|
||||
ctx->a3 = regs->r_areg[3];
|
||||
ctx->a4 = regs->r_areg[4];
|
||||
ctx->a5 = regs->r_areg[5];
|
||||
ctx->a6 = regs->r_areg[6];
|
||||
ctx->a7 = regs->r_areg[7];
|
||||
|
||||
ctx->sr = regs->r_sr;
|
||||
ctx->pc = regs->r_pc;
|
||||
ctx->vecnum = regs->r_vec;
|
||||
}
|
||||
|
||||
void
|
||||
get_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
|
||||
{
|
||||
/*
|
||||
* ISR stores d0-d1/a0-a1, calls _Thread_Dispatch
|
||||
* _Thread_Dispatch calls _Context_Switch == _CPU_Context_switch
|
||||
* _CPU_Context_switch stores/restores sr,d2-d7,a2-a7
|
||||
* so if my reasoning is correct, *sp points to a location in
|
||||
* _Thread_Dispatch
|
||||
*/
|
||||
ctx->vecnum = 0xdeadbeef;
|
||||
ctx->sr = thread->Registers.sr;
|
||||
ctx->pc = *(uint32_t *) thread->Registers.a7_msp;
|
||||
ctx->d0 = 0xdeadbeef;
|
||||
ctx->d1 = 0xdeadbeef;
|
||||
ctx->a0 = 0xdeadbeef;
|
||||
ctx->a1 = 0xdeadbeef;
|
||||
|
||||
ctx->a2 = (uint32_t) thread->Registers.a2;
|
||||
ctx->a3 = (uint32_t) thread->Registers.a3;
|
||||
ctx->a4 = (uint32_t) thread->Registers.a4;
|
||||
ctx->a5 = (uint32_t) thread->Registers.a5;
|
||||
ctx->a6 = (uint32_t) thread->Registers.a6;
|
||||
ctx->a7 = (uint32_t) thread->Registers.a7_msp;
|
||||
ctx->d2 = thread->Registers.d2;
|
||||
ctx->d3 = thread->Registers.d3;
|
||||
ctx->d4 = thread->Registers.d4;
|
||||
ctx->d5 = thread->Registers.d5;
|
||||
ctx->d6 = thread->Registers.d6;
|
||||
ctx->d7 = thread->Registers.d7;
|
||||
}
|
||||
|
||||
void
|
||||
set_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
|
||||
{
|
||||
thread->Registers.sr = ctx->sr;
|
||||
thread->Registers.d2 = ctx->d2;
|
||||
thread->Registers.d3 = ctx->d3;
|
||||
thread->Registers.d4 = ctx->d4;
|
||||
thread->Registers.d5 = ctx->d5;
|
||||
thread->Registers.d6 = ctx->d6;
|
||||
thread->Registers.d7 = ctx->d7;
|
||||
thread->Registers.a2 = (void *) ctx->a2;
|
||||
thread->Registers.a3 = (void *) ctx->a3;
|
||||
thread->Registers.a4 = (void *) ctx->a4;
|
||||
thread->Registers.a5 = (void *) ctx->a5;
|
||||
thread->Registers.a6 = (void *) ctx->a6;
|
||||
thread->Registers.a7_msp = (void *) ctx->a7;
|
||||
}
|
||||
|
||||
int
|
||||
Single_Step (CPU_Exception_frame * ctx)
|
||||
{
|
||||
if ((ctx->sr & (1 << 15)) != 0 || ExitForSingleStep != 0) {
|
||||
/*
|
||||
* Check coherency
|
||||
*/
|
||||
assert ((ctx->sr & (1 << 15)) != 0);
|
||||
assert (ExitForSingleStep != 0);
|
||||
return 0;
|
||||
}
|
||||
ctx->sr |= 1 << 15;
|
||||
++ExitForSingleStep;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CheckForSingleStep (CPU_Exception_frame * ctx)
|
||||
{
|
||||
if (ExitForSingleStep) {
|
||||
ctx->sr &= ~(1 << 15);
|
||||
ExitForSingleStep = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CancelSingleStep (CPU_Exception_frame * ctx)
|
||||
{
|
||||
/*
|
||||
* Cancel scheduled SS
|
||||
*/
|
||||
ctx->sr &= ~(1 << 15);
|
||||
ExitForSingleStep--;
|
||||
}
|
||||
|
||||
extern rtems_isr excHandler ();
|
||||
|
||||
void
|
||||
connect_rdbg_exception (void)
|
||||
{
|
||||
set_vector (excHandler, 9, 0);
|
||||
set_vector (excHandler, 47, 0);
|
||||
set_vector (excHandler, 36, 0);
|
||||
}
|
||||
|
||||
void
|
||||
disconnect_rdbg_exception (void)
|
||||
{
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component =
|
||||
*
|
||||
* Synopsis = rdbg/powerpc/excep_f.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
|
||||
int
|
||||
ExcepToSig (Exception_context * ctx)
|
||||
{
|
||||
int excep = getExcNum (ctx);
|
||||
|
||||
switch (excep) {
|
||||
case ASM_FLOAT_VECTOR:
|
||||
return SIGFPE;
|
||||
|
||||
case ASM_TRACE_VECTOR:
|
||||
case ASM_PROG_VECTOR:
|
||||
case ASM_SYS_VECTOR:
|
||||
return SIGTRAP;
|
||||
|
||||
/* At lest the MPC5xx series does not have this vector */
|
||||
#if defined(ASM_ISI_VECTOR)
|
||||
case ASM_ISI_VECTOR:
|
||||
return SIGSEGV;
|
||||
#endif
|
||||
|
||||
case ASM_RESET_VECTOR:
|
||||
case ASM_MACH_VECTOR:
|
||||
case ASM_EXT_VECTOR:
|
||||
case ASM_ALIGN_VECTOR:
|
||||
return SIGILL;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SIGKILL;
|
||||
}
|
||||
|
||||
/*----- Breakpoint Exception management -----*/
|
||||
|
||||
/*
|
||||
* Handler for Breakpoint Exceptions :
|
||||
* software breakpoints.
|
||||
*/
|
||||
|
||||
void
|
||||
BreakPointExcHdl (CPU_Exception_frame * ctx)
|
||||
{
|
||||
rtems_status_code status;
|
||||
rtems_id continueSemId;
|
||||
|
||||
/*
|
||||
* we must re-enable the floating point engine
|
||||
* if the interrupted thread is FP. Otherwise,
|
||||
* the semaphore primitives may crash when they
|
||||
* try to save FP context while switching this
|
||||
* thread... NB : deferred fp context switching
|
||||
* would 1) avoid to have to save FP, make this code
|
||||
* obsolete.
|
||||
*/
|
||||
if (ctx->EXC_SRR1 & MSR_FP) {
|
||||
register unsigned long msr;
|
||||
__asm__ __volatile__ ("mfmsr %0":"=r" (msr));
|
||||
__asm__ __volatile__ ("mtmsr %0"::"r" (msr | MSR_FP));
|
||||
}
|
||||
|
||||
if ((justSaveContext) && (ctx->_EXC_number == ASM_SYS_VECTOR)) {
|
||||
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
|
||||
justSaveContext = 0;
|
||||
} else {
|
||||
if (ctx->_EXC_number != ASM_TRACE_VECTOR) {
|
||||
NbSerializedCtx++;
|
||||
rtems_semaphore_obtain (serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
NbSerializedCtx--;
|
||||
}
|
||||
|
||||
currentTargetThread = _Thread_Executing->Object.id;
|
||||
|
||||
#ifdef DDEBUG
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk ("Exception %d caught at PC %x by thread %d\n",
|
||||
ctx->_EXC_number, ctx->EXC_SRR0, _Thread_Executing->Object.id);
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk ("Processor execution context at time of the fault was :\n");
|
||||
printk ("----------------------------------------------------------\n");
|
||||
printk ("\t R0 = %x\n", ctx->GPR0);
|
||||
printk ("\t R1 = %x\n", ctx->GPR1);
|
||||
printk ("\t R2 = %x\n", ctx->GPR2);
|
||||
printk ("\t R3 = %x\n", ctx->GPR3);
|
||||
printk ("\t R4 = %x\n", ctx->GPR4);
|
||||
printk ("\t R5 = %x\n", ctx->GPR5);
|
||||
printk ("\t R6 = %x\n", ctx->GPR6);
|
||||
printk ("\t R7 = %x\n", ctx->GPR7);
|
||||
printk ("\t R8 = %x\n", ctx->GPR8);
|
||||
printk ("\t R9 = %x\n", ctx->GPR9);
|
||||
printk ("\t R10 = %x\n", ctx->GPR10);
|
||||
printk ("\t R11 = %x\n", ctx->GPR11);
|
||||
printk ("\t R12 = %x\n", ctx->GPR12);
|
||||
printk ("\t R13 = %x\n", ctx->GPR13);
|
||||
printk ("\t R14 = %x\n", ctx->GPR14);
|
||||
printk ("\t R15 = %x\n", ctx->GPR15);
|
||||
printk ("\t R16 = %x\n", ctx->GPR16);
|
||||
printk ("\t R17 = %x\n", ctx->GPR17);
|
||||
printk ("\t R18 = %x\n", ctx->GPR18);
|
||||
printk ("\t R19 = %x\n", ctx->GPR19);
|
||||
printk ("\t R20 = %x\n", ctx->GPR20);
|
||||
printk ("\t R21 = %x\n", ctx->GPR21);
|
||||
printk ("\t R22 = %x\n", ctx->GPR22);
|
||||
printk ("\t R23 = %x\n", ctx->GPR23);
|
||||
printk ("\t R24 = %x\n", ctx->GPR24);
|
||||
printk ("\t R25 = %x\n", ctx->GPR25);
|
||||
printk ("\t R26 = %x\n", ctx->GPR26);
|
||||
printk ("\t R27 = %x\n", ctx->GPR27);
|
||||
printk ("\t R28 = %x\n", ctx->GPR28);
|
||||
printk ("\t R29 = %x\n", ctx->GPR29);
|
||||
printk ("\t R30 = %x\n", ctx->GPR30);
|
||||
printk ("\t R31 = %x\n", ctx->GPR31);
|
||||
printk ("\t CR = %x\n", ctx->EXC_CR);
|
||||
printk ("\t CTR = %x\n", ctx->EXC_CTR);
|
||||
printk ("\t XER = %x\n", ctx->EXC_XER);
|
||||
printk ("\t LR = %x\n", ctx->EXC_LR);
|
||||
printk ("\t MSR = %x\n", ctx->EXC_SRR1);
|
||||
#endif
|
||||
|
||||
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 'c'),
|
||||
0,
|
||||
RTEMS_FIFO |
|
||||
RTEMS_COUNTING_SEMAPHORE |
|
||||
RTEMS_NO_INHERIT_PRIORITY |
|
||||
RTEMS_NO_PRIORITY_CEILING |
|
||||
RTEMS_LOCAL, 0, &continueSemId);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_panic ("Can't create continue semaphore: `%s'\n",
|
||||
rtems_status_text (status));
|
||||
|
||||
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
|
||||
|
||||
switch (ctx->_EXC_number) {
|
||||
case ASM_TRACE_VECTOR:
|
||||
DPRINTF ((" TRACE EXCEPTION !!!\n"));
|
||||
ctx->EXC_SRR1 &= ~MSR_SE;
|
||||
ExitForSingleStep--;
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
|
||||
case ASM_PROG_VECTOR:
|
||||
DPRINTF ((" BREAKPOINT EXCEPTION !!!\n"));
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
|
||||
case ASM_SYS_VECTOR:
|
||||
DPRINTF ((" ENTER RDBG !!!\n"));
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTF ((" OTHER EXCEPTION !!!\n"));
|
||||
rtems_semaphore_release (wakeupEventSemId);
|
||||
break;
|
||||
}
|
||||
|
||||
rtems_semaphore_obtain (continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
|
||||
PopExceptCtx (_Thread_Executing->Object.id);
|
||||
rtems_semaphore_delete (continueSemId);
|
||||
}
|
||||
}
|
||||
@@ -1,544 +0,0 @@
|
||||
/*
|
||||
* Please do not edit this file.
|
||||
* It was generated using rpcgen.
|
||||
*/
|
||||
|
||||
#ifndef _REMDEB_H_RPCGEN
|
||||
#define _REMDEB_H_RPCGEN
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RTEMS_PORT 2071
|
||||
#define RTEMS_BACK_PORT 2073
|
||||
#ifndef REMDEB_H
|
||||
#define RPCGENSRVNAME(a) a
|
||||
|
||||
enum rpc_type {
|
||||
SUNRPC = 0,
|
||||
BADRPCTYPE = 25,
|
||||
};
|
||||
typedef enum rpc_type rpc_type;
|
||||
#define NET_SAFE 1400
|
||||
|
||||
struct UDP_MSG {
|
||||
u_char type;
|
||||
u_char msg_num;
|
||||
u_short spec;
|
||||
long pid;
|
||||
u_long context;
|
||||
};
|
||||
typedef struct UDP_MSG UDP_MSG;
|
||||
/*
|
||||
* Sun request values for the remote ptrace system call
|
||||
*/
|
||||
|
||||
|
||||
enum ptracereq {
|
||||
RPT_TRACEME = 0,
|
||||
RPT_CHILDDONE = 0,
|
||||
RPT_PEEKTEXT = 0 + 1,
|
||||
RPT_PEEKDATA = 0 + 2,
|
||||
RPT_PEEKUSER = 0 + 3,
|
||||
RPT_POKETEXT = 0 + 4,
|
||||
RPT_POKEDATA = 0 + 5,
|
||||
RPT_POKEUSER = 0 + 6,
|
||||
RPT_CONT = 0 + 7,
|
||||
RPT_KILL = 0 + 8,
|
||||
RPT_SINGLESTEP = 0 + 9,
|
||||
RPT_ATTACH = 0 + 10,
|
||||
RPT_DETACH = 0 + 11,
|
||||
RPT_GETREGS = 0 + 12,
|
||||
RPT_SETREGS = 0 + 13,
|
||||
RPT_GETFPREGS = 0 + 14,
|
||||
RPT_SETFPREGS = 0 + 15,
|
||||
RPT_READDATA = 0 + 16,
|
||||
RPT_WRITEDATA = 0 + 17,
|
||||
RPT_READTEXT = 0 + 18,
|
||||
RPT_WRITETEXT = 0 + 19,
|
||||
RPT_GETFPAREGS = 0 + 20,
|
||||
RPT_SETFPAREGS = 0 + 21,
|
||||
RPT_22 = 0 + 22,
|
||||
RPT_23 = 0 + 23,
|
||||
RPT_SYSCALL = 0 + 24,
|
||||
RPT_DUMPCORE = 0 + 25,
|
||||
RPT_26 = 0 + 26,
|
||||
RPT_27 = 0 + 27,
|
||||
RPT_28 = 0 + 28,
|
||||
RPT_GETUCODE = 0 + 29,
|
||||
RPT_GETTARGETTHREAD = 50,
|
||||
RPT_SETTARGETTHREAD = 51,
|
||||
RPT_THREADSUSPEND = 52,
|
||||
RPT_THREADRESUME = 53,
|
||||
RPT_THREADLIST = 54,
|
||||
RPT_GETTHREADNAME = 55,
|
||||
RPT_SETTHREADNAME = 56,
|
||||
RPT_SETTHREADREGS = 57,
|
||||
RPT_GETTHREADREGS = 58,
|
||||
RPT_STEPRANGE = 75,
|
||||
RPT_CONTTO = 76,
|
||||
RPT_SETBREAK = 77,
|
||||
RPT_CLRBREAK = 78,
|
||||
RPT_GETBREAK = 79,
|
||||
RPT_GETNAME = 80,
|
||||
RPT_STOP = 81,
|
||||
RPT_PGETREGS = 82,
|
||||
RPT_PSETREGS = 83,
|
||||
RPT_PSETTHREADREGS = 84,
|
||||
RPT_PGETTHREADREGS = 85,
|
||||
};
|
||||
typedef enum ptracereq ptracereq;
|
||||
|
||||
struct xdr_regs {
|
||||
u_int tabreg[40];
|
||||
};
|
||||
typedef struct xdr_regs xdr_regs;
|
||||
/* now define register macros to apply to xdr_regs struct */
|
||||
|
||||
#define R_PC 0
|
||||
#define R_MSR 1
|
||||
#define R_EXCEPNB 2
|
||||
#define R_R0 3
|
||||
#define R_R1 (R_R0 + 1)
|
||||
#define R_R2 (R_R0 + 2)
|
||||
#define R_R3 (R_R0 + 3)
|
||||
#define R_R4 (R_R0 + 4)
|
||||
#define R_R5 (R_R0 + 5)
|
||||
#define R_R6 (R_R0 + 6)
|
||||
#define R_R7 (R_R0 + 7)
|
||||
#define R_R8 (R_R0 + 8)
|
||||
#define R_R9 (R_R0 + 9)
|
||||
#define R_R10 (R_R0 + 10)
|
||||
#define R_R11 (R_R0 + 11)
|
||||
#define R_R12 (R_R0 + 12)
|
||||
#define R_R13 (R_R0 + 13)
|
||||
#define R_R14 (R_R0 + 14)
|
||||
#define R_R15 (R_R0 + 15)
|
||||
#define R_R16 (R_R0 + 16)
|
||||
#define R_R17 (R_R0 + 17)
|
||||
#define R_R18 (R_R0 + 18)
|
||||
#define R_R19 (R_R0 + 19)
|
||||
#define R_R20 (R_R0 + 20)
|
||||
#define R_R21 (R_R0 + 21)
|
||||
#define R_R22 (R_R0 + 22)
|
||||
#define R_R23 (R_R0 + 23)
|
||||
#define R_R24 (R_R0 + 24)
|
||||
#define R_R25 (R_R0 + 25)
|
||||
#define R_R26 (R_R0 + 26)
|
||||
#define R_R27 (R_R0 + 27)
|
||||
#define R_R28 (R_R0 + 28)
|
||||
#define R_R29 (R_R0 + 29)
|
||||
#define R_R30 (R_R0 + 30)
|
||||
#define R_R31 (R_R0 + 31)
|
||||
#define R_CR 35
|
||||
#define R_CTR 36
|
||||
#define R_XER 37
|
||||
#define R_LR 38
|
||||
#define R_MQ 39
|
||||
|
||||
#include <libcpu/raw_exception.h>
|
||||
|
||||
#define REG_PC tabreg[R_PC] /* PC register offset */
|
||||
#define REG_SP tabreg[R_R1] /* SP register offset */
|
||||
#define REG_FP tabreg[R_R1] /* SP register offset (no FP on PPC) */
|
||||
#define BREAK_SIZE 4 /* Breakpoint occupies 4 bytes */
|
||||
#define BREAK_ADJ 0 /* Nothing to subtract from address after bp */
|
||||
#define IS_BREAK(l) ((l) == 0x7d8d6808)
|
||||
#define SET_BREAK(l) (0x7d8d6808)
|
||||
#define ORG_BREAK(c,p) (p)
|
||||
#define IS_STEP(regs) (regs.tabreg[R_EXCEPNB] == ASM_TRACE_VECTOR) /* Was step and not break */
|
||||
#define TARGET_PROC_TYPE 3
|
||||
#define MAXDEBUGGEE 150
|
||||
#define NAMEMAX 17
|
||||
/*
|
||||
* Memory data for read/write text or data. The size is in data. The target
|
||||
* addr is in the addr field.
|
||||
* Be careful before modifying because this value goes into internal
|
||||
* pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
* become too small if this value gets incremented.
|
||||
*/
|
||||
#define MEM_DATA_MAX 256
|
||||
|
||||
struct xdr_mem {
|
||||
u_long addr;
|
||||
u_int dataNb;
|
||||
u_char data[MEM_DATA_MAX];
|
||||
};
|
||||
typedef struct xdr_mem xdr_mem;
|
||||
|
||||
enum break_type {
|
||||
BRKT_NONE = 0,
|
||||
BRKT_INSTR = 1,
|
||||
BRKT_READ = 2,
|
||||
BRKT_WRITE = 3,
|
||||
BRKT_ACCESS = 4,
|
||||
BRKT_EXEC = 5,
|
||||
BRKT_OS_CALL = 6,
|
||||
BRKT_OS_SWITCH = 7,
|
||||
BRKT_STEPEMUL = 8,
|
||||
};
|
||||
typedef enum break_type break_type;
|
||||
#define MAX_THRD_BRK 4
|
||||
|
||||
struct xdr_break {
|
||||
u_char type;
|
||||
u_char thread_spec;
|
||||
u_short handle;
|
||||
u_long ee_loc;
|
||||
u_long ee_type;
|
||||
u_short length;
|
||||
u_char pass_count;
|
||||
u_char curr_pass;
|
||||
u_long thread_list[MAX_THRD_BRK];
|
||||
};
|
||||
typedef struct xdr_break xdr_break;
|
||||
#define UTHREAD_MAX 64
|
||||
#define THREADNAMEMAX 16
|
||||
|
||||
typedef char *thread_name;
|
||||
|
||||
struct KernThread {
|
||||
u_int threadLi;
|
||||
};
|
||||
typedef struct KernThread KernThread;
|
||||
typedef KernThread *ptThreadList;
|
||||
|
||||
struct thread_list {
|
||||
u_int nbThread;
|
||||
ptThreadList threads;
|
||||
};
|
||||
typedef struct thread_list thread_list;
|
||||
|
||||
struct ptrace_addr_data_in {
|
||||
ptracereq req;
|
||||
union {
|
||||
xdr_regs regs;
|
||||
struct {
|
||||
u_int pregs_len;
|
||||
u_int *pregs_val;
|
||||
} pregs;
|
||||
thread_name name;
|
||||
xdr_mem mem;
|
||||
xdr_break breakp;
|
||||
u_int address;
|
||||
} ptrace_addr_data_in_u;
|
||||
};
|
||||
typedef struct ptrace_addr_data_in ptrace_addr_data_in;
|
||||
|
||||
struct ptrace_addr_data_out {
|
||||
ptracereq req;
|
||||
union {
|
||||
xdr_regs regs;
|
||||
struct {
|
||||
u_int pregs_len;
|
||||
u_int *pregs_val;
|
||||
} pregs;
|
||||
thread_list threads;
|
||||
thread_name name;
|
||||
xdr_mem mem;
|
||||
xdr_break breakp;
|
||||
u_int addr;
|
||||
} ptrace_addr_data_out_u;
|
||||
};
|
||||
typedef struct ptrace_addr_data_out ptrace_addr_data_out;
|
||||
|
||||
typedef struct {
|
||||
u_int CHAR_DATA_len;
|
||||
char *CHAR_DATA_val;
|
||||
} CHAR_DATA;
|
||||
|
||||
typedef char *one_arg;
|
||||
/* now open_connex() routine which establishes a connection to server */
|
||||
|
||||
enum debug_type {
|
||||
DEBTYP_PROCESS = 0,
|
||||
DEBTYP_C_ACTOR = 1,
|
||||
DEBTYP_KERNEL = 2,
|
||||
DEBTYP_OTHER = 3,
|
||||
};
|
||||
typedef enum debug_type debug_type;
|
||||
#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
|
||||
struct open_in {
|
||||
u_char back_port[16];
|
||||
u_short debug_type;
|
||||
u_short flags;
|
||||
u_char destination[16];
|
||||
one_arg user_name;
|
||||
};
|
||||
typedef struct open_in open_in;
|
||||
|
||||
struct open_out {
|
||||
u_long port;
|
||||
u_int pad[4];
|
||||
u_int fp;
|
||||
u_char cmd_table_num;
|
||||
u_char cmd_table_vers;
|
||||
u_short server_vers;
|
||||
};
|
||||
typedef struct open_out open_out;
|
||||
/* now close_connex() routine which detaches from server */
|
||||
|
||||
enum close_control {
|
||||
CLOSE_IGNORE = 0,
|
||||
CLOSE_KILL = 1,
|
||||
CLOSE_DETACH = 2,
|
||||
};
|
||||
typedef enum close_control close_control;
|
||||
|
||||
struct close_in {
|
||||
close_control control;
|
||||
};
|
||||
typedef struct close_in close_in;
|
||||
/* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
|
||||
struct signal_in {
|
||||
int pid;
|
||||
int sig;
|
||||
};
|
||||
typedef struct signal_in signal_in;
|
||||
|
||||
struct signal_out {
|
||||
int kill_return;
|
||||
int errNo;
|
||||
};
|
||||
typedef struct signal_out signal_out;
|
||||
/* now wait_info() routine which returns results of polling the wait status
|
||||
of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
|
||||
enum stop_code {
|
||||
STOP_ERROR = 0,
|
||||
STOP_NONE = 1,
|
||||
STOP_UNKNOWN = 2,
|
||||
STOP_BREAK = 3,
|
||||
STOP_STEP = 4,
|
||||
STOP_SIGNAL = 5,
|
||||
STOP_TERM_EXIT = 6,
|
||||
STOP_TERM_SIG = 7,
|
||||
STOP_DETACHED = 8,
|
||||
STOP_KILLED = 9,
|
||||
STOP_SPAWN_FAILED = 10,
|
||||
};
|
||||
typedef enum stop_code stop_code;
|
||||
|
||||
struct wait_in {
|
||||
int pid;
|
||||
};
|
||||
typedef struct wait_in wait_in;
|
||||
|
||||
struct wait_out {
|
||||
int wait_return;
|
||||
int errNo;
|
||||
int status;
|
||||
stop_code reason;
|
||||
int handle;
|
||||
u_long PC;
|
||||
u_long SP;
|
||||
u_long FP;
|
||||
u_long thread;
|
||||
};
|
||||
typedef struct wait_out wait_out;
|
||||
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
some additions */
|
||||
#define PTRFLG_FORCE 1
|
||||
#define PTRFLG_NON_OWNER 2
|
||||
#define PTRFLG_FREE 4
|
||||
#define PTRDET_UNOWN 0x100
|
||||
|
||||
struct ptrace_in {
|
||||
int pid;
|
||||
ptrace_addr_data_in addr;
|
||||
u_int data;
|
||||
u_int flags;
|
||||
};
|
||||
typedef struct ptrace_in ptrace_in;
|
||||
|
||||
struct ptrace_out {
|
||||
ptrace_addr_data_out addr;
|
||||
int result;
|
||||
int errNo;
|
||||
};
|
||||
typedef struct ptrace_out ptrace_out;
|
||||
|
||||
struct one_symbol {
|
||||
char *symbolName;
|
||||
long symbolValue;
|
||||
};
|
||||
typedef struct one_symbol one_symbol;
|
||||
|
||||
typedef struct {
|
||||
u_int all_symbols_len;
|
||||
one_symbol *all_symbols_val;
|
||||
} all_symbols;
|
||||
|
||||
struct get_global_symbols_out {
|
||||
all_symbols symbols;
|
||||
};
|
||||
typedef struct get_global_symbols_out get_global_symbols_out;
|
||||
|
||||
struct get_text_data_in {
|
||||
int pid;
|
||||
char *actorName;
|
||||
};
|
||||
typedef struct get_text_data_in get_text_data_in;
|
||||
|
||||
struct get_text_data_out {
|
||||
int result;
|
||||
int errNo;
|
||||
u_long textStart;
|
||||
u_long textSize;
|
||||
u_long dataStart;
|
||||
u_long dataSize;
|
||||
};
|
||||
typedef struct get_text_data_out get_text_data_out;
|
||||
|
||||
struct one_signal {
|
||||
u_int number;
|
||||
char *name;
|
||||
};
|
||||
typedef struct one_signal one_signal;
|
||||
|
||||
typedef struct {
|
||||
u_int all_signals_len;
|
||||
one_signal *all_signals_val;
|
||||
} all_signals;
|
||||
|
||||
struct get_signal_names_out {
|
||||
all_signals signals;
|
||||
};
|
||||
typedef struct get_signal_names_out get_signal_names_out;
|
||||
/* now define the actual calls we support */
|
||||
#define REMDEB_H
|
||||
#endif
|
||||
|
||||
#define REMOTEDEB 0x20000fff
|
||||
#define REMOTEVERS 2
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
#define OPEN_CONNEX 1
|
||||
extern open_out * open_connex_2(open_in *, CLIENT *);
|
||||
extern open_out * open_connex_2_svc(open_in *, struct svc_req *);
|
||||
#define SEND_SIGNAL 2
|
||||
extern signal_out * send_signal_2(signal_in *, CLIENT *);
|
||||
extern signal_out * send_signal_2_svc(signal_in *, struct svc_req *);
|
||||
#define CLOSE_CONNEX 10
|
||||
extern void * close_connex_2(close_in *, CLIENT *);
|
||||
extern void * close_connex_2_svc(close_in *, struct svc_req *);
|
||||
#define PTRACE 11
|
||||
extern ptrace_out * ptrace_2(ptrace_in *, CLIENT *);
|
||||
extern ptrace_out * ptrace_2_svc(ptrace_in *, struct svc_req *);
|
||||
#define WAIT_INFO 13
|
||||
extern wait_out * wait_info_2(wait_in *, CLIENT *);
|
||||
extern wait_out * wait_info_2_svc(wait_in *, struct svc_req *);
|
||||
#define GET_SIGNAL_NAMES 17
|
||||
extern get_signal_names_out * get_signal_names_2(void *, CLIENT *);
|
||||
extern get_signal_names_out * get_signal_names_2_svc(void *, struct svc_req *);
|
||||
extern int remotedeb_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
|
||||
|
||||
#else /* K&R C */
|
||||
#define OPEN_CONNEX 1
|
||||
extern open_out * open_connex_2();
|
||||
extern open_out * open_connex_2_svc();
|
||||
#define SEND_SIGNAL 2
|
||||
extern signal_out * send_signal_2();
|
||||
extern signal_out * send_signal_2_svc();
|
||||
#define CLOSE_CONNEX 10
|
||||
extern void * close_connex_2();
|
||||
extern void * close_connex_2_svc();
|
||||
#define PTRACE 11
|
||||
extern ptrace_out * ptrace_2();
|
||||
extern ptrace_out * ptrace_2_svc();
|
||||
#define WAIT_INFO 13
|
||||
extern wait_out * wait_info_2();
|
||||
extern wait_out * wait_info_2_svc();
|
||||
#define GET_SIGNAL_NAMES 17
|
||||
extern get_signal_names_out * get_signal_names_2();
|
||||
extern get_signal_names_out * get_signal_names_2_svc();
|
||||
extern int remotedeb_2_freeresult ();
|
||||
#endif /* K&R C */
|
||||
|
||||
/* the xdr functions */
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
extern bool_t xdr_rpc_type (XDR *, rpc_type*);
|
||||
extern bool_t xdr_UDP_MSG (XDR *, UDP_MSG*);
|
||||
extern bool_t xdr_ptracereq (XDR *, ptracereq*);
|
||||
extern bool_t xdr_xdr_regs (XDR *, xdr_regs*);
|
||||
extern bool_t xdr_xdr_mem (XDR *, xdr_mem*);
|
||||
extern bool_t xdr_break_type (XDR *, break_type*);
|
||||
extern bool_t xdr_xdr_break (XDR *, xdr_break*);
|
||||
extern bool_t xdr_thread_name (XDR *, thread_name*);
|
||||
extern bool_t xdr_KernThread (XDR *, KernThread*);
|
||||
extern bool_t xdr_thread_list (XDR *, thread_list*);
|
||||
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in*);
|
||||
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out*);
|
||||
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA*);
|
||||
extern bool_t xdr_one_arg (XDR *, one_arg*);
|
||||
extern bool_t xdr_debug_type (XDR *, debug_type*);
|
||||
extern bool_t xdr_open_in (XDR *, open_in*);
|
||||
extern bool_t xdr_open_out (XDR *, open_out*);
|
||||
extern bool_t xdr_close_control (XDR *, close_control*);
|
||||
extern bool_t xdr_close_in (XDR *, close_in*);
|
||||
extern bool_t xdr_signal_in (XDR *, signal_in*);
|
||||
extern bool_t xdr_signal_out (XDR *, signal_out*);
|
||||
extern bool_t xdr_stop_code (XDR *, stop_code*);
|
||||
extern bool_t xdr_wait_in (XDR *, wait_in*);
|
||||
extern bool_t xdr_wait_out (XDR *, wait_out*);
|
||||
extern bool_t xdr_ptrace_in (XDR *, ptrace_in*);
|
||||
extern bool_t xdr_ptrace_out (XDR *, ptrace_out*);
|
||||
extern bool_t xdr_one_symbol (XDR *, one_symbol*);
|
||||
extern bool_t xdr_all_symbols (XDR *, all_symbols*);
|
||||
extern bool_t xdr_get_global_symbols_out (XDR *, get_global_symbols_out*);
|
||||
extern bool_t xdr_get_text_data_in (XDR *, get_text_data_in*);
|
||||
extern bool_t xdr_get_text_data_out (XDR *, get_text_data_out*);
|
||||
extern bool_t xdr_one_signal (XDR *, one_signal*);
|
||||
extern bool_t xdr_all_signals (XDR *, all_signals*);
|
||||
extern bool_t xdr_get_signal_names_out (XDR *, get_signal_names_out*);
|
||||
|
||||
#else /* K&R C */
|
||||
extern bool_t xdr_rpc_type ();
|
||||
extern bool_t xdr_UDP_MSG ();
|
||||
extern bool_t xdr_ptracereq ();
|
||||
extern bool_t xdr_xdr_regs ();
|
||||
extern bool_t xdr_xdr_mem ();
|
||||
extern bool_t xdr_break_type ();
|
||||
extern bool_t xdr_xdr_break ();
|
||||
extern bool_t xdr_thread_name ();
|
||||
extern bool_t xdr_KernThread ();
|
||||
extern bool_t xdr_thread_list ();
|
||||
extern bool_t xdr_ptrace_addr_data_in ();
|
||||
extern bool_t xdr_ptrace_addr_data_out ();
|
||||
extern bool_t xdr_CHAR_DATA ();
|
||||
extern bool_t xdr_one_arg ();
|
||||
extern bool_t xdr_debug_type ();
|
||||
extern bool_t xdr_open_in ();
|
||||
extern bool_t xdr_open_out ();
|
||||
extern bool_t xdr_close_control ();
|
||||
extern bool_t xdr_close_in ();
|
||||
extern bool_t xdr_signal_in ();
|
||||
extern bool_t xdr_signal_out ();
|
||||
extern bool_t xdr_stop_code ();
|
||||
extern bool_t xdr_wait_in ();
|
||||
extern bool_t xdr_wait_out ();
|
||||
extern bool_t xdr_ptrace_in ();
|
||||
extern bool_t xdr_ptrace_out ();
|
||||
extern bool_t xdr_one_symbol ();
|
||||
extern bool_t xdr_all_symbols ();
|
||||
extern bool_t xdr_get_global_symbols_out ();
|
||||
extern bool_t xdr_get_text_data_in ();
|
||||
extern bool_t xdr_get_text_data_out ();
|
||||
extern bool_t xdr_one_signal ();
|
||||
extern bool_t xdr_all_signals ();
|
||||
extern bool_t xdr_get_signal_names_out ();
|
||||
|
||||
#endif /* K&R C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_REMDEB_H_RPCGEN */
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component = rdblib
|
||||
* Synopsis = remdeb_f.x
|
||||
*
|
||||
**************************************************************************
|
||||
* $Id$
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
struct xdr_regs
|
||||
{
|
||||
unsigned int tabreg[40];
|
||||
};
|
||||
|
||||
#ifdef RPC_HDR
|
||||
|
||||
%/* now define register macros to apply to xdr_regs struct */
|
||||
%
|
||||
%#define R_PC 0
|
||||
%#define R_MSR 1
|
||||
%#define R_EXCEPNB 2
|
||||
%#define R_R0 3
|
||||
%#define R_R1 (R_R0 + 1)
|
||||
%#define R_R2 (R_R0 + 2)
|
||||
%#define R_R3 (R_R0 + 3)
|
||||
%#define R_R4 (R_R0 + 4)
|
||||
%#define R_R5 (R_R0 + 5)
|
||||
%#define R_R6 (R_R0 + 6)
|
||||
%#define R_R7 (R_R0 + 7)
|
||||
%#define R_R8 (R_R0 + 8)
|
||||
%#define R_R9 (R_R0 + 9)
|
||||
%#define R_R10 (R_R0 + 10)
|
||||
%#define R_R11 (R_R0 + 11)
|
||||
%#define R_R12 (R_R0 + 12)
|
||||
%#define R_R13 (R_R0 + 13)
|
||||
%#define R_R14 (R_R0 + 14)
|
||||
%#define R_R15 (R_R0 + 15)
|
||||
%#define R_R16 (R_R0 + 16)
|
||||
%#define R_R17 (R_R0 + 17)
|
||||
%#define R_R18 (R_R0 + 18)
|
||||
%#define R_R19 (R_R0 + 19)
|
||||
%#define R_R20 (R_R0 + 20)
|
||||
%#define R_R21 (R_R0 + 21)
|
||||
%#define R_R22 (R_R0 + 22)
|
||||
%#define R_R23 (R_R0 + 23)
|
||||
%#define R_R24 (R_R0 + 24)
|
||||
%#define R_R25 (R_R0 + 25)
|
||||
%#define R_R26 (R_R0 + 26)
|
||||
%#define R_R27 (R_R0 + 27)
|
||||
%#define R_R28 (R_R0 + 28)
|
||||
%#define R_R29 (R_R0 + 29)
|
||||
%#define R_R30 (R_R0 + 30)
|
||||
%#define R_R31 (R_R0 + 31)
|
||||
%#define R_CR 35
|
||||
%#define R_CTR 36
|
||||
%#define R_XER 37
|
||||
%#define R_LR 38
|
||||
%#define R_MQ 39
|
||||
%
|
||||
%#include <libcpu/raw_exception.h>
|
||||
%
|
||||
%#define REG_PC tabreg[R_PC] /* PC register offset */
|
||||
%#define REG_SP tabreg[R_R1] /* SP register offset */
|
||||
%#define REG_FP tabreg[R_R1] /* SP register offset (no FP on PPC) */
|
||||
%#define BREAK_SIZE 4 /* Breakpoint occupies 4 bytes */
|
||||
%#define BREAK_ADJ 0 /* Nothing to subtract from address after bp */
|
||||
%#define IS_BREAK(l) ((l) == 0x7d8d6808)
|
||||
%#define SET_BREAK(l) (0x7d8d6808)
|
||||
%#define ORG_BREAK(c,p) (p)
|
||||
%#define IS_STEP(regs) (regs.tabreg[R_EXCEPNB] == ASM_TRACE_VECTOR) /* Was step and not break */
|
||||
%#define TARGET_PROC_TYPE 3
|
||||
|
||||
#endif
|
||||
@@ -1,120 +0,0 @@
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <bsp.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
#define printf(c)
|
||||
/*HEADER_START*/
|
||||
#define RTEMS_PORT 2071
|
||||
#define RTEMS_BACK_PORT 2073
|
||||
/*
|
||||
* Sun request values for the remote ptrace system call
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory data for read/write text or data. The size is in data. The target
|
||||
* addr is in the addr field.
|
||||
* Be careful before modifying because this value goes into internal
|
||||
* pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
* become too small if this value gets incremented.
|
||||
*/
|
||||
/* now open_connex() routine which establishes a connection to server */
|
||||
#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
/* now close_connex() routine which detaches from server */
|
||||
/* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
/* now wait_info() routine which returns results of polling the wait status
|
||||
of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
some additions */
|
||||
/* now define the actual calls we support */
|
||||
const char* names [] = {
|
||||
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
|
||||
"name4", "name5", "name6", "name7",
|
||||
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
|
||||
"name12", "WAIT_INFO", "name14", "name15",
|
||||
"name16", "GET_SIGNAL_NAMES", "name18"
|
||||
};
|
||||
|
||||
void
|
||||
remotedeb_2(struct svc_req *rqstp, register SVCXPRT *transp)
|
||||
{
|
||||
union {
|
||||
open_in open_connex_2_arg;
|
||||
signal_in send_signal_2_arg;
|
||||
close_in close_connex_2_arg;
|
||||
ptrace_in ptrace_2_arg;
|
||||
wait_in wait_info_2_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
xdrproc_t _xdr_argument, _xdr_result;
|
||||
char *(*local)(char *, struct svc_req *);
|
||||
|
||||
DPRINTF (("remotedeb_2: %s (%d)\n",
|
||||
(unsigned) rqstp->rq_proc <
|
||||
(unsigned) (sizeof names / sizeof names[0]) ?
|
||||
names [rqstp->rq_proc] : "???",
|
||||
(int) rqstp->rq_proc));
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
case NULLPROC:
|
||||
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
|
||||
return;
|
||||
|
||||
case OPEN_CONNEX:
|
||||
_xdr_argument = (xdrproc_t) xdr_open_in;
|
||||
_xdr_result = (xdrproc_t) xdr_open_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) open_connex_2_svc;
|
||||
break;
|
||||
|
||||
case SEND_SIGNAL:
|
||||
_xdr_argument = (xdrproc_t) xdr_signal_in;
|
||||
_xdr_result = (xdrproc_t) xdr_signal_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) send_signal_2_svc;
|
||||
break;
|
||||
|
||||
case CLOSE_CONNEX:
|
||||
_xdr_argument = (xdrproc_t) xdr_close_in;
|
||||
_xdr_result = (xdrproc_t) xdr_void;
|
||||
local = (char *(*)(char *, struct svc_req *)) close_connex_2_svc;
|
||||
break;
|
||||
|
||||
case PTRACE:
|
||||
_xdr_argument = (xdrproc_t) xdr_ptrace_in;
|
||||
_xdr_result = (xdrproc_t) xdr_ptrace_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) ptrace_2_svc;
|
||||
break;
|
||||
|
||||
case WAIT_INFO:
|
||||
_xdr_argument = (xdrproc_t) xdr_wait_in;
|
||||
_xdr_result = (xdrproc_t) xdr_wait_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) wait_info_2_svc;
|
||||
break;
|
||||
|
||||
case GET_SIGNAL_NAMES:
|
||||
_xdr_argument = (xdrproc_t) xdr_void;
|
||||
_xdr_result = (xdrproc_t) xdr_get_signal_names_out;
|
||||
local = (char *(*)(char *, struct svc_req *)) get_signal_names_2_svc;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc (transp);
|
||||
return;
|
||||
}
|
||||
memset ((char *)&argument, 0, sizeof (argument));
|
||||
if (!svc_getargs (transp, _xdr_argument, (caddr_t) &argument)) {
|
||||
svcerr_decode (transp);
|
||||
return;
|
||||
}
|
||||
result = (*local)((char *)&argument, rqstp);
|
||||
if (result != NULL && !svc_sendreply(transp, _xdr_result, result)) {
|
||||
svcerr_systemerr (transp);
|
||||
}
|
||||
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument)) {
|
||||
printf( "unable to free arguments");
|
||||
exit (1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,841 +0,0 @@
|
||||
/*
|
||||
* Please do not edit this file.
|
||||
* It was generated using rpcgen.
|
||||
*/
|
||||
|
||||
#include "src/powerpc/new_exception_processing/remdeb.h"
|
||||
#define RTEMS_PORT 2071
|
||||
#define RTEMS_BACK_PORT 2073
|
||||
|
||||
bool_t
|
||||
xdr_rpc_type (XDR *xdrs, rpc_type *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_UDP_MSG (XDR *xdrs, UDP_MSG *objp)
|
||||
{
|
||||
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->msg_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->spec))
|
||||
return FALSE;
|
||||
if (!xdr_long (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->context))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* Sun request values for the remote ptrace system call
|
||||
*/
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_ptracereq (XDR *xdrs, ptracereq *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_xdr_regs (XDR *xdrs, xdr_regs *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, ( 40 ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->tabreg, 40,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->tabreg;
|
||||
i < 40; ++i) {
|
||||
IXDR_PUT_U_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, ( 40 ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->tabreg, 40,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->tabreg;
|
||||
i < 40; ++i) {
|
||||
*genp++ = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_vector (xdrs, (char *)objp->tabreg, 40,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* Memory data for read/write text or data. The size is in data. The target
|
||||
* addr is in the addr field.
|
||||
* Be careful before modifying because this value goes into internal
|
||||
* pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
* become too small if this value gets incremented.
|
||||
*/
|
||||
bool_t xdr_xdr_mem(xdrs, objp)
|
||||
XDR *xdrs;
|
||||
struct xdr_mem *objp;
|
||||
{
|
||||
if (!xdr_u_long(xdrs, &objp->addr)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_u_int(xdrs, &objp->dataNb)) {
|
||||
return(FALSE);
|
||||
}
|
||||
return (xdr_opaque(xdrs, objp->data, objp->dataNb));
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_break_type (XDR *xdrs, break_type *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_xdr_break (XDR *xdrs, xdr_break *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->thread_spec))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_short (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_loc))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->length))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
IXDR_PUT_U_SHORT(buf, objp->handle);
|
||||
IXDR_PUT_U_LONG(buf, objp->ee_loc);
|
||||
IXDR_PUT_U_LONG(buf, objp->ee_type);
|
||||
IXDR_PUT_U_SHORT(buf, objp->length);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->pass_count))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->curr_pass))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, ( MAX_THRD_BRK ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
|
||||
sizeof (u_long), (xdrproc_t) xdr_u_long))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_long *genp;
|
||||
|
||||
for (i = 0, genp = objp->thread_list;
|
||||
i < MAX_THRD_BRK; ++i) {
|
||||
IXDR_PUT_U_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->thread_spec))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_short (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_loc))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->length))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
objp->handle = IXDR_GET_U_SHORT(buf);
|
||||
objp->ee_loc = IXDR_GET_U_LONG(buf);
|
||||
objp->ee_type = IXDR_GET_U_LONG(buf);
|
||||
objp->length = IXDR_GET_U_SHORT(buf);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->pass_count))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->curr_pass))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, ( MAX_THRD_BRK ) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
|
||||
sizeof (u_long), (xdrproc_t) xdr_u_long))
|
||||
return FALSE;
|
||||
} else {
|
||||
{
|
||||
register u_long *genp;
|
||||
|
||||
for (i = 0, genp = objp->thread_list;
|
||||
i < MAX_THRD_BRK; ++i) {
|
||||
*genp++ = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_u_char (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->thread_spec))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_loc))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->ee_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->length))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->pass_count))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->curr_pass))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->thread_list, MAX_THRD_BRK,
|
||||
sizeof (u_long), (xdrproc_t) xdr_u_long))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_thread_name (XDR *xdrs, thread_name *objp)
|
||||
{
|
||||
|
||||
if (!xdr_string (xdrs, objp, THREADNAMEMAX))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_KernThread (XDR *xdrs, KernThread *objp)
|
||||
{
|
||||
|
||||
if (!xdr_u_int (xdrs, &objp->threadLi))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
bool_t xdr_thread_list(xdrs, objp)
|
||||
XDR *xdrs;
|
||||
struct thread_list *objp;
|
||||
{
|
||||
return (xdr_array(xdrs, (char**)&objp->threads, &objp->nbThread,
|
||||
UTHREAD_MAX, sizeof(KernThread), xdr_KernThread));
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_addr_data_in (XDR *xdrs, ptrace_addr_data_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_ptracereq (xdrs, &objp->req))
|
||||
return FALSE;
|
||||
switch (objp->req) {
|
||||
case RPT_SETTHREADREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_SETREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_in_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PSETTHREADREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PSETREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_in_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_in_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_SETTHREADNAME:
|
||||
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_in_u.name))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_WRITETEXT:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_WRITEDATA:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_in_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_SETBREAK:
|
||||
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_in_u.breakp))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_in_u.address))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_addr_data_out (XDR *xdrs, ptrace_addr_data_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_ptracereq (xdrs, &objp->req))
|
||||
return FALSE;
|
||||
switch (objp->req) {
|
||||
case RPT_GETREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETTHREADREGS:
|
||||
if (!xdr_xdr_regs (xdrs, &objp->ptrace_addr_data_out_u.regs))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PGETREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_PGETTHREADREGS:
|
||||
if (!xdr_array (xdrs, (char **)&objp->ptrace_addr_data_out_u.pregs.pregs_val, (u_int *) &objp->ptrace_addr_data_out_u.pregs.pregs_len, ~0,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_THREADLIST:
|
||||
if (!xdr_thread_list (xdrs, &objp->ptrace_addr_data_out_u.threads))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETTHREADNAME:
|
||||
if (!xdr_thread_name (xdrs, &objp->ptrace_addr_data_out_u.name))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_READTEXT:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETNAME:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_READDATA:
|
||||
if (!xdr_xdr_mem (xdrs, &objp->ptrace_addr_data_out_u.mem))
|
||||
return FALSE;
|
||||
break;
|
||||
case RPT_GETBREAK:
|
||||
if (!xdr_xdr_break (xdrs, &objp->ptrace_addr_data_out_u.breakp))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
if (!xdr_u_int (xdrs, &objp->ptrace_addr_data_out_u.addr))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_CHAR_DATA (XDR *xdrs, CHAR_DATA *objp)
|
||||
{
|
||||
|
||||
if (!xdr_bytes (xdrs, (char **)&objp->CHAR_DATA_val, (u_int *) &objp->CHAR_DATA_len, NET_SAFE))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_one_arg (XDR *xdrs, one_arg *objp)
|
||||
{
|
||||
|
||||
if (!xdr_string (xdrs, objp, NET_SAFE))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now open_connex() routine which establishes a connection to server */
|
||||
|
||||
bool_t
|
||||
xdr_debug_type (XDR *xdrs, debug_type *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
|
||||
bool_t
|
||||
xdr_open_in (XDR *xdrs, open_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_vector (xdrs, (char *)objp->back_port, 16,
|
||||
sizeof (u_char), (xdrproc_t) xdr_u_char))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->debug_type))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->flags))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->destination, 16,
|
||||
sizeof (u_char), (xdrproc_t) xdr_u_char))
|
||||
return FALSE;
|
||||
if (!xdr_one_arg (xdrs, &objp->user_name))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_open_out (XDR *xdrs, open_out *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_long (xdrs, &objp->port))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->fp))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
IXDR_PUT_U_LONG(buf, objp->port);
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->pad;
|
||||
i < 4; ++i) {
|
||||
IXDR_PUT_U_LONG(buf, *genp++);
|
||||
}
|
||||
}
|
||||
IXDR_PUT_U_LONG(buf, objp->fp);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->server_vers))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, (2 + ( 4 )) * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_u_long (xdrs, &objp->port))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->fp))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
objp->port = IXDR_GET_U_LONG(buf);
|
||||
{
|
||||
register u_int *genp;
|
||||
|
||||
for (i = 0, genp = objp->pad;
|
||||
i < 4; ++i) {
|
||||
*genp++ = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
}
|
||||
objp->fp = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->server_vers))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_u_long (xdrs, &objp->port))
|
||||
return FALSE;
|
||||
if (!xdr_vector (xdrs, (char *)objp->pad, 4,
|
||||
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->fp))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_num))
|
||||
return FALSE;
|
||||
if (!xdr_u_char (xdrs, &objp->cmd_table_vers))
|
||||
return FALSE;
|
||||
if (!xdr_u_short (xdrs, &objp->server_vers))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now close_connex() routine which detaches from server */
|
||||
|
||||
bool_t
|
||||
xdr_close_control (XDR *xdrs, close_control *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_close_in (XDR *xdrs, close_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_close_control (xdrs, &objp->control))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
|
||||
bool_t
|
||||
xdr_signal_in (XDR *xdrs, signal_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->sig))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_signal_out (XDR *xdrs, signal_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->kill_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now wait_info() routine which returns results of polling the wait status
|
||||
of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
|
||||
bool_t
|
||||
xdr_stop_code (XDR *xdrs, stop_code *objp)
|
||||
{
|
||||
|
||||
if (!xdr_enum (xdrs, (enum_t *) objp))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_wait_in (XDR *xdrs, wait_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_wait_out (XDR *xdrs, wait_out *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->wait_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
IXDR_PUT_LONG(buf, objp->wait_return);
|
||||
IXDR_PUT_LONG(buf, objp->errNo);
|
||||
IXDR_PUT_LONG(buf, objp->status);
|
||||
}
|
||||
if (!xdr_stop_code (xdrs, &objp->reason))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->PC))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->SP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->FP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->thread))
|
||||
return FALSE;
|
||||
} else {
|
||||
IXDR_PUT_LONG(buf, objp->handle);
|
||||
IXDR_PUT_U_LONG(buf, objp->PC);
|
||||
IXDR_PUT_U_LONG(buf, objp->SP);
|
||||
IXDR_PUT_U_LONG(buf, objp->FP);
|
||||
IXDR_PUT_U_LONG(buf, objp->thread);
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->wait_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
objp->wait_return = IXDR_GET_LONG(buf);
|
||||
objp->errNo = IXDR_GET_LONG(buf);
|
||||
objp->status = IXDR_GET_LONG(buf);
|
||||
}
|
||||
if (!xdr_stop_code (xdrs, &objp->reason))
|
||||
return FALSE;
|
||||
buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->PC))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->SP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->FP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->thread))
|
||||
return FALSE;
|
||||
} else {
|
||||
objp->handle = IXDR_GET_LONG(buf);
|
||||
objp->PC = IXDR_GET_U_LONG(buf);
|
||||
objp->SP = IXDR_GET_U_LONG(buf);
|
||||
objp->FP = IXDR_GET_U_LONG(buf);
|
||||
objp->thread = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_int (xdrs, &objp->wait_return))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
if (!xdr_stop_code (xdrs, &objp->reason))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->handle))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->PC))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->SP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->FP))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->thread))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
some additions */
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_in (XDR *xdrs, ptrace_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_ptrace_addr_data_in (xdrs, &objp->addr))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->data))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->flags))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_ptrace_out (XDR *xdrs, ptrace_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_ptrace_addr_data_out (xdrs, &objp->addr))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_one_symbol (XDR *xdrs, one_symbol *objp)
|
||||
{
|
||||
|
||||
if (!xdr_string (xdrs, &objp->symbolName, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_long (xdrs, &objp->symbolValue))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_all_symbols (XDR *xdrs, all_symbols *objp)
|
||||
{
|
||||
|
||||
if (!xdr_array (xdrs, (char **)&objp->all_symbols_val, (u_int *) &objp->all_symbols_len, ~0,
|
||||
sizeof (one_symbol), (xdrproc_t) xdr_one_symbol))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_global_symbols_out (XDR *xdrs, get_global_symbols_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_all_symbols (xdrs, &objp->symbols))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_text_data_in (XDR *xdrs, get_text_data_in *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int (xdrs, &objp->pid))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->actorName, 16))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_text_data_out (XDR *xdrs, get_text_data_out *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textSize))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataSize))
|
||||
return FALSE;
|
||||
} else {
|
||||
IXDR_PUT_LONG(buf, objp->result);
|
||||
IXDR_PUT_LONG(buf, objp->errNo);
|
||||
IXDR_PUT_U_LONG(buf, objp->textStart);
|
||||
IXDR_PUT_U_LONG(buf, objp->textSize);
|
||||
IXDR_PUT_U_LONG(buf, objp->dataStart);
|
||||
IXDR_PUT_U_LONG(buf, objp->dataSize);
|
||||
}
|
||||
return TRUE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
|
||||
if (buf == NULL) {
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textSize))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataSize))
|
||||
return FALSE;
|
||||
} else {
|
||||
objp->result = IXDR_GET_LONG(buf);
|
||||
objp->errNo = IXDR_GET_LONG(buf);
|
||||
objp->textStart = IXDR_GET_U_LONG(buf);
|
||||
objp->textSize = IXDR_GET_U_LONG(buf);
|
||||
objp->dataStart = IXDR_GET_U_LONG(buf);
|
||||
objp->dataSize = IXDR_GET_U_LONG(buf);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!xdr_int (xdrs, &objp->result))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->errNo))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->textSize))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataStart))
|
||||
return FALSE;
|
||||
if (!xdr_u_long (xdrs, &objp->dataSize))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_one_signal (XDR *xdrs, one_signal *objp)
|
||||
{
|
||||
|
||||
if (!xdr_u_int (xdrs, &objp->number))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->name, ~0))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_all_signals (XDR *xdrs, all_signals *objp)
|
||||
{
|
||||
|
||||
if (!xdr_array (xdrs, (char **)&objp->all_signals_val, (u_int *) &objp->all_signals_len, ~0,
|
||||
sizeof (one_signal), (xdrproc_t) xdr_one_signal))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_get_signal_names_out (XDR *xdrs, get_signal_names_out *objp)
|
||||
{
|
||||
|
||||
if (!xdr_all_signals (xdrs, &objp->signals))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* now define the actual calls we support */
|
||||
@@ -1,83 +0,0 @@
|
||||
/* cpu_asm.s
|
||||
*
|
||||
* This file contains all assembly code for the Intel i386 implementation
|
||||
* of RDBG.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <libcpu/io.h>
|
||||
|
||||
BEGIN_CODE
|
||||
|
||||
/*
|
||||
* void copyback_data_cache_and_invalidate_instr_cache(addr, size)
|
||||
*
|
||||
* This routine performs a copy of the data cache
|
||||
* and invalidate the instruction cache
|
||||
*/
|
||||
|
||||
.p2align 5
|
||||
PUBLIC_VAR (copyback_data_cache_and_invalidate_instr_cache)
|
||||
|
||||
SYM (copyback_data_cache_and_invalidate_instr_cache):
|
||||
/* make sure the data changed is in the cache */
|
||||
sync
|
||||
/* r3 address to handle, r4 length in bytes */
|
||||
addi r6, r0, PPC_CACHE_ALIGNMENT
|
||||
/* r5 = last address to handle */
|
||||
add r5,r3,r4
|
||||
/* r3 = cache_align(r3, PPC_CACHE_ALIGNMENT) */
|
||||
subi r0,r6,1
|
||||
andc r3,r3,r0
|
||||
/* R4 = R3 = copy of first address */
|
||||
mr r4,r3
|
||||
/*
|
||||
* Copyback data cache
|
||||
*/
|
||||
1: cmplw r4,r5 /* r4 >= r5 then done */
|
||||
dcbst 0,r4 /* flush (data cache bloc store) */
|
||||
add r4,r4,r6 /* r4 = next cache line addr */
|
||||
blt 1b /* end r4 >= r5 then done */
|
||||
sync /* Wait for all dcbst to complete on bus */
|
||||
/*
|
||||
* invalidate instruction cache
|
||||
*/
|
||||
/* R4 = fisrt address */
|
||||
mr r4,r3
|
||||
2: cmplw r4,r5 /* r4 >= r5 then done */
|
||||
icbi 0,r4 /* invalidate (instruction cache bloc invalidate) */
|
||||
add r4,r4,r6 /* r4 = next cache line addr */
|
||||
blt 2b /* end r4 >= r5 then done */
|
||||
sync /* Wait for all icbi to complete on bus */
|
||||
isync
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* void enterRdbg(void)
|
||||
*
|
||||
* This function perform a call to the exception SYSTEM call
|
||||
* It is used :
|
||||
* 1 - in the user code, to simulate a Breakpoint.
|
||||
* (with justSaveContext = 0)
|
||||
* 2 - in the RDBG code, to push a ctx in the list.
|
||||
* (with justSaveContext = 1)
|
||||
*
|
||||
* In most of case, it will be use as described in 1.
|
||||
* The 2nd possibility will be used by RDBG to obtain
|
||||
* its own ctx
|
||||
*/
|
||||
|
||||
PUBLIC_VAR (enterRdbg)
|
||||
|
||||
SYM (enterRdbg):
|
||||
sc
|
||||
blr
|
||||
|
||||
END_CODE
|
||||
|
||||
END
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component =
|
||||
*
|
||||
* Synopsis = rdbg/powerpc/rdbg_f.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/reg.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
|
||||
void
|
||||
CtxToRegs (const CPU_Exception_frame * ctx, xdr_regs * regs)
|
||||
{
|
||||
*((CPU_Exception_frame *) regs) = *ctx;
|
||||
}
|
||||
|
||||
void
|
||||
RegsToCtx (const xdr_regs * regs, CPU_Exception_frame * ctx)
|
||||
{
|
||||
*ctx = *((CPU_Exception_frame *) regs);
|
||||
}
|
||||
|
||||
void
|
||||
get_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
|
||||
{
|
||||
unsigned int *ptr;
|
||||
unsigned int i;
|
||||
|
||||
ctx->EXC_SRR0 = thread->Registers.pc;
|
||||
ctx->EXC_SRR1 = thread->Registers.msr;
|
||||
ctx->_EXC_number = 0xdeadbeef;
|
||||
|
||||
ctx->GPR1 = thread->Registers.gpr1;
|
||||
ctx->GPR2 = thread->Registers.gpr2;
|
||||
/*
|
||||
* Fill with dummy values...
|
||||
*/
|
||||
ptr = &ctx->GPR3;
|
||||
for (i = 0; i < 10; i++)
|
||||
ptr[i] = 0xdeadbeef;
|
||||
|
||||
ctx->GPR13 = thread->Registers.gpr13;
|
||||
ctx->GPR14 = thread->Registers.gpr14;
|
||||
ctx->GPR15 = thread->Registers.gpr15;
|
||||
ctx->GPR16 = thread->Registers.gpr16;
|
||||
ctx->GPR17 = thread->Registers.gpr17;
|
||||
ctx->GPR18 = thread->Registers.gpr18;
|
||||
ctx->GPR19 = thread->Registers.gpr19;
|
||||
ctx->GPR20 = thread->Registers.gpr20;
|
||||
ctx->GPR21 = thread->Registers.gpr21;
|
||||
ctx->GPR22 = thread->Registers.gpr22;
|
||||
ctx->GPR23 = thread->Registers.gpr23;
|
||||
ctx->GPR24 = thread->Registers.gpr24;
|
||||
ctx->GPR25 = thread->Registers.gpr25;
|
||||
ctx->GPR26 = thread->Registers.gpr26;
|
||||
ctx->GPR27 = thread->Registers.gpr27;
|
||||
ctx->GPR28 = thread->Registers.gpr28;
|
||||
ctx->GPR29 = thread->Registers.gpr29;
|
||||
ctx->GPR30 = thread->Registers.gpr30;
|
||||
ctx->GPR31 = thread->Registers.gpr31;
|
||||
ctx->EXC_CR = thread->Registers.cr;
|
||||
ctx->EXC_CTR = 0xdeadbeef;
|
||||
ctx->EXC_XER = 0xdeadbeef;
|
||||
ctx->EXC_LR = 0xdeadbeef;
|
||||
ctx->EXC_MSR = 0xdeadbeef;
|
||||
ctx->EXC_DAR = 0xdeadbeef;
|
||||
}
|
||||
|
||||
void
|
||||
set_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
|
||||
{
|
||||
thread->Registers.gpr1 = ctx->GPR1;
|
||||
thread->Registers.gpr2 = ctx->GPR2;
|
||||
|
||||
thread->Registers.gpr13 = ctx->GPR13;
|
||||
thread->Registers.gpr14 = ctx->GPR14;
|
||||
thread->Registers.gpr15 = ctx->GPR15;
|
||||
thread->Registers.gpr16 = ctx->GPR16;
|
||||
thread->Registers.gpr17 = ctx->GPR17;
|
||||
thread->Registers.gpr18 = ctx->GPR18;
|
||||
thread->Registers.gpr19 = ctx->GPR19;
|
||||
thread->Registers.gpr20 = ctx->GPR20;
|
||||
thread->Registers.gpr21 = ctx->GPR21;
|
||||
thread->Registers.gpr22 = ctx->GPR22;
|
||||
thread->Registers.gpr23 = ctx->GPR23;
|
||||
thread->Registers.gpr24 = ctx->GPR24;
|
||||
thread->Registers.gpr25 = ctx->GPR25;
|
||||
thread->Registers.gpr26 = ctx->GPR26;
|
||||
thread->Registers.gpr27 = ctx->GPR27;
|
||||
thread->Registers.gpr28 = ctx->GPR28;
|
||||
thread->Registers.gpr29 = ctx->GPR29;
|
||||
thread->Registers.gpr30 = ctx->GPR30;
|
||||
thread->Registers.gpr31 = ctx->GPR31;
|
||||
thread->Registers.cr = ctx->EXC_CR;
|
||||
thread->Registers.pc = ctx->EXC_SRR0;
|
||||
thread->Registers.msr = ctx->EXC_SRR1;
|
||||
}
|
||||
|
||||
int
|
||||
Single_Step (CPU_Exception_frame * ctx)
|
||||
{
|
||||
if ((ctx->EXC_SRR1 & MSR_SE) != 0 || ExitForSingleStep != 0) {
|
||||
/*
|
||||
* Check coherency
|
||||
*/
|
||||
assert ((ctx->EXC_SRR1 & MSR_SE) != 0);
|
||||
assert (ExitForSingleStep != 0);
|
||||
return 0;
|
||||
}
|
||||
ctx->EXC_SRR1 |= MSR_SE;
|
||||
++ExitForSingleStep;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CheckForSingleStep (CPU_Exception_frame * ctx)
|
||||
{
|
||||
if (ExitForSingleStep) {
|
||||
/*
|
||||
* This functions can be called both from
|
||||
* INT1 and INT3 handlers. In case it is
|
||||
* called from INT3, need to clear TF.
|
||||
*/
|
||||
ctx->EXC_SRR1 &= ~MSR_SE;
|
||||
ExitForSingleStep = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CancelSingleStep (CPU_Exception_frame * ctx)
|
||||
{
|
||||
/*
|
||||
* Cancel scheduled SS
|
||||
*/
|
||||
ctx->EXC_SRR1 &= ~MSR_SE;
|
||||
ExitForSingleStep--;
|
||||
}
|
||||
|
||||
static cpuExcHandlerType oldExcHandler;
|
||||
|
||||
void
|
||||
connect_rdbg_exception ()
|
||||
{
|
||||
/*
|
||||
* test if rdbg already connected its exception handler
|
||||
*/
|
||||
if (globalExceptHdl != BreakPointExcHdl) {
|
||||
oldExcHandler = globalExceptHdl;
|
||||
globalExceptHdl = BreakPointExcHdl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
disconnect_rdbg_exception ()
|
||||
{
|
||||
/*
|
||||
* test if current execption handler is rdbg's one
|
||||
* and restore the original one in this case.
|
||||
*/
|
||||
if (globalExceptHdl == BreakPointExcHdl) {
|
||||
globalExceptHdl = oldExcHandler;
|
||||
}
|
||||
}
|
||||
@@ -1,328 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component =
|
||||
*
|
||||
* Synopsis = rkdb/rkdb.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/rdbg_f.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
|
||||
extern rtems_id serializeSemId;
|
||||
extern rtems_id wakeupEventSemId;
|
||||
extern rtems_id eventTaskId;
|
||||
extern rtems_id debugId;
|
||||
extern Exception_context *FirstCtx;
|
||||
extern Exception_context *LastCtx;
|
||||
extern CPU_Exception_frame SavedContext;
|
||||
extern unsigned int NbExceptCtx;
|
||||
|
||||
/*
|
||||
* return a pointer to the Thread Control structure of the specified
|
||||
* Id
|
||||
*/
|
||||
|
||||
Thread_Control *
|
||||
Thread_Get_RDBG (Objects_Id Id)
|
||||
{
|
||||
unsigned index;
|
||||
|
||||
if (Id < _Objects_Information_table[OBJECTS_CLASSIC_API][1]->maximum_id &&
|
||||
Id > _Objects_Information_table[OBJECTS_CLASSIC_API][1]->minimum_id) {
|
||||
|
||||
index = Id - _Objects_Information_table[OBJECTS_CLASSIC_API][1]->minimum_id;
|
||||
if (_Objects_Information_table[OBJECTS_CLASSIC_API][1]->local_table[1 + index] != NULL) {
|
||||
return (Thread_Control*) (_Objects_Information_table[OBJECTS_CLASSIC_API][1]->local_table[1 + index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (Id < _Objects_Information_table[OBJECTS_POSIX_API][1]->maximum_id &&
|
||||
Id > _Objects_Information_table[OBJECTS_POSIX_API][1]->minimum_id) {
|
||||
|
||||
index = Id - _Objects_Information_table[OBJECTS_POSIX_API][1]->minimum_id;
|
||||
if (_Objects_Information_table[OBJECTS_POSIX_API][1]->
|
||||
local_table[1 + index] != NULL)
|
||||
return (Thread_Control*) (_Objects_Information_table[OBJECTS_POSIX_API][1]->local_table[1 + index]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
safeMemRead (void *src, void *dest, int nbBytes)
|
||||
{
|
||||
|
||||
/*
|
||||
* safe because if it generates an exception,
|
||||
* it must return normally
|
||||
* TBD
|
||||
*/
|
||||
|
||||
memcpy (dest, src, nbBytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
safeMemWrite (void *src, void *dest, int nbBytes)
|
||||
{
|
||||
|
||||
/*
|
||||
* safe because if it generates an exception,
|
||||
* it must return normally
|
||||
* TBD
|
||||
*/
|
||||
|
||||
memcpy (dest, src, nbBytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ptrace (int request, int pid, char *addr, int data, char *addr2)
|
||||
{
|
||||
int diag;
|
||||
errno = 0;
|
||||
if (pid != 1) {
|
||||
errno = ESRCH;
|
||||
return -1;
|
||||
}
|
||||
switch (request) {
|
||||
|
||||
case RPT_SINGLESTEP:{
|
||||
Exception_context *ctx;
|
||||
|
||||
if (CannotRestart == 1) {
|
||||
setErrno (EIO);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
|
||||
Single_Step (ctx->ctx);
|
||||
rtems_semaphore_release (ctx->semaphoreId);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case RPT_PEEKTEXT:
|
||||
case RPT_PEEKDATA:{
|
||||
diag = safeMemRead (addr, &data, sizeof data);
|
||||
if (diag == 0)
|
||||
return data;
|
||||
mem_error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
case RPT_POKETEXT:{
|
||||
diag = safeMemWrite (&data, addr, sizeof data);
|
||||
|
||||
/*
|
||||
* We must flush the INSTR and DATA cache to be sure the
|
||||
* opcode modification is taken into account, because
|
||||
* the breakpoint opcode is written via the data cache
|
||||
* while execution code is fetched via the instruction
|
||||
* cache
|
||||
*/
|
||||
|
||||
if (diag == 0) {
|
||||
copyback_data_cache_and_invalidate_instr_cache(
|
||||
(unsigned char *)addr, sizeof data);
|
||||
return 0;
|
||||
}
|
||||
goto mem_error;
|
||||
}
|
||||
case RPT_POKEDATA:{
|
||||
diag = safeMemWrite (&data, addr, sizeof data);
|
||||
if (diag == 0)
|
||||
return 0;
|
||||
goto mem_error;
|
||||
}
|
||||
case RPT_CONT:{
|
||||
Exception_context *ctx;
|
||||
|
||||
if (CannotRestart == 1) {
|
||||
setErrno (EIO);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx = GetExceptCtx (currentTargetThread);
|
||||
if (ctx == NULL)
|
||||
ctx = GetExceptCtx (debugId);
|
||||
|
||||
if (ctx != NULL) {
|
||||
|
||||
if (!isRdbgException (ctx)) {
|
||||
CannotRestart = 1;
|
||||
setErrno (EIO);
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert (data == 0);
|
||||
assert (ExitForSingleStep == 0);
|
||||
|
||||
rtems_semaphore_release (ctx->semaphoreId);
|
||||
}
|
||||
rtems_semaphore_release (serializeSemId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case RPT_ATTACH:
|
||||
return 0;
|
||||
|
||||
case RPT_DETACH:{
|
||||
Exception_context *ctx;
|
||||
|
||||
if (NbExceptCtx || NbSerializedCtx) {
|
||||
ctx = FirstCtx;
|
||||
rtems_task_delete (eventTaskId);
|
||||
rtems_semaphore_delete (serializeSemId);
|
||||
rtems_semaphore_delete (wakeupEventSemId);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case RPT_GETREGS:{
|
||||
Exception_context *ctx;
|
||||
|
||||
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
|
||||
CtxToRegs (ctx->ctx, (xdr_regs *) addr);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case RPT_SETREGS:{
|
||||
Exception_context *ctx;
|
||||
|
||||
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
|
||||
RegsToCtx ((xdr_regs *) addr, ctx->ctx);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case RPT_READTEXT:
|
||||
case RPT_READDATA:{
|
||||
diag = safeMemRead (addr, addr2, data);
|
||||
if (diag == 0)
|
||||
return 0;
|
||||
goto mem_error;
|
||||
}
|
||||
case RPT_WRITETEXT:
|
||||
case RPT_WRITEDATA:{
|
||||
diag = safeMemWrite (addr2, addr, data);
|
||||
if (diag == 0)
|
||||
return 0;
|
||||
goto mem_error;
|
||||
}
|
||||
|
||||
case RPT_GETTARGETTHREAD:
|
||||
if (!NbExceptCtx) {
|
||||
errno = EBUSY;
|
||||
return -1;
|
||||
}
|
||||
return currentTargetThread;
|
||||
|
||||
case RPT_SETTARGETTHREAD:
|
||||
if (!NbExceptCtx) {
|
||||
errno = EBUSY;
|
||||
return -1;
|
||||
}
|
||||
currentTargetThread = data;
|
||||
return 0;
|
||||
|
||||
case RPT_GETTHREADNAME:{
|
||||
return TgtGetThreadName (NULL, (unsigned) (data), (char *) addr);
|
||||
}
|
||||
|
||||
case RPT_THREADLIST:{
|
||||
int count = TgtThreadList (NULL, (unsigned *) addr, UTHREAD_MAX
|
||||
* sizeof (unsigned));
|
||||
if (count < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
case RPT_SETTHREADREGS:{
|
||||
Exception_context *ctx;
|
||||
CPU_Exception_frame Ectx;
|
||||
Thread_Control *thread;
|
||||
rtems_id id;
|
||||
|
||||
rtems_task_ident (RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
|
||||
if (data == (unsigned) id)
|
||||
break;
|
||||
|
||||
if ((ctx = GetExceptCtx (data)) != NULL) {
|
||||
RegsToCtx ((xdr_regs *) addr, ctx->ctx);
|
||||
return 0;
|
||||
}
|
||||
thread = Thread_Get_RDBG ((Objects_Id) (data));
|
||||
if (thread != NULL) {
|
||||
RegsToCtx ((xdr_regs *) addr, &Ectx);
|
||||
set_ctx_thread (thread, &Ectx);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case RPT_GETTHREADREGS:{
|
||||
Exception_context *ctx;
|
||||
CPU_Exception_frame Ectx;
|
||||
Thread_Control *thread;
|
||||
rtems_id id;
|
||||
|
||||
rtems_task_ident (RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
|
||||
if (data == (unsigned) id) {
|
||||
justSaveContext = 1;
|
||||
enterRdbg ();
|
||||
CtxToRegs (&(SavedContext), (xdr_regs *) addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ctx = GetExceptCtx (data)) != NULL) {
|
||||
CtxToRegs (ctx->ctx, (xdr_regs *) addr);
|
||||
return 0;
|
||||
}
|
||||
thread = Thread_Get_RDBG ((Objects_Id) (data));
|
||||
if (thread != NULL) {
|
||||
get_ctx_thread (thread, &Ectx);
|
||||
CtxToRegs (&Ectx, (xdr_regs *) addr);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case RPT_KILL:
|
||||
TotalReboot = 1;
|
||||
return 0;
|
||||
|
||||
case RPT_TRACEME:
|
||||
case RPT_PEEKUSER:
|
||||
case RPT_POKEUSER:
|
||||
case RPT_GETFPREGS:
|
||||
case RPT_SETFPREGS:
|
||||
case RPT_GETFPAREGS:
|
||||
case RPT_SETFPAREGS:
|
||||
case RPT_SYSCALL:
|
||||
case RPT_DUMPCORE:
|
||||
case RPT_GETUCODE:
|
||||
case RPT_THREADSUSPEND:
|
||||
case RPT_THREADRESUME:
|
||||
case RPT_SETTHREADNAME:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component =
|
||||
*
|
||||
* Synopsis = rdbg.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
#include <rtems/rtems_bsdnet.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
u_short rtemsPort = RTEMS_PORT;
|
||||
int BackPort = RTEMS_BACK_PORT;
|
||||
int rtemsActive = 0;
|
||||
SVCXPRT *rtemsXprt;
|
||||
int rtemsSock;
|
||||
char taskName[] = "RTEMS rdbg daemon";
|
||||
volatile int ExitForSingleStep = 0;
|
||||
volatile int Continue;
|
||||
volatile int justSaveContext;
|
||||
volatile Objects_Id currentTargetThread;
|
||||
volatile int CannotRestart = 0;
|
||||
volatile int TotalReboot = 0;
|
||||
int CONN_LIST_INC = 3;
|
||||
int PID_LIST_INC = 1;
|
||||
int TSP_RETRIES = 10;
|
||||
|
||||
int
|
||||
getId ()
|
||||
{
|
||||
rtems_id id;
|
||||
|
||||
rtems_task_ident (RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
|
||||
return (int) (id);
|
||||
}
|
||||
|
||||
static int
|
||||
rdbgInit (void)
|
||||
{
|
||||
int sock;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock == -1) {
|
||||
printf ("%s: rdbgInit: cannot allocate socket\n", taskName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset ((void *) &addr, 0, sizeof (struct sockaddr_in));
|
||||
addr.sin_port = htons (rtemsPort);
|
||||
if ((bind (sock, (struct sockaddr *) &addr, sizeof (addr))) == -1) {
|
||||
printf ("%s: rdbgInit: cannot bind socket\n", taskName);
|
||||
return -2;
|
||||
}
|
||||
rtemsXprt = svcudp_create (sock);
|
||||
if (svcudp_enablecache (rtemsXprt, 1) == 0) {
|
||||
printf ("%s: rdbgInit: cannot enable rpc cache\n", taskName);
|
||||
return -3;
|
||||
}
|
||||
rtemsSock = sock;
|
||||
if (!svc_register (rtemsXprt, REMOTEDEB, REMOTEVERS, remotedeb_2, 0)) {
|
||||
fprintf (stderr, "unable to register (REMOTEDEB, REMOTEVERS, udp).");
|
||||
return -4;
|
||||
}
|
||||
connect_rdbg_exception ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
rtems_task
|
||||
rdbgDaemon (rtems_task_argument argument)
|
||||
{
|
||||
svc_run ();
|
||||
}
|
||||
|
||||
void
|
||||
rtems_rdbg_initialize (void)
|
||||
{
|
||||
rtems_name task_name;
|
||||
rtems_id tid;
|
||||
rtems_status_code status;
|
||||
|
||||
#ifdef DDEBUG
|
||||
rdb_debug = 1; /* DPRINTF now will display */
|
||||
#endif
|
||||
|
||||
DPRINTF (("%s init starting\n", taskName));
|
||||
|
||||
/*
|
||||
* Print version string
|
||||
*/
|
||||
#ifdef DDEBUG
|
||||
printk ("RDBG v.%d built on [%s %s]\n", SERVER_VERS, __DATE__, __TIME__);
|
||||
#else
|
||||
printk ("RDBG v.%d\n", SERVER_VERS);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create socket and init UDP RPC server
|
||||
*/
|
||||
if (rdbgInit () != 0)
|
||||
goto error;
|
||||
|
||||
Continue = 1;
|
||||
justSaveContext = 0;
|
||||
currentTargetThread = 0;
|
||||
|
||||
task_name = rtems_build_name ('R', 'D', 'B', 'G');
|
||||
if ((status = rtems_task_create (task_name, 5, 24576,
|
||||
RTEMS_INTERRUPT_LEVEL (0),
|
||||
RTEMS_DEFAULT_ATTRIBUTES |
|
||||
RTEMS_SYSTEM_TASK, &tid))
|
||||
!= RTEMS_SUCCESSFUL) {
|
||||
printf ("status = %d\n", status);
|
||||
rtems_panic ("Can't create task.\n");
|
||||
}
|
||||
|
||||
status = rtems_task_start (tid, rdbgDaemon, 0);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
printf ("initialization failed.\n");
|
||||
}
|
||||
|
||||
void
|
||||
setErrno (int error)
|
||||
{
|
||||
errno = error;
|
||||
}
|
||||
|
||||
int
|
||||
getErrno ()
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
@@ -1,511 +0,0 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* Component: RDBG servers
|
||||
* Module: remdeb.x
|
||||
*
|
||||
* Synopsis: XDR definitions for remote debug server RPC calls.
|
||||
* XDR definitions for RPCGEN to build remote debug server.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifdef RPC_SVC
|
||||
%/*HEADER_START*/
|
||||
#endif
|
||||
|
||||
%#define RTEMS_PORT 2071
|
||||
%#define RTEMS_BACK_PORT 2073
|
||||
|
||||
#ifdef RPC_HDR
|
||||
%#ifndef REMDEB_H
|
||||
%#define RPCGENSRVNAME(a) a
|
||||
#endif
|
||||
|
||||
enum rpc_type {
|
||||
SUNRPC = 0,
|
||||
BADRPCTYPE = 25
|
||||
};
|
||||
|
||||
|
||||
const NET_SAFE = 1400; /* this is safe for UDP messages */
|
||||
|
||||
struct UDP_MSG
|
||||
{ /* format of UDP messages (should be in .h) */
|
||||
unsigned char type; /* type of message (BMSG_xx) */
|
||||
unsigned char msg_num; /* ringed number for resend detect */
|
||||
unsigned short spec; /* specific information for type */
|
||||
long pid; /* process this affects */
|
||||
unsigned long context; /* specific information to request */
|
||||
};
|
||||
|
||||
/* First we support the overhead structures and types needed for RPC
|
||||
requests. Then, we have all RPC routines input/output args. */
|
||||
|
||||
%/*
|
||||
% * Sun request values for the remote ptrace system call
|
||||
% */
|
||||
%
|
||||
enum ptracereq
|
||||
{ /* these match PTRACE_xxx numbers */
|
||||
RPT_TRACEME = 0, /* 0, by tracee to begin tracing */
|
||||
RPT_CHILDDONE = 0, /* 0, tracee is done with his half */
|
||||
RPT_PEEKTEXT, /* 1, read word from text segment */
|
||||
RPT_PEEKDATA, /* 2, read word from data segment */
|
||||
RPT_PEEKUSER, /* 3, read word from user struct */
|
||||
RPT_POKETEXT, /* 4, write word into text segment */
|
||||
RPT_POKEDATA, /* 5, write word into data segment */
|
||||
RPT_POKEUSER, /* 6, write word into user struct */
|
||||
RPT_CONT, /* 7, continue process */
|
||||
RPT_KILL, /* 8, terminate process */
|
||||
RPT_SINGLESTEP, /* 9, single step process */
|
||||
RPT_ATTACH, /* 10, attach to an existing process (returns 2 if not primary)*/
|
||||
RPT_DETACH, /* 11, detach from a process */
|
||||
RPT_GETREGS, /* 12, get all registers */
|
||||
RPT_SETREGS, /* 13, set all registers */
|
||||
RPT_GETFPREGS, /* 14, get all floating point regs */
|
||||
RPT_SETFPREGS, /* 15, set all floating point regs */
|
||||
RPT_READDATA, /* 16, read data segment */
|
||||
RPT_WRITEDATA, /* 17, write data segment */
|
||||
RPT_READTEXT, /* 18, read text segment */
|
||||
RPT_WRITETEXT, /* 19, write text segment */
|
||||
RPT_GETFPAREGS, /* 20, get all fpa regs */
|
||||
RPT_SETFPAREGS, /* 21, set all fpa regs */
|
||||
RPT_22, /* 22, filler */
|
||||
RPT_23, /* 23, filler */
|
||||
RPT_SYSCALL, /* 24, trap next sys call */
|
||||
RPT_DUMPCORE, /* 25, dump process core */
|
||||
RPT_26, /* 26, filler */
|
||||
RPT_27, /* 27, filler */
|
||||
RPT_28, /* 28, filler */
|
||||
RPT_GETUCODE, /* 29, get u.u_code */
|
||||
/* Begin specific ptrace options */
|
||||
RPT_GETTARGETTHREAD = 50, /* get PM target thread identifier */
|
||||
RPT_SETTARGETTHREAD = 51, /* set PM target thread identifier */
|
||||
RPT_THREADSUSPEND = 52, /* suspend a thread */
|
||||
RPT_THREADRESUME = 53, /* resume a thread */
|
||||
RPT_THREADLIST = 54, /* get list of process's threads */
|
||||
RPT_GETTHREADNAME = 55, /* get the name of the thread */
|
||||
RPT_SETTHREADNAME = 56, /* set the name of the thread */
|
||||
RPT_SETTHREADREGS = 57, /* set all registers for a specific thread*/
|
||||
RPT_GETTHREADREGS = 58, /* get all registers for a specific thread*/
|
||||
/* Begin extended ptrace options for remote debug server */
|
||||
RPT_STEPRANGE = 75, /* step while in range (addr=start, data=len) */
|
||||
RPT_CONTTO = 76, /* cont from PC to temp break in addr */
|
||||
RPT_SETBREAK = 77, /* set a breakpoint (addr=break) */
|
||||
RPT_CLRBREAK = 78, /* clear a breakpoint (data=handle or 0 for all) */
|
||||
RPT_GETBREAK = 79, /* get breakpoint (data=handle, addr=buffer to
|
||||
fill). Returns next break. If data=0,
|
||||
returns number of breaks. */
|
||||
RPT_GETNAME = 80, /* get name of process (data 0=name, 1=path
|
||||
as started, 2=fullpath). Return in addr
|
||||
as mem) */
|
||||
RPT_STOP = 81, /* (C-actors) Stop the C-actor */
|
||||
RPT_PGETREGS = 82, /* portable version */
|
||||
RPT_PSETREGS = 83, /* portable version */
|
||||
RPT_PSETTHREADREGS = 84, /* portable version */
|
||||
RPT_PGETTHREADREGS = 85 /* portable version */
|
||||
};
|
||||
|
||||
#include FRONTEND
|
||||
|
||||
const MAXDEBUGGEE= 150;
|
||||
const NAMEMAX = 17;
|
||||
|
||||
% /*
|
||||
% * Memory data for read/write text or data. The size is in data. The target
|
||||
% * addr is in the addr field.
|
||||
% * Be careful before modifying because this value goes into internal
|
||||
% * pipes and is allocated on stack too. Pipes and/or the stack could
|
||||
% * become too small if this value gets incremented.
|
||||
% */
|
||||
|
||||
const MEM_DATA_MAX = 256;
|
||||
|
||||
#ifndef RPC_XDR
|
||||
|
||||
struct xdr_mem {
|
||||
u_long addr;
|
||||
u_int dataNb;
|
||||
unsigned char data[MEM_DATA_MAX];
|
||||
};
|
||||
|
||||
#else
|
||||
/* manually define best XDR function for this */
|
||||
%bool_t xdr_xdr_mem(xdrs, objp)
|
||||
% XDR *xdrs;
|
||||
% struct xdr_mem *objp;
|
||||
%{
|
||||
% if (!xdr_u_long(xdrs, &objp->addr)) {
|
||||
% return (FALSE);
|
||||
% }
|
||||
% if (!xdr_u_int(xdrs, &objp->dataNb)) {
|
||||
% return(FALSE);
|
||||
% }
|
||||
% return (xdr_opaque(xdrs, objp->data, objp->dataNb));
|
||||
%}
|
||||
|
||||
#endif
|
||||
|
||||
/* Breakpoint structure maps to same structure on host. Do not change one
|
||||
without changing the other. */
|
||||
|
||||
enum break_type
|
||||
{ /* types of breakpoints */
|
||||
BRKT_NONE, /* unused entry */
|
||||
BRKT_INSTR, /* general instruction break */
|
||||
BRKT_READ, /* read break */
|
||||
BRKT_WRITE, /* write breakpoint */
|
||||
BRKT_ACCESS, /* read-or-write break */
|
||||
BRKT_EXEC, /* execution HW breakpoint */
|
||||
BRKT_OS_CALL, /* break on OS call, addr is call number */
|
||||
BRKT_OS_SWITCH, /* dispatch breakpoint */
|
||||
BRKT_STEPEMUL /* emulate hardware single-step */
|
||||
};
|
||||
const MAX_THRD_BRK = 4; /* enough for 128 threads per process */
|
||||
struct xdr_break
|
||||
{ /* one per process local breakpoint */
|
||||
u_char type; /* BRKT_xxx type of break */
|
||||
u_char thread_spec; /* 0=all, else count of threads it affects */
|
||||
u_short handle; /* handle of breakpoint returned */
|
||||
u_long ee_loc; /* address of start */
|
||||
u_long ee_type; /* type/method of address */
|
||||
u_short length; /* length of break if range, else 0 */
|
||||
u_char pass_count; /* pass count to initialize to (0=none) */
|
||||
u_char curr_pass; /* pass count current value */
|
||||
u_long thread_list[MAX_THRD_BRK]; /* bit map for thread list */
|
||||
}; /* 20 bytes+4 per thread_list (4x4=16) = 36 */
|
||||
|
||||
const UTHREAD_MAX = 64;
|
||||
|
||||
const THREADNAMEMAX = 16;
|
||||
typedef string thread_name <THREADNAMEMAX>;
|
||||
|
||||
struct KernThread {
|
||||
unsigned int threadLi;
|
||||
};
|
||||
|
||||
#ifndef RPC_XDR
|
||||
|
||||
#ifdef RPC_HDR
|
||||
%typedef KernThread *ptThreadList;
|
||||
#endif
|
||||
|
||||
struct thread_list {
|
||||
unsigned int nbThread;
|
||||
ptThreadList threads;
|
||||
};
|
||||
|
||||
#else /* RPC_XDR */
|
||||
|
||||
/* must write this function by hand */
|
||||
|
||||
%bool_t xdr_thread_list(xdrs, objp)
|
||||
% XDR *xdrs;
|
||||
% struct thread_list *objp;
|
||||
%{
|
||||
% return (xdr_array(xdrs, (char**)&objp->threads, &objp->nbThread,
|
||||
% UTHREAD_MAX, sizeof(KernThread), xdr_KernThread));
|
||||
%}
|
||||
|
||||
#endif /* not RPC_XDR */
|
||||
|
||||
|
||||
union ptrace_addr_data_in switch (ptracereq req) {
|
||||
/*
|
||||
* due to rpcgen poor features, we cannot put RPC_SETREGS
|
||||
* AND RPC_SETTHREADREGS in the case list. So we use a hack (FIX rpcgen).
|
||||
*/
|
||||
#ifndef RPC_HDR
|
||||
case RPT_SETTHREADREGS :
|
||||
xdr_regs regs;
|
||||
#endif
|
||||
case RPT_SETREGS:
|
||||
|
||||
xdr_regs regs;
|
||||
|
||||
#ifndef RPC_HDR
|
||||
case RPT_PSETTHREADREGS:
|
||||
u_int pregs<>;
|
||||
#endif
|
||||
case RPT_PSETREGS:
|
||||
u_int pregs<>;
|
||||
|
||||
#ifdef LATER
|
||||
case RPT_SETFPREGS:
|
||||
xdr_fp_status fpregs;
|
||||
#endif
|
||||
case RPT_SETTHREADNAME:
|
||||
thread_name name;
|
||||
#ifndef RPC_HDR
|
||||
case RPT_WRITETEXT:
|
||||
xdr_mem mem;
|
||||
#endif
|
||||
case RPT_WRITEDATA:
|
||||
xdr_mem mem;
|
||||
case RPT_SETBREAK:
|
||||
xdr_break breakp;
|
||||
default:
|
||||
u_int address;
|
||||
};
|
||||
|
||||
union ptrace_addr_data_out switch (ptracereq req) {
|
||||
case RPT_GETREGS:
|
||||
xdr_regs regs;
|
||||
#ifndef RPC_HDR
|
||||
case RPT_GETTHREADREGS:
|
||||
xdr_regs regs;
|
||||
#endif
|
||||
|
||||
case RPT_PGETREGS:
|
||||
u_int pregs<>;
|
||||
|
||||
#ifndef RPC_HDR
|
||||
case RPT_PGETTHREADREGS:
|
||||
u_int pregs<>;
|
||||
#endif
|
||||
|
||||
#ifdef LATER
|
||||
case RPT_GETFPREGS:
|
||||
xdr_fp_status fpregs;
|
||||
#endif
|
||||
case RPT_THREADLIST:
|
||||
thread_list threads;
|
||||
case RPT_GETTHREADNAME:
|
||||
thread_name name;
|
||||
#ifndef RPC_HDR
|
||||
case RPT_READTEXT:
|
||||
xdr_mem mem;
|
||||
case RPT_GETNAME:
|
||||
xdr_mem mem;
|
||||
#endif
|
||||
case RPT_READDATA:
|
||||
xdr_mem mem;
|
||||
case RPT_GETBREAK:
|
||||
xdr_break breakp;
|
||||
default:
|
||||
u_int addr;
|
||||
};
|
||||
|
||||
typedef opaque CHAR_DATA <NET_SAFE>; /* variable sized data */
|
||||
|
||||
typedef string one_arg <NET_SAFE>;
|
||||
|
||||
% /* now open_connex() routine which establishes a connection to server */
|
||||
|
||||
enum debug_type
|
||||
{ /* type of connection requested */
|
||||
DEBTYP_PROCESS = 0, /* process connection */
|
||||
DEBTYP_C_ACTOR = 1, /* C-Actor connection */
|
||||
DEBTYP_KERNEL = 2, /* kernel debug connection */
|
||||
DEBTYP_OTHER = 3 /* other subsystem */
|
||||
};
|
||||
|
||||
%#define DEBUGGER_IS_GDB 0x2 /* */
|
||||
|
||||
struct open_in
|
||||
{ /* input args to open a connection */
|
||||
u_char back_port[16]; /* opaque NET address format */
|
||||
u_short debug_type; /* type of process DEBTYP_xxx */
|
||||
u_short flags; /* connection information OPNFLG_xxx */
|
||||
u_char destination[16];/* opaque address if to router */
|
||||
one_arg user_name; /* name of user on host */
|
||||
};
|
||||
|
||||
struct open_out
|
||||
{ /* return from open_connex */
|
||||
u_long port; /* connection number to server or -1 if error */
|
||||
u_int pad[4]; /* Planned to be KnIpcDest. Never used */
|
||||
u_int fp; /* True if floating point processor. If error,
|
||||
set to errno for open error. */
|
||||
u_char cmd_table_num; /* command table used */
|
||||
u_char cmd_table_vers; /* version of command table */
|
||||
u_short server_vers; /* version number of server itself */
|
||||
};
|
||||
|
||||
% /* now close_connex() routine which detaches from server */
|
||||
|
||||
enum close_control
|
||||
{ /* choice of how to handle owned processes */
|
||||
CLOSE_IGNORE = 0, /* ignore all controlled pids on close */
|
||||
CLOSE_KILL = 1, /* kill all controlled pids on close */
|
||||
CLOSE_DETACH = 2 /* detach free running all controlled pids */
|
||||
};
|
||||
|
||||
struct close_in
|
||||
{ /* arg to close connection */
|
||||
close_control control; /* shutdown of owned processes control */
|
||||
};
|
||||
|
||||
% /* now send_signal() routine which sends signals to processes like kill(2) */
|
||||
|
||||
struct signal_in
|
||||
{ /* input to send_signal */
|
||||
int pid; /* process/actor to send signal to */
|
||||
int sig; /* signal to send (from /usr/include/signal.h) */
|
||||
};
|
||||
|
||||
struct signal_out
|
||||
{ /* return from send_signal */
|
||||
int kill_return; /* return code from kill(2) call */
|
||||
int errNo; /* error code if failed */
|
||||
};
|
||||
|
||||
|
||||
% /* now wait_info() routine which returns results of polling the wait status
|
||||
% of a process/actor. It may return 0 if running, else pid or -1 */
|
||||
|
||||
enum stop_code
|
||||
{ /* stop code information */
|
||||
STOP_ERROR = 0, /* error, errno set */
|
||||
STOP_NONE = 1, /* not stopped */
|
||||
STOP_UNKNOWN = 2, /* unknown stop reason */
|
||||
STOP_BREAK = 3, /* stopped on breakpoint */
|
||||
STOP_STEP = 4, /* stopped on step */
|
||||
STOP_SIGNAL = 5, /* stopped on signal receieve */
|
||||
STOP_TERM_EXIT = 6, /* terminated normally */
|
||||
STOP_TERM_SIG = 7, /* terminated by signal */
|
||||
STOP_DETACHED = 8, /* detached from server */
|
||||
STOP_KILLED = 9, /* killed by ptrace KILL */
|
||||
STOP_SPAWN_FAILED = 10 /* spawn failed in exec part, handle=errno */
|
||||
};
|
||||
|
||||
struct wait_in
|
||||
{ /* input arg to wait is process */
|
||||
int pid; /* process/actor id */
|
||||
};
|
||||
|
||||
struct wait_out
|
||||
{ /* result of wait_info call */
|
||||
int wait_return; /* -1=error,0=running,pid=stopped */
|
||||
int errNo; /* error code if error */
|
||||
int status; /* wait(2) status if stopped */
|
||||
stop_code reason; /* reason in more abstracted terms */
|
||||
int handle; /* handle of break if stopped on break,
|
||||
or signal number or exit code */
|
||||
u_long PC; /* program counter if stopped */
|
||||
u_long SP; /* stack pointer if stopped */
|
||||
u_long FP; /* frame pointer if stopped */
|
||||
u_long thread; /* thread that stopped if applies (else -1) */
|
||||
};
|
||||
|
||||
% /* now ptrace() routine. This matches the Sun UNIX ptrace as well as
|
||||
% some additions */
|
||||
|
||||
const PTRFLG_FORCE = 1; /* when set and process running, forces process
|
||||
to stop, make the request, then start again.
|
||||
This is used for breakpoints and the like */
|
||||
const PTRFLG_NON_OWNER = 2; /* do request even if not primary owner (will
|
||||
notify all owners including caller if owns) */
|
||||
const PTRFLG_FREE = 4; /* free pid_list after KILL/DETACH */
|
||||
|
||||
const PTRDET_UNOWN = 0x100; /* data value in RPT_DETACH just disconnects
|
||||
caller as an owner of process. */
|
||||
|
||||
struct ptrace_in
|
||||
{ /* input args matches ptrace but for XDR */
|
||||
int pid; /* process to act on */
|
||||
ptrace_addr_data_in addr; /* mappings for addr and addr2 */
|
||||
u_int data; /* simple data arg of ptrace */
|
||||
u_int flags; /* mask of PTRFLG_xxx flags. */
|
||||
};
|
||||
|
||||
struct ptrace_out
|
||||
{ /* return information from ptrace */
|
||||
ptrace_addr_data_out addr; /* return through addr/addr2 */
|
||||
int result; /* result of ptrace call (return value) */
|
||||
int errNo; /* error code if error */
|
||||
};
|
||||
|
||||
/* Data for GET_GLOBAL_SYMBOLS */
|
||||
struct one_symbol { /* Must match common/src/lib/ctx/ctx.h */
|
||||
string symbolName<>;
|
||||
long symbolValue;
|
||||
};
|
||||
|
||||
typedef one_symbol all_symbols<>;
|
||||
|
||||
struct get_global_symbols_out {
|
||||
all_symbols symbols;
|
||||
};
|
||||
|
||||
/* Data for GET_TEXT_DATA */
|
||||
struct get_text_data_in {
|
||||
int pid; /* process/actor id if non-zero */
|
||||
string actorName<16>; /* actor name for system mode */
|
||||
};
|
||||
|
||||
struct get_text_data_out {
|
||||
int result;
|
||||
int errNo;
|
||||
u_long textStart;
|
||||
u_long textSize;
|
||||
u_long dataStart;
|
||||
u_long dataSize;
|
||||
};
|
||||
|
||||
/* Data for GET_SIGNAL_NAMES */
|
||||
struct one_signal {
|
||||
u_int number;
|
||||
string name<>;
|
||||
};
|
||||
|
||||
typedef one_signal all_signals<>;
|
||||
|
||||
struct get_signal_names_out {
|
||||
all_signals signals;
|
||||
};
|
||||
|
||||
% /* now define the actual calls we support */
|
||||
|
||||
program REMOTEDEB {
|
||||
version REMOTEVERS {
|
||||
|
||||
/* open a connection to server or router */
|
||||
open_out
|
||||
OPEN_CONNEX(open_in) = 1;
|
||||
|
||||
/* send a signal to a process */
|
||||
signal_out
|
||||
SEND_SIGNAL(signal_in) = 2;
|
||||
|
||||
/* all routines below require a connection first */
|
||||
|
||||
/* close the connection to the server */
|
||||
void
|
||||
CLOSE_CONNEX(close_in) = 10;
|
||||
|
||||
/* process ptrace request */
|
||||
ptrace_out
|
||||
PTRACE(ptrace_in) = 11;
|
||||
|
||||
/* poll for status of process */
|
||||
wait_out
|
||||
WAIT_INFO(wait_in) = 13;
|
||||
|
||||
get_signal_names_out
|
||||
GET_SIGNAL_NAMES(void) = 17;
|
||||
|
||||
} = 2; /* now version 2 */
|
||||
} = 0x20000fff;
|
||||
|
||||
#ifdef RPC_HDR
|
||||
%#define REMDEB_H
|
||||
%#endif
|
||||
#endif
|
||||
|
||||
#ifdef RPC_SVC
|
||||
|
||||
%const char* names [] = {
|
||||
% "NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
|
||||
% "name4", "name5", "name6", "name7",
|
||||
% "name8", "name9", "CLOSE_CONNEX", "PTRACE",
|
||||
% "name12", "WAIT_INFO", "name14", "name15",
|
||||
% "name16", "GET_SIGNAL_NAMES", "name18"
|
||||
%};
|
||||
%
|
||||
|
||||
%/*HEADER_END*/
|
||||
#endif
|
||||
@@ -1,644 +0,0 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* Component: RDB servers
|
||||
* Module: servbkpt.c
|
||||
*
|
||||
* Synopsis: Management of breakpoints
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
|
||||
/*----- Macros -----*/
|
||||
|
||||
#define BKPT0(plst) ((BASE_BREAK*)(plst)->break_list)
|
||||
#define BKPT_INCR 5 /* how many bkpt slots alloc at a time */
|
||||
|
||||
#define BKPT_OVER(plst,idx,addr,size) \
|
||||
((plst)->break_list[idx].ee_loc + BREAK_SIZE > (UINT32) (addr) \
|
||||
&& (plst)->break_list[idx].ee_loc < (UINT32) (addr) + (size))
|
||||
|
||||
#define BKPT_SLOTS \
|
||||
(sizeof ((xdr_break*) 0)->thread_list / \
|
||||
sizeof ((xdr_break*) 0)->thread_list [0])
|
||||
|
||||
/*
|
||||
* BreakAlloc - alloc a breakpoint entry.
|
||||
*
|
||||
* This is a generic routine to insert an entry in the
|
||||
* breakpoint list. It returns the number of entry just
|
||||
* created. It returns -1 if failed.
|
||||
*/
|
||||
|
||||
static int
|
||||
BreakAlloc (PID_LIST * plst, Boolean normal)
|
||||
{
|
||||
int idx, len;
|
||||
xdr_break *blst;
|
||||
|
||||
if (!normal) { /* want 0 entry */
|
||||
if (plst->break_list) {
|
||||
return (0); /* already there */
|
||||
}
|
||||
idx = 1; /* force alloc below */
|
||||
} else {
|
||||
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
|
||||
if (plst->break_list[idx].type == BRKT_NONE) {
|
||||
/*
|
||||
* got a free one
|
||||
*/
|
||||
memset (&plst->break_list[idx], 0, sizeof (xdr_break));
|
||||
return (idx); /* found one */
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* idx is the requested entry
|
||||
*/
|
||||
|
||||
if (idx >= (int) plst->break_alloc) { /* need more space */
|
||||
len = plst->break_alloc + BKPT_INCR;
|
||||
blst = (xdr_break *) Realloc (plst->break_list, len * sizeof (xdr_break));
|
||||
if (!blst) {
|
||||
return (-1); /* failed, no space */
|
||||
}
|
||||
plst->break_alloc = len; /* got more */
|
||||
plst->break_list = blst;
|
||||
|
||||
/*
|
||||
* Clear new space
|
||||
*/
|
||||
memset (blst + len - BKPT_INCR, 0, BKPT_INCR * sizeof (xdr_break));
|
||||
idx = len - BKPT_INCR; /* next available */
|
||||
if (!idx) {
|
||||
idx = 1; /* for normal cases */
|
||||
}
|
||||
}
|
||||
return (normal ? idx : 0); /* return it */
|
||||
}
|
||||
|
||||
/*
|
||||
* BreakSet - set a breakpoint in process
|
||||
*
|
||||
* Returns the number or -1/errno.
|
||||
*/
|
||||
|
||||
#ifdef DDEBUG
|
||||
static const char *BreakTypes[] = {
|
||||
"NONE", "INSTR", "READ", "WRITE",
|
||||
"ACCESS", "EXEC", "OS_CALL", "OS_SWITCH",
|
||||
"STEPEMUL"
|
||||
};
|
||||
|
||||
#define BN_MAX (sizeof BreakTypes / sizeof BreakTypes[0])
|
||||
#define BREAK_NAME(t) ((unsigned) (t) < BN_MAX ? BreakTypes[t] : "???")
|
||||
#endif
|
||||
|
||||
int
|
||||
BreakSet (PID_LIST * plst, int conn_idx, xdr_break * bkpt)
|
||||
{
|
||||
int pid = plst->pid;
|
||||
int type = bkpt->type;
|
||||
void *addr = (void *) bkpt->ee_loc;
|
||||
int idx;
|
||||
int data;
|
||||
|
||||
DPRINTF (("BreakSet: type %d (%s) at 0x%x th %d ee_type %d len %d "
|
||||
"pass %d curr %d list %d %d %d %d\n", type, BREAK_NAME (type),
|
||||
(int) addr,
|
||||
bkpt->thread_spec, bkpt->ee_type, bkpt->length, bkpt->pass_count,
|
||||
bkpt->curr_pass, bkpt->thread_list[0], bkpt->thread_list[1],
|
||||
bkpt->thread_list[2], bkpt->thread_list[3]));
|
||||
|
||||
idx = BreakAlloc (plst, True); /* get entry */
|
||||
if (idx < 0) { /* no memory */
|
||||
setErrno (ENOMEM); /* set for safety */
|
||||
return -1; /* return the error */
|
||||
}
|
||||
|
||||
data = TgtPtrace (RPT_PEEKTEXT, pid, addr, 0, NULL); /* current */
|
||||
if (getErrno ()) {
|
||||
return -1; /* failed, return the error */
|
||||
}
|
||||
if (IS_BREAK (data)) { /* There is already a break here */
|
||||
DPRINTF (("BreakSet: already have soft bkpt at %x\n", addr));
|
||||
if (type == BRKT_STEPEMUL) {
|
||||
++BKPT0 (plst)->pad1;
|
||||
return 1; /* Any non-error value is OK */
|
||||
}
|
||||
setErrno (EBUSY);
|
||||
return -1;
|
||||
}
|
||||
|
||||
TgtPtrace (RPT_POKETEXT, pid, addr, SET_BREAK (data), NULL);
|
||||
|
||||
if (getErrno ()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
plst->break_list[idx] = *bkpt;
|
||||
plst->break_list[idx].ee_type = data; /* saved data */
|
||||
|
||||
/*
|
||||
* Inform other owners
|
||||
*/
|
||||
if (type != BRKT_STEPEMUL) {
|
||||
TgtNotifyAll (plst - pid_list, BMSG_BREAK, 1 /*added */ , idx,
|
||||
conn_idx, False);
|
||||
} else {
|
||||
++BKPT0 (plst)->pad1;
|
||||
}
|
||||
/*
|
||||
* Return the number
|
||||
*/
|
||||
setErrno (0); /* Just in case */
|
||||
return idx;
|
||||
}
|
||||
|
||||
int
|
||||
BreakSetAt (PID_LIST * plst, int conn_idx, unsigned long addr,
|
||||
break_type type)
|
||||
{
|
||||
xdr_break xb;
|
||||
|
||||
memset (&xb, 0, sizeof xb);
|
||||
xb.type = type;
|
||||
xb.ee_loc = addr;
|
||||
return BreakSet (plst, conn_idx, &xb);
|
||||
}
|
||||
|
||||
/*----- Find a breakpoint by address -----*/
|
||||
|
||||
int
|
||||
BreakGetIndex (PID_LIST * plst, void *addr)
|
||||
{
|
||||
int idx;
|
||||
int data = -1;
|
||||
|
||||
if (!plst->break_alloc) {
|
||||
setErrno (EFAULT);
|
||||
return -1;
|
||||
}
|
||||
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
|
||||
if ((u_long) addr == plst->break_list[idx].ee_loc) {
|
||||
data = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/*----- Getting information about breakpoint -----*/
|
||||
|
||||
/*
|
||||
* If data > 0, fill "bkpt" with information about breakpoint
|
||||
* and return the number of the next one.
|
||||
* If data == 0, return the count of breakpoints.
|
||||
*/
|
||||
|
||||
int
|
||||
BreakGet (const PID_LIST * plst, int data, xdr_break * bkpt)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if (!data) { /* just count them */
|
||||
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
|
||||
if (plst->break_list[idx].type != BRKT_NONE) {
|
||||
data++;
|
||||
}
|
||||
}
|
||||
return data; /* count */
|
||||
}
|
||||
if ((unsigned) data >= plst->break_alloc) {
|
||||
/*
|
||||
* out of range
|
||||
*/
|
||||
setErrno (EFAULT); /* closest match */
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* get it and say which is next
|
||||
*/
|
||||
*bkpt = plst->break_list[data];
|
||||
for (idx = (int) data + 1; idx < (int) plst->break_alloc; idx++) {
|
||||
if (plst->break_list[idx].type != BRKT_NONE) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return 0; /* otherwise returns 0 for no more */
|
||||
}
|
||||
|
||||
/*----- Clearing bkpts -----*/
|
||||
|
||||
/*
|
||||
* BreakClear - clear one (if data != 0) or all breakpoints
|
||||
* (if data == 0). Return the number of bkpts cleared.
|
||||
* If (data == -1), remove step-emulation breakpoints.
|
||||
*/
|
||||
|
||||
int
|
||||
BreakClear (PID_LIST * plst, int conn_idx, int data)
|
||||
{
|
||||
int pid_idx = plst - pid_list;
|
||||
int idx;
|
||||
int cleared = 0;
|
||||
int clearStepEmul = 0;
|
||||
int terminated = PROC_TERMINATED (plst);
|
||||
int stepEmulCount = 0;
|
||||
|
||||
/*
|
||||
* break handle in data
|
||||
*/
|
||||
if (!plst->break_alloc) { /* there are no breaks */
|
||||
DPRINTF (("BreakClear: no bkpts defined.\n"));
|
||||
setErrno (EFAULT); /* closest match */
|
||||
return -1; /* return error */
|
||||
}
|
||||
if (!data) { /* clear all */
|
||||
idx = 1;
|
||||
data = plst->break_alloc - 1;
|
||||
|
||||
/*
|
||||
* Inform other owners
|
||||
*/
|
||||
DPRINTF (("BreakClear: clearing all bkpts.\n"));
|
||||
TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr */ , 0, conn_idx, False);
|
||||
|
||||
} else if (data == -1) { /* clear all step-emul bkpts */
|
||||
DPRINTF (("BreakClear: removing %d step-emul bkpts\n",
|
||||
BKPT0 (plst)->pad1));
|
||||
|
||||
stepEmulCount = BKPT0 (plst)->pad1;
|
||||
BKPT0 (plst)->pad1 = 0;
|
||||
|
||||
clearStepEmul = 1;
|
||||
idx = 1;
|
||||
data = plst->break_alloc - 1;
|
||||
} else if ((unsigned) data >= plst->break_alloc
|
||||
|| plst->break_list[data].type == BRKT_NONE) {
|
||||
|
||||
/*
|
||||
* out of range
|
||||
*/
|
||||
DPRINTF (("BreakClear: invalid bkpt %d\n", data));
|
||||
setErrno (EFAULT); /* closest match */
|
||||
return -1; /* return error */
|
||||
} else {
|
||||
idx = data;
|
||||
/*
|
||||
* Inform other owners
|
||||
*/
|
||||
TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr */ , idx, conn_idx, False);
|
||||
DPRINTF (("BreakClear: clearing bkpt %d\n", data));
|
||||
}
|
||||
|
||||
for (; idx <= data; idx++) { /* clear each one */
|
||||
int type = plst->break_list[idx].type;
|
||||
|
||||
if (clearStepEmul && type != BRKT_STEPEMUL)
|
||||
continue;
|
||||
|
||||
if (type == BRKT_INSTR || (clearStepEmul && type == BRKT_STEPEMUL)) {
|
||||
/*
|
||||
* just patch back
|
||||
*/
|
||||
char *addr = (char *) plst->break_list[idx].ee_loc;
|
||||
int val;
|
||||
|
||||
if (BKPT0 (plst)->clr_step && BKPT0 (plst)->last_break == idx) {
|
||||
BKPT0 (plst)->clr_step = 0; /* not needed */
|
||||
}
|
||||
/*
|
||||
* Neighboring bytes can have breakpoints too...
|
||||
*/
|
||||
if (!terminated) {
|
||||
setErrno (0);
|
||||
val = TgtPtrace (RPT_PEEKTEXT, plst->pid, addr, 0, NULL);
|
||||
if (getErrno ()) {
|
||||
DPRINTF (("BreakClear: addr %x not readable!\n", addr));
|
||||
setErrno (0); /* Forget bkpt */
|
||||
} else {
|
||||
assert (IS_BREAK (val));
|
||||
val = ORG_BREAK (val, (int) plst->break_list[idx].ee_type);
|
||||
TgtPtrace (RPT_POKETEXT, plst->pid, addr, val, NULL);
|
||||
if (getErrno ()) {
|
||||
DPRINTF (("BreakClear: addr %x not writable!\n", addr));
|
||||
setErrno (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
++cleared; /* indicate cleared */
|
||||
}
|
||||
memset (&plst->break_list[idx], 0, sizeof (xdr_break));
|
||||
}
|
||||
assert (!clearStepEmul || cleared <= stepEmulCount);
|
||||
if (stepEmulCount && cleared == 0) {
|
||||
DPRINTF (("BreakClear: all STEPEMUL bkpts were shared\n"));
|
||||
return 1;
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
|
||||
/*----- Hiding of breakpoints -----*/
|
||||
|
||||
/*
|
||||
* PatchBreak - patch original data from break into data buffer.
|
||||
*
|
||||
* Notes:
|
||||
* - this routine patches the original data under a break into the data
|
||||
* buffer from a ptrace read/peek.
|
||||
*/
|
||||
|
||||
static void
|
||||
PatchBreak (char *buff, UINT32 bstart, int bsize, UINT32 dstart, char *dvalue)
|
||||
{
|
||||
int size = BREAK_SIZE; /* default size */
|
||||
|
||||
/*
|
||||
* Must deal with all sorts of unalignments
|
||||
* * (3 full overlaps, 3 unaligns)
|
||||
*/
|
||||
if (bsize < BREAK_SIZE) {
|
||||
/*
|
||||
* case where buffer is smaller than data
|
||||
*/
|
||||
memcpy (buff, dvalue + (bstart - dstart), bsize); /* copy over */
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* buffer larger than data.
|
||||
* * we need to see where break fits in buffer and whether
|
||||
* * we have part of it off the end. We set bstart to be the
|
||||
* * buffer offset, dtart to be the break data offset, and
|
||||
* * size to be the amount to copy
|
||||
*/
|
||||
if (dstart < bstart) {
|
||||
/*
|
||||
* break before actual buffer
|
||||
*/
|
||||
dstart = bstart - dstart; /* offset in data */
|
||||
size -= dstart; /* amount to copy */
|
||||
bstart = 0; /* offset in buffer */
|
||||
|
||||
} else if (dstart + size > bstart + bsize) {
|
||||
/*
|
||||
* off end
|
||||
*/
|
||||
bstart += bsize; /* end of buffer */
|
||||
size -= (dstart + size) - bstart;
|
||||
bstart = bsize - size; /* come back into buffer enough */
|
||||
dstart = 0; /* start of data */
|
||||
|
||||
} else { /* normal case */
|
||||
bstart = dstart - bstart; /* offset in buffer */
|
||||
dstart = 0;
|
||||
}
|
||||
memcpy (buff + bstart, dvalue + dstart, size);
|
||||
}
|
||||
|
||||
void
|
||||
BreakHide (const PID_LIST * plst, void *addr, int data, void *addr2)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if (!plst->break_list) /* no breaks exist, so skip this */
|
||||
return;
|
||||
|
||||
/*
|
||||
* if breakpoints, replace
|
||||
*/
|
||||
|
||||
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
|
||||
int type = plst->break_list[idx].type;
|
||||
|
||||
if (type != BRKT_INSTR && type != BRKT_STEPEMUL) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* break, see if overlaps
|
||||
*/
|
||||
if (BKPT_OVER (plst, idx, addr, data)) {
|
||||
|
||||
/*
|
||||
* overlaps, patch in old value
|
||||
*/
|
||||
PatchBreak ((char *) addr2, (UINT32) addr, data,
|
||||
plst->break_list[idx].ee_loc,
|
||||
(char *) &plst->break_list[idx].ee_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----- Checking of breakpoint overwrites -----*/
|
||||
|
||||
/*
|
||||
* BreakOverwrite - check if memory write does not involve addresses
|
||||
* having software breakpoints.
|
||||
*/
|
||||
|
||||
int
|
||||
BreakOverwrite (const PID_LIST * plst, const char *addr, unsigned int size)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if (!plst->break_list) { /* No breaks exist */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
|
||||
int type = plst->break_list[idx].type;
|
||||
|
||||
/*
|
||||
* Consider only breakpoints involving modified memory
|
||||
*/
|
||||
if (type != BRKT_INSTR && type != BRKT_STEPEMUL) {
|
||||
continue;
|
||||
}
|
||||
if (BKPT_OVER (plst, idx, addr, size)) {
|
||||
return -1; /* overlaps */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----- Execution support -----*/
|
||||
|
||||
/*
|
||||
* BreakStepRange - Start stepping in a range.
|
||||
*
|
||||
* Range is saved in breakpoint 0.
|
||||
*/
|
||||
|
||||
int
|
||||
BreakStepRange (PID_LIST * plst, void *addr, int len)
|
||||
{
|
||||
if (!plst->break_list) {
|
||||
/*
|
||||
* get list
|
||||
*/
|
||||
if (BreakAlloc (plst, False) == -1) { /* must not be any memory */
|
||||
setErrno (ENOMEM); /* to be safe */
|
||||
return -1; /* fails */
|
||||
}
|
||||
}
|
||||
BKPT0 (plst)->range_start = (UINT32) addr;
|
||||
BKPT0 (plst)->range_end = (UINT32) addr + (len - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the Program Counter is changed, consider that the
|
||||
* current breakpoint has not been reached yet.
|
||||
*/
|
||||
|
||||
void
|
||||
BreakPcChanged (PID_LIST * plst)
|
||||
{
|
||||
if (plst->break_list) {
|
||||
/*
|
||||
* clear break stuff
|
||||
*/
|
||||
BKPT0 (plst)->clr_step = False;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* BreakStepOff - prepare stepping off a breakpoint.
|
||||
*/
|
||||
|
||||
int
|
||||
BreakStepOff (const PID_LIST * plst, void **paddr2)
|
||||
{
|
||||
if (plst->break_list && BKPT0 (plst)->clr_step) {
|
||||
|
||||
/*
|
||||
* need clear then step off break
|
||||
*/
|
||||
int last = BKPT0 (plst)->last_break;
|
||||
|
||||
/*
|
||||
* clear break, step, then do exec
|
||||
*/
|
||||
|
||||
*paddr2 = (void *) plst->break_list[last].ee_type;
|
||||
|
||||
/*
|
||||
* Need to clr_step after TgtPtrace() when wait() returns
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* BreakSteppedOff - check if just stepped off a breakpoint
|
||||
* and re-insert it into the code.
|
||||
*/
|
||||
|
||||
void
|
||||
BreakSteppedOff (PID_LIST * plst)
|
||||
{
|
||||
if (plst->break_list && BKPT0 (plst)->clr_step) {
|
||||
int idx = BKPT0 (plst)->last_break;
|
||||
int data;
|
||||
|
||||
BKPT0 (plst)->clr_step = 0;
|
||||
|
||||
/*
|
||||
* Re-insert the breakpoint.
|
||||
*/
|
||||
data = TgtPtrace (RPT_PEEKTEXT, plst->pid,
|
||||
(char *) plst->break_list[idx].ee_loc, 0, NULL);
|
||||
assert (!IS_BREAK (data));
|
||||
TgtPtrace (RPT_POKETEXT, plst->pid,
|
||||
(char *) plst->break_list[idx].ee_loc,
|
||||
(int) SET_BREAK (data), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns whether a thread matches a breakpoint.
|
||||
*/
|
||||
|
||||
static int
|
||||
BreakThreadMatch (xdr_break * xb, int thread)
|
||||
{
|
||||
int slot;
|
||||
|
||||
if (thread < 0)
|
||||
return 1; /* Break existence check only */
|
||||
|
||||
if (xb->thread_list[0] == 0)
|
||||
return 1; /* Universal break */
|
||||
|
||||
for (slot = 0; slot < BKPT_SLOTS; ++slot) {
|
||||
if (xb->thread_list[slot] == 0)
|
||||
return 0; /* End of list */
|
||||
if (xb->thread_list[slot] == thread)
|
||||
return 1; /* Match */
|
||||
}
|
||||
return 0; /* No matches found */
|
||||
}
|
||||
|
||||
int
|
||||
BreakAdjustPC (PID_LIST * plst)
|
||||
{
|
||||
/*
|
||||
* BREAK_ADJ is the value by which the Program Counter
|
||||
* has to be decremented after a software breakpoint
|
||||
* is hit. It must be defined and can be zero.
|
||||
*/
|
||||
#if BREAK_ADJ
|
||||
/*
|
||||
* subtract back if necessary
|
||||
*/
|
||||
plst->regs.REG_PC -= BREAK_ADJ; /* now write back */
|
||||
TgtPtrace (RPT_SETREGS, plst->pid, (char *) &plst->regs, 0, NULL);
|
||||
#else
|
||||
(void) plst;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Identify the current breakpoint. The process just stopped.
|
||||
*/
|
||||
|
||||
int
|
||||
BreakIdentify (PID_LIST * plst, int adjust, int thread)
|
||||
{
|
||||
int foreignBkpt = 0;
|
||||
int bidx;
|
||||
|
||||
for (bidx = 1; bidx < (int) plst->break_alloc; bidx++) {
|
||||
int type = plst->break_list[bidx].type;
|
||||
|
||||
if ((type == BRKT_INSTR || type == BRKT_STEPEMUL)
|
||||
&& plst->regs.REG_PC - BREAK_ADJ == plst->break_list[bidx].ee_loc) { /* found matching */
|
||||
if (!BreakThreadMatch (&plst->break_list[bidx], thread)) {
|
||||
if (foreignBkpt == 0) {
|
||||
foreignBkpt = bidx;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (adjust) {
|
||||
BreakAdjustPC (plst);
|
||||
}
|
||||
return bidx;
|
||||
}
|
||||
}
|
||||
if (foreignBkpt) {
|
||||
if (adjust) {
|
||||
BreakAdjustPC (plst);
|
||||
}
|
||||
return -foreignBkpt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component: RDBG
|
||||
* Module: servcon.c
|
||||
*
|
||||
* Synopsis: Management of RPC client connections.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
|
||||
/*
|
||||
* ConnCreate - create a new connection entry for a client.
|
||||
*
|
||||
* This function finds an empty entry in the connection array
|
||||
* or makes space. It fills in the fields that are passed to it.
|
||||
* It does not do any validation on net addresses nor does it
|
||||
* start a validation cycle on other clients. This is done by
|
||||
* the caller.
|
||||
*/
|
||||
|
||||
int
|
||||
ConnCreate (struct svc_req *rqstp, open_in * in)
|
||||
{
|
||||
NET_OPAQUE sender;
|
||||
int idx;
|
||||
CONN_LIST *clst;
|
||||
|
||||
setErrno (0);
|
||||
|
||||
/*
|
||||
* Convert to valid Net address
|
||||
*/
|
||||
if (!TspTranslateRpcAddr (rqstp, &sender)) {
|
||||
DPRINTF (("ConnCreate: TspTranslateRpcAddr failed\n"));
|
||||
return -1;
|
||||
}
|
||||
if (!TspValidateAddr ((NET_OPAQUE *) in->back_port, &sender)) {
|
||||
DPRINTF (("ConnCreate: TspValidateAddr failed\n"));
|
||||
return -1; /* errno now setup with error */
|
||||
}
|
||||
|
||||
/*
|
||||
* look for an empty connection entry
|
||||
*/
|
||||
for (idx = 0; idx < conn_list_cnt; idx++) {
|
||||
if (!conn_list[idx].in_use)
|
||||
break; /* an empty one found */
|
||||
}
|
||||
|
||||
if (idx >= conn_list_cnt) { /* no empties, create space */
|
||||
CONN_LIST *tmp_conn_list = conn_list;
|
||||
|
||||
conn_list_cnt += CONN_LIST_INC;
|
||||
if (conn_list) {
|
||||
conn_list = (CONN_LIST *) Realloc (conn_list, /* extend */
|
||||
conn_list_cnt * sizeof (CONN_LIST));
|
||||
} else {
|
||||
conn_list = (CONN_LIST *) Malloc (conn_list_cnt * sizeof (CONN_LIST));
|
||||
}
|
||||
|
||||
if (!conn_list) { /* unable to get space */
|
||||
if ((conn_list_cnt -= CONN_LIST_INC)) {
|
||||
/*
|
||||
* was realloc, restore space
|
||||
*/
|
||||
conn_list = tmp_conn_list;
|
||||
}
|
||||
return -1; /* errno set by failed alloc */
|
||||
}
|
||||
/*
|
||||
* clear newly created memory
|
||||
*/
|
||||
memset (conn_list + idx, 0, CONN_LIST_INC * sizeof (CONN_LIST));
|
||||
} else { /* clear new entry */
|
||||
memset (conn_list + idx, 0, sizeof (CONN_LIST));
|
||||
}
|
||||
clst = conn_list + idx;
|
||||
|
||||
clst->in_use = True; /* now in use */
|
||||
clst->sender = sender;
|
||||
memcpy (&clst->back_port, &in->back_port, sizeof (NET_OPAQUE));
|
||||
memcpy (&clst->route, &in->destination, sizeof (NET_OPAQUE));
|
||||
clst->debug_type = (UCHAR) in->debug_type;
|
||||
clst->flags = in->flags;
|
||||
strncpy (clst->user_name, in->user_name, NAMEMAX - 1);
|
||||
clst->user_name[NAMEMAX - 1] = 0;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* ConnDelete - remove connection entry when shutdown.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
ConnDelete (int conn, struct svc_req *rqstp, close_control control)
|
||||
{
|
||||
CONN_LIST *clst = conn_list + conn;
|
||||
int idx;
|
||||
Boolean prim;
|
||||
|
||||
if (!clst->in_use)
|
||||
return; /* not active */
|
||||
|
||||
for (idx = 0; idx < pid_list_cnt; idx++) {
|
||||
PID_LIST *plst = pid_list + idx;
|
||||
|
||||
if (!PIDMAP_TEST (conn, idx))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* found a controlled pid
|
||||
*/
|
||||
prim = (plst->primary_conn == conn) ? True : False;
|
||||
TgtDetachCon (conn, idx, True);
|
||||
|
||||
/*
|
||||
* if still running or alive, we use close control on it
|
||||
*/
|
||||
if (!plst->pid)
|
||||
continue; /* entry gone */
|
||||
|
||||
if (prim && control == CLOSE_KILL) {
|
||||
/*
|
||||
* kill off process
|
||||
*/
|
||||
TgtKillAndDelete (plst, rqstp, True);
|
||||
} else if (!plst->owners) {
|
||||
/*
|
||||
* no owners left
|
||||
*/
|
||||
if (control == CLOSE_DETACH) {
|
||||
TgtKillAndDelete (plst, rqstp, False);
|
||||
}
|
||||
if (control == CLOSE_DETACH || PROC_TERMINATED (plst)) {
|
||||
TgtDelete (plst, conn, (control == CLOSE_DETACH) ? BMSG_DETACH : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (clst->list) {
|
||||
Free (clst->list); /* free allocated memory */
|
||||
}
|
||||
DPRINTF (("ConnDelete: Connection closed for port %u\n",
|
||||
HL_W (*((UINT16 *) & clst->back_port.c[2]))));
|
||||
|
||||
clst->in_use = False; /* free it back */
|
||||
}
|
||||
@@ -1,771 +0,0 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* Component: RDBG
|
||||
* Module: servrpc.c
|
||||
*
|
||||
* Synopsis: support routines for RPC dispatch for remote debug server.
|
||||
* Main server dispatch routines from RPC to support remote debug.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/remdeb.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
open_connex_2_svc - setup a new connection from a client.
|
||||
|
||||
Notes:
|
||||
- this function creates a new connection to a client. It allocates
|
||||
an entry in the connection structure and fills in the information
|
||||
sent and implied by the message.
|
||||
- a client connection entry is needed for all further messages to work
|
||||
properly.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
open_out *
|
||||
RPCGENSRVNAME (open_connex_2_svc) (open_in * in,
|
||||
struct svc_req * rqstp)
|
||||
{
|
||||
static open_out out; /* output response. This could be heap local */
|
||||
int idx;
|
||||
static int one_time = 0; /* we do one-time setup on back port */
|
||||
|
||||
/*
|
||||
* need to support in->debug_type, in->flags, and in->destination!!!
|
||||
*/
|
||||
|
||||
if (!one_time) { /* only setup one backport socket */
|
||||
/*
|
||||
* now setup signals and the like for handling process changes
|
||||
*/
|
||||
setErrno (0);
|
||||
TspInit (rqstp->rq_xprt->xp_sock); /* init transport system */
|
||||
if (getErrno ()) { /* failed in setup */
|
||||
out.port = (u_long) - 1;
|
||||
out.fp = getErrno (); /* error causing to fail */
|
||||
return (&out); /* fail */
|
||||
}
|
||||
one_time = True; /* disable doing this again */
|
||||
}
|
||||
|
||||
DPRINTF (("open_connex_2_svc: Opening connection from '%s'\n",
|
||||
in->user_name));
|
||||
|
||||
/*
|
||||
* now setup a validation of all other connections
|
||||
*/
|
||||
for (idx = 0; idx < conn_list_cnt; idx++)
|
||||
if (conn_list[idx].in_use) { /* setup retry timer */
|
||||
DPRINTF (("open_connex_2_svc: Still have connection %d with port %d\n",
|
||||
idx, HL_W (*((UINT16 *) & conn_list[idx].back_port.c[2]))));
|
||||
}
|
||||
|
||||
idx = ConnCreate (rqstp, in); /* setup the connection */
|
||||
out.port = idx; /* connection number */
|
||||
if (idx == -1)
|
||||
out.fp = getErrno (); /* error causing to fail */
|
||||
else
|
||||
out.fp = TARGET_PROC_TYPE;
|
||||
|
||||
out.server_vers = SERVER_VERS;
|
||||
return (&out);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
send_signal_2_svc - send a kill/signal to the specified process.
|
||||
|
||||
Notes:
|
||||
- this function sends a signal to the process specified. This process
|
||||
does not have to be under debug nor attached by this server. The kill
|
||||
may be refused on other grounds though.
|
||||
- kill(pid, 0) can be used to validate the process still exists if
|
||||
needed.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
signal_out *
|
||||
RPCGENSRVNAME (send_signal_2_svc) (signal_in * in,
|
||||
struct svc_req * rqstp)
|
||||
{
|
||||
static signal_out out; /* return code from kill */
|
||||
|
||||
/*
|
||||
* we do not care if connected
|
||||
*/
|
||||
setErrno (0);
|
||||
out.kill_return = 0;
|
||||
out.errNo = 0;
|
||||
TotalReboot = 1;
|
||||
return (&out);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
close_connex_2_svc - close a connection from a client.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
void *
|
||||
RPCGENSRVNAME (close_connex_2_svc) (close_in * in,
|
||||
struct svc_req * rqstp)
|
||||
{
|
||||
int conn_idx = TspConnGetIndex (rqstp);
|
||||
|
||||
if (conn_idx != -1) /* found it, clear out */
|
||||
ConnDelete (conn_idx, rqstp, in->control);
|
||||
|
||||
return (void *) ""; /* need to return something */
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
ptrace_2_svc - control process under debug.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define REG_COUNT \
|
||||
(sizeof (xdr_regs) / sizeof (int))
|
||||
|
||||
ptrace_out *
|
||||
RPCGENSRVNAME (ptrace_2_svc) (ptrace_in * in,
|
||||
struct svc_req * rqstp)
|
||||
{
|
||||
int conn_idx = rqstp ? TspConnGetIndex (rqstp) : -1;
|
||||
static ptrace_out out; /* outut response (error or data) */
|
||||
void *addr, *addr2; /* used for actual ptrace call */
|
||||
unsigned int data;
|
||||
int req, pid, ret, pid_idx, idx;
|
||||
static union { /* local buffer for returned data */
|
||||
Objects_Id t_list[UTHREAD_MAX]; /* thread_list return */
|
||||
char t_name[THREADNAMEMAX]; /* thread name return */
|
||||
} local_buff; /* for return handling of strings and the like */
|
||||
PID_LIST *plst = NULL; /* current pid_list entry */
|
||||
|
||||
DPRINTF (("ptrace_2_svc: entered (%s (%d), %d, XXXX, %d, XXXX)\n",
|
||||
PtraceName (in->addr.req), in->addr.req, in->pid, in->data));
|
||||
|
||||
out.addr.ptrace_addr_data_out_u.addr = 0;
|
||||
|
||||
/*
|
||||
* validate the connection
|
||||
*/
|
||||
if (conn_idx == -1 && rqstp != NULL) { /* no connection, error */
|
||||
DPRINTF (("ptrace_2_svc: msg from unknown debugger!\n"));
|
||||
out.result = -1;
|
||||
out.errNo = ECHILD; /* closest error */
|
||||
out.addr.req = 0; /* to avoid copies that should not occur */
|
||||
return (&out);
|
||||
}
|
||||
/*
|
||||
* Consider that the last back-message is acknowledged
|
||||
*/
|
||||
if (conn_idx >= 0 && conn_list[conn_idx].retry) {
|
||||
TspMessageReceive (conn_idx, in->pid);
|
||||
}
|
||||
|
||||
req = in->addr.req;
|
||||
out.addr.req = req; /* needed for RPC */
|
||||
pid = in->pid;
|
||||
addr = addr2 = NULL;
|
||||
data = in->data;
|
||||
setErrno (0); /* assume works */
|
||||
out.result = 0; /* assume worked ok */
|
||||
out.errNo = 0;
|
||||
|
||||
/*
|
||||
* lookup process to make sure we have under control
|
||||
*/
|
||||
pid_idx = FindPidEntry (in->pid);
|
||||
if (pid_idx >= 0) { /* found it */
|
||||
plst = &pid_list[pid_idx];
|
||||
if (conn_idx < 0)
|
||||
conn_idx = plst->primary_conn;
|
||||
}
|
||||
|
||||
/*
|
||||
* now we handle the special case of ATTACH to a pid we already control
|
||||
*/
|
||||
if (req == RPT_ATTACH) { /* look it up first */
|
||||
if (plst) { /* we have controlled , so return ok+show conn */
|
||||
ret = 2; /* normally secondary connection */
|
||||
if (!PIDMAP_TEST (conn_idx, pid_idx)) { /* mark as an owner if not already */
|
||||
plst->owners++;
|
||||
PIDMAP_SET (conn_idx, pid_idx); /* mask in */
|
||||
} else if (plst->primary_conn != NO_PRIMARY) { /* regrab makes primary */
|
||||
/*
|
||||
* Only if not primary already
|
||||
*/
|
||||
if (plst->primary_conn != conn_idx) {
|
||||
TspSendWaitChange (plst->primary_conn, BMSG_NOT_PRIM, conn_idx, plst->pid, 0, False); /* tell old owner */
|
||||
}
|
||||
plst->primary_conn = NO_PRIMARY;
|
||||
}
|
||||
|
||||
if (plst->primary_conn == NO_PRIMARY) { /* none now, so take over */
|
||||
plst->primary_conn = conn_idx; /* new primary */
|
||||
ret = 1; /* primary */
|
||||
}
|
||||
out.result = ret; /* primary or secondary owner */
|
||||
return (&out);
|
||||
}
|
||||
/*
|
||||
* else attach process using target code
|
||||
*/
|
||||
setErrno (ESRCH); /* assume the worst */
|
||||
if (!TgtAttach (conn_idx, pid)) { /* failed */
|
||||
out.errNo = getErrno ();
|
||||
out.result = 0;
|
||||
}
|
||||
return (&out);
|
||||
} else if (req == RPT_DETACH) { /* see which kind of detach */
|
||||
if (data == PTRDET_UNOWN) { /* only want to disconnect from */
|
||||
TgtDetachCon (conn_idx, pid_idx, True); /* remove from control */
|
||||
return (&out); /* done */
|
||||
}
|
||||
} else if (plst && (req == RPT_GETNAME || req == RPT_GETBREAK)) {
|
||||
/*
|
||||
* do nothing
|
||||
*/
|
||||
}
|
||||
|
||||
else if (plst && req == RPT_CLRBREAK) {
|
||||
/*
|
||||
* To be able to remove breakpoints from a "running" system
|
||||
*/
|
||||
DPRINTF (("ptrace_2_svc: allowing RPT_CLRBREAK %d\n", data));
|
||||
/*
|
||||
* do nothing
|
||||
*/
|
||||
}
|
||||
|
||||
else if (plst && plst->running) { /* error, process is running and not detach */
|
||||
out.result = -1;
|
||||
out.errNo = ETXTBSY; /* closest error */
|
||||
DPRINTF (("ptrace_2_svc: failed, still running.\n"));
|
||||
return (&out);
|
||||
}
|
||||
if (plst == NULL) {
|
||||
out.result = -1;
|
||||
out.errNo = ESRCH;
|
||||
DPRINTF (("ptrace_2_svc: No such process.\n"));
|
||||
return (&out);
|
||||
}
|
||||
|
||||
/*
|
||||
* now make sure secondary owner is not trying to modify
|
||||
*/
|
||||
if (!(in->flags & PTRFLG_NON_OWNER)) /* if not overriden */
|
||||
if (conn_idx != plst->primary_conn
|
||||
&& ((req >= RPT_POKETEXT && req <= RPT_SINGLESTEP)
|
||||
|| (req >= RPT_SETREGS && req <= RPT_SETFPAREGS && (req & 1))
|
||||
|| (req >= RPT_SYSCALL && req <= RPT_DUMPCORE)
|
||||
|| (req >= RPT_SETTARGETTHREAD && req <= RPT_THREADRESUME)
|
||||
|| (req >= RPT_SETTHREADNAME && req <= RPT_SETTHREADREGS)
|
||||
|| (req >= RPT_STEPRANGE && req <= RPT_CLRBREAK)
|
||||
|| (req == RPT_STOP)
|
||||
|| (req >= RPT_PSETREGS && req <= RPT_PSETTHREADREGS))) { /* not owner */
|
||||
out.result = -1;
|
||||
out.errNo = EPERM; /* cannot alter as not primary */
|
||||
DPRINTF (("ptrace_2_svc: refused, not owner, flags %d conn_idx %d primary_conn %d\n", in->flags, conn_idx, plst->primary_conn));
|
||||
return (&out);
|
||||
}
|
||||
|
||||
addr = (void *) in->addr.ptrace_addr_data_in_u.address; /* default */
|
||||
/*
|
||||
* now setup normal ptrace request by unpacking. May execute here.
|
||||
*/
|
||||
switch (req) { /* handle unpacking or setup for real call */
|
||||
/*
|
||||
* first the ones where addr points to input data
|
||||
*/
|
||||
case RPT_SETREGS:
|
||||
case RPT_SETTHREADREGS:
|
||||
addr = (void *) &in->addr.ptrace_addr_data_in_u.regs; /* reg list */
|
||||
break;
|
||||
|
||||
case RPT_PSETREGS:
|
||||
case RPT_PSETTHREADREGS:
|
||||
if (in->addr.ptrace_addr_data_in_u.pregs.pregs_len != REG_COUNT) {
|
||||
DPRINTF (("ptrace_2_svc: pid %d got %d expected %d\n", pid,
|
||||
in->addr.ptrace_addr_data_in_u.pregs.pregs_len, REG_COUNT));
|
||||
setErrno (EINVAL);
|
||||
break;
|
||||
}
|
||||
req = req == RPT_PSETREGS ? RPT_SETREGS : RPT_SETTHREADREGS;
|
||||
addr = (void *) in->addr.ptrace_addr_data_in_u.pregs.pregs_val;
|
||||
break;
|
||||
|
||||
case RPT_SETTHREADNAME:
|
||||
addr = (void *) in->addr.ptrace_addr_data_in_u.name;
|
||||
break;
|
||||
case RPT_WRITETEXT:
|
||||
case RPT_WRITEDATA:
|
||||
if ((int) data < 0) {
|
||||
setErrno (EINVAL);
|
||||
break;
|
||||
}
|
||||
addr = (void *) in->addr.ptrace_addr_data_in_u.mem.addr; /* targ addr */
|
||||
addr2 = (void *) in->addr.ptrace_addr_data_in_u.mem.data; /* buff */
|
||||
|
||||
/*
|
||||
* Forbid writing over breakpoints
|
||||
*/
|
||||
if (BreakOverwrite (plst, addr, data)) {
|
||||
setErrno (EBUSY);
|
||||
}
|
||||
break;
|
||||
|
||||
case RPT_POKETEXT:
|
||||
case RPT_POKEDATA:
|
||||
/*
|
||||
* Forbid writing over breakpoints
|
||||
*/
|
||||
if (BreakOverwrite (plst, addr, sizeof (int))) {
|
||||
setErrno (EBUSY);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* now ones where we handle locally
|
||||
*/
|
||||
case RPT_GETTARGETTHREAD:
|
||||
out.result = plst->thread;
|
||||
req = 0; /* force exit */
|
||||
break;
|
||||
|
||||
case RPT_PGETREGS: /* return from our buffer */
|
||||
out.addr.ptrace_addr_data_out_u.pregs.pregs_len = REG_COUNT;
|
||||
out.addr.ptrace_addr_data_out_u.pregs.pregs_val = (u_int *) & plst->regs;
|
||||
req = 0; /* force exit */
|
||||
break;
|
||||
|
||||
case RPT_GETREGS:
|
||||
/*
|
||||
* return directly from our buffer
|
||||
*/
|
||||
/*
|
||||
* this buffer is refreshed when changing target thread
|
||||
*/
|
||||
out.addr.ptrace_addr_data_out_u.regs = plst->regs;
|
||||
req = 0; /* force exit */
|
||||
break;
|
||||
|
||||
case RPT_SETBREAK:
|
||||
idx = BreakSet (plst, conn_idx, &in->addr.ptrace_addr_data_in_u.breakp);
|
||||
if (idx < 0)
|
||||
break;
|
||||
req = 0; /* force exit */
|
||||
out.result = idx; /* return break index (>0) */
|
||||
break;
|
||||
|
||||
case RPT_CLRBREAK:
|
||||
if (conn_list[conn_idx].flags & DEBUGGER_IS_GDB) {
|
||||
data = BreakGetIndex (plst, addr);
|
||||
}
|
||||
out.result = BreakClear (plst, conn_idx, data);
|
||||
/*
|
||||
* if errored, errno will still be set
|
||||
*/
|
||||
req = 0;
|
||||
break;
|
||||
|
||||
case RPT_GETBREAK:
|
||||
/*
|
||||
* data=handle, addr=in_buffer, returns next break. Data=0, returns cnt
|
||||
*/
|
||||
out.result = BreakGet (plst, data, &out.addr.
|
||||
ptrace_addr_data_out_u.breakp);
|
||||
req = 0; /* handle locally */
|
||||
break;
|
||||
|
||||
case RPT_GETNAME: /* get the name of the process */
|
||||
if (!plst->name)
|
||||
out.addr.ptrace_addr_data_out_u.mem.dataNb = 0;
|
||||
else {
|
||||
int maxLen = sizeof(out.addr.ptrace_addr_data_out_u.mem.data) - 1;
|
||||
data = strlen (plst->name);
|
||||
if (data > maxLen)
|
||||
data = maxLen;
|
||||
out.addr.ptrace_addr_data_out_u.mem.dataNb = data + 1;
|
||||
memcpy (out.addr.ptrace_addr_data_out_u.mem.data, plst->name, data + 1);
|
||||
out.addr.ptrace_addr_data_out_u.mem.data[maxLen] = '\0';
|
||||
}
|
||||
req = 0;
|
||||
break;
|
||||
|
||||
case RPT_CONTTO:
|
||||
if (BreakSetAt (plst, conn_idx, (u_long) addr, BRKT_STEPEMUL) < 0) {
|
||||
DPRINTF (("ptrace_2_svc: BreakSet failed at %x", addr));
|
||||
break;
|
||||
}
|
||||
req = RPT_CONT;
|
||||
/*
|
||||
* data can contain a signal number, addr2 is unused
|
||||
*/
|
||||
goto case_RPT_CONT;
|
||||
|
||||
case RPT_STEPRANGE:
|
||||
/*
|
||||
* convert to step
|
||||
*/
|
||||
if (!data)
|
||||
data = 1; /* should we give an error?? */
|
||||
BreakStepRange (plst, addr, data);
|
||||
if (getErrno ())
|
||||
break;
|
||||
|
||||
req = RPT_SINGLESTEP; /* do by stepping */
|
||||
addr = (void *) 1; /* start from current PC */
|
||||
data = -2; /* want non-atomic stepping */
|
||||
/*
|
||||
* fall through to other exec cases
|
||||
*/
|
||||
|
||||
case RPT_CONT:
|
||||
case_RPT_CONT:
|
||||
case RPT_SINGLESTEP:
|
||||
|
||||
if (BreakStepOff (plst, &addr2)) { /* need clear then step off break */
|
||||
/*
|
||||
* clear break, step, then do exec
|
||||
*/
|
||||
if (addr == (void *) 1)
|
||||
addr = (void *) plst->regs.REG_PC; /* need for patch */
|
||||
|
||||
/*
|
||||
* data is always 0, so atomic single-step
|
||||
*/
|
||||
} else if (req == RPT_SINGLESTEP) {
|
||||
data = -2; /* want non-atomic stepping */
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* now ones where addr points to an output area
|
||||
*/
|
||||
case RPT_PGETTHREADREGS:
|
||||
addr = (void *) out.addr.ptrace_addr_data_out_u.mem.data;
|
||||
if (sizeof(out.addr.ptrace_addr_data_out_u.mem.data) < REG_COUNT * sizeof (int)) {
|
||||
setErrno (EINVAL);
|
||||
break;
|
||||
}
|
||||
if (data == plst->thread) {
|
||||
out.addr.ptrace_addr_data_out_u.pregs.pregs_len = REG_COUNT;
|
||||
out.addr.ptrace_addr_data_out_u.pregs.pregs_val =
|
||||
(u_int *) & plst->regs;
|
||||
req = 0; /* force exit */
|
||||
break;
|
||||
}
|
||||
req = RPT_GETTHREADREGS;
|
||||
break;
|
||||
|
||||
case RPT_GETTHREADREGS:
|
||||
addr = (void *) &out.addr.ptrace_addr_data_out_u.regs;
|
||||
break;
|
||||
case RPT_GETTHREADNAME:
|
||||
out.addr.ptrace_addr_data_out_u.name = local_buff.t_name;
|
||||
addr = (void *) out.addr.ptrace_addr_data_out_u.name;
|
||||
break;
|
||||
case RPT_THREADLIST:
|
||||
out.addr.ptrace_addr_data_out_u.threads.threads =
|
||||
(ptThreadList) local_buff.t_list;
|
||||
addr = (void *) out.addr.ptrace_addr_data_out_u.threads.threads;
|
||||
break;
|
||||
case RPT_READTEXT:
|
||||
case RPT_READDATA:
|
||||
if ((int) data < 0) {
|
||||
setErrno (EINVAL);
|
||||
break;
|
||||
}
|
||||
addr = (void *) in->addr.ptrace_addr_data_in_u.address;
|
||||
addr2 = (void *) out.addr.ptrace_addr_data_out_u.mem.data;
|
||||
out.addr.ptrace_addr_data_out_u.mem.dataNb = data;
|
||||
break;
|
||||
case RPT_DETACH:
|
||||
/*
|
||||
* Do not allow detaching if breakpoints still there
|
||||
*/
|
||||
if (BreakGet (plst, 0, NULL)) { /* some bkpts still set */
|
||||
setErrno (EINVAL); /* cannot detach safely */
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* fall through
|
||||
*/
|
||||
case RPT_KILL:
|
||||
/*
|
||||
* in the event they are trying to detach or kill a terminated process,
|
||||
* we just delete the entry.
|
||||
*/
|
||||
if (PROC_TERMINATED (plst)) {
|
||||
TgtDelete (plst, -1, BMSG_KILLED); /* just blow off */
|
||||
req = 0; /* now exit */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (getErrno ()) { /* failed in code above */
|
||||
out.result = -1;
|
||||
out.errNo = getErrno ();
|
||||
DPRINTF (("ptrace_2_svc: result %d errNo %d\n", out.result, out.errNo));
|
||||
return (&out);
|
||||
} else if (!req) { /* bail out now */
|
||||
DPRINTF (("ptrace_2_svc: result %d errNo %d\n", out.result, out.errNo));
|
||||
return (&out);
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, make the call
|
||||
*/
|
||||
out.result = TgtPtrace (req, pid, addr, data, addr2);
|
||||
out.errNo = getErrno ();
|
||||
|
||||
/*
|
||||
* if no error, cleanup afterwards
|
||||
*/
|
||||
if (getErrno ()) {
|
||||
/*
|
||||
* Remove step-emul breakpoints if any
|
||||
*/
|
||||
if (req == RPT_SINGLESTEP || req == RPT_CONT) {
|
||||
BreakClear (plst, -1, -1);
|
||||
}
|
||||
DPRINTF (("ptrace_2_svc: result %d errNo %d\n", out.result, out.errNo));
|
||||
return (&out); /* return error */
|
||||
}
|
||||
|
||||
switch (in->addr.req) { /* handle some special calls that affect state */
|
||||
case RPT_CONT:
|
||||
case RPT_STEPRANGE:
|
||||
/*
|
||||
* change to running
|
||||
*/
|
||||
if (in->addr.req == RPT_STEPRANGE)
|
||||
plst->last_start = LAST_RANGE; /* so range steps */
|
||||
else if (addr2)
|
||||
plst->last_start = LAST_STEPOFF; /* now continue after wait */
|
||||
else
|
||||
plst->last_start = LAST_CONT;
|
||||
plst->running = 1; /* mark as running */
|
||||
if (!rqstp) /* Called internally to restart bkpt, no msg to anybody */
|
||||
break;
|
||||
TgtNotifyAll (pid_idx, BMSG_WAIT, 0, 0, (in->flags & PTRFLG_NON_OWNER)
|
||||
? -1 : conn_idx, True);
|
||||
break;
|
||||
case RPT_SINGLESTEP:
|
||||
/*
|
||||
* mark as step
|
||||
*/
|
||||
plst->last_start = LAST_STEP; /* so we know how started */
|
||||
plst->running = 1; /* mark as running (wait should catch fast) */
|
||||
break;
|
||||
case RPT_DETACH: /* mark as disconnected */
|
||||
case RPT_KILL: /* mark as killed */
|
||||
if (in->flags & PTRFLG_FREE) /* notify and delete entry */
|
||||
TgtDelete (plst, -1,
|
||||
(in->addr.req == RPT_KILL) ? BMSG_KILLED : BMSG_DETACH);
|
||||
else { /* notify and mark */
|
||||
plst->last_start = (in->addr.req == RPT_KILL) ?
|
||||
LAST_KILLED : LAST_DETACHED;
|
||||
plst->state = -1;
|
||||
plst->running = False;
|
||||
TgtNotifyAll (pid_idx, (in->addr.req == RPT_KILL) ?
|
||||
BMSG_KILLED : BMSG_DETACH, 0, 0, -1, True);
|
||||
}
|
||||
break;
|
||||
case RPT_SETTHREADREGS:
|
||||
case RPT_PSETTHREADREGS:
|
||||
if (data != plst->thread)
|
||||
break;
|
||||
DPRINTF (("ptrace_2_svc: pid %d target thread regs changed!\n", pid));
|
||||
|
||||
case RPT_SETREGS:
|
||||
case RPT_PSETREGS:
|
||||
/*
|
||||
* change our buffer as well
|
||||
*/
|
||||
if (plst->regs.REG_PC != ((xdr_regs *) addr)->REG_PC)
|
||||
BreakPcChanged (plst);
|
||||
plst->regs = *(xdr_regs *) addr; /* copy in */
|
||||
break;
|
||||
|
||||
/*
|
||||
* case RPT_PGETREGS has been handled locally above
|
||||
*/
|
||||
case RPT_PGETTHREADREGS:
|
||||
/*
|
||||
* We need to update pointer so that XDR works on return
|
||||
*/
|
||||
out.addr.ptrace_addr_data_out_u.pregs.pregs_len = REG_COUNT;
|
||||
out.addr.ptrace_addr_data_out_u.pregs.pregs_val =
|
||||
(void *) out.addr.ptrace_addr_data_out_u.mem.data;
|
||||
break;
|
||||
|
||||
case RPT_PEEKTEXT:
|
||||
case RPT_PEEKDATA:
|
||||
case RPT_READDATA:
|
||||
case RPT_READTEXT:
|
||||
if (req < RPT_READDATA) { /* peek */
|
||||
/*
|
||||
* addr is start
|
||||
*/
|
||||
data = sizeof (int);
|
||||
addr2 = &out.result; /* data buffer */
|
||||
/*
|
||||
* Like read: addr is start, data is length, addr2 is buffer
|
||||
*/
|
||||
}
|
||||
BreakHide (plst, addr, data, addr2);
|
||||
break;
|
||||
|
||||
case RPT_SETTARGETTHREAD:
|
||||
DPRINTF (("ptrace_2_svc: pid %d new target thread %d\n", pid, data));
|
||||
TgtPtrace (RPT_GETREGS, pid, (char *) &plst->regs, 0, NULL);
|
||||
plst->thread = data;
|
||||
if (plst->break_list) { /* Forget we had to step off breakpoint */
|
||||
BASE_BREAK *base = (BASE_BREAK *) plst->break_list;
|
||||
DPRINTF (("ptrace_2_svc: clr_step %d last_break %d\n", base->clr_step,
|
||||
base->last_break));
|
||||
base->clr_step = 0; /* Not stopped on break */
|
||||
base->last_break = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case RPT_THREADLIST:
|
||||
out.addr.ptrace_addr_data_out_u.threads.nbThread = out.result;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* end switch */
|
||||
DPRINTF (("ptrace_2_svc 2: result %d errNo %d\n", out.result, out.errNo));
|
||||
return (&out);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
wait_info_2_svc - non-blocking wait request to check status.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
wait_out *
|
||||
RPCGENSRVNAME (wait_info_2_svc) (wait_in * in, struct svc_req *rqstp)
|
||||
{
|
||||
int conn_idx = TspConnGetIndex (rqstp);
|
||||
static wait_out out; /* output of pid and status */
|
||||
int idx;
|
||||
PID_LIST *plst;
|
||||
|
||||
memset (&out, 0, sizeof (out)); /* zero for safety */
|
||||
out.reason = STOP_ERROR; /* assume the worst */
|
||||
|
||||
if (conn_idx == -1) { /* no connection, error */
|
||||
DPRINTF (("wait_info_2_svc: msg from unknown debugger!\n"));
|
||||
out.wait_return = -1;
|
||||
out.errNo = ECHILD; /* closest error */
|
||||
return (&out);
|
||||
} else { /* see if confirming message received */
|
||||
if (conn_list[conn_idx].retry)
|
||||
TspMessageReceive (conn_idx, in->pid);
|
||||
}
|
||||
|
||||
if (!in->pid) { /* warm test verify only */
|
||||
/*
|
||||
* this call (pid==0) is made to confirm that that connection is still
|
||||
* active.
|
||||
*/
|
||||
/*
|
||||
* we let it fall through as an error since any use other than connection
|
||||
* reset would be an error (there is no pid0).
|
||||
*/
|
||||
} else { /* normal request */
|
||||
idx = FindPidEntry (in->pid);
|
||||
if (idx >= 0) { /* found process they requested on */
|
||||
plst = &pid_list[idx];
|
||||
out.wait_return = plst->running ? 0 : in->pid;
|
||||
/*
|
||||
* return: 0 is running, pid is stopped/term
|
||||
*/
|
||||
out.errNo = 0;
|
||||
out.status = plst->state; /* last stopped reason if stopped */
|
||||
out.thread = plst->thread; /* current thread (or -1 if none) from stop */
|
||||
if (!out.wait_return)
|
||||
out.reason = STOP_NONE; /* running, no action */
|
||||
else if (STS_SIGNALLED (out.status)) { /* stopped on signal */
|
||||
out.handle = STS_GETSIG (out.status); /* signal number */
|
||||
if (out.handle == SIGTRAP)
|
||||
if (plst->is_step) { /* single step with hitting a break */
|
||||
out.reason = STOP_STEP;
|
||||
out.handle = 0; /* no information */
|
||||
} else { /* stopped on break */
|
||||
out.reason = STOP_BREAK;
|
||||
if (plst->break_list)
|
||||
out.handle = ((BASE_BREAK *) plst->break_list)->last_break;
|
||||
else
|
||||
out.handle = 0; /* no break */
|
||||
} else
|
||||
out.reason = STOP_SIGNAL;
|
||||
out.PC = plst->regs.REG_PC; /* copy standard regs */
|
||||
out.SP = plst->regs.REG_SP;
|
||||
out.FP = plst->regs.REG_FP;
|
||||
} else { /* terminated, so lower use count */
|
||||
if (plst->last_start == LAST_KILLED)
|
||||
out.reason = STOP_KILLED;
|
||||
else if (plst->last_start == LAST_DETACHED)
|
||||
out.reason = STOP_DETACHED;
|
||||
else if (plst->last_start == LAST_START) { /* failed in exec */
|
||||
out.reason = STOP_SPAWN_FAILED;
|
||||
out.handle = STS_GETCODE (out.status); /* errno reason */
|
||||
} else if (STS_TERMONSIG (out.status)) { /* terminated on signal */
|
||||
out.reason = STOP_TERM_SIG;
|
||||
/*
|
||||
* mask off the core-dumped bit 7
|
||||
*/
|
||||
out.handle = (int) (unsigned) (u_char) STS_TERMGETSIG (out.status);
|
||||
} else { /* exit(2)ed */
|
||||
out.reason = STOP_TERM_EXIT;
|
||||
out.handle = STS_GETCODE (out.status); /* code */
|
||||
}
|
||||
}
|
||||
DPRINTF (("wait_info_2_svc: pid %d return %d status %x errNo %d"
|
||||
" reason %d handle %d pc %x sp %x fp %x thread %d\n",
|
||||
in->pid, out.wait_return, out.status, out.errNo, out.reason,
|
||||
out.handle, out.PC, out.SP, out.FP, out.thread));
|
||||
return (&out);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* if not found in list, we return error: no such process
|
||||
*/
|
||||
out.wait_return = -1;
|
||||
out.errNo = ESRCH; /* no process */
|
||||
out.status = 0;
|
||||
return (&out);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
get_signal_names_2_svc - return names for signals
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
static one_signal SignalNames[] = {
|
||||
{SIGILL, "SIGILL/EVT_ILL"},
|
||||
{SIGTRAP, "SIGTRAP/EVT_BKPT"},
|
||||
{SIGFPE, "SIGFPE/EVT_FPE"},
|
||||
{SIGKILL, "SIGKILL/EVT_AKILL"},
|
||||
{SIGSEGV, "SIGSEGV/EVT_SEGV"},
|
||||
{17, "SIGSTOP"},
|
||||
{23, "SIGSTOP"}
|
||||
};
|
||||
|
||||
get_signal_names_out *
|
||||
RPCGENSRVNAME (get_signal_names_2_svc) (void * in, struct svc_req * rqstp)
|
||||
{
|
||||
static get_signal_names_out out;
|
||||
|
||||
out.signals.all_signals_len = sizeof (SignalNames) / sizeof (SignalNames[0]);
|
||||
out.signals.all_signals_val = SignalNames;
|
||||
|
||||
return (&out);
|
||||
}
|
||||
@@ -1,576 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component: RDB servers
|
||||
* Module: servtgt.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef DDEBUG
|
||||
#define Ptrace TgtDbgPtrace
|
||||
#else
|
||||
#define Ptrace TgtRealPtrace
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TgtBreakRestoreOrig - Restore original instruction at "addr"
|
||||
* just before single-stepping it.
|
||||
*/
|
||||
|
||||
int
|
||||
TgtBreakRestoreOrig (int pid, void *addr, void *addr2)
|
||||
/*
|
||||
* Process identifier
|
||||
*/
|
||||
/*
|
||||
* Breakpoint address
|
||||
*/
|
||||
/*
|
||||
* Original instruction or bkpt number
|
||||
*/
|
||||
{
|
||||
int ret;
|
||||
int l;
|
||||
|
||||
l = (long) Ptrace (RPT_PEEKTEXT, pid, addr, 0, NULL); /* assume ok */
|
||||
ret = ORG_BREAK (l, (UINT32) addr2); /* reconstruct old instr */
|
||||
ret = Ptrace (RPT_POKETEXT, pid, addr, ret, NULL); /* poke back old */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* TgtBreakCancelStep - Restore the breakpoint at "addr" if the single-step
|
||||
* has failed at the ptrace level.
|
||||
*/
|
||||
|
||||
#define BKPT0(plst) ((BASE_BREAK*)(plst)->break_list)
|
||||
|
||||
void
|
||||
TgtBreakCancelStep (PID_LIST * plst)
|
||||
{
|
||||
assert (plst->break_list);
|
||||
assert (BKPT0 (plst)->clr_step);
|
||||
|
||||
if (plst->break_list && BKPT0 (plst)->clr_step) {
|
||||
int idx = BKPT0 (plst)->last_break;
|
||||
int data;
|
||||
|
||||
data = Ptrace (RPT_PEEKTEXT, plst->pid,
|
||||
(char *) plst->break_list[idx].ee_loc, 0, NULL);
|
||||
assert (!IS_BREAK (data));
|
||||
Ptrace (RPT_POKETEXT, plst->pid,
|
||||
(char *) plst->break_list[idx].ee_loc,
|
||||
(int) SET_BREAK (data), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TgtCreateNew - add a new process into the process management lists.
|
||||
*/
|
||||
|
||||
void
|
||||
TgtCreateNew (PID pid, int conn, INT32 child, char *name, Boolean spawn)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < pid_list_cnt; idx++)
|
||||
if (!pid_list[idx].pid)
|
||||
break; /* find empty */
|
||||
|
||||
if (idx >= pid_list_cnt) { /* no empties, add more */
|
||||
PID_LIST *tmp_pid_list = pid_list;
|
||||
|
||||
pid_list_cnt += PID_LIST_INC;
|
||||
pid_list = (PID_LIST *) Realloc (pid_list, /* get new or extend */
|
||||
pid_list_cnt * sizeof (PID_LIST));
|
||||
if (!pid_list) { /* out of memory */
|
||||
pid_list_cnt -= PID_LIST_INC;
|
||||
if (pid_list_cnt) { /* realloc failed - malloc again */
|
||||
pid_list = tmp_pid_list;
|
||||
/*
|
||||
* above relies on old pointer being valid after failed realloc
|
||||
*/
|
||||
}
|
||||
return; /* failed */
|
||||
}
|
||||
/*
|
||||
* now clear newly added space
|
||||
*/
|
||||
memset (pid_list + pid_list_cnt - PID_LIST_INC, 0,
|
||||
PID_LIST_INC * sizeof (PID_LIST));
|
||||
idx = pid_list_cnt - PID_LIST_INC;
|
||||
} else /* clear entry we found */
|
||||
memset (&pid_list[idx], 0, sizeof (PID_LIST));
|
||||
|
||||
/*
|
||||
* now fill in empty entry
|
||||
*/
|
||||
pid_list[idx].pid = pid;
|
||||
pid_list[idx].running = 1; /* we have not called wait yet */
|
||||
pid_list[idx].primary_conn = (UCHAR) conn; /* primary owner */
|
||||
if (conn != -1) { /* found caller */
|
||||
pid_list[idx].owners = 1;
|
||||
PIDMAP_SET (conn, idx); /* mask in */
|
||||
}
|
||||
pid_list[idx].thread = (UINT32) - 1; /* no thread for now */
|
||||
pid_list[idx].last_start = LAST_START; /* handle MiX bug */
|
||||
|
||||
pid_list[idx].name = name ? (char *) StrDup (name) : (char *) NULL;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* TgtNotifyWaitChange - send event to clients indicating child changed state.
|
||||
*/
|
||||
|
||||
void
|
||||
TgtNotifyWaitChange (PID pid, int status, Boolean exclude)
|
||||
{
|
||||
int conn, idx;
|
||||
|
||||
idx = FindPidEntry (pid); /* locate the pid that changed */
|
||||
if (idx < 0) {
|
||||
DPRINTF (("TgtNotifyWaitChange: pid %d not in our list\n", (int) pid));
|
||||
return; /* not in our list */
|
||||
}
|
||||
pid_list[idx].running = 0; /* not running */
|
||||
pid_list[idx].state = status; /* save status of stop/term */
|
||||
if (!pid_list[idx].owners && !STS_SIGNALLED (status))
|
||||
TgtDelete (&pid_list[idx], -1, 0); /* terminated and no owners */
|
||||
else { /* normal cases */
|
||||
for (conn = 0; conn < conn_list_cnt; conn++) { /* now find all interested clients */
|
||||
if (!conn_list[conn].in_use /* free entry */
|
||||
|| !PIDMAP_TEST (conn, idx))
|
||||
continue; /* not using this pid */
|
||||
if (conn == exclude)
|
||||
continue; /* do not do this one */
|
||||
TspSendWaitChange (conn, BMSG_WAIT, 1, pid, 0, False); /* notify of change */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TgtNotifyAll - send a message to all clients interested in process.
|
||||
*/
|
||||
|
||||
void
|
||||
TgtNotifyAll (int pid_idx, BACK_MSG msg, UINT16 spec,
|
||||
UINT32 context, int exclude, Boolean force)
|
||||
{
|
||||
int conn;
|
||||
|
||||
DPRINTF (("TgtNotifyAll: msg %d (%s) for pid_idx=%d (%d,%d)\n",
|
||||
msg, BmsgNames[msg], pid_idx, exclude, force));
|
||||
for (conn = 0; conn < conn_list_cnt; conn++)
|
||||
if (conn_list[conn].in_use /* not free */
|
||||
&& PIDMAP_TEST (conn, pid_idx)) {
|
||||
if (conn != exclude)
|
||||
TspSendWaitChange (conn, msg, spec, pid_list[pid_idx].pid, context,
|
||||
force);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TgtDelete - mark process as now uncontrolled.
|
||||
*
|
||||
* Notes:
|
||||
* - this function removes a process from the process list.
|
||||
* - the notify argument indicates a message to send if needed.
|
||||
*/
|
||||
|
||||
void
|
||||
TgtDelete (PID_LIST * plst, int conn_idx, BACK_MSG notify)
|
||||
{
|
||||
int idx = plst - pid_list, cnt, conn;
|
||||
|
||||
/*
|
||||
* found
|
||||
*/
|
||||
cnt = pid_list[idx].owners;
|
||||
if (cnt) { /* some connections to break */
|
||||
for (conn = 0; cnt && conn < conn_list_cnt; conn++)
|
||||
if (conn_list[conn].in_use /* not free */
|
||||
&& PIDMAP_TEST (conn, idx)) { /* found one that uses it */
|
||||
PIDMAP_CLEAR (conn, idx);
|
||||
if (notify && conn != conn_idx)
|
||||
TspSendWaitChange (conn, notify, 0, plst->pid, 0, True);
|
||||
if (!--cnt)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pid_list[idx].name)
|
||||
Free (pid_list[idx].name); /* free string name back */
|
||||
/*
|
||||
* Free breakpoint list
|
||||
*/
|
||||
if (pid_list[idx].break_list != NULL) {
|
||||
Free (pid_list[idx].break_list);
|
||||
}
|
||||
pid_list[idx].pid = 0; /* gone */
|
||||
}
|
||||
|
||||
/*
|
||||
* TgtKillAndDelete - kill or detach process and remove entry.
|
||||
*/
|
||||
|
||||
int
|
||||
TgtKillAndDelete (PID_LIST * plst, struct svc_req *rqstp, Boolean term)
|
||||
{
|
||||
ptrace_in pin; /* used for ptrace call */
|
||||
ptrace_out *pout;
|
||||
|
||||
/*
|
||||
* Remove breakpoints
|
||||
*/
|
||||
if (plst->break_alloc > 0) {
|
||||
pin.pid = plst->pid;
|
||||
pin.addr.req = RPT_CLRBREAK;
|
||||
pin.data = 0; /* clear all */
|
||||
pin.flags = PTRFLG_NON_OWNER;
|
||||
pout = RPCGENSRVNAME (ptrace_2_svc) (&pin, rqstp);
|
||||
if (pout->result < 0) {
|
||||
DPRINTF (("TgtKillAndDelete: RPT_CLRBREAK failed %d\n", getErrno ()));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (term) { /* kill */
|
||||
pin.addr.ptrace_addr_data_in_u.address = 0;
|
||||
pin.data = -1; /* Don't want notification from slave */
|
||||
pin.addr.req = RPT_KILL;
|
||||
} else { /* detach */
|
||||
pin.addr.ptrace_addr_data_in_u.address = 1;
|
||||
pin.data = 0;
|
||||
pin.addr.req = RPT_DETACH;
|
||||
}
|
||||
pin.pid = plst->pid;
|
||||
pin.flags = PTRFLG_FREE | PTRFLG_NON_OWNER;
|
||||
|
||||
DPRINTF (("TgtKillAndDelete: ptrace_2_svc (%s (%d), %d)\n",
|
||||
PtraceName (pin.addr.req), pin.addr.req, pin.pid));
|
||||
|
||||
pout = RPCGENSRVNAME (ptrace_2_svc) (&pin, rqstp); /* start it */
|
||||
if (pout->errNo == ESRCH && plst->pid)
|
||||
TgtDelete (plst, -1, BMSG_KILLED); /* only entry remains */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TgtDetachCon - detach a connection's ownership of a process.
|
||||
*/
|
||||
|
||||
void
|
||||
TgtDetachCon (int conn_idx, int pid_idx, Boolean delete)
|
||||
{
|
||||
if ((unsigned) pid_idx >= pid_list_cnt || !pid_list[pid_idx].pid)
|
||||
return; /* not valid */
|
||||
if (PIDMAP_TEST (conn_idx, pid_idx)) { /* if an owner, release control */
|
||||
PIDMAP_CLEAR (conn_idx, pid_idx);
|
||||
|
||||
if (pid_list[pid_idx].owners)
|
||||
pid_list[pid_idx].owners--;
|
||||
if (pid_list[pid_idx].primary_conn == conn_idx)
|
||||
pid_list[pid_idx].primary_conn = NO_PRIMARY;
|
||||
if (delete
|
||||
&& !pid_list[pid_idx].owners && PROC_TERMINATED (pid_list + pid_idx))
|
||||
TgtDelete (&pid_list[pid_idx], -1, 0); /* remove entry */
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
TgtHandleChildChange - decide what action to take after wait() returns.
|
||||
Used in the master only.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifdef DDEBUG
|
||||
static char *LastStartNames[] = {
|
||||
"NONE", "STEP", "CONT", "RANGE",
|
||||
"STEPOFF", "KILLED", "DETACHED"
|
||||
};
|
||||
|
||||
char *
|
||||
GetLastStartName (int last_start)
|
||||
{
|
||||
static char buf[32];
|
||||
|
||||
strcpy (buf, LastStartNames[last_start & ~LAST_START]);
|
||||
if (last_start & LAST_START) {
|
||||
strcat (buf, "+START");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
Boolean
|
||||
TgtHandleChildChange (PID pid, int *status, int *unexp,
|
||||
CPU_Exception_frame * ctx)
|
||||
{ /* return False if continue, else stop */
|
||||
int idx, sig;
|
||||
int bidx = 0;
|
||||
PID_LIST *plst;
|
||||
unsigned long PC;
|
||||
BASE_BREAK *base = NULL; /* break_list[0] is really BASE_BREAK */
|
||||
int hadStepEmul;
|
||||
int origHadStepEmul;
|
||||
int stopWanted;
|
||||
|
||||
DPRINTF (("TgtHandleChildChange: pid %d status %x cap\n",
|
||||
(int) pid, *status));
|
||||
if (unexp)
|
||||
*unexp = 0; /* initialize to ok */
|
||||
|
||||
/*
|
||||
* first, find pid in question
|
||||
*/
|
||||
idx = FindPidEntry (pid);
|
||||
if (idx < 0) { /* cannot locate this process */
|
||||
DPRINTF (("TgtHandleChildChange: unknown process (%s pid)\n",
|
||||
FindPidEntry (pid) >= 0 ? "stale" : "unknown"));
|
||||
if (unexp)
|
||||
*unexp = 1; /* Unexpected change */
|
||||
return (False); /* unknown: ignore (used to stop and notify) */
|
||||
}
|
||||
|
||||
/*
|
||||
* found
|
||||
*/
|
||||
plst = &pid_list[idx]; /* pointer to entry */
|
||||
/*
|
||||
* first we see if just stopped
|
||||
*/
|
||||
|
||||
/*
|
||||
* copy ctxt
|
||||
*/
|
||||
CtxToRegs (ctx, &(plst->regs));
|
||||
|
||||
stopWanted = plst->stop_wanted;
|
||||
plst->stop_wanted = 0; /* For the next time */
|
||||
|
||||
hadStepEmul = BreakClear (plst, -1, -1) > 0;
|
||||
origHadStepEmul = hadStepEmul; /* hadStepEmul is cleared if real bkpt met */
|
||||
|
||||
if (STS_SIGNALLED (*status)) { /* stopped, not terminated */
|
||||
sig = STS_GETSIG (*status); /* signal that stopped us */
|
||||
|
||||
/*
|
||||
* now, we read the registers and see what to do next
|
||||
*/
|
||||
if (TgtPtrace (RPT_GETREGS, pid, (void *) &plst->regs, 0, NULL) < 0) {
|
||||
memset (&plst->regs, 0, sizeof (plst->regs));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get current thread
|
||||
*/
|
||||
plst->thread = TgtPtrace (RPT_GETTARGETTHREAD, pid, NULL, 0, NULL);
|
||||
|
||||
if (sig == SIGTRAP) { /* stopped from break/step */
|
||||
PC = plst->regs.REG_PC;
|
||||
/*
|
||||
* Must check PC to see whether in situations where we had
|
||||
* step emulation we are on a breakpoint or just
|
||||
* have returned from an emulated single-step
|
||||
*/
|
||||
if (BreakIdentify (plst, 0 /*no adjust */ , -1 /*no thread */ ) > 0) {
|
||||
hadStepEmul = 0;
|
||||
}
|
||||
plst->is_step = hadStepEmul || IS_STEP (plst->regs)
|
||||
|| plst->last_start == LAST_START;
|
||||
DPRINTF (("TgtHandleChildChange: %s last_start %s\n", plst->is_step
|
||||
? "step" : "break", GetLastStartName (plst->last_start)));
|
||||
|
||||
if ((plst->is_step || origHadStepEmul || stopWanted)
|
||||
&& (plst->last_start == LAST_STEP
|
||||
|| plst->last_start == LAST_STEPOFF
|
||||
|| plst->last_start == LAST_RANGE)) {
|
||||
DPRINTF (("TgtHandleChildChange: restoring stepped-off bkpt\n"));
|
||||
BreakSteppedOff (plst);
|
||||
}
|
||||
|
||||
if (plst->last_start == LAST_STEPOFF && (plst->is_step || origHadStepEmul)) { /* stepped off break and now need cont */
|
||||
DPRINTF (("TgtHandleChildChange: auto-resuming after step-off\n"));
|
||||
plst->last_start = LAST_CONT; /* convert to normal cont */
|
||||
if (!stopWanted) {
|
||||
if (TgtPtrace (RPT_CONT, pid, (char *) 1, 0, NULL))
|
||||
return True; /* tell people */
|
||||
return (False); /* wait for change */
|
||||
}
|
||||
DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-off\n",
|
||||
stopWanted));
|
||||
*status = STS_MAKESIG (stopWanted);
|
||||
return True; /* Stop and notify */
|
||||
}
|
||||
|
||||
base = plst->break_list ? ((BASE_BREAK *) plst->break_list) :
|
||||
((BASE_BREAK *) NULL);
|
||||
/*
|
||||
* now see if step in range
|
||||
*/
|
||||
|
||||
if (plst->last_start == LAST_RANGE /* step in range */
|
||||
&& (plst->is_step || origHadStepEmul) /* not a breakpoint */
|
||||
&&PC >= base->range_start && PC <= base->range_end) { /* still in range, keep going */
|
||||
if (stopWanted) {
|
||||
DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-range\n",
|
||||
stopWanted));
|
||||
} else {
|
||||
DPRINTF (("TgtHandleChildChange: Reservation at %x\n",
|
||||
plst->regs.REG_PC));
|
||||
}
|
||||
}
|
||||
if (!plst->is_step) { /* was break */
|
||||
bidx = BreakIdentify (plst, 1 /*adjust */ , plst->thread);
|
||||
if (bidx == 0) {
|
||||
DPRINTF (("TgtHandleChildChange: forwarding bkpt to kernel\n"));
|
||||
if (unexp) {
|
||||
*unexp = 1;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
if (bidx < 0) { /* Unwanted breakpoint, must step it off */
|
||||
ptrace_in pin;
|
||||
ptrace_out *out;
|
||||
if (origHadStepEmul) {
|
||||
DPRINTF (("TgtHandleChildChange: bkpt %x becomes step\n",
|
||||
plst->regs.REG_PC));
|
||||
bidx = -bidx;
|
||||
plst->is_step = 1;
|
||||
base->clr_step = plst->break_list[bidx].type == BRKT_INSTR;
|
||||
base->last_break = bidx;
|
||||
return True;
|
||||
}
|
||||
if (stopWanted) {
|
||||
DPRINTF (("TgtHandleChildChange: stop_wanted %d at bkpt %x\n",
|
||||
stopWanted, plst->regs.REG_PC));
|
||||
/*
|
||||
* The PC has already been adjusted by BreakIdentify
|
||||
*/
|
||||
*status = STS_MAKESIG (stopWanted);
|
||||
return True;
|
||||
}
|
||||
/*
|
||||
* All the handling is done in ptrace_2_svc() so call it
|
||||
*/
|
||||
bidx = -bidx;
|
||||
DPRINTF (("TgtHandleChildChange: last %d (%s) restarting bkpt %d\n",
|
||||
plst->last_start, GetLastStartName (plst->last_start),
|
||||
bidx));
|
||||
base->clr_step = 1;
|
||||
base->last_break = bidx; /* remember which one */
|
||||
plst->running = 0; /* So that ptrace is accepted */
|
||||
pin.pid = plst->pid;
|
||||
|
||||
if (plst->last_start == LAST_STEP) {
|
||||
pin.addr.req = RPT_SINGLESTEP;
|
||||
} else {
|
||||
pin.addr.req = RPT_CONT;
|
||||
}
|
||||
pin.addr.ptrace_addr_data_in_u.address = 1;
|
||||
pin.data = 0;
|
||||
pin.flags = PTRFLG_NON_OWNER;
|
||||
out = RPCGENSRVNAME (ptrace_2_svc) (&pin, NULL);
|
||||
if (out->result == 0)
|
||||
return False; /* Continue waiting */
|
||||
DPRINTF (("TgtHandleChildChange: failed to restart bkpt!\n"));
|
||||
/*
|
||||
* If something went wrong, just stop on breakpoint
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* else sig != SIGTRAP
|
||||
*/
|
||||
/*
|
||||
* finally, fill in stop info in break point array base
|
||||
*/
|
||||
if (bidx > 0) { /* store break info */
|
||||
/*
|
||||
* will need to get off the break for SW breakpoints only
|
||||
*/
|
||||
base->clr_step = plst->break_list[bidx].type == BRKT_INSTR;
|
||||
base->last_break = bidx; /* remember which one */
|
||||
} else if (base) { /* clear break info */
|
||||
base->clr_step = False; /* not stopped on break */
|
||||
base->last_break = 0;
|
||||
}
|
||||
/*
|
||||
* decision to notify owner based on last_start
|
||||
*/
|
||||
} /* stopped */
|
||||
else { /* terminated */
|
||||
|
||||
if (plst->last_start == LAST_START) { /* spawn failed */
|
||||
TgtNotifyAll (idx, BMSG_EXEC_FAIL, 0, 0, -1, True);
|
||||
plst->running = False; /* not running - dead */
|
||||
plst->state = *status; /* contains errno in high word */
|
||||
return (False);
|
||||
}
|
||||
|
||||
else if ((UCHAR) (plst->last_start & ~LAST_START) < (UCHAR) LAST_KILLED)
|
||||
plst->last_start = LAST_NONE; /* doesn't matter anymore */
|
||||
else
|
||||
return (False); /* killed and detach already notified */
|
||||
}
|
||||
return (True); /* stop and notify */
|
||||
}
|
||||
|
||||
#ifdef DDEBUG
|
||||
|
||||
/*
|
||||
* TgtDbgPtrace - debug version of ptrace.
|
||||
*/
|
||||
|
||||
int
|
||||
TgtDbgPtrace (int request, PID pid, char *addr, int data, void *addr2)
|
||||
{
|
||||
int diag;
|
||||
|
||||
DPRINTF (("TgtDbgPtrace: entered (%s (%d), %d, %x, %d, %x)\n",
|
||||
PtraceName (request), request, pid, (int) addr, data,
|
||||
(int) addr2));
|
||||
|
||||
if (request == RPT_WRITETEXT || request == RPT_WRITEDATA) {
|
||||
int i;
|
||||
|
||||
DPRINTF (("TgtDbgPtrace:"));
|
||||
if (rdb_debug) {
|
||||
for (i = 0; i < data && i < 16; ++i) {
|
||||
printf (" %02x", ((char *) addr2)[i] & 0xFF);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
diag = TgtRealPtrace (request, pid, addr, data, addr2);
|
||||
|
||||
DPRINTF (("TgtDbgPtrace: returned %d (%x) errno %d\n",
|
||||
diag, diag, getErrno ()));
|
||||
|
||||
if (request == RPT_GETREGS || request == RPT_GETTHREADREGS
|
||||
|| request == RPT_SETREGS || request == RPT_SETTHREADREGS) {
|
||||
/*
|
||||
* Use DPRINTF() so as to have the id prefix
|
||||
*/
|
||||
DPRINTF (("TgtDbgPtrace: (%s) PC = %x, SP = %x, FP = %x\n",
|
||||
PtraceName (request),
|
||||
((xdr_regs *) addr)->REG_PC,
|
||||
((xdr_regs *) addr)->REG_SP, ((xdr_regs *) addr)->REG_FP));
|
||||
}
|
||||
|
||||
return (diag);
|
||||
}
|
||||
#endif /* DDEBUG */
|
||||
@@ -1,355 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Component: RDBG
|
||||
* Module: servtsp.c
|
||||
*
|
||||
* Synopsis: Transport management for remote debug server.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
#include <signal.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/svc.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
static int out_sock;
|
||||
static int warm_test;
|
||||
|
||||
static void TimeTestHandler ();
|
||||
|
||||
/*
|
||||
* TspInit - Initialize the transport system.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
TspInit (int id)
|
||||
{
|
||||
struct sigaction sa;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/*
|
||||
* setup a socket to send event messages back through
|
||||
*/
|
||||
out_sock = socket (PF_INET, SOCK_DGRAM, 0);
|
||||
if (out_sock < 0) {
|
||||
DPRINTF (("TspInit: socket() failed %d errno %d\n",
|
||||
out_sock, getErrno ()));
|
||||
return; /* failed to open socket, let caller deal with */
|
||||
}
|
||||
|
||||
memset ((void *) (&addr), 0, sizeof (addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons (BackPort);
|
||||
if (bind (out_sock, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
|
||||
DPRINTF (("TspInit: bind() failed\n"));
|
||||
}
|
||||
/*
|
||||
* setup alarm timer for warm testing
|
||||
*/
|
||||
memset (&sa, 0, sizeof (sa));
|
||||
sa.sa_handler = TimeTestHandler;
|
||||
sigaction (SIGALRM, &sa, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* TspTranslateRpcAddr - translate from an RPC handle to an
|
||||
* opaque address.
|
||||
*
|
||||
* Converts the sender's address into the opaque data structure
|
||||
* used for network addresses. This is used to look up the sender
|
||||
* on each call.
|
||||
*/
|
||||
|
||||
Boolean
|
||||
TspTranslateRpcAddr (struct svc_req *rqstp, NET_OPAQUE * opaque)
|
||||
{
|
||||
struct sockaddr_in *addr; /* used as template to extract net info */
|
||||
unsigned char *up;
|
||||
|
||||
memset (opaque, 0, sizeof (NET_OPAQUE));
|
||||
/*
|
||||
* We interpret the remote address as a standard netbuf name.
|
||||
* The format is 2 bytes of address family (normally AF_INET)
|
||||
* and then a length (5) and then the IP address.
|
||||
*/
|
||||
if (rqstp->rq_xprt->xp_addrlen != 16) {
|
||||
DPRINTF (("TspTranslateRpcAddr: Unknown remote address!!!\n"));
|
||||
setErrno (EPROTONOSUPPORT);
|
||||
return False; /* invalid, so fails */
|
||||
}
|
||||
/*
|
||||
* addr = &rqstp->rq_xprt->xp_raddr;
|
||||
*/
|
||||
addr = svc_getcaller (rqstp->rq_xprt);
|
||||
/*
|
||||
* verify it is AF_INET
|
||||
*/
|
||||
if (addr->sin_family != AF_INET) { /* no, error */
|
||||
DPRINTF (("TspTranslateRpcAddr: Not an internet address!!\n"));
|
||||
setErrno (EAFNOSUPPORT); /* invalid addr family */
|
||||
return False;
|
||||
}
|
||||
/*
|
||||
* good address type
|
||||
*/
|
||||
up = (unsigned char *) &addr->sin_addr.s_addr;
|
||||
DPRINTF (("TspTranslateRpcAddr: Sent by %u.%u.%u.%u port #%u\n",
|
||||
up[0], up[1], up[2], up[3], htons (addr->sin_port)));
|
||||
memcpy (opaque, addr, sizeof (struct sockaddr_in));
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
* TspValidateAddr - validate a passed in opaque address.
|
||||
*
|
||||
* Checks that the passed in address is in the format
|
||||
* expected.
|
||||
*/
|
||||
|
||||
Boolean
|
||||
TspValidateAddr (NET_OPAQUE * opaque, NET_OPAQUE * sender)
|
||||
{
|
||||
struct sockaddr_in *addr; /* used as template to extract net info */
|
||||
|
||||
addr = (struct sockaddr_in *) opaque;
|
||||
/*
|
||||
* Verify it is AF_INET. Should check against sender IP address too
|
||||
*/
|
||||
if (addr->sin_family != AF_INET) {
|
||||
DPRINTF (("TspValidateAddr: Back port invalid: %d\n",
|
||||
htons (addr->sin_port)));
|
||||
return False; /* not valid */
|
||||
}
|
||||
/*
|
||||
* otherwise, we copy in the IP address, since client may not know it
|
||||
*/
|
||||
addr->sin_addr.s_addr = ((struct sockaddr_in *) sender)->sin_addr.s_addr;
|
||||
DPRINTF (("TspValidateAddr: Back port is %d\n", htons (addr->sin_port)));
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
* TspConnGetIndex - lookup an rpc caller's address as a connection entry.
|
||||
*
|
||||
* Looks up an ip address of a caller to locate the
|
||||
* connection index in our connection array.
|
||||
*/
|
||||
|
||||
int
|
||||
TspConnGetIndex (struct svc_req *rqstp)
|
||||
{
|
||||
int conn;
|
||||
/*
|
||||
* &rqstp->rq_xprt->xp_raddr;
|
||||
*/
|
||||
struct sockaddr_in *addr = svc_getcaller (rqstp->rq_xprt);
|
||||
|
||||
for (conn = 0; conn < conn_list_cnt; conn++) {
|
||||
if (!conn_list[conn].in_use)
|
||||
continue; /* not used */
|
||||
|
||||
if (addr->sin_addr.s_addr == ((struct sockaddr_in *)
|
||||
&conn_list[conn].sender)->sin_addr.s_addr
|
||||
&& addr->sin_port == ((struct sockaddr_in *)
|
||||
&conn_list[conn].sender)->sin_port) {
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* TspSendWaitChange - send wait-change message to clients to
|
||||
* notify change.
|
||||
*/
|
||||
|
||||
void
|
||||
TspSendWaitChange (int conn, /* connection to send to */
|
||||
BACK_MSG msg, /* BMSG type */
|
||||
UINT16 spec, /* special information */
|
||||
PID pid, /* pid it refers to */
|
||||
UINT32 context, /* additional context for message */
|
||||
Boolean force) /* force into being only message */
|
||||
{
|
||||
int idx;
|
||||
struct SEND_LIST *snd_ptr;
|
||||
|
||||
if (force) {
|
||||
/*
|
||||
* force to top, which means others gone
|
||||
*/
|
||||
idx = 0;
|
||||
conn_list[conn].send_idx = 1;
|
||||
conn_list[conn].retry = 0;
|
||||
} else {
|
||||
for (idx = 0; idx < (int) conn_list[conn].send_idx; idx++) {
|
||||
if (conn_list[conn].send_list[idx].send_type == msg
|
||||
&& conn_list[conn].send_list[idx].pid == pid)
|
||||
return; /* already pended for this pid */
|
||||
}
|
||||
idx = conn_list[conn].send_idx;
|
||||
if (idx + 1 > MAX_SEND)
|
||||
return; /* we lose it, what should we do??? */
|
||||
conn_list[conn].send_idx++;
|
||||
}
|
||||
snd_ptr = &conn_list[conn].send_list[idx];
|
||||
snd_ptr->send_type = msg; /* message to send */
|
||||
snd_ptr->retry = TSP_RETRIES; /* about 1 minute of retries */
|
||||
snd_ptr->spec = htons ((u_short) spec);
|
||||
snd_ptr->pid = htonl (pid);
|
||||
snd_ptr->context = htonl (context);
|
||||
TspSendMessage (conn, False); /* now do the send */
|
||||
}
|
||||
|
||||
/*
|
||||
* TspSendMessage - send message at top of send list for connection.
|
||||
*/
|
||||
|
||||
void
|
||||
TspSendMessage (int conn, Boolean resend)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct UDP_MSG msg;
|
||||
int cnt;
|
||||
|
||||
if (!resend && conn_list[conn].retry)
|
||||
return; /* already waiting for reply */
|
||||
|
||||
/*
|
||||
* Note on above: if no back port we can't remove unless
|
||||
* someone blows off.
|
||||
*/
|
||||
if (!resend) {
|
||||
/*
|
||||
* first time, setup. Set retry count:
|
||||
*/
|
||||
conn_list[conn].retry = conn_list[conn].send_list[0].retry;
|
||||
conn_list[conn].last_msg_num++; /* new sequence number */
|
||||
if (!warm_test++) { /* starting, so enable timer */
|
||||
alarm (2); /* resend every 2 seconds as needed */
|
||||
}
|
||||
}
|
||||
|
||||
msg.type = conn_list[conn].send_list[0].send_type;
|
||||
msg.msg_num = conn_list[conn].last_msg_num;
|
||||
msg.spec = conn_list[conn].send_list[0].spec;
|
||||
msg.pid = conn_list[conn].send_list[0].pid;
|
||||
msg.context = conn_list[conn].send_list[0].context;
|
||||
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port =
|
||||
((struct sockaddr_in *) &conn_list[conn].back_port)->sin_port;
|
||||
addr.sin_addr.s_addr =
|
||||
((struct sockaddr_in *) &conn_list[conn].back_port)->sin_addr.s_addr;
|
||||
|
||||
DPRINTF (("TspSendMessage: Sending msg %d (%s) to port %d\n",
|
||||
msg.type, BmsgNames[msg.type], HL_W (addr.sin_port)));
|
||||
|
||||
cnt = sendto (out_sock, &msg, sizeof (msg), 0, (struct sockaddr *) &addr,
|
||||
sizeof (addr));
|
||||
if (cnt != sizeof (msg)) { /* failed on send */
|
||||
printf ("%s: Failed to send msg %d to conn %d (%d vs. %ld)\n",
|
||||
taskName, msg.type, conn, cnt, (long int) sizeof (msg));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TspMessageReceive - confirmation received, now send next if any.
|
||||
*
|
||||
* - since UDP is connectionless, we batch up the sends and use
|
||||
* one at a time until we get a message indicating ready for
|
||||
* next (from ack).
|
||||
*/
|
||||
|
||||
void
|
||||
TspMessageReceive (int conn, PID pid)
|
||||
{
|
||||
/*
|
||||
* We remove the send list entry and use next if any
|
||||
*/
|
||||
conn_list[conn].retry = 0; /* reset */
|
||||
if (!warm_test || !--warm_test) {
|
||||
alarm (0); /* reset timer if not used */
|
||||
}
|
||||
#ifdef DDEBUG
|
||||
if (conn_list[conn].send_list[0].send_type == BMSG_WARM) {
|
||||
DPRINTF (("TspMessageReceive: Connection reset for conn %d\n", conn));
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Move up by one if needed
|
||||
*/
|
||||
if (!--conn_list[conn].send_idx)
|
||||
return; /* no more to do */
|
||||
|
||||
memcpy (conn_list[conn].send_list, conn_list[conn].send_list + 1, conn_list[conn].send_idx * sizeof (struct SEND_LIST)); /* copy down */
|
||||
TspSendMessage (conn, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* TspGetHostName - return client's host name.
|
||||
*
|
||||
* - this routine returns the name of the client's host or the net
|
||||
* number of unknown.
|
||||
*/
|
||||
|
||||
char *
|
||||
TspGetHostName (conn_idx)
|
||||
int conn_idx; /* client connection number */
|
||||
{
|
||||
static char buff[30]; /* largest net num */
|
||||
unsigned char *cp;
|
||||
|
||||
cp = conn_list[conn_idx].sender.c + 4;
|
||||
sprintf (buff, "%u.%u.%u.%u", cp[0], cp[1], cp[2], cp[3]);
|
||||
return buff;
|
||||
}
|
||||
|
||||
/*
|
||||
* TimeTestHandler - alarm timer handler to resend warm/wait test.
|
||||
*/
|
||||
|
||||
static void
|
||||
TimeTestHandler ()
|
||||
{
|
||||
int conn;
|
||||
|
||||
if (!warm_test)
|
||||
return; /* no longer enabled */
|
||||
|
||||
for (conn = 0; conn < conn_list_cnt; conn++) {
|
||||
/*
|
||||
* locate all that are using this
|
||||
*/
|
||||
if (!conn_list[conn].in_use)
|
||||
continue; /* not used */
|
||||
|
||||
if (!conn_list[conn].retry)
|
||||
continue;
|
||||
/*
|
||||
* found one that we are testing
|
||||
*/
|
||||
if (!--conn_list[conn].retry) {
|
||||
/*
|
||||
* Counted down the retries: blow off.
|
||||
* Need to have connection flag to indicate not blowing
|
||||
* off for cases where client is stopped due to being
|
||||
* debugged.
|
||||
*/
|
||||
ConnDelete (conn, NULL, CLOSE_IGNORE);
|
||||
continue;
|
||||
}
|
||||
TspSendMessage (conn, True); /* send another message */
|
||||
}
|
||||
alarm (2); /* setup for 2 seconds from now */
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* Component: RDB
|
||||
* Module: servutil.c
|
||||
*
|
||||
* Synopsis: Various utility routines
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <rdbg/rdbg.h>
|
||||
#include <rdbg/servrpc.h>
|
||||
|
||||
/*----- Management of per-process list ----*/
|
||||
|
||||
/*
|
||||
* ListAlloc - build up list entry.
|
||||
*
|
||||
* Notes:
|
||||
* - this is a generic routine to build up entries in the per-connection
|
||||
* list. The fields list, list_sz and list_alloc are affected.
|
||||
*/
|
||||
|
||||
Boolean
|
||||
ListAlloc (buff, clst)
|
||||
char *buff;
|
||||
CONN_LIST *clst; /* place to copy it */
|
||||
{
|
||||
int tmp;
|
||||
char *name;
|
||||
int new_len;
|
||||
int len;
|
||||
|
||||
tmp = strlen (buff);
|
||||
new_len = (int) clst->list_sz + 1 + tmp;
|
||||
if (clst->list_alloc < (unsigned) new_len) {
|
||||
/*
|
||||
* need more space
|
||||
*/
|
||||
name = (char *) Realloc (clst->list, len = new_len + MAX_FILENAME);
|
||||
if (name == NULL) {
|
||||
return (False); /* failed, no space */
|
||||
}
|
||||
clst->list_alloc = len;
|
||||
clst->list = name;
|
||||
}
|
||||
strcpy (clst->list + clst->list_sz, buff);
|
||||
clst->list_sz += tmp;
|
||||
return (True);
|
||||
}
|
||||
|
||||
/*----- Management of processes -----*/
|
||||
|
||||
/*
|
||||
* FindPidEntry - locate pid_list entry from pid
|
||||
*/
|
||||
|
||||
int
|
||||
FindPidEntry (int pid) /* pid = process identifier */
|
||||
{
|
||||
int idx;
|
||||
|
||||
/*
|
||||
* pid 0 is invalid, and signals a free slot
|
||||
*/
|
||||
if (pid_list == NULL || pid == 0) {
|
||||
return -1;
|
||||
}
|
||||
for (idx = 0; idx < pid_list_cnt; idx++) {
|
||||
if (pid_list[idx].pid == pid)
|
||||
return idx;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*----- Debug suport -----*/
|
||||
|
||||
#ifdef DDEBUG
|
||||
|
||||
/*
|
||||
* Names of debug primitives
|
||||
*/
|
||||
|
||||
const char *PtraceNames[] = {
|
||||
|
||||
"RPT_TRACEME", "RPT_PEEKTEXT", "RPT_PEEKDATA", "RPT_PEEKUSER",
|
||||
"RPT_POKETEXT", "RPT_POKEDATA", "RPT_POKEUSER", "RPT_CONT",
|
||||
"RPT_KILL", "RPT_SINGLESTEP", "RPT_ATTACH", "RPT_DETACH",
|
||||
"RPT_GETREGS", "RPT_SETREGS", "RPT_GETFPREGS", "RPT_SETFPREGS",
|
||||
"RPT_READDATA", "RPT_WRITEDATA", "RPT_READTEXT", "RPT_WRITETEXT",
|
||||
"RPT_GETFPAREGS", "RPT_SETFPAREGS", "RPT_22", "RPT_23",
|
||||
"RPT_SYSCALL", "RPT_DUMPCORE", "RPT_26", "RPT_27",
|
||||
"RPT_28", "RPT_GETUCODE", "RPT_30", "RPT_31",
|
||||
"RPT_32", "RPT_33", "RPT_34", "RPT_35",
|
||||
"RPT_36", "RPT_37", "RPT_38", "RPT_39",
|
||||
"RPT_40", "RPT_41", "RPT_42", "RPT_43",
|
||||
"RPT_44", "RPT_45", "RPT_46", "RPT_47",
|
||||
"RPT_48", "RPT_49", "RPT_GETTARGETTHREAD", "RPT_SETTARGETTHREAD",
|
||||
"RPT_THREADSUSPEND", "RPT_THREADRESUME", "RPT_THREADLIST",
|
||||
"RPT_GETTHREADNAME",
|
||||
"RPT_SETTHREADNAME", "RPT_SETTHREADREGS", "RPT_GETTHREADREGS",
|
||||
"RPT_59",
|
||||
"RPT_60", "RPT_61", "RPT_62", "RPT_63",
|
||||
"RPT_64", "RPT_65", "RPT_66", "RPT_67",
|
||||
"RPT_68", "RPT_69", "RPT_70", "RPT_71",
|
||||
"RPT_72", "RPT_73", "RPT_74", "RPT_STEPRANGE",
|
||||
"RPT_CONTTO", "RPT_SETBREAK", "RPT_CLRBREAK", "RPT_GETBREAK",
|
||||
"RPT_GETNAME", "RPT_STOP",
|
||||
"RPT_PGETREGS", "RPT_PSETREGS",
|
||||
"RPT_PSETTHREADREGS", "RPT_PGETTHREADREGS"
|
||||
};
|
||||
|
||||
const char *
|
||||
PtraceName (int req)
|
||||
{
|
||||
static char bufret[40];
|
||||
|
||||
if ((req < 0) || (req >= sizeof (PtraceNames) / sizeof (char *))) {
|
||||
sprintf (bufret, "BAD_REQ_%d", req);
|
||||
return bufret;
|
||||
}
|
||||
return PtraceNames[req];
|
||||
}
|
||||
|
||||
const char *BmsgNames[] = {
|
||||
"?", "WARM", "WAIT", "BREAK",
|
||||
"EXEC_FAIL", "DETACH", "KILLED", "NOT_PRIM",
|
||||
"NEW_PID"
|
||||
};
|
||||
|
||||
#endif /* DDEBUG */
|
||||
@@ -16,10 +16,6 @@ if HAS_LIBBSP
|
||||
SRCS += ../lib/libbsp/@RTEMS_CPU@/@RTEMS_BSP_FAMILY@/libbsp.a
|
||||
endif
|
||||
|
||||
if HAS_RDBG
|
||||
SRCS += ../librdbg/librdbg.a
|
||||
endif
|
||||
|
||||
# FIXME: ATM, there is no libcpu.a, anymore.
|
||||
# SRCS += $(wildcard $(PROJECT_LIB)/libcpu.a)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user