svn commit: r398712 - in head/devel/gdb: . files files/kgdb
John Baldwin
jhb at FreeBSD.org
Tue Oct 6 18:53:01 UTC 2015
Author: jhb (src,doc committer)
Date: Tue Oct 6 18:52:58 2015
New Revision: 398712
URL: https://svnweb.freebsd.org/changeset/ports/398712
Log:
Add a new KGDB option to the devel/gdb port. This adds a forward port
of the kernel-specific bits of kgdb to recent gdb. It only supports
amd64, i386, powerpc, powerpc64, and sparc64.
PR: 203299
Reviewed by: bdrewery
Glanced at by: emaste, jilles, luca.pizzamiglio at gmail.com (maintainer)
Differential Revision: https://reviews.freebsd.org/D3727
Added:
head/devel/gdb/files/extrapatch-kgdb (contents, props changed)
head/devel/gdb/files/extrapatch-kgdb-configure.tgt-plain (contents, props changed)
head/devel/gdb/files/extrapatch-kgdb-configure.tgt-threads (contents, props changed)
head/devel/gdb/files/kgdb/
head/devel/gdb/files/kgdb/amd64fbsd-kern.c (contents, props changed)
head/devel/gdb/files/kgdb/fbsd-kld.c (contents, props changed)
head/devel/gdb/files/kgdb/fbsd-kthr.c (contents, props changed)
head/devel/gdb/files/kgdb/fbsd-kvm.c (contents, props changed)
head/devel/gdb/files/kgdb/i386fbsd-kern.c (contents, props changed)
head/devel/gdb/files/kgdb/kgdb-main.c (contents, props changed)
head/devel/gdb/files/kgdb/kgdb.h (contents, props changed)
head/devel/gdb/files/kgdb/ppcfbsd-kern.c (contents, props changed)
head/devel/gdb/files/kgdb/sparc64fbsd-kern.c (contents, props changed)
Modified:
head/devel/gdb/Makefile
head/devel/gdb/pkg-plist
Modified: head/devel/gdb/Makefile
==============================================================================
--- head/devel/gdb/Makefile Tue Oct 6 18:26:29 2015 (r398711)
+++ head/devel/gdb/Makefile Tue Oct 6 18:52:58 2015 (r398712)
@@ -32,7 +32,7 @@ PLIST_SUB= VER=${VER}
ONLY_FOR_ARCHS= i386 amd64 powerpc powerpc64 # untested elsewhere, might work
-OPTIONS_DEFINE= DEBUG EXPAT GDB_LINK GUILE PYTHON THREADS TUI
+OPTIONS_DEFINE= DEBUG EXPAT GDB_LINK GUILE KGDB PYTHON THREADS TUI
OPTIONS_DEFAULT= GDB_LINK THREADS TUI PORT_READLINE
@@ -40,6 +40,7 @@ OPTIONS_SINGLE= READLINE
OPTIONS_SINGLE_READLINE= BASE_READLINE BUNDLED_READLINE PORT_READLINE
GDB_LINK_DESC= Create ${PREFIX}/bin/gdb symlink
+KGDB_DESC= Kernel Debugging Support
BASE_READLINE_DESC= from base system (experimental)
BUNDLED_READLINE_DESC= from gdb distfile
PORT_READLINE_DESC= from devel/readline port
@@ -76,10 +77,21 @@ CONFIGURE_TARGET= x86_64-portbld-freebsd
post-patch:
@${REINPLACE_CMD} -e 's|$$| [GDB v${PORTVERSION} for FreeBSD]|' \
${WRKSRC}/gdb/version.in
-
-post-patch-THREADS-on:
+.if ${PORT_OPTIONS:MTHREADS}
@${CP} ${FILESDIR}/fbsd-threads.c ${WRKSRC}/gdb/
@${PATCH} ${PATCH_ARGS} < ${FILESDIR}/extrapatch-threads
+.endif
+.if ${PORT_OPTIONS:MKGDB}
+ @${CP} -r ${FILESDIR}/kgdb/*.[ch] ${WRKSRC}/gdb/
+ @${PATCH} ${PATCH_ARGS} < ${FILESDIR}/extrapatch-kgdb
+.if ${PORT_OPTIONS:MTHREADS}
+ @${PATCH} ${PATCH_ARGS} < \
+ ${FILESDIR}/extrapatch-kgdb-configure.tgt-threads
+.else
+ @${PATCH} ${PATCH_ARGS} < \
+ ${FILESDIR}/extrapatch-kgdb-configure.tgt-plain
+.endif
+.endif
do-install:
${INSTALL_PROGRAM} ${WRKSRC}/gdb/gdb \
@@ -87,11 +99,18 @@ do-install:
${INSTALL_MAN} ${WRKSRC}/gdb/doc/gdb.1 \
${STAGEDIR}${MAN1PREFIX}/man/man1/gdb${VER}.1
+do-install-KGDB-on:
+ ${INSTALL_PROGRAM} ${WRKSRC}/gdb/kgdb \
+ ${STAGEDIR}${PREFIX}/bin/kgdb${VER}
+
do-install-TUI-on:
${LN} -sf gdb${VER} ${STAGEDIR}${PREFIX}/bin/gdbtui${VER}
do-install-GDB_LINK-on:
${LN} -sf gdb${VER} ${STAGEDIR}${PREFIX}/bin/gdb
+.if ${PORT_OPTIONS:MKGDB}
+ ${LN} -sf kgdb${VER} ${STAGEDIR}${PREFIX}/bin/kgdb
+.endif
do-install-PYTHON-on:
(cd ${WRKSRC}/gdb; ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python )
Added: head/devel/gdb/files/extrapatch-kgdb
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/devel/gdb/files/extrapatch-kgdb Tue Oct 6 18:52:58 2015 (r398712)
@@ -0,0 +1,226 @@
+diff --git gdb/Makefile.in gdb/Makefile.in
+index dfaa8a3..182d875 100644
+--- gdb/Makefile.in
++++ gdb/Makefile.in
+@@ -650,7 +650,8 @@ ALL_64_TARGET_OBS = \
+ ia64-linux-tdep.o ia64-vms-tdep.o ia64-tdep.o \
+ mips64obsd-tdep.o \
+ sparc64fbsd-tdep.o sparc64-linux-tdep.o sparc64nbsd-tdep.o \
+- sparc64obsd-tdep.o sparc64-sol2-tdep.o sparc64-tdep.o
++ sparc64obsd-tdep.o sparc64-sol2-tdep.o sparc64-tdep.o \
++ amd64fbsd-kern.o sparc64fbsd-kern.o
+
+ # All other target-dependent objects files (used with --enable-targets=all).
+ ALL_TARGET_OBS = \
+@@ -672,6 +673,7 @@ ALL_TARGET_OBS = \
+ i386-sol2-tdep.o i386-tdep.o i387-tdep.o \
+ i386-dicos-tdep.o i386-darwin-tdep.o \
+ iq2000-tdep.o \
++ fbsd-kld.o fbsd-kthr.o fbsd-kvm.o i386fbsd-kern.o ppcfbsd-kern.o \
+ linux-tdep.o \
+ lm32-tdep.o \
+ m32c-tdep.o \
+@@ -1123,7 +1125,7 @@ generated_files = config.h observer.h observer.inc ada-lex.c jit-reader.h \
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
+-all: gdb$(EXEEXT) $(CONFIG_ALL)
++all: gdb$(EXEEXT) kgdb$(EXEEXT) $(CONFIG_ALL)
+ @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do
+
+ installcheck:
+@@ -1393,6 +1395,12 @@ gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
+ -o gdb$(EXEEXT) gdb.o $(LIBGDB_OBS) \
+ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES)
+
++kgdb$(EXEEXT): kgdb-main.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
++ rm -f kgdb$(EXEEXT)
++ $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
++ -o kgdb$(EXEEXT) kgdb-main.o $(LIBGDB_OBS) \
++ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES)
++
+ # Convenience rule to handle recursion.
+ $(LIBGNU) $(GNULIB_H): all-lib
+ all-lib: $(GNULIB_BUILDDIR)/Makefile
+@@ -1437,7 +1445,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
+ @$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(CLEANDIRS)" subdir_do
+ rm -f *.o *.a $(ADD_FILES) *~ init.c-tmp init.l-tmp version.c-tmp
+ rm -f init.c version.c observer.h observer.inc
+- rm -f gdb$(EXEEXT) core make.log
++ rm -f gdb$(EXEEXT) core make.log kgdb$(EXEEXT)
+ rm -f gdb[0-9]$(EXEEXT)
+ rm -f test-cp-name-parser$(EXEEXT)
+ rm -f xml-builtin.c stamp-xml
+@@ -1667,6 +1675,9 @@ ALLDEPFILES = \
+ core-regset.c \
+ dcache.c dicos-tdep.c darwin-nat.c \
+ exec.c \
++ fbsd-kld.c fbsd-kthr.c fbsd-kvm.c \
++ amd64fbsd-kern.c i386fbsd-kern.c ppcfbsd-kern.c \
++ sparc64fbsd-kern.c \
+ fbsd-nat.c \
+ fbsd-tdep.c \
+ fork-child.c \
+diff --git gdb/config.in gdb/config.in
+index 9ef53b3..c55c01b 100644
+--- gdb/config.in
++++ gdb/config.in
+@@ -216,6 +216,9 @@
+ /* Define to 1 if your system has the kinfo_getvmmap function. */
+ #undef HAVE_KINFO_GETVMMAP
+
++/* Define to 1 if your system has the kvm_open2 function. */
++#undef HAVE_KVM_OPEN2
++
+ /* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
+ #undef HAVE_LANGINFO_CODESET
+
+diff --git gdb/configure gdb/configure
+index 48acfe5..f0cd958 100755
+--- gdb/configure
++++ gdb/configure
+@@ -7104,6 +7104,66 @@ $as_echo "#define HAVE_KINFO_GETVMMAP 1" >>confdefs.h
+ fi
+
+
++# kgdb needs kvm_open2 for cross-debugging
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kvm_open2" >&5
++$as_echo_n "checking for library containing kvm_open2... " >&6; }
++if test "${ac_cv_search_kvm_open2+set}" = set; then :
++ $as_echo_n "(cached) " >&6
++else
++ ac_func_search_save_LIBS=$LIBS
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++/* Override any GCC internal prototype to avoid an error.
++ Use char because int might match the return type of a GCC
++ builtin and then its argument prototype would still apply. */
++#ifdef __cplusplus
++extern "C"
++#endif
++char kvm_open2 ();
++int
++main ()
++{
++return kvm_open2 ();
++ ;
++ return 0;
++}
++_ACEOF
++for ac_lib in '' kvm; do
++ if test -z "$ac_lib"; then
++ ac_res="none required"
++ else
++ ac_res=-l$ac_lib
++ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
++ fi
++ if ac_fn_c_try_link "$LINENO"; then :
++ ac_cv_search_kvm_open2=$ac_res
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext
++ if test "${ac_cv_search_kvm_open2+set}" = set; then :
++ break
++fi
++done
++if test "${ac_cv_search_kvm_open2+set}" = set; then :
++
++else
++ ac_cv_search_kvm_open2=no
++fi
++rm conftest.$ac_ext
++LIBS=$ac_func_search_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kvm_open2" >&5
++$as_echo "$ac_cv_search_kvm_open2" >&6; }
++ac_res=$ac_cv_search_kvm_open2
++if test "$ac_res" != no; then :
++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
++
++$as_echo "#define HAVE_KVM_OPEN2 1" >>confdefs.h
++
++fi
++
++
+
+
+
+diff --git gdb/configure.ac gdb/configure.ac
+index a40860a..9035d48 100644
+--- gdb/configure.ac
++++ gdb/configure.ac
+@@ -539,6 +539,11 @@ AC_SEARCH_LIBS(kinfo_getvmmap, util,
+ [AC_DEFINE(HAVE_KINFO_GETVMMAP, 1,
+ [Define to 1 if your system has the kinfo_getvmmap function. ])])
+
++# kgdb needs kvm_open2 for cross-debugging
++AC_SEARCH_LIBS(kvm_open2, kvm,
++ [AC_DEFINE(HAVE_KVM_OPEN2, 1,
++ [Define to 1 if your system has the kvm_open2 function. ])])
++
+ AM_ICONV
+
+ # GDB may fork/exec the iconv program to get the list of supported character
+diff --git gdb/defs.h gdb/defs.h
+index ccdab18..499944f 100644
+--- gdb/defs.h
++++ gdb/defs.h
+@@ -549,6 +549,7 @@ enum gdb_osabi
+ GDB_OSABI_LINUX,
+ GDB_OSABI_FREEBSD_AOUT,
+ GDB_OSABI_FREEBSD_ELF,
++ GDB_OSABI_FREEBSD_ELF_KERNEL,
+ GDB_OSABI_NETBSD_AOUT,
+ GDB_OSABI_NETBSD_ELF,
+ GDB_OSABI_OPENBSD_ELF,
+diff --git gdb/osabi.c gdb/osabi.c
+index 3581eb3..d12656e 100644
+--- gdb/osabi.c
++++ gdb/osabi.c
+@@ -66,6 +66,7 @@ static const struct osabi_names gdb_osabi_names[] =
+ { "GNU/Linux", "linux(-gnu)?" },
+ { "FreeBSD a.out", NULL },
+ { "FreeBSD ELF", NULL },
++ { "FreeBSD ELF kernel", NULL },
+ { "NetBSD a.out", NULL },
+ { "NetBSD ELF", NULL },
+ { "OpenBSD ELF", NULL },
+diff --git gdb/regcache.c gdb/regcache.c
+index 86e648a..26a0fd5 100644
+--- gdb/regcache.c
++++ gdb/regcache.c
+@@ -1065,6 +1065,20 @@ regcache_raw_supply (struct regcache *regcache, int regnum, const void *buf)
+ }
+ }
+
++void
++regcache_raw_supply_unsigned (struct regcache *regcache, int regnum,
++ ULONGEST val)
++{
++ void *buf;
++
++ gdb_assert (regcache != NULL);
++ gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers);
++ buf = alloca (regcache->descr->sizeof_register[regnum]);
++ store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum],
++ gdbarch_byte_order (regcache->descr->gdbarch), val);
++ regcache_raw_supply (regcache, regnum, buf);
++}
++
+ /* Collect register REGNUM from REGCACHE and store its contents in BUF. */
+
+ void
+diff --git gdb/regcache.h gdb/regcache.h
+index a9fb44b..a156918 100644
+--- gdb/regcache.h
++++ gdb/regcache.h
+@@ -147,6 +147,8 @@ extern void regcache_write_pc (struct regcache *regcache, CORE_ADDR pc);
+
+ extern void regcache_raw_supply (struct regcache *regcache,
+ int regnum, const void *buf);
++extern void regcache_raw_supply_unsigned (struct regcache *regcache,
++ int regnum, ULONGEST val);
+ extern void regcache_raw_collect (const struct regcache *regcache,
+ int regnum, void *buf);
+
Added: head/devel/gdb/files/extrapatch-kgdb-configure.tgt-plain
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/devel/gdb/files/extrapatch-kgdb-configure.tgt-plain Tue Oct 6 18:52:58 2015 (r398712)
@@ -0,0 +1,50 @@
+diff --git gdb/configure.tgt gdb/configure.tgt
+index 4e4d6a9..57e4b3a 100644
+--- gdb/configure.tgt
++++ gdb/configure.tgt
+@@ -185,7 +185,13 @@ i[34567]86-*-dicos*)
+ i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
+ # Target: FreeBSD/i386
+ gdb_target_obs="i386-tdep.o i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \
+- bsd-uthread.o fbsd-tdep.o solib-svr4.o"
++ bsd-uthread.o fbsd-tdep.o solib-svr4.o \
++ fbsd-kld.o fbsd-kthr.o fbsd-kvm.o i386fbsd-kern.o"
++ if test "x$enable_64_bit_bfd" = "xyes"; then
++ # Target: FreeBSD amd64
++ gdb_target_obs="amd64-tdep.o amd64fbsd-tdep.o amd64fbsd-kern.o \
++ ${gdb_target_obs}"
++ fi
+ ;;
+ i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
+ # Target: NetBSD/i386
+@@ -405,7 +411,8 @@ powerpc*-*-freebsd*)
+ # Target: FreeBSD/powerpc
+ gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
+ ppcfbsd-tdep.o fbsd-tdep.o solib-svr4.o \
+- ravenscar-thread.o ppc-ravenscar-thread.o"
++ ravenscar-thread.o ppc-ravenscar-thread.o \
++ fbsd-kld.o fbsd-kthr.o fbsd-kvm.o ppcfbsd-kern.o"
+ ;;
+
+ powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
+@@ -534,7 +541,8 @@ sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
+ # Target: FreeBSD/sparc64
+ gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64fbsd-tdep.o \
+ fbsd-tdep.o solib-svr4.o \
+- ravenscar-thread.o sparc-ravenscar-thread.o"
++ ravenscar-thread.o sparc-ravenscar-thread.o \
++ fbsd-kld.o fbsd-kthr.o fbsd-kvm.o sparc64fbsd-kern.o"
+ ;;
+ sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
+ # Target: NetBSD/sparc
+@@ -662,7 +670,9 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
+ # Target: FreeBSD/amd64
+ gdb_target_obs="amd64-tdep.o amd64fbsd-tdep.o i386-tdep.o \
+ i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \
+- bsd-uthread.o fbsd-tdep.o solib-svr4.o"
++ bsd-uthread.o fbsd-tdep.o solib-svr4.o \
++ fbsd-kld.o fbsd-kthr.o fbsd-kvm.o amd64fbsd-kern.o \
++ i386fbsd-kern.o"
+ ;;
+ x86_64-*-mingw* | x86_64-*-cygwin*)
+ # Target: MingW/amd64
Added: head/devel/gdb/files/extrapatch-kgdb-configure.tgt-threads
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/devel/gdb/files/extrapatch-kgdb-configure.tgt-threads Tue Oct 6 18:52:58 2015 (r398712)
@@ -0,0 +1,50 @@
+diff --git gdb/configure.tgt gdb/configure.tgt
+index 4e4d6a9..57e4b3a 100644
+--- gdb/configure.tgt
++++ gdb/configure.tgt
+@@ -185,7 +185,13 @@ i[34567]86-*-dicos*)
+ i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
+ # Target: FreeBSD/i386
+ gdb_target_obs="i386-tdep.o i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \
+- fbsd-threads.o fbsd-tdep.o solib-svr4.o"
++ fbsd-threads.o fbsd-tdep.o solib-svr4.o \
++ fbsd-kld.o fbsd-kthr.o fbsd-kvm.o i386fbsd-kern.o"
++ if test "x$enable_64_bit_bfd" = "xyes"; then
++ # Target: FreeBSD amd64
++ gdb_target_obs="amd64-tdep.o amd64fbsd-tdep.o amd64fbsd-kern.o \
++ ${gdb_target_obs}"
++ fi
+ ;;
+ i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
+ # Target: NetBSD/i386
+@@ -405,7 +411,8 @@ powerpc*-*-freebsd*)
+ # Target: FreeBSD/powerpc
+ gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
+ ppcfbsd-tdep.o fbsd-threads.o fbsd-tdep.o solib-svr4.o \
+- ravenscar-thread.o ppc-ravenscar-thread.o"
++ ravenscar-thread.o ppc-ravenscar-thread.o \
++ fbsd-kld.o fbsd-kthr.o fbsd-kvm.o ppcfbsd-kern.o"
+ ;;
+
+ powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
+@@ -534,7 +541,8 @@ sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
+ # Target: FreeBSD/sparc64
+ gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64fbsd-tdep.o \
+ fbsd-tdep.o solib-svr4.o \
+- ravenscar-thread.o sparc-ravenscar-thread.o"
++ ravenscar-thread.o sparc-ravenscar-thread.o \
++ fbsd-kld.o fbsd-kthr.o fbsd-kvm.o sparc64fbsd-kern.o"
+ ;;
+ sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
+ # Target: NetBSD/sparc
+@@ -662,7 +670,9 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
+ # Target: FreeBSD/amd64
+ gdb_target_obs="amd64-tdep.o amd64fbsd-tdep.o i386-tdep.o \
+ i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \
+- fbsd-threads.o fbsd-tdep.o solib-svr4.o"
++ fbsd-threads.o fbsd-tdep.o solib-svr4.o \
++ fbsd-kld.o fbsd-kthr.o fbsd-kvm.o amd64fbsd-kern.o \
++ i386fbsd-kern.o"
+ ;;
+ x86_64-*-mingw* | x86_64-*-cygwin*)
+ # Target: MingW/amd64
Added: head/devel/gdb/files/kgdb/amd64fbsd-kern.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/devel/gdb/files/kgdb/amd64fbsd-kern.c Tue Oct 6 18:52:58 2015 (r398712)
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#ifdef __amd64__
+#include <machine/pcb.h>
+#include <machine/frame.h>
+#endif
+#include <string.h>
+
+#include <defs.h>
+#include <frame-unwind.h>
+#include "gdbcore.h"
+#include "osabi.h"
+#include <regcache.h>
+#include "solib.h"
+#include "stack.h"
+#include "symtab.h"
+#include "trad-frame.h"
+#include <amd64-tdep.h>
+
+#include "kgdb.h"
+
+static const int amd64fbsd_pcb_offset[] = {
+ -1, /* %rax */
+ 6 * 8, /* %rbx */
+ -1, /* %rcx */
+ -1, /* %rdx */
+ -1, /* %rsi */
+ -1, /* %rdi */
+ 4 * 8, /* %rbp */
+ 5 * 8, /* %rsp */
+ -1, /* %r8 ... */
+ -1,
+ -1,
+ -1,
+ 3 * 8,
+ 2 * 8,
+ 1 * 8,
+ 0 * 8, /* ... %r15 */
+ 7 * 8, /* %rip */
+ -1, /* %eflags */
+ -1, /* %cs */
+ -1, /* %ss */
+ -1, /* %ds */
+ -1, /* %es */
+ -1, /* %fs */
+ -1 /* %gs */
+};
+
+#define CODE_SEL (4 << 3)
+#define DATA_SEL (5 << 3)
+
+static void
+amd64fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr)
+{
+ gdb_byte buf[8];
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE (amd64fbsd_pcb_offset); i++)
+ if (amd64fbsd_pcb_offset[i] != -1) {
+ if (target_read_memory(pcb_addr + amd64fbsd_pcb_offset[i], buf,
+ sizeof buf) != 0)
+ continue;
+ regcache_raw_supply(regcache, i, buf);
+ }
+
+ regcache_raw_supply_unsigned(regcache, AMD64_CS_REGNUM, CODE_SEL);
+ regcache_raw_supply_unsigned(regcache, AMD64_SS_REGNUM, DATA_SEL);
+}
+
+static const int amd64fbsd_trapframe_offset[] = {
+ 6 * 8, /* %rax */
+ 7 * 8, /* %rbx */
+ 3 * 8, /* %rcx */
+ 2 * 8, /* %rdx */
+ 1 * 8, /* %rsi */
+ 0 * 8, /* %rdi */
+ 8 * 8, /* %rbp */
+ 22 * 8, /* %rsp */
+ 4 * 8, /* %r8 ... */
+ 5 * 8,
+ 9 * 8,
+ 10 * 8,
+ 11 * 8,
+ 12 * 8,
+ 13 * 8,
+ 14 * 8, /* ... %r15 */
+ 19 * 8, /* %rip */
+ 21 * 8, /* %eflags */
+ 20 * 8, /* %cs */
+ 23 * 8, /* %ss */
+ -1, /* %ds */
+ -1, /* %es */
+ -1, /* %fs */
+ -1 /* %gs */
+};
+
+#define TRAPFRAME_SIZE 192
+
+static struct trad_frame_cache *
+amd64fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ struct trad_frame_cache *cache;
+ CORE_ADDR addr, func, pc, sp;
+ const char *name;
+ int i;
+
+ if (*this_cache != NULL)
+ return (*this_cache);
+
+ cache = trad_frame_cache_zalloc (this_frame);
+ *this_cache = cache;
+
+ func = get_frame_func (this_frame);
+ sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
+
+ find_pc_partial_function (func, &name, NULL, NULL);
+ if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func)
+ {
+ /* fork_exit hasn't been called (kthread has never run), so %rsp
+ in the pcb points to the trapframe. GDB has auto-adjusted
+ %rsp for this frame to account for the "call" into
+ fork_trampoline, so "undo" the adjustment. */
+ sp += 8;
+ }
+
+ for (i = 0; i < ARRAY_SIZE (amd64fbsd_trapframe_offset); i++)
+ if (amd64fbsd_trapframe_offset[i] != -1)
+ trad_frame_set_reg_addr (cache, i, sp + amd64fbsd_trapframe_offset[i]);
+
+ /* Read %rip from trap frame. */
+ addr = sp + amd64fbsd_trapframe_offset[AMD64_RIP_REGNUM];
+ pc = read_memory_unsigned_integer (addr, 8, byte_order);
+
+ if (pc == 0 && strcmp(name, "fork_trampoline") == 0)
+ {
+ /* Initial frame of a kthread; terminate backtrace. */
+ trad_frame_set_id (cache, outer_frame_id);
+ }
+ else
+ {
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (cache, frame_id_build (sp + TRAPFRAME_SIZE, func));
+ }
+
+ return cache;
+}
+
+static void
+amd64fbsd_trapframe_this_id (struct frame_info *this_frame,
+ void **this_cache, struct frame_id *this_id)
+{
+ struct trad_frame_cache *cache =
+ amd64fbsd_trapframe_cache (this_frame, this_cache);
+
+ trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+amd64fbsd_trapframe_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct trad_frame_cache *cache =
+ amd64fbsd_trapframe_cache (this_frame, this_cache);
+
+ return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static int
+amd64fbsd_trapframe_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_prologue_cache)
+{
+ const char *name;
+
+ find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL);
+ return (name && ((strcmp (name, "calltrap") == 0)
+ || (strcmp (name, "fork_trampoline") == 0)
+ || (strcmp (name, "nmi_calltrap") == 0)
+ || (name[0] == 'X' && name[1] != '_')));
+}
+
+static const struct frame_unwind amd64fbsd_trapframe_unwind = {
+ NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
+ amd64fbsd_trapframe_this_id,
+ amd64fbsd_trapframe_prev_register,
+ NULL,
+ amd64fbsd_trapframe_sniffer
+};
+
+static void
+amd64fbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+
+ amd64_init_abi(info, gdbarch);
+
+ frame_unwind_prepend_unwinder(gdbarch, &amd64fbsd_trapframe_unwind);
+
+ set_solib_ops(gdbarch, &kld_so_ops);
+
+ fbsd_vmcore_set_supply_pcb(gdbarch, amd64fbsd_supply_pcb);
+ fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb);
+}
+
+void _initialize_amd64_kgdb_tdep(void);
+
+void
+_initialize_amd64_kgdb_tdep(void)
+{
+ gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
+ GDB_OSABI_FREEBSD_ELF_KERNEL, amd64fbsd_kernel_init_abi);
+
+#ifdef __amd64__
+ gdb_assert(offsetof(struct pcb, pcb_rbx)
+ == amd64fbsd_pcb_offset[AMD64_RBX_REGNUM]);
+ gdb_assert(offsetof(struct pcb, pcb_rbp)
+ == amd64fbsd_pcb_offset[AMD64_RBP_REGNUM]);
+ gdb_assert(offsetof(struct pcb, pcb_rsp)
+ == amd64fbsd_pcb_offset[AMD64_RSP_REGNUM]);
+ gdb_assert(offsetof(struct pcb, pcb_r12)
+ == amd64fbsd_pcb_offset[AMD64_R12_REGNUM]);
+ gdb_assert(offsetof(struct pcb, pcb_r13)
+ == amd64fbsd_pcb_offset[AMD64_R13_REGNUM]);
+ gdb_assert(offsetof(struct pcb, pcb_r14)
+ == amd64fbsd_pcb_offset[AMD64_R14_REGNUM]);
+ gdb_assert(offsetof(struct pcb, pcb_r15)
+ == amd64fbsd_pcb_offset[AMD64_R15_REGNUM]);
+ gdb_assert(offsetof(struct pcb, pcb_rip)
+ == amd64fbsd_pcb_offset[AMD64_RIP_REGNUM]);
+ gdb_assert(CODE_SEL == GSEL(GCODE_SEL, SEL_KPL));
+ gdb_assert(DATA_SEL == GSEL(GDATA_SEL, SEL_KPL));
+ gdb_assert(sizeof(struct trapframe) == TRAPFRAME_SIZE);
+ gdb_assert(offsetof(struct trapframe, tf_rax)
+ == amd64fbsd_trapframe_offset[AMD64_RAX_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_rbx)
+ == amd64fbsd_trapframe_offset[AMD64_RBX_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_rcx)
+ == amd64fbsd_trapframe_offset[AMD64_RCX_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_rdx)
+ == amd64fbsd_trapframe_offset[AMD64_RDX_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_rsi)
+ == amd64fbsd_trapframe_offset[AMD64_RSI_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_rdi)
+ == amd64fbsd_trapframe_offset[AMD64_RDI_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_rbp)
+ == amd64fbsd_trapframe_offset[AMD64_RBP_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_rsp)
+ == amd64fbsd_trapframe_offset[AMD64_RSP_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_r8)
+ == amd64fbsd_trapframe_offset[AMD64_R8_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_r9)
+ == amd64fbsd_trapframe_offset[AMD64_R9_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_r10)
+ == amd64fbsd_trapframe_offset[AMD64_R10_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_r11)
+ == amd64fbsd_trapframe_offset[AMD64_R11_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_r12)
+ == amd64fbsd_trapframe_offset[AMD64_R12_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_r13)
+ == amd64fbsd_trapframe_offset[AMD64_R13_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_r14)
+ == amd64fbsd_trapframe_offset[AMD64_R14_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_r15)
+ == amd64fbsd_trapframe_offset[AMD64_R15_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_rip)
+ == amd64fbsd_trapframe_offset[AMD64_RIP_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_rflags)
+ == amd64fbsd_trapframe_offset[AMD64_EFLAGS_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_cs)
+ == amd64fbsd_trapframe_offset[AMD64_CS_REGNUM]);
+ gdb_assert(offsetof(struct trapframe, tf_ss)
+ == amd64fbsd_trapframe_offset[AMD64_SS_REGNUM]);
+#endif
+}
Added: head/devel/gdb/files/kgdb/fbsd-kld.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/devel/gdb/files/kgdb/fbsd-kld.c Tue Oct 6 18:52:58 2015 (r398712)
@@ -0,0 +1,591 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <libgen.h>
+
+#include <defs.h>
+#include <command.h>
+#include <completer.h>
+#include <environ.h>
+#include <exec.h>
+#include <frame-unwind.h>
+#include <inferior.h>
+#include <objfiles.h>
+#include <gdbcore.h>
+#include <language.h>
+#include "solib.h"
+#include <solist.h>
+
+#include "kgdb.h"
+
+struct lm_info {
+ CORE_ADDR base_address;
+};
+
+struct kld_info {
+ /* Offsets of fields in linker_file structure. */
+ CORE_ADDR off_address, off_filename, off_pathname, off_next;
+
+ /* KVA of 'linker_path' which corresponds to the kern.module_path sysctl .*/
+ CORE_ADDR module_path_addr;
+ CORE_ADDR linker_files_addr;
+ CORE_ADDR kernel_file_addr;
+};
+
+struct target_so_ops kld_so_ops;
+
+/* Per-program-space data key. */
+static const struct program_space_data *kld_pspace_data;
+
+static void
+kld_pspace_data_cleanup (struct program_space *pspace, void *arg)
+{
+ struct kld_info *info = arg;
+
+ xfree (info);
+}
+
+/* Get the current kld data. If none is found yet, add it now. This
+ function always returns a valid object. */
+
+static struct kld_info *
+get_kld_info (void)
+{
+ struct kld_info *info;
+
+ info = program_space_data (current_program_space, kld_pspace_data);
+ if (info != NULL)
+ return info;
+
+ info = XCNEW (struct kld_info);
+ set_program_space_data (current_program_space, kld_pspace_data, info);
+ return info;
+}
+
+static int
+kld_ok (char *path)
+{
+ struct stat sb;
+
+ if (stat(path, &sb) == 0 && S_ISREG(sb.st_mode))
+ return (1);
+ return (0);
+}
+
+/*
+ * Look for a matching file checking for debug suffixes before the raw file:
+ * - filename + ".debug" (e.g. foo.ko.debug)
+ * - filename (e.g. foo.ko)
+ */
+static const char *kld_suffixes[] = {
+ ".debug",
+ ".symbols",
+ "",
+ NULL
+};
+
+static int
+check_kld_path (char *path, size_t path_size)
+{
+ const char **suffix;
+ char *ep;
+
+ ep = path + strlen(path);
+ suffix = kld_suffixes;
+ while (*suffix != NULL) {
+ if (strlcat(path, *suffix, path_size) < path_size) {
+ if (kld_ok(path))
+ return (1);
+ }
+
+ /* Restore original path to remove suffix. */
+ *ep = '\0';
+ suffix++;
+ }
+ return (0);
+}
+
+/*
+ * Try to find the path for a kld by looking in the kernel's directory and
+ * in the various paths in the module path.
+ */
+static int
+find_kld_path (char *filename, char *path, size_t path_size)
+{
+ struct kld_info *info;
+ struct cleanup *cleanup;
+ char *module_path;
+ char *kernel_dir, *module_dir, *cp;
+ int error;
+
+ info = get_kld_info();
+ if (exec_bfd) {
+ kernel_dir = dirname(bfd_get_filename(exec_bfd));
+ if (kernel_dir != NULL) {
+ snprintf(path, path_size, "%s/%s", kernel_dir,
+ filename);
+ if (check_kld_path(path, path_size))
+ return (1);
+ }
+ }
+ if (info->module_path_addr != 0) {
+ target_read_string(info->module_path_addr, &module_path,
+ PATH_MAX, &error);
+ if (error == 0) {
+ cleanup = make_cleanup(xfree, module_path);
+ cp = module_path;
+ while ((module_dir = strsep(&cp, ";")) != NULL) {
+ snprintf(path, path_size, "%s/%s", module_dir,
+ filename);
+ if (check_kld_path(path, path_size)) {
+ do_cleanups(cleanup);
+ return (1);
+ }
+ }
+ do_cleanups(cleanup);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Read a kernel pointer given a KVA in 'address'.
+ */
+static CORE_ADDR
+read_pointer (CORE_ADDR address)
+{
+ struct type *ptr_type;
+ gdb_byte ptr_buf[8];
+ int arch_size;
+
+ arch_size = bfd_get_arch_size (exec_bfd);
+ if (arch_size == -1)
+ return (0);
+ ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
+ if (target_read_memory(address, ptr_buf, arch_size / 8) != 0)
+ return (0);
+ return (extract_typed_address (ptr_buf, ptr_type));
+}
+
+/*
+ * Try to find this kld in the kernel linker's list of linker files.
+ */
+static int
+find_kld_address (char *arg, CORE_ADDR *address)
+{
+ struct kld_info *info;
+ CORE_ADDR kld;
+ char *kld_filename;
+ char *filename;
+ int error;
+
+ info = get_kld_info();
+ if (info->linker_files_addr == 0 || info->off_address == 0 ||
+ info->off_filename == 0 || info->off_next == 0)
+ return (0);
+
+ filename = basename(arg);
+ for (kld = read_pointer(info->linker_files_addr); kld != 0;
+ kld = read_pointer(kld + info->off_next)) {
+ /* Try to read this linker file's filename. */
+ target_read_string(read_pointer(kld + info->off_filename),
+ &kld_filename, PATH_MAX, &error);
+ if (error)
+ continue;
+
+ /* Compare this kld's filename against our passed in name. */
+ if (strcmp(kld_filename, filename) != 0) {
+ xfree(kld_filename);
+ continue;
+ }
+ xfree(kld_filename);
+
+ /*
+ * We found a match, use its address as the base
+ * address if we can read it.
+ */
+ *address = read_pointer(kld + info->off_address);
+ if (*address == 0)
+ return (0);
+ return (1);
+ }
+ return (0);
+}
+
+static void
+adjust_section_address (struct target_section *sec, CORE_ADDR *curr_base)
+{
+ struct bfd_section *asect = sec->the_bfd_section;
+ bfd *abfd = asect->owner;
+
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) {
+ sec->addr += *curr_base;
+ sec->endaddr += *curr_base;
+ return;
+ }
+
+ *curr_base = align_power(*curr_base,
+ bfd_get_section_alignment(abfd, asect));
+ sec->addr = *curr_base;
+ sec->endaddr = sec->addr + bfd_section_size(abfd, asect);
+ *curr_base = sec->endaddr;
+}
+
+static void
+load_kld (char *path, CORE_ADDR base_addr, int from_tty)
+{
+ struct section_addr_info *sap;
+ struct target_section *sections = NULL, *sections_end = NULL, *s;
+ struct cleanup *cleanup;
+ bfd *bfd;
+ CORE_ADDR curr_addr;
+ int add_flags, i;
+
+ /* Open the kld. */
+ bfd = bfd_openr(path, gnutarget);
+ if (bfd == NULL)
+ error("\"%s\": can't open: %s", path,
+ bfd_errmsg(bfd_get_error()));
+ cleanup = make_cleanup_bfd_unref(bfd);
+
+ if (!bfd_check_format(bfd, bfd_object))
+ error("\%s\": not an object file", path);
+
+ /* Make sure we have a .text section. */
+ if (bfd_get_section_by_name (bfd, ".text") == NULL)
+ error("\"%s\": can't find text section", path);
+
+ /* Build a section table from the bfd and relocate the sections. */
+ if (build_section_table (bfd, §ions, §ions_end))
+ error("\"%s\": can't find file sections", path);
+ make_cleanup(xfree, sections);
+ curr_addr = base_addr;
+ for (s = sections; s < sections_end; s++)
+ adjust_section_address(s, &curr_addr);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-ports-head
mailing list