diff --git a/devel/gdb/Makefile b/devel/gdb/Makefile index 029f36d86653..df5668984623 100644 --- a/devel/gdb/Makefile +++ b/devel/gdb/Makefile @@ -1,195 +1,194 @@ PORTNAME= gdb -DISTVERSION= 14.1 -PORTREVISION= 2 +DISTVERSION= 15.1 CATEGORIES= devel MASTER_SITES= GNU MAINTAINER= pizzamig@FreeBSD.org COMMENT= GNU Project Debugger WWW= https://www.gnu.org/software/gdb/ LICENSE= GPLv3 LICENSE_FILE= ${WRKSRC}/COPYING3 LIB_DEPENDS= libexpat.so:textproc/expat2 \ libgmp.so:math/gmp \ libmpfr.so:math/mpfr \ libzstd.so:archivers/zstd TEST_DEPENDS= runtest:misc/dejagnu -USES= compiler:c++11-lang cpe gmake libtool makeinfo pkgconfig tar:xz +USES= compiler:c++17-lang cpe gmake libtool makeinfo pkgconfig tar:xz USE_PYTHON= flavors py3kplist TEST_TARGET= check CPE_VENDOR= gnu GNU_CONFIGURE= yes CONFIGURE_ENV= CONFIGURED_M4=m4 CONFIGURED_BISON=byacc CONFIGURE_ARGS= --program-suffix=${VER} \ --disable-sim \ --enable-targets=all --enable-64-bit-bfd \ --with-separate-debug-dir=/usr/lib/debug \ --with-additional-debug-dirs=${LOCALBASE}/lib/debug \ ${ICONV_CONFIGURE_ARG} \ --without-libunwind-ia64 CONFIGURE_OUTSOURCE= yes CFLAGS:= ${CFLAGS:C/ +$//} # blanks at EOL creep in sometimes CFLAGS+= -DRL_NO_COMPAT EXCLUDE= dejagnu expect texinfo intl EXTRACT_AFTER_ARGS= ${EXCLUDE:S/^/--exclude /} VER= ${DISTVERSION:S/.//g} PLIST_SUB= VER=${VER} OPTIONS_DEFINE= DEBUGINFOD GDB_LINK GUILE KGDB NLS PYTHON \ SOURCE_HIGHLIGHT TUI XXHASH OPTIONS_DEFAULT= GDB_LINK KGDB NLS PYTHON SOURCE_HIGHLIGHT \ TUI XXHASH OPTIONS_DEFAULT+= PORT_READLINE PORT_ICONV SYSTEM_ZLIB OPTIONS_SINGLE= READLINE ICONV ZLIB OPTIONS_SINGLE_READLINE= BUNDLED_READLINE PORT_READLINE OPTIONS_SINGLE_ICONV= PORT_ICONV SYSTEM_ICONV OPTIONS_SINGLE_ZLIB= BUNDLED_ZLIB SYSTEM_ZLIB DEBUGINFOD_DESC= Build gdb with debuginfod server support GDB_LINK_DESC= Create ${PREFIX}/bin/gdb symlink KGDB_DESC= Kernel debugging support BUNDLED_READLINE_DESC= from gdb distfile BUNDLED_ZLIB_DESC= from gdb distfile PORT_READLINE_DESC= from devel/readline port PORT_ICONV_DESC= use libiconv, with wider charset support SOURCE_HIGHLIGHT_DESC= Syntax highlighting support SYSTEM_ICONV_DESC= use libc iconv, with no wchar support SYSTEM_ZLIB_DESC= use system zlib TUI_DESC= Text User Interface support XXHASH_DESC= Use xxHash for hashing (faster) OPTIONS_SUB= yes BUNDLED_READLINE_CONFIGURE_OFF= --with-system-readline DEBUGINFOD_CONFIGURE_WITH= debuginfod DEBUGINFOD_LIB_DEPENDS= libdebuginfod.so:devel/elfutils GUILE_CONFIGURE_WITH= guile=guile-${GUILE_VER} GUILE_USES= guile:2.2,3.0 NLS_USES= gettext-runtime PORT_READLINE_USES= readline PORT_ICONV_USES= iconv:wchar_t PYTHON_CONFIGURE_ON= --with-python=${PYTHON_CMD} PYTHON_CONFIGURE_OFF= --without-python PYTHON_USES= python SOURCE_HIGHLIGHT_CONFIGURE_ENABLE= source-highlight SOURCE_HIGHLIGHT_LIB_DEPENDS= \ libsource-highlight.so:textproc/source-highlight SYSTEM_ICONV_USES= iconv SYSTEM_ZLIB_CONFIGURE_WITH= system-zlib TUI_CONFIGURE_ENABLE= tui XXHASH_CONFIGURE_OFF= --with-xxhash=no XXHASH_LIB_DEPENDS= libxxhash.so:devel/xxhash ALL_TARGET= all-gdb .include .if ${PORT_OPTIONS:MPYTHON} .if ${PYTHON_VER} != ${PYTHON_DEFAULT} PKGNAMESUFFIX= ${PYTHON_PKGNAMESUFFIX} .endif .endif .if ${PORT_OPTIONS:MPYTHON} && \ (exists(/usr/lib/libc++.so.1) || exists(/lib/libc++.so.1)) USE_GITHUB= nodefault GH_ACCOUNT= bsdjhb:libcxx GH_PROJECT= libcxx-gdbpy:libcxx -GH_TAGNAME= 03d0d9b:libcxx +GH_TAGNAME= 4bb8585:libcxx # Workaround USE_GITHUB preventing the default DISTFILES DISTFILES= ${DISTNAME}${EXTRACT_SUFX} .if exists(/usr/lib/libc++.so.1) LIBCXX_DIR= /usr/lib .else LIBCXX_DIR= /lib .endif PLIST_SUB+= LIBCXX_DIR="${LIBCXX_DIR}" PLIST_SUB+= LIBCXX="" .else PLIST_SUB+= LIBCXX="@comment " .endif .if ! ${PORT_OPTIONS:MBUNDLED_ZLIB} EXCLUDE+= zlib .endif .if ${ARCH} == amd64 CONFIGURE_TARGET= x86_64-portbld-freebsd${OSREL} .endif post-patch: @${REINPLACE_CMD} -e 's|$$| [GDB v${DISTVERSION} for FreeBSD]|' \ ${WRKSRC}/gdb/version.in post-patch-KGDB-on: @${CP} -r ${FILESDIR}/kgdb/*.[ch] ${WRKSRC}/gdb/ @${PATCH} -d ${PATCH_WRKSRC} ${PATCH_ARGS} < ${FILESDIR}/extrapatch-kgdb do-install: ${INSTALL_PROGRAM} ${INSTALL_WRKSRC}/gdb/gdb \ ${STAGEDIR}${PREFIX}/bin/gdb${VER} ${INSTALL_MAN} ${WRKSRC}/gdb/doc/gdb.1 \ ${STAGEDIR}${PREFIX}/share/man/man1/gdb${VER}.1 (cd ${INSTALL_WRKSRC}/gdb/data-directory ; ${SETENVI} ${WRK_ENV} \ ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-syscalls ) do-install-KGDB-on: ${INSTALL_PROGRAM} ${INSTALL_WRKSRC}/gdb/kgdb \ ${STAGEDIR}${PREFIX}/bin/kgdb${VER} ${INSTALL_MAN} ${FILESDIR}/kgdb/kgdb.1 \ ${STAGEDIR}${PREFIX}/share/man/man1/kgdb${VER}.1 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 ${LN} -sf gdb${VER}.1 ${STAGEDIR}${PREFIX}/share/man/man1/gdb.1 .if ${PORT_OPTIONS:MKGDB} ${LN} -sf kgdb${VER} ${STAGEDIR}${PREFIX}/bin/kgdb ${LN} -sf kgdb${VER}.1 ${STAGEDIR}${PREFIX}/share/man/man1/kgdb.1 .endif do-install-PYTHON-on: (cd ${INSTALL_WRKSRC}/gdb ; ${SETENVI} ${WRK_ENV} \ ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python ) (cd ${INSTALL_WRKSRC}/gdb/data-directory ; ${SETENVI} ${WRK_ENV} \ ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python ) @(cd ${STAGEDIR}${PREFIX}/share/gdb/python && \ ${PYTHON_CMD} -m compileall .) . for f in gdb gdb/command gdb/function gdb/printer @(cd ${STAGEDIR}${PREFIX}/share/gdb/python/${f} ; ${CHMOD} 644 *.py* ) . endfor .if exists(/usr/lib/libc++.so.1) || exists(/lib/libc++.so.1) @(cd ${WRKSRC_libcxx} ; ${SETENVI} ${WRK_ENV} \ ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} \ LIBCXX_DIR="${LIBCXX_DIR}" install ) @(cd ${STAGEDIR}${PREFIX}/share/gdb/auto-load/${LIBCXX_DIR} && \ ${PYTHON_CMD} -m compileall .) @(cd ${STAGEDIR}${PREFIX}/share/libcxx-gdbpy/libcxx && \ ${PYTHON_CMD} -m compileall .) .endif # DO NOT try and add rules here to strip .go files, no matter how loudly # testport / stage-qa shouts at you about it, because .go files (which are # compiled bytecode) are not intended to be stripped and doing so causes # breakage at run time. do-install-GUILE-on: (cd ${INSTALL_WRKSRC}/gdb ; ${SETENVI} ${WRK_ENV} \ ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-guile ) (cd ${INSTALL_WRKSRC}/gdb/data-directory ; ${SETENVI} ${WRK_ENV} \ ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-guile ) .include diff --git a/devel/gdb/distinfo b/devel/gdb/distinfo index 95fd730add1c..68103e44a681 100644 --- a/devel/gdb/distinfo +++ b/devel/gdb/distinfo @@ -1,5 +1,5 @@ -TIMESTAMP = 1702493574 -SHA256 (gdb-14.1.tar.xz) = d66df51276143451fcbff464cc8723d68f1e9df45a6a2d5635a54e71643edb80 -SIZE (gdb-14.1.tar.xz) = 24108624 -SHA256 (bsdjhb-libcxx-gdbpy-03d0d9b_GH0.tar.gz) = 2c1563f361d4fb59b54b1b39bff5cdf609d73962758eb05a8cdfe2c22551b259 -SIZE (bsdjhb-libcxx-gdbpy-03d0d9b_GH0.tar.gz) = 6052 +TIMESTAMP = 1722632408 +SHA256 (gdb-15.1.tar.xz) = 38254eacd4572134bca9c5a5aa4d4ca564cbbd30c369d881f733fb6b903354f2 +SIZE (gdb-15.1.tar.xz) = 24295712 +SHA256 (bsdjhb-libcxx-gdbpy-4bb8585_GH0.tar.gz) = f182d52b7a88260846ce65a451e9631a04dceaeb738889156e1168fa351306ea +SIZE (bsdjhb-libcxx-gdbpy-4bb8585_GH0.tar.gz) = 6234 diff --git a/devel/gdb/files/extrapatch-kgdb b/devel/gdb/files/extrapatch-kgdb index f9098cc19de8..340f63662257 100644 --- a/devel/gdb/files/extrapatch-kgdb +++ b/devel/gdb/files/extrapatch-kgdb @@ -1,605 +1,601 @@ diff --git gdb/Makefile.in gdb/Makefile.in -index 9c0a0bff2cd..0e62786dd31 100644 +index 84bc54b303e..e2df898d907 100644 --- gdb/Makefile.in +++ gdb/Makefile.in -@@ -704,6 +704,7 @@ ALL_AMD_DBGAPI_TARGET_OBS = \ +@@ -723,6 +723,7 @@ ALL_AMD_DBGAPI_TARGET_OBS = \ # All target-dependent objects files that require 64-bit CORE_ADDR # (used with --enable-targets=all --enable-64-bit-bfd). ALL_64_TARGET_OBS = \ + aarch64-fbsd-kern.o \ aarch64-fbsd-tdep.o \ aarch64-linux-tdep.o \ aarch64-newlib-tdep.o \ -@@ -718,6 +719,7 @@ ALL_64_TARGET_OBS = \ +@@ -737,6 +738,7 @@ ALL_64_TARGET_OBS = \ amd64-darwin-tdep.o \ amd64-dicos-tdep.o \ amd64-fbsd-tdep.o \ + amd64fbsd-kern.o \ amd64-linux-tdep.o \ amd64-netbsd-tdep.o \ amd64-obsd-tdep.o \ -@@ -737,18 +739,21 @@ ALL_64_TARGET_OBS = \ +@@ -756,18 +758,21 @@ ALL_64_TARGET_OBS = \ ia64-vms-tdep.o \ loongarch-linux-tdep.o \ loongarch-tdep.o \ + mipsfbsd-kern.o \ mips-fbsd-tdep.o \ mips-linux-tdep.o \ mips-netbsd-tdep.o \ mips-sde-tdep.o \ mips-tdep.o \ mips64-obsd-tdep.o \ + riscv-fbsd-kern.o \ riscv-fbsd-tdep.o \ riscv-linux-tdep.o \ riscv-none-tdep.o \ riscv-ravenscar-thread.o \ riscv-tdep.o \ sparc64-fbsd-tdep.o \ + sparc64fbsd-kern.o \ sparc64-linux-tdep.o \ sparc64-netbsd-tdep.o \ sparc64-obsd-tdep.o \ -@@ -773,6 +778,7 @@ ALL_TARGET_OBS = \ +@@ -792,6 +797,7 @@ ALL_TARGET_OBS = \ arch/loongarch.o \ arch/ppc-linux-common.o \ arm-bsd-tdep.o \ + arm-fbsd-kern.o \ arm-fbsd-tdep.o \ arm-linux-tdep.o \ arm-netbsd-tdep.o \ -@@ -790,6 +796,8 @@ ALL_TARGET_OBS = \ +@@ -809,6 +815,8 @@ ALL_TARGET_OBS = \ csky-linux-tdep.o \ csky-tdep.o \ dicos-tdep.o \ + fbsd-kld.o \ + fbsd-kthr.o \ fbsd-tdep.o \ frv-linux-tdep.o \ frv-tdep.o \ -@@ -804,6 +812,7 @@ ALL_TARGET_OBS = \ +@@ -823,6 +831,7 @@ ALL_TARGET_OBS = \ i386-bsd-tdep.o \ i386-darwin-tdep.o \ i386-dicos-tdep.o \ + i386fbsd-kern.o \ i386-fbsd-tdep.o \ i386-gnu-tdep.o \ i386-go32-tdep.o \ -@@ -841,6 +850,7 @@ ALL_TARGET_OBS = \ +@@ -860,6 +869,7 @@ ALL_TARGET_OBS = \ obsd-tdep.o \ or1k-linux-tdep.o \ or1k-tdep.o \ + ppcfbsd-kern.o \ ppc-fbsd-tdep.o \ ppc-linux-tdep.o \ ppc-netbsd-tdep.o \ -@@ -1642,6 +1652,7 @@ ALLDEPFILES = \ +@@ -1666,6 +1676,7 @@ ALLDEPFILES = \ arch/riscv.c \ arch/tic6x.c \ aarch32-tdep.c \ + aarch64-fbsd-kern.c \ aarch64-fbsd-nat.c \ aarch64-fbsd-tdep.c \ aarch64-linux-nat.c \ -@@ -1662,6 +1673,7 @@ ALLDEPFILES = \ +@@ -1686,6 +1697,7 @@ ALLDEPFILES = \ amd64-bsd-nat.c \ amd64-darwin-tdep.c \ amd64-dicos-tdep.c \ + amd64fbsd-kern.c \ amd64-fbsd-nat.c \ amd64-fbsd-tdep.c \ amd64-linux-nat.c \ -@@ -1678,6 +1690,7 @@ ALLDEPFILES = \ +@@ -1702,6 +1714,7 @@ ALLDEPFILES = \ arc-linux-nat.c \ arc-tdep.c \ arm-bsd-tdep.c \ + arm-fbsd-kern.c \ arm-fbsd-nat.c \ arm-fbsd-tdep.c \ arm-linux-nat.c \ -@@ -1697,6 +1710,9 @@ ALLDEPFILES = \ +@@ -1721,6 +1734,9 @@ ALLDEPFILES = \ csky-tdep.c \ darwin-nat.c \ dicos-tdep.c \ + fbsd-kld.c \ + fbsd-kthr.c \ + fbsd-kvm.c \ fbsd-nat.c \ fbsd-tdep.c \ fork-child.c \ -@@ -1717,6 +1733,7 @@ ALLDEPFILES = \ +@@ -1741,6 +1757,7 @@ ALLDEPFILES = \ i386-darwin-nat.c \ i386-darwin-tdep.c \ i386-dicos-tdep.c \ + i386fbsd-kern.c \ i386-fbsd-nat.c \ i386-fbsd-tdep.c \ i386-gnu-nat.c \ -@@ -1757,6 +1774,7 @@ ALLDEPFILES = \ +@@ -1781,6 +1798,7 @@ ALLDEPFILES = \ microblaze-linux-tdep.c \ microblaze-tdep.c \ mingw-hdep.c \ + mipsfbsd-kern.c \ mips-fbsd-nat.c \ mips-fbsd-tdep.c \ mips-linux-nat.c \ -@@ -1777,6 +1795,7 @@ ALLDEPFILES = \ +@@ -1801,6 +1819,7 @@ ALLDEPFILES = \ obsd-tdep.c \ or1k-linux-nat.c \ posix-hdep.c \ + ppcfbsd-kern.c \ ppc-fbsd-nat.c \ ppc-fbsd-tdep.c \ ppc-linux-nat.c \ -@@ -1791,6 +1810,7 @@ ALLDEPFILES = \ +@@ -1815,6 +1834,7 @@ ALLDEPFILES = \ procfs.c \ ravenscar-thread.c \ remote-sim.c \ + riscv-fbsd-kern.c \ riscv-fbsd-nat.c \ riscv-fbsd-tdep.c \ riscv-linux-nat.c \ -@@ -1828,6 +1848,7 @@ ALLDEPFILES = \ +@@ -1852,6 +1872,7 @@ ALLDEPFILES = \ sparc-sol2-nat.c \ sparc-sol2-tdep.c \ sparc-tdep.c \ + sparc64fbsd-kern.c \ sparc64-fbsd-nat.c \ sparc64-fbsd-tdep.c \ sparc64-linux-nat.c \ -@@ -1915,7 +1936,7 @@ generated_files = \ +@@ -1939,7 +1960,7 @@ generated_files = \ # Flags needed to compile Python code PYTHON_CFLAGS = @PYTHON_CFLAGS@ --all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb -+all: gdb$(EXEEXT) kgdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb +-all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb gcore ++all: gdb$(EXEEXT) kgdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb gcore @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=$(SUBDIRS)" subdir_do # Rule for compiling .c files in the top-level gdb directory. -@@ -2178,6 +2199,12 @@ ifneq ($(CODESIGN_CERT),) +@@ -2205,6 +2226,12 @@ ifneq ($(CODESIGN_CERT),) $(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT) endif +kgdb$(EXEEXT): kgdb-main.o $(LIBGDB_OBS) $(CDEPS) $(TDEPLIBS) + $(SILENCE) rm -f kgdb$(EXEEXT) + $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \ + -o kgdb$(EXEEXT) kgdb-main.o $(LIBGDB_OBS) \ + $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) + # This is useful when debugging GDB, because some Unix's don't let you run GDB # on itself without copying the executable. So "make gdb1" will make # gdb and put a copy in gdb1, and you can run it with "gdb gdb1". -@@ -2213,6 +2240,7 @@ clean mostlyclean: $(CONFIG_CLEAN) +@@ -2240,6 +2267,7 @@ clean mostlyclean: $(CONFIG_CLEAN) rm -f init.c stamp-init version.c stamp-version rm -f gdb$(EXEEXT) core make.log rm -f gdb[0-9]$(EXEEXT) + rm -f kgdb$(EXEEXT) - rm -f test-cp-name-parser$(EXEEXT) rm -f xml-builtin.c stamp-xml rm -f $(DEPDIR)/* -@@ -2636,7 +2664,7 @@ endif + for i in $(CONFIG_SRC_SUBDIR); do \ +@@ -2672,7 +2700,7 @@ endif # A list of all the objects we might care about in this build, for # dependency tracking. --all_object_files = gdb.o $(LIBGDB_OBS) gdbtk-main.o \ -+all_object_files = kgdb-main.o gdb.o $(LIBGDB_OBS) gdbtk-main.o \ - test-cp-name-parser.o +-all_object_files = gdb.o $(LIBGDB_OBS) gdbtk-main.o ++all_object_files = kgdb-main.o gdb.o $(LIBGDB_OBS) gdbtk-main.o # All the .deps files to include. + all_deps_files = $(foreach dep,$(patsubst %.o,%.Po,$(all_object_files)),\ diff --git gdb/config.in gdb/config.in -index e17245156d8..e1be9fdbc40 100644 +index 0c144c8918b..b18687e766f 100644 --- gdb/config.in +++ gdb/config.in -@@ -229,6 +229,12 @@ +@@ -244,6 +244,12 @@ /* Define to 1 if you have the `kinfo_getfile' function. */ #undef HAVE_KINFO_GETFILE +/* Define to 1 if your system has the kvm_kerndisp function. */ +#undef HAVE_KVM_DISP + +/* Define to 1 if your system has the kvm_open2 function. */ +#undef HAVE_KVM_OPEN2 + /* Define if you have and nl_langinfo(CODESET). */ #undef HAVE_LANGINFO_CODESET diff --git gdb/configure gdb/configure -index 5361bf42952..9f4c500fd22 100755 +index 66a7ad8d256..198c3a4b43d 100755 --- gdb/configure +++ gdb/configure -@@ -19724,6 +19724,126 @@ fi +@@ -26398,6 +26398,126 @@ 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 ${ac_cv_search_kvm_open2+:} false; 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 ${ac_cv_search_kvm_open2+:} false; then : + break +fi +done +if ${ac_cv_search_kvm_open2+:} false; 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 + + +# kgdb needs kvm_kerndisp for relocatable kernels +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kvm_kerndisp" >&5 +$as_echo_n "checking for library containing kvm_kerndisp... " >&6; } +if ${ac_cv_search_kvm_kerndisp+:} false; 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_kerndisp (); +int +main () +{ +return kvm_kerndisp (); + ; + 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_kerndisp=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_kvm_kerndisp+:} false; then : + break +fi +done +if ${ac_cv_search_kvm_kerndisp+:} false; then : + +else + ac_cv_search_kvm_kerndisp=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_kerndisp" >&5 +$as_echo "$ac_cv_search_kvm_kerndisp" >&6; } +ac_res=$ac_cv_search_kvm_kerndisp +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_KVM_DISP 1" >>confdefs.h + +fi + + # Check whether --with-zstd was given. if test "${with_zstd+set}" = set; then : diff --git gdb/configure.ac gdb/configure.ac -index 3912b77b27f..bc960202b22 100644 +index 62ff09cea20..3baeb32d3bc 100644 --- gdb/configure.ac +++ gdb/configure.ac -@@ -516,6 +516,16 @@ AC_SEARCH_LIBS(gethostbyname, nsl) +@@ -518,6 +518,16 @@ AC_SEARCH_LIBS(gethostbyname, nsl) AM_ZLIB AC_ZSTD +# 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. ])]) + +# kgdb needs kvm_kerndisp for relocatable kernels +AC_SEARCH_LIBS(kvm_kerndisp, kvm, + [AC_DEFINE(HAVE_KVM_DISP, 1, + [Define to 1 if your system has the kvm_kerndisp function. ])]) + AM_ICONV # GDB may fork/exec the iconv program to get the list of supported character diff --git gdb/configure.nat gdb/configure.nat -index 1dc4206b69c..cb46e1505c7 100644 +index 8b98511cef7..c222e482ce9 100644 --- gdb/configure.nat +++ gdb/configure.nat @@ -63,7 +63,8 @@ case ${gdb_host} in LOADLIBES='-ldl $(RDYNAMIC)' ;; fbsd*) - NATDEPFILES='fork-child.o nat/fork-inferior.o inf-ptrace.o fbsd-nat.o' + NATDEPFILES='fork-child.o nat/fork-inferior.o inf-ptrace.o fbsd-nat.o \ + fbsd-kvm.o' HAVE_NATIVE_GCORE_HOST=1 LOADLIBES='-lkvm' ;; diff --git gdb/configure.tgt gdb/configure.tgt index 47a674201f9..4b4b6893edf 100644 --- gdb/configure.tgt +++ gdb/configure.tgt @@ -122,7 +122,7 @@ esac case "${targ}" in *-*-freebsd* | *-*-kfreebsd*-gnu) - os_obs="fbsd-tdep.o solib-svr4.o";; + os_obs="fbsd-tdep.o solib-svr4.o fbsd-kld.o fbsd-kthr.o";; *-*-netbsd* | *-*-knetbsd*-gnu) os_obs="netbsd-tdep.o solib-svr4.o";; *-*-openbsd*) @@ -139,7 +139,7 @@ aarch64*-*-elf | aarch64*-*-rtems*) aarch64*-*-freebsd*) # Target: FreeBSD/aarch64 - gdb_target_obs="aarch64-fbsd-tdep.o" + gdb_target_obs="aarch64-fbsd-tdep.o aarch64-fbsd-kern.o" ;; aarch64*-*-linux*) @@ -202,7 +202,7 @@ arm*-*-linux*) ;; arm*-*-freebsd*) # Target: FreeBSD/arm - gdb_target_obs="arm-fbsd-tdep.o" + gdb_target_obs="arm-fbsd-tdep.o arm-fbsd-kern.o" ;; arm*-*-netbsd* | arm*-*-knetbsd*-gnu) # Target: NetBSD/arm @@ -294,7 +294,11 @@ i[34567]86-*-dicos*) ;; i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu) # Target: FreeBSD/i386 - gdb_target_obs="i386-bsd-tdep.o i386-fbsd-tdep.o " + gdb_target_obs="i386-bsd-tdep.o i386-fbsd-tdep.o i386fbsd-kern.o" + if test "x$enable_64_bit_bfd" = "xyes"; then + # Target: FreeBSD amd64 + gdb_target_obs="amd64fbsd-tdep.o amd64fbsd-kern.o ${gdb_target_obs}" + fi ;; i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu) # Target: NetBSD/i386 @@ -434,7 +438,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu) ;; mips*-*-freebsd*) # Target: MIPS running FreeBSD - gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o" + gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o mipsfbsd-kern.o" ;; mips64*-*-openbsd*) # Target: OpenBSD/mips64 @@ -492,7 +496,7 @@ or1k-*-* | or1knd-*-*) powerpc*-*-freebsd*) # Target: FreeBSD/powerpc gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \ - ppc-fbsd-tdep.o \ + ppc-fbsd-tdep.o ppcfbsd-kern.o \ ravenscar-thread.o ppc-ravenscar-thread.o" ;; @@ -541,7 +545,7 @@ s390*-*-linux*) riscv*-*-freebsd*) # Target: FreeBSD/riscv - gdb_target_obs="riscv-fbsd-tdep.o" + gdb_target_obs="riscv-fbsd-tdep.o riscv-fbsd-kern.o" ;; riscv*-*-linux*) @@ -606,6 +610,7 @@ sparc64-*-linux*) sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu) # Target: FreeBSD/sparc64 gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64-fbsd-tdep.o \ + sparc64fbsd-kern.o \ ravenscar-thread.o sparc-ravenscar-thread.o" ;; sparc-*-netbsd* | sparc-*-knetbsd*-gnu) @@ -722,8 +727,8 @@ x86_64-*-linux*) ;; x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) # Target: FreeBSD/amd64 - gdb_target_obs="amd64-fbsd-tdep.o ${i386_tobjs} \ - i386-bsd-tdep.o i386-fbsd-tdep.o" + gdb_target_obs="amd64-fbsd-tdep.o amd64fbsd-kern.o ${i386_tobjs} \ + i386-bsd-tdep.o i386-fbsd-tdep.o i386fbsd-kern.o" ;; x86_64-*-mingw* | x86_64-*-cygwin*) # Target: MingW/amd64 diff --git gdb/osabi.c gdb/osabi.c -index ad3dad5b849..29e8578d031 100644 +index d494d899623..f04e0cb3699 100644 --- gdb/osabi.c +++ gdb/osabi.c -@@ -67,6 +67,7 @@ static const struct osabi_names gdb_osabi_names[] = +@@ -66,6 +66,7 @@ static const struct osabi_names gdb_osabi_names[] = { "Solaris", NULL }, { "GNU/Linux", "linux(-gnu[^-]*)?" }, { "FreeBSD", NULL }, + { "FreeBSD/kernel", NULL }, { "NetBSD", NULL }, { "OpenBSD", NULL }, { "WindowsCE", NULL }, diff --git gdb/osabi.h gdb/osabi.h -index 35f14ec433c..1276d34d5f7 100644 +index c1a85d1b9a3..88feacab384 100644 --- gdb/osabi.h +++ gdb/osabi.h @@ -31,6 +31,7 @@ enum gdb_osabi GDB_OSABI_SOLARIS, GDB_OSABI_LINUX, GDB_OSABI_FREEBSD, + GDB_OSABI_FREEBSD_KERNEL, GDB_OSABI_NETBSD, GDB_OSABI_OPENBSD, GDB_OSABI_WINCE, diff --git gdb/regcache.c gdb/regcache.c -index 91b20b7a2a2..0cfa1bae3d9 100644 +index f04354d822f..b239064ac16 100644 --- gdb/regcache.c +++ gdb/regcache.c -@@ -1123,6 +1123,22 @@ reg_buffer::raw_supply_zeroed (int regnum) +@@ -1187,6 +1187,18 @@ reg_buffer::raw_supply_zeroed (int regnum) m_register_status[regnum] = REG_VALID; } +void +reg_buffer::raw_supply_unsigned (int regnum, ULONGEST val) +{ -+ enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch); -+ gdb_byte *regbuf; -+ size_t regsize; -+ + assert_regnum (regnum); + -+ regbuf = register_buffer (regnum); -+ regsize = m_descr->sizeof_register[regnum]; ++ gdb::array_view dst = register_buffer (regnum); ++ enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch); + -+ store_unsigned_integer (regbuf, regsize, byte_order, val); ++ store_unsigned_integer (dst.data (), dst.size (), byte_order, val); + m_register_status[regnum] = REG_VALID; +} + /* See gdbsupport/common-regcache.h. */ void -@@ -1289,6 +1305,53 @@ regcache::collect_regset (const struct regset *regset, int regbase, +@@ -1353,6 +1365,53 @@ regcache::collect_regset (const struct regset *regset, int regbase, size); } +/* See regcache.h */ + +int +regcache_map_entry_size (const struct regcache_map_entry *map, gdbarch *gdbarch) +{ + int size = 0, count; + + for (; (count = map->count) != 0; map++) + { + int regno = map->regno; + int slot_size = map->size; + + if (slot_size == 0 && regno != REGCACHE_MAP_SKIP) + slot_size = register_size (gdbarch, regno); + + size += count * slot_size; + } + return size; +} + +/* See regcache.h */ + +int +regcache_map_offset (const struct regcache_map_entry *map, int regnum, + gdbarch *gdbarch) +{ + int offs = 0, count; + + for (; (count = map->count) != 0; map++) + { + int regno = map->regno; + int slot_size = map->size; + + if (slot_size == 0 && regno != REGCACHE_MAP_SKIP) + slot_size = register_size (gdbarch, regno); + + if (regno != REGCACHE_MAP_SKIP && regnum >= regno + && regnum < regno + count) + return offs + (regno - regnum) * slot_size; + + offs += count * slot_size; + } + return -1; +} + +/* See regcache.h */ + bool regcache_map_supplies (const struct regcache_map_entry *map, int regnum, struct gdbarch *gdbarch, size_t size) diff --git gdb/regcache.h gdb/regcache.h -index 57ddac465f0..b9f62994901 100644 +index 2f4b7d94c69..7ae67a309a7 100644 --- gdb/regcache.h +++ gdb/regcache.h -@@ -133,6 +133,11 @@ regcache_map_entry_size (const struct regcache_map_entry *map) +@@ -130,6 +130,11 @@ regcache_map_entry_size (const struct regcache_map_entry *map) return size; } +/* Same as above, but accepts a gdbarch to handle entries with a + variable register size. */ +extern int regcache_map_entry_size (const struct regcache_map_entry *map, + gdbarch *gdbarch); + /* Transfer a set of registers (as described by REGSET) between REGCACHE and BUF. If REGNUM == -1, transfer all registers belonging to the regset, otherwise just the register numbered -@@ -151,6 +156,13 @@ extern void regcache_collect_regset (const struct regset *regset, +@@ -148,6 +153,13 @@ extern void regcache_collect_regset (const struct regset *regset, int regnum, void *buf, size_t size); +/* Return the offset of REGNUM in a block of registers described by an + array of regcache_map_entries. If the register is not found, + returns -1. */ + +extern int regcache_map_offset (const struct regcache_map_entry *map, + int regnum, gdbarch *gdbarch); + /* Return true if a set of registers contains the value of the register numbered REGNUM. The size of the set of registers is given in SIZE, and the layout of the set of registers is described -@@ -238,6 +250,8 @@ class reg_buffer : public reg_buffer_common - only LEN, without editing the rest of the register. */ - void raw_supply_part (int regnum, int offset, int len, const gdb_byte *in); +@@ -249,6 +261,8 @@ class reg_buffer : public reg_buffer_common + void raw_supply_part (int regnum, int offset, + gdb::array_view src); + void raw_supply_unsigned (int regnum, ULONGEST val); + void invalidate (int regnum); virtual ~reg_buffer () = default; diff --git a/devel/gdb/files/kgdb/aarch64-fbsd-kern.c b/devel/gdb/files/kgdb/aarch64-fbsd-kern.c index 2eb89a7da5e1..3ff80e0d7b76 100644 --- a/devel/gdb/files/kgdb/aarch64-fbsd-kern.c +++ b/devel/gdb/files/kgdb/aarch64-fbsd-kern.c @@ -1,265 +1,266 @@ /*- * Copyright (c) 2017 John Baldwin * 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. */ /* Target-dependent code for FreeBSD/aarch64 kernels. */ #include "defs.h" #include "aarch64-tdep.h" #include "frame-unwind.h" #include "gdbarch.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "regset.h" #include "solib.h" #include "target.h" #include "trad-frame.h" #include "kgdb.h" struct aarch64_fbsd_kern_info { LONGEST osreldate = 0; }; /* Per-program-space data key. */ static const registry::key aarch64_fbsd_kern_pspace_data; /* Get the current aarch64_fbsd_kern data. If none is found yet, add it now. This function always returns a valid object. */ static struct aarch64_fbsd_kern_info * get_aarch64_fbsd_kern_info (void) { struct aarch64_fbsd_kern_info *info; info = aarch64_fbsd_kern_pspace_data.get (current_program_space); if (info != nullptr) return info; info = aarch64_fbsd_kern_pspace_data.emplace (current_program_space); info->osreldate = parse_and_eval_long ("osreldate"); return info; } static const struct regcache_map_entry aarch64_fbsd_pcbmap[] = { { 11, AARCH64_X0_REGNUM + 19, 8 }, /* x19 ... x29 */ { 1, AARCH64_PC_REGNUM, 8 }, { 1, AARCH64_SP_REGNUM, 8 }, { 0 } }; static const struct regset aarch64_fbsd_pcbregset = { aarch64_fbsd_pcbmap, regcache_supply_regset, regcache_collect_regset }; /* In kernels prior to __FreeBSD_version 1400084, struct pcb used an alternate layout. */ static const struct regcache_map_entry aarch64_fbsd13_pcbmap[] = { { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */ { 1, AARCH64_PC_REGNUM, 8 }, { 1, REGCACHE_MAP_SKIP, 8 }, { 1, AARCH64_SP_REGNUM, 8 }, { 0 } }; static const struct regset aarch64_fbsd13_pcbregset = { aarch64_fbsd13_pcbmap, regcache_supply_regset, regcache_collect_regset }; static void aarch64_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { const struct regset *pcbregset; struct aarch64_fbsd_kern_info *info = get_aarch64_fbsd_kern_info(); gdb_byte buf[8 * 33]; if (info->osreldate >= 1400084) pcbregset = &aarch64_fbsd_pcbregset; else pcbregset = &aarch64_fbsd13_pcbregset; if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) regcache_supply_regset (pcbregset, regcache, -1, buf, sizeof (buf)); } static const struct regcache_map_entry aarch64_fbsd_trapframe_map[] = { { 1, AARCH64_SP_REGNUM, 8 }, { 1, AARCH64_LR_REGNUM, 8 }, { 1, AARCH64_PC_REGNUM, 8 }, { 1, AARCH64_CPSR_REGNUM, 8 }, { 1, REGCACHE_MAP_SKIP, 8 }, /* esr */ { 1, REGCACHE_MAP_SKIP, 8 }, /* far */ { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */ { 0 } }; /* In kernels prior to __FreeBSD_version 1400084, struct trapframe used an alternate layout. */ static const struct regcache_map_entry aarch64_fbsd13_trapframe_map[] = { { 1, AARCH64_SP_REGNUM, 8 }, { 1, AARCH64_LR_REGNUM, 8 }, { 1, AARCH64_PC_REGNUM, 8 }, { 1, AARCH64_CPSR_REGNUM, 4 }, { 1, REGCACHE_MAP_SKIP, 4 }, /* esr */ { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */ { 0 } }; static struct trad_frame_cache * -aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) +aarch64_fbsd_trapframe_cache (const frame_info_ptr &this_frame, + void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct aarch64_fbsd_kern_info *info = get_aarch64_fbsd_kern_info(); struct trad_frame_cache *cache; CORE_ADDR func, offset, pc, sp; const char *name; int i, tf_size; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); const struct regcache_map_entry *trapframe_map; if (info->osreldate >= 1400084) trapframe_map = aarch64_fbsd_trapframe_map; else trapframe_map = aarch64_fbsd13_trapframe_map; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM); tf_size = regcache_map_entry_size (trapframe_map); trad_frame_set_reg_regmap (cache, trapframe_map, sp, tf_size); /* Read $PC from trap frame. */ func = get_frame_func (this_frame); find_pc_partial_function (func, &name, NULL, NULL); offset = regcache_map_offset (trapframe_map, AARCH64_PC_REGNUM, gdbarch); pc = read_memory_unsigned_integer (sp + offset, 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, func)); } return cache; } static void -aarch64_fbsd_trapframe_this_id (frame_info_ptr this_frame, +aarch64_fbsd_trapframe_this_id (const frame_info_ptr &this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = aarch64_fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * -aarch64_fbsd_trapframe_prev_register (frame_info_ptr this_frame, +aarch64_fbsd_trapframe_prev_register (const frame_info_ptr &this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = aarch64_fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int aarch64_fbsd_trapframe_sniffer (const struct frame_unwind *self, - frame_info_ptr this_frame, + const frame_info_ptr &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, "handle_el1h_sync") == 0) || (strcmp (name, "handle_el1h_irq") == 0) || (strcmp (name, "handle_el0_sync") == 0) || (strcmp (name, "handle_el0_irq") == 0) || (strcmp (name, "handle_el0_error") == 0) || (strcmp (name, "fork_trampoline") == 0))); } static const struct frame_unwind aarch64_fbsd_trapframe_unwind = { "aarch64 FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, aarch64_fbsd_trapframe_this_id, aarch64_fbsd_trapframe_prev_register, NULL, aarch64_fbsd_trapframe_sniffer }; /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */ static void aarch64_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); frame_unwind_prepend_unwinder (gdbarch, &aarch64_fbsd_trapframe_unwind); set_gdbarch_so_ops (gdbarch, &kld_so_ops); /* Enable longjmp. */ tdep->jb_pc = 13; fbsd_vmcore_set_supply_pcb (gdbarch, aarch64_fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); } void _initialize_aarch64_kgdb_tdep (); void _initialize_aarch64_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_aarch64, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_FREEBSD_KERNEL, aarch64_fbsd_kernel_init_abi); } diff --git a/devel/gdb/files/kgdb/amd64fbsd-kern.c b/devel/gdb/files/kgdb/amd64fbsd-kern.c index 7c71bf919cdc..347215009861 100644 --- a/devel/gdb/files/kgdb/amd64fbsd-kern.c +++ b/devel/gdb/files/kgdb/amd64fbsd-kern.c @@ -1,310 +1,310 @@ /* * 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 "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 "gdbsupport/x86-xstate.h" #ifdef __amd64__ #include #include #endif #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; memset(buf, 0, sizeof(buf)); /* * XXX The PCB may have been swapped out. Supply a dummy %rip value * so as to avoid triggering an exception during stack unwinding. */ regcache->raw_supply(AMD64_RIP_REGNUM, buf); 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(i, buf); } regcache->raw_supply_unsigned(AMD64_CS_REGNUM, CODE_SEL); regcache->raw_supply_unsigned(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 (frame_info_ptr this_frame, void **this_cache) +amd64fbsd_trapframe_cache (const frame_info_ptr &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 ((struct trad_frame_cache *)*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 (frame_info_ptr this_frame, +amd64fbsd_trapframe_this_id (const frame_info_ptr &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 (frame_info_ptr this_frame, +amd64fbsd_trapframe_prev_register (const frame_info_ptr &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, - frame_info_ptr this_frame, + const frame_info_ptr &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, "fast_syscall_common") == 0) || (strcmp (name, "fork_trampoline") == 0) || (strcmp (name, "mchk_calltrap") == 0) || (strcmp (name, "nmi_calltrap") == 0) || (name[0] == 'X' && name[1] != '_'))); } static const struct frame_unwind amd64fbsd_trapframe_unwind = { "amd64 FreeBSD kernel trap", SIGTRAMP_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, amd64_target_description (X86_XSTATE_SSE_MASK, true)); frame_unwind_prepend_unwinder(gdbarch, &amd64fbsd_trapframe_unwind); set_gdbarch_so_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 _initialize_amd64_kgdb_tdep () { gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_FREEBSD_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 } diff --git a/devel/gdb/files/kgdb/arm-fbsd-kern.c b/devel/gdb/files/kgdb/arm-fbsd-kern.c index 0caa5af96cb5..eaa0364b268e 100644 --- a/devel/gdb/files/kgdb/arm-fbsd-kern.c +++ b/devel/gdb/files/kgdb/arm-fbsd-kern.c @@ -1,211 +1,211 @@ /*- * Copyright (c) 2018 John Baldwin * 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. */ /* Target-dependent code for FreeBSD/arm kernels. */ #include "defs.h" #include "arm-tdep.h" #include "frame-unwind.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "regset.h" #include "solib.h" #include "target.h" #include "trad-frame.h" #include "kgdb.h" static const struct regcache_map_entry arm_fbsd_pcbmap[] = { { 9, 4, 4 }, /* r4 ... r12 */ { 1, ARM_SP_REGNUM, 4 }, { 1, ARM_LR_REGNUM, 4 }, { 1, ARM_PC_REGNUM, 4 }, { 0 } }; static const struct regset arm_fbsd_pcbregset = { arm_fbsd_pcbmap, regcache_supply_regset, regcache_collect_regset }; static void arm_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[4 * 12]; if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) regcache->supply_regset (&arm_fbsd_pcbregset, -1, buf, sizeof (buf)); /* * XXX: This is a gross hack, but the ARM frame unwinders need the value * of xPSR to determine if Thumb mode is active. FreeBSD's kernels never * use Thumb. */ - regcache->raw_supply_unsigned(ARM_PS_REGNUM, 0); + regcache->raw_supply_zeroed (ARM_PS_REGNUM); } #define PSR_MODE 0x0000001f /* mode mask */ #define PSR_USR32_MODE 0x00000010 static struct trad_frame_cache * -arm_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) +arm_fbsd_trapframe_cache (const frame_info_ptr &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; uint32_t psr; CORE_ADDR func, pc, sp; const char *name; int i; if (*this_cache != NULL) return ((struct trad_frame_cache *)*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, ARM_SP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); /* Read $PSR to determine where SP and LR are. */ psr = read_memory_unsigned_integer (sp, 4, byte_order); for (i = 0; i <= 12; i++) trad_frame_set_reg_addr (cache, ARM_A1_REGNUM + i, sp + 4 + i * 4); if ((psr & PSR_MODE) == PSR_USR32_MODE) { trad_frame_set_reg_addr (cache, ARM_SP_REGNUM, sp + 14 * 4); trad_frame_set_reg_addr (cache, ARM_LR_REGNUM, sp + 15 * 4); } else { trad_frame_set_reg_addr (cache, ARM_SP_REGNUM, sp + 16 * 4); trad_frame_set_reg_addr (cache, ARM_LR_REGNUM, sp + 17 * 4); } trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sp + 18 * 4); trad_frame_set_reg_addr (cache, ARM_PS_REGNUM, sp); /* Read $PC from trap frame. */ pc = read_memory_unsigned_integer (sp + 18 * 4, 4, byte_order); if (pc == 0 && strcmp(name, "swi_entry") == 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 + 4 * 19, func)); } return cache; } static void -arm_fbsd_trapframe_this_id (frame_info_ptr this_frame, +arm_fbsd_trapframe_this_id (const frame_info_ptr &this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = arm_fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * -arm_fbsd_trapframe_prev_register (frame_info_ptr this_frame, +arm_fbsd_trapframe_prev_register (const frame_info_ptr &this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = arm_fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int arm_fbsd_trapframe_sniffer (const struct frame_unwind *self, - frame_info_ptr this_frame, + const frame_info_ptr &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, "data_abort_entry") == 0) || (strcmp (name, "prefetch_abort_entry") == 0) || (strcmp (name, "undefined_entry") == 0) || (strcmp (name, "exception_exit") == 0) || (strcmp (name, "irq_entry") == 0) || (strcmp (name, "swi_entry") == 0) || (strcmp (name, "swi_exit") == 0))); } static const struct frame_unwind arm_fbsd_trapframe_unwind = { "arm FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, arm_fbsd_trapframe_this_id, arm_fbsd_trapframe_prev_register, NULL, arm_fbsd_trapframe_sniffer }; /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */ static void arm_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { arm_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); frame_unwind_prepend_unwinder (gdbarch, &arm_fbsd_trapframe_unwind); set_gdbarch_so_ops (gdbarch, &kld_so_ops); tdep->jb_pc = 24; tdep->jb_elt_size = 4; fbsd_vmcore_set_supply_pcb (gdbarch, arm_fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); /* Single stepping. */ set_gdbarch_software_single_step (gdbarch, arm_software_single_step); } void _initialize_arm_kgdb_tdep (); void _initialize_arm_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_arm, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_FREEBSD_KERNEL, arm_fbsd_kernel_init_abi); } diff --git a/devel/gdb/files/kgdb/fbsd-kld.c b/devel/gdb/files/kgdb/fbsd-kld.c index 55121d87d974..df5b6a6d7be2 100644 --- a/devel/gdb/files/kgdb/fbsd-kld.c +++ b/devel/gdb/files/kgdb/fbsd-kld.c @@ -1,536 +1,518 @@ /* * 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 "defs.h" #include "command.h" #include "completer.h" #include "environ.h" #include "exec.h" +#include "extract-store-integer.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_kld : public lm_info_base { +struct lm_info_kld final : public 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; +solib_ops kld_so_ops; /* Per-program-space data key. */ static const registry::key kld_pspace_data; /* 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) +get_kld_info (program_space *pspace) { struct kld_info *info; - info = kld_pspace_data.get (current_program_space); + info = kld_pspace_data.get (pspace); if (info == nullptr) - info = kld_pspace_data.emplace (current_program_space); + info = kld_pspace_data.emplace (pspace); return info; } static int kld_ok (const 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", "", }; static bool check_kld_path (std::string &path) { for (const char *suffix : kld_suffixes) { std::string new_path = path + suffix; if (kld_ok (new_path.c_str ())) { path = new_path; return true; } } return false; } /* * 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 gdb::optional +static std::optional find_kld_path (const char *filename) { bfd *exec_bfd = current_program_space->exec_bfd (); if (exec_bfd != nullptr) { std::string kernel_dir = ldirname (bfd_get_filename (exec_bfd)); if (!kernel_dir.empty ()) { std::string path = string_printf("%s/%s", kernel_dir.c_str (), filename); if (check_kld_path (path)) return path; } } - struct kld_info *info = get_kld_info (); + struct kld_info *info = get_kld_info (current_program_space); if (info->module_path_addr != 0) { gdb::unique_xmalloc_ptr module_path = target_read_string(info->module_path_addr, PATH_MAX); if (module_path != nullptr) { char *cp = module_path.get(); char *module_dir; while ((module_dir = strsep(&cp, ";")) != NULL) { std::string path = string_printf("%s/%s", module_dir, filename); if (check_kld_path (path)) return path; } } } return {}; } /* * 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 (current_program_space->exec_bfd ()); if (arch_size == -1) return (0); - ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; + ptr_type = builtin_type (current_inferior ()->arch ())->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 (const char *arg, CORE_ADDR *address) { - struct kld_info *info = get_kld_info(); + struct kld_info *info = get_kld_info(current_program_space); if (info->linker_files_addr == 0 || info->off_address == 0 || info->off_filename == 0 || info->off_next == 0) return (0); const char *filename = lbasename(arg); for (CORE_ADDR kld = read_pointer(info->linker_files_addr); kld != 0; kld = read_pointer(kld + info->off_next)) { /* Try to read this linker file's filename. */ gdb::unique_xmalloc_ptr kld_filename = target_read_string (read_pointer (kld + info->off_filename), PATH_MAX); if (kld_filename == nullptr) continue; /* Compare this kld's filename against our passed in name. */ if (strcmp(kld_filename.get (), filename) != 0) continue; /* * 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_section_alignment(asect)); sec->addr = *curr_base; sec->endaddr = sec->addr + bfd_section_size(asect); *curr_base = sec->endaddr; } static void load_kld (const char *path, CORE_ADDR base_addr, int from_tty) { /* Open the kld. */ gdb_bfd_ref_ptr bfd = gdb_bfd_openr(path, gnutarget); if (bfd == NULL) error("\"%s\": can't open: %s", path, bfd_errmsg(bfd_get_error())); if (!bfd_check_format(bfd.get(), bfd_object)) error("\%s\": not an object file", path); /* Make sure we have a .text section. */ if (bfd_get_section_by_name (bfd.get(), ".text") == NULL) error("\"%s\": can't find text section", path); /* Build a section table from the bfd and relocate the sections. */ - target_section_table sections = build_section_table (bfd.get()); + std::vector sections = build_section_table (bfd.get()); CORE_ADDR curr_addr = base_addr; for (target_section &s : sections) adjust_section_address(&s, &curr_addr); /* Build a section addr info to pass to symbol_file_add(). */ section_addr_info sap = build_section_addr_info_from_section_table (sections); printf_unfiltered("add symbol table from file \"%s\" at\n", path); for (const other_sections &s : sap) printf_unfiltered("\t%s_addr = %s\n", s.name.c_str(), - paddress(target_gdbarch(), s.addr)); + paddress(current_inferior ()->arch (), s.addr)); if (from_tty && (!query("%s", ""))) error("Not confirmed."); symfile_add_flags add_flags = 0; if (from_tty) add_flags |= SYMFILE_VERBOSE; symbol_file_add_from_bfd(bfd, path, add_flags, &sap, OBJF_USERLOADED, NULL); } static void kgdb_add_kld_cmd (const char *arg, int from_tty) { CORE_ADDR base_addr; if (current_program_space->exec_bfd () == nullptr) error("No kernel symbol file"); /* Try to open the raw path to handle absolute paths first. */ std::string path (arg); if (!check_kld_path(path)) { /* * If that didn't work, look in the various possible * paths for the module. */ - gdb::optional found = find_kld_path (arg); + std::optional found = find_kld_path (arg); if (!found) { error("Unable to locate kld"); return; } path = std::move(*found); } if (!find_kld_address(arg, &base_addr)) { error("Unable to find kld in kernel"); return; } load_kld(path.c_str (), base_addr, from_tty); reinit_frame_cache(); } static void -kld_relocate_section_addresses (struct so_list *so, struct target_section *sec) +kld_relocate_section_addresses (solib &so, struct target_section *sec) { - lm_info_kld *li = (lm_info_kld *) so->lm_info; + auto *li = gdb::checked_static_cast (so.lm_info.get ()); static CORE_ADDR curr_addr; - if (sec == &so->sections->front()) + if (sec == &so.sections.front()) curr_addr = li->base_address; - adjust_section_address(sec, &curr_addr); + adjust_section_address (sec, &curr_addr); } static void -kld_free_so (struct so_list *so) +kld_clear_so (const solib &so) { - lm_info_kld *li = (lm_info_kld *) so->lm_info; - - delete li; -} - -static void -kld_clear_so (struct so_list *so) -{ - lm_info_kld *li = (lm_info_kld *) so->lm_info; + auto *li = gdb::checked_static_cast (so.lm_info.get ()); if (li != NULL) li->base_address = 0; } static void -kld_clear_solib (void) +kld_clear_solib (program_space *pspace) { - struct kld_info *info; + kld_info *info = get_kld_info (pspace); - info = get_kld_info(); - - memset(info, 0, sizeof(*info)); + memset(info, 0, sizeof(*info)); } static void kld_solib_create_inferior_hook (int from_tty) { struct kld_info *info; - info = get_kld_info(); + info = get_kld_info (current_program_space); /* * Compute offsets of relevant members in struct linker_file * and the addresses of global variables. Newer kernels * include constants we can use without requiring debug * symbols. */ try { info->off_address = parse_and_eval_long("kld_off_address"); info->off_filename = parse_and_eval_long("kld_off_filename"); info->off_pathname = parse_and_eval_long("kld_off_pathname"); info->off_next = parse_and_eval_long("kld_off_next"); } catch (const gdb_exception_error &e) { try { struct symbol *linker_file_sym = lookup_symbol_in_language ("struct linker_file", - NULL, STRUCT_DOMAIN, language_c, NULL).symbol; + NULL, SEARCH_TYPE_DOMAIN, language_c, NULL).symbol; if (linker_file_sym == NULL) error (_( "Unable to find struct linker_file symbol")); info->off_address = lookup_struct_elt (linker_file_sym->type (), "address", 0).offset / 8; info->off_filename = lookup_struct_elt (linker_file_sym->type (), "filename", 0).offset / 8; info->off_pathname = lookup_struct_elt (linker_file_sym->type (), "pathname", 0).offset / 8; struct type *link_type = lookup_struct_elt_type (linker_file_sym->type (), "link", 0); if (link_type == NULL) error (_("Unable to find link type")); info->off_next = lookup_struct_elt (link_type, "tqe_next", 0).offset / 8; } catch (const gdb_exception_error &e2) { return; } } try { info->module_path_addr = parse_and_eval_address("linker_path"); info->linker_files_addr = kgdb_lookup("linker_files"); info->kernel_file_addr = kgdb_lookup("linker_kernel_file"); } catch (const gdb_exception_error &e) { return; } solib_add(NULL, from_tty, auto_solib_add); } -static struct so_list * +static intrusive_list kld_current_sos (void) { - struct kld_info *info = get_kld_info(); + struct kld_info *info = get_kld_info(current_program_space); if (info->linker_files_addr == 0 || info->kernel_file_addr == 0 || info->off_address == 0 || info->off_filename == 0 || info->off_next == 0) - return (NULL); + return {}; - struct so_list *head = NULL; - struct so_list **prev = &head; + intrusive_list sos; /* - * Walk the list of linker files creating so_list entries for + * Walk the list of linker files creating solib entries for * each non-kernel file. */ CORE_ADDR kernel = read_pointer(info->kernel_file_addr); for (CORE_ADDR kld = read_pointer(info->linker_files_addr); kld != 0; kld = read_pointer(kld + info->off_next)) { /* Skip the main kernel file. */ if (kld == kernel) continue; - struct so_list *newobj = XCNEW (struct so_list); + solib *newobj = new solib; - lm_info_kld *li = new lm_info_kld; + auto li = std::make_unique (); li->base_address = 0; - newobj->lm_info = li; - /* Read the base filename and store it in so_original_name. */ - gdb::unique_xmalloc_ptr path = + gdb::unique_xmalloc_ptr filename = target_read_string (read_pointer (kld + info->off_filename), - sizeof(newobj->so_original_name)); - if (path == nullptr) { + SO_NAME_MAX_PATH_SIZE - 1); + if (filename == nullptr) { warning("kld_current_sos: Can't read filename\n"); - free_so(newobj); + delete newobj; continue; } - strlcpy(newobj->so_original_name, path.get(), - sizeof(newobj->so_original_name)); + newobj->so_original_name = filename.get (); /* * Try to read the pathname (if it exists) and store * it in so_name. */ if (info->off_pathname != 0) { - path = target_read_string (read_pointer (kld + - info->off_pathname), - sizeof(newobj->so_name)); + gdb::unique_xmalloc_ptr path = + target_read_string (read_pointer (kld + + info->off_pathname), SO_NAME_MAX_PATH_SIZE - 1); if (path == nullptr) { warning( "kld_current_sos: Can't read pathname for \"%s\"\n", - newobj->so_original_name); - strlcpy(newobj->so_name, newobj->so_original_name, - sizeof(newobj->so_name)); + newobj->so_original_name.c_str ()); + newobj->so_name = newobj->so_original_name; } else { - strlcpy(newobj->so_name, path.get(), - sizeof(newobj->so_name)); + newobj->so_name = path.get(); } } else - strlcpy(newobj->so_name, newobj->so_original_name, - sizeof(newobj->so_name)); + newobj->so_name = newobj->so_original_name; /* Read this kld's base address. */ li->base_address = read_pointer(kld + info->off_address); if (li->base_address == 0) { warning( "kld_current_sos: Invalid address for kld \"%s\"", - newobj->so_original_name); - free_so(newobj); + newobj->so_original_name.c_str ()); + delete newobj; continue; } - /* Append to the list. */ - *prev = newobj; - prev = &newobj->next; + newobj->lm_info = std::move (li); + sos.push_back (*newobj); } - return (head); + return sos; } static int kld_open_symbol_file_object (int from_tty) { return (0); } static int kld_in_dynsym_resolve_code (CORE_ADDR pc) { return (0); } static int kld_find_and_open_solib (const char *solib, unsigned o_flags, gdb::unique_xmalloc_ptr *temp_pathname) { temp_pathname->reset (NULL); - gdb::optional found = find_kld_path (solib); + std::optional found = find_kld_path (solib); if (!found) { errno = ENOENT; return (-1); } int fd = open(found->c_str (), o_flags, 0); if (fd >= 0) temp_pathname->reset (xstrdup (found->c_str ())); return (fd); } void _initialize_kld_target (); void _initialize_kld_target () { struct cmd_list_element *c; kld_so_ops.relocate_section_addresses = kld_relocate_section_addresses; - kld_so_ops.free_so = kld_free_so; kld_so_ops.clear_so = kld_clear_so; kld_so_ops.clear_solib = kld_clear_solib; kld_so_ops.solib_create_inferior_hook = kld_solib_create_inferior_hook; kld_so_ops.current_sos = kld_current_sos; kld_so_ops.open_symbol_file_object = kld_open_symbol_file_object; kld_so_ops.in_dynsym_resolve_code = kld_in_dynsym_resolve_code; kld_so_ops.bfd_open = solib_bfd_open; kld_so_ops.find_and_open_solib = kld_find_and_open_solib; c = add_com("add-kld", class_files, kgdb_add_kld_cmd, "Usage: add-kld FILE\n\ Load the symbols from the kernel loadable module FILE."); set_cmd_completer(c, filename_completer); } diff --git a/devel/gdb/files/kgdb/fbsd-kthr.c b/devel/gdb/files/kgdb/fbsd-kthr.c index 603e9bd4178f..19b7f0a621fb 100644 --- a/devel/gdb/files/kgdb/fbsd-kthr.c +++ b/devel/gdb/files/kgdb/fbsd-kthr.c @@ -1,435 +1,436 @@ /* * 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 #include #include #include "defs.h" #include "gdbcore.h" +#include "inferior.h" #include "objfiles.h" #include "value.h" #include "kgdb.h" static CORE_ADDR dumppcb; static LONGEST dumptid; static CORE_ADDR stopped_cpus; static LONGEST mp_maxid; static struct kthr *first, *last; struct kthr *curkthr; static int proc_off_p_pid, proc_off_p_comm, proc_off_p_hash, proc_off_p_list; static int proc_off_p_threads; static int thread_off_td_tid, thread_off_td_oncpu, thread_off_td_pcb; static int thread_off_td_name, thread_off_td_plist; static int thread_oncpu_size; CORE_ADDR kgdb_lookup(const char *sym) { struct bound_minimal_symbol msym; msym = lookup_minimal_symbol(sym, NULL, NULL); if (msym.minsym == NULL) return (0); return (msym.value_address ()); } /* * Perform the equivalent of CPU_ISSET() to see if 'cpu' is set in the * kernel's stopped_cpus set. The set contains an array of longs. * This function determines the specific long to read and tests the * necessary bit in the long. */ static bool cpu_stopped(int cpu) { - struct gdbarch *gdbarch = target_gdbarch (); + struct gdbarch *gdbarch = current_inferior ()->arch (); CORE_ADDR addr; ULONGEST mask; int bit, long_bytes, word; if (cpu < 0 || cpu > mp_maxid || stopped_cpus == 0) return (false); bit = cpu % gdbarch_long_bit (gdbarch); word = cpu / gdbarch_long_bit (gdbarch); long_bytes = gdbarch_long_bit (gdbarch) / 8; addr = stopped_cpus + word * long_bytes; mask = read_memory_unsigned_integer (addr, long_bytes, gdbarch_byte_order (gdbarch)); return (mask & ((ULONGEST)1 << bit)) != 0; } struct kthr * kgdb_thr_first(void) { return (first); } static void kgdb_thr_add_proc(CORE_ADDR paddr, CORE_ADDR (*cpu_pcb_addr) (u_int)) { - struct gdbarch *gdbarch = target_gdbarch (); + struct gdbarch *gdbarch = current_inferior ()->arch (); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct kthr *kt; CORE_ADDR pcb, tdaddr, tdnext; ULONGEST oncpu; LONGEST pid, tid; try { tdaddr = read_memory_typed_address (paddr + proc_off_p_threads, ptr_type); pid = read_memory_integer (paddr + proc_off_p_pid, 4, byte_order); } catch (const gdb_exception_error &e) { return; } while (tdaddr != 0) { try { tid = read_memory_integer (tdaddr + thread_off_td_tid, 4, byte_order); oncpu = read_memory_unsigned_integer (tdaddr + thread_off_td_oncpu, thread_oncpu_size, byte_order); pcb = read_memory_typed_address (tdaddr + thread_off_td_pcb, ptr_type); tdnext = read_memory_typed_address (tdaddr + thread_off_td_plist, ptr_type); } catch (const gdb_exception_error &e) { return; } kt = XNEW (struct kthr); if (last == NULL) first = last = kt; else last->next = kt; kt->next = NULL; kt->kaddr = tdaddr; if (tid == dumptid) kt->pcb = dumppcb; else if (cpu_stopped(oncpu)) kt->pcb = cpu_pcb_addr(oncpu); else kt->pcb = pcb; kt->tid = tid; kt->pid = pid; kt->paddr = paddr; kt->cpu = oncpu; last = kt; tdaddr = tdnext; } } static void kgdb_thr_add_procs_hash(CORE_ADDR pidhashtbl, CORE_ADDR (*cpu_pcb_addr) (u_int)) { - struct gdbarch *gdbarch = target_gdbarch (); + struct gdbarch *gdbarch = current_inferior ()->arch (); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR paddr, pnext; ULONGEST i, pidhash; pidhash = parse_and_eval_long("pidhash"); for (i = 0; i < pidhash; i++) { try { paddr = read_memory_typed_address (pidhashtbl + i * ptr_type->length (), ptr_type); } catch (const gdb_exception_error &e) { continue; } while (paddr != 0) { try { pnext = read_memory_typed_address (paddr + proc_off_p_hash, ptr_type); } catch (const gdb_exception_error &e) { break; } kgdb_thr_add_proc(paddr, cpu_pcb_addr); paddr = pnext; } } } static void kgdb_thr_add_procs_list(CORE_ADDR paddr, CORE_ADDR (*cpu_pcb_addr) (u_int)) { - struct gdbarch *gdbarch = target_gdbarch (); + struct gdbarch *gdbarch = current_inferior ()->arch (); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR pnext; while (paddr != 0) { try { pnext = read_memory_typed_address (paddr + proc_off_p_list, ptr_type); } catch (const gdb_exception_error &e) { break; } kgdb_thr_add_proc(paddr, cpu_pcb_addr); paddr = pnext; } } struct kthr * kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int)) { - struct gdbarch *gdbarch = target_gdbarch (); + struct gdbarch *gdbarch = current_inferior ()->arch (); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; struct kthr *kt; CORE_ADDR addr, paddr; while (first != NULL) { kt = first; first = kt->next; free(kt); } last = NULL; dumppcb = kgdb_lookup("dumppcb"); if (dumppcb == 0) return (NULL); try { dumptid = parse_and_eval_long("dumptid"); } catch (const gdb_exception_error &e) { dumptid = -1; } try { mp_maxid = parse_and_eval_long("mp_maxid"); } catch (const gdb_exception_error &e) { mp_maxid = 0; } stopped_cpus = kgdb_lookup("stopped_cpus"); /* * Newer kernels export a set of global variables with the offsets * of certain members in struct proc and struct thread. For older * kernels, try to extract these offsets using debug symbols. If * that fails, use native values. */ try { proc_off_p_pid = parse_and_eval_long("proc_off_p_pid"); proc_off_p_comm = parse_and_eval_long("proc_off_p_comm"); proc_off_p_list = parse_and_eval_long("proc_off_p_list"); proc_off_p_threads = parse_and_eval_long("proc_off_p_threads"); thread_off_td_tid = parse_and_eval_long("thread_off_td_tid"); thread_off_td_name = parse_and_eval_long("thread_off_td_name"); thread_off_td_oncpu = parse_and_eval_long("thread_off_td_oncpu"); thread_off_td_pcb = parse_and_eval_long("thread_off_td_pcb"); thread_off_td_plist = parse_and_eval_long("thread_off_td_plist"); thread_oncpu_size = 4; } catch (const gdb_exception_error &e) { try { struct symbol *proc_sym = lookup_symbol_in_language ("struct proc", NULL, - STRUCT_DOMAIN, language_c, NULL).symbol; + SEARCH_TYPE_DOMAIN, language_c, NULL).symbol; if (proc_sym == NULL) error (_("Unable to find struct proc symbol")); proc_off_p_pid = lookup_struct_elt (proc_sym->type (), "p_pid", 0).offset / 8; proc_off_p_comm = lookup_struct_elt (proc_sym->type (), "p_comm", 0).offset / 8; proc_off_p_list = lookup_struct_elt (proc_sym->type (), "p_list", 0).offset / 8; proc_off_p_threads = lookup_struct_elt (proc_sym->type (), "p_threads", 0).offset / 8; struct symbol *thread_sym = lookup_symbol_in_language ("struct thread", NULL, - STRUCT_DOMAIN, language_c, NULL).symbol; + SEARCH_TYPE_DOMAIN, language_c, NULL).symbol; if (thread_sym == NULL) error (_("Unable to find struct thread symbol")); thread_off_td_tid = lookup_struct_elt (proc_sym->type (), "td_tid", 0).offset / 8; thread_off_td_name = lookup_struct_elt (proc_sym->type (), "td_name", 0).offset / 8; thread_off_td_pcb = lookup_struct_elt (proc_sym->type (), "td_pcb", 0).offset / 8; thread_off_td_plist = lookup_struct_elt (proc_sym->type (), "td_plist", 0).offset / 8; struct_elt td_oncpu = lookup_struct_elt (proc_sym->type (), "td_oncpu", 0); thread_off_td_oncpu = td_oncpu.offset / 8; thread_oncpu_size = td_oncpu.field->bitsize () / 8; } catch (const gdb_exception_error &e2) { proc_off_p_pid = offsetof(struct proc, p_pid); proc_off_p_comm = offsetof(struct proc, p_comm); proc_off_p_list = offsetof(struct proc, p_list); proc_off_p_threads = offsetof(struct proc, p_threads); thread_off_td_tid = offsetof(struct thread, td_tid); thread_off_td_name = offsetof(struct thread, td_name); thread_off_td_oncpu = offsetof(struct thread, td_oncpu); thread_off_td_pcb = offsetof(struct thread, td_pcb); thread_off_td_plist = offsetof(struct thread, td_plist); thread_oncpu_size = sizeof(((struct thread *)0)->td_oncpu); } } /* * Handle p_hash separately. */ try { proc_off_p_hash = parse_and_eval_long("proc_off_p_hash"); } catch (const gdb_exception_error &e) { try { struct symbol *proc_sym = lookup_symbol_in_language ("struct proc", NULL, - STRUCT_DOMAIN, language_c, NULL).symbol; + SEARCH_TYPE_DOMAIN, language_c, NULL).symbol; if (proc_sym == NULL) error (_("Unable to find struct proc symbol")); proc_off_p_hash = lookup_struct_elt (proc_sym->type (), "p_hash", 0).offset / 8; } catch (const gdb_exception_error &e2) { proc_off_p_hash = offsetof(struct proc, p_hash); } } addr = kgdb_lookup("zombproc"); if (addr != 0) { addr = kgdb_lookup("allproc"); try { paddr = read_memory_typed_address (addr, ptr_type); kgdb_thr_add_procs_list(paddr, cpu_pcb_addr); } catch (const gdb_exception_error &e) { return (NULL); } try { paddr = read_memory_typed_address (addr, ptr_type); kgdb_thr_add_procs_list(paddr, cpu_pcb_addr); } catch (const gdb_exception_error &e) { } } else { addr = kgdb_lookup("pidhashtbl"); try { addr = read_memory_typed_address (addr, ptr_type); kgdb_thr_add_procs_hash(addr, cpu_pcb_addr); } catch (const gdb_exception_error &e) { return (NULL); } } curkthr = kgdb_thr_lookup_tid(dumptid); if (curkthr == NULL) curkthr = first; return (first); } struct kthr * kgdb_thr_lookup_tid(int tid) { struct kthr *kt; kt = first; while (kt != NULL && kt->tid != tid) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_taddr(uintptr_t taddr) { struct kthr *kt; kt = first; while (kt != NULL && kt->kaddr != taddr) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_pid(int pid) { struct kthr *kt; kt = first; while (kt != NULL && kt->pid != pid) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_paddr(uintptr_t paddr) { struct kthr *kt; kt = first; while (kt != NULL && kt->paddr != paddr) kt = kt->next; return (kt); } struct kthr * kgdb_thr_next(struct kthr *kt) { return (kt->next); } const char * kgdb_thr_extra_thread_info(int tid) { static char buf[64]; struct kthr *kt = kgdb_thr_lookup_tid(tid); if (kt == nullptr) return (nullptr); snprintf(buf, sizeof (buf), "PID=%d", kt->pid); gdb::unique_xmalloc_ptr comm = target_read_string (kt->paddr + proc_off_p_comm, MAXCOMLEN + 1); if (comm != nullptr) { strlcat(buf, ": ", sizeof (buf)); strlcat(buf, comm.get (), sizeof (buf)); gdb::unique_xmalloc_ptr td_name = target_read_string (kt->kaddr + thread_off_td_name, MAXCOMLEN + 1); if (td_name != nullptr && strcmp (comm.get (), td_name.get ()) != 0) { strlcat(buf, "/", sizeof (buf)); strlcat(buf, td_name.get (), sizeof (buf)); } } return (buf); } diff --git a/devel/gdb/files/kgdb/fbsd-kvm.c b/devel/gdb/files/kgdb/fbsd-kvm.c index 8c7406c0b177..29dda6c9c349 100644 --- a/devel/gdb/files/kgdb/fbsd-kvm.c +++ b/devel/gdb/files/kgdb/fbsd-kvm.c @@ -1,629 +1,629 @@ /* * 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 "defs.h" #include "command.h" #include "elf-bfd.h" #include "filenames.h" #include "gdbcore.h" #include "gdbthread.h" #include "gdbsupport/gdb_obstack.h" #include "inferior.h" #include "objfiles.h" #include "osabi.h" #include "process-stratum-target.h" #include "solib.h" #include "target.h" #include "value.h" #include "readline/tilde.h" #include "gdbsupport/buildargv.h" #include "gdbsupport/pathstuff.h" #include "gdbsupport/gdb_tilde_expand.h" #include #include #include #include "kgdb.h" static CORE_ADDR stoppcbs; static LONGEST pcb_size; static std::string vmcore; struct fbsd_vmcore_ops { /* Supply registers for a pcb to a register cache. */ void (*supply_pcb)(struct regcache *, CORE_ADDR) = nullptr; /* Return address of pcb for thread running on a CPU. */ CORE_ADDR (*cpu_pcb_addr)(u_int) = nullptr; }; /* Per-architecture data key. */ static const registry::key fbsd_vmcore_data; static struct fbsd_vmcore_ops * get_fbsd_vmcore_ops (struct gdbarch *gdbarch) { struct fbsd_vmcore_ops *ops = fbsd_vmcore_data.get (gdbarch); if (ops == nullptr) ops = fbsd_vmcore_data.emplace (gdbarch); return ops; } /* Set the function that supplies registers from a pcb for architecture GDBARCH to SUPPLY_PCB. */ void fbsd_vmcore_set_supply_pcb (struct gdbarch *gdbarch, void (*supply_pcb) (struct regcache *, CORE_ADDR)) { struct fbsd_vmcore_ops *ops = get_fbsd_vmcore_ops (gdbarch); ops->supply_pcb = supply_pcb; } /* Set the function that returns the address of the pcb for a thread running on a CPU for architecture GDBARCH to CPU_PCB_ADDR. */ void fbsd_vmcore_set_cpu_pcb_addr (struct gdbarch *gdbarch, CORE_ADDR (*cpu_pcb_addr) (u_int)) { struct fbsd_vmcore_ops *ops = get_fbsd_vmcore_ops (gdbarch); ops->cpu_pcb_addr = cpu_pcb_addr; } static CORE_ADDR kernstart; static kvm_t *kvm; int kgdb_quiet; static ptid_t fbsd_vmcore_ptid(int tid) { if (kvm == NULL) /* * The remote target stores the 'tid' in the lwp * field. */ return ptid_t(inferior_ptid.pid(), tid, 0); /* * This follows the model described in bsd-kvm.c except that * in kernel tids are used as the tid of the ptid instead of a * process ID. */ return ptid_t(1, 1, tid); } #define MSGBUF_SEQ_TO_POS(size, seq) ((seq) % (size)) static void kgdb_dmesg(void) { CORE_ADDR bufp; int size, rseq, wseq; gdb_byte c; /* * Display the unread portion of the message buffer. This gives the * user a some initial data to work from. */ if (kgdb_quiet) return; try { bufp = parse_and_eval_address("msgbufp->msg_ptr"); size = parse_and_eval_long("msgbufp->msg_size"); rseq = parse_and_eval_long("msgbufp->msg_rseq"); wseq = parse_and_eval_long("msgbufp->msg_wseq"); } catch (const gdb_exception_error &e) { return; } if (size == 0) return; rseq = MSGBUF_SEQ_TO_POS(size, rseq); wseq = MSGBUF_SEQ_TO_POS(size, wseq); if (rseq == wseq) return; printf("\nUnread portion of the kernel message buffer:\n"); while (rseq < wseq) { read_memory(bufp + rseq, &c, 1); putchar(c); rseq++; if (rseq == size) rseq = 0; } if (c != '\n') putchar('\n'); putchar('\n'); } #define KERNEL_INTERP "/red/herring" enum gdb_osabi fbsd_kernel_osabi_sniffer(bfd *abfd) { asection *s; bfd_byte buf[sizeof(KERNEL_INTERP)]; bfd_byte *bufp; /* First, determine if this is a FreeBSD/ELF binary. */ switch (elf_elfheader(abfd)->e_ident[EI_OSABI]) { case ELFOSABI_FREEBSD: break; case ELFOSABI_NONE: { enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; for (asection *sect : gdb_bfd_sections (abfd)) generic_elf_osabi_sniff_abi_tag_sections (abfd, sect, &osabi); /* * aarch64 and RISC-V kernels don't have the right * note tag for kernels so just look for /red/herring * anyway. */ if (osabi == GDB_OSABI_UNKNOWN && ((elf_elfheader(abfd)->e_machine == EM_AARCH64) || (elf_elfheader(abfd)->e_machine == EM_RISCV))) break; if (osabi != GDB_OSABI_FREEBSD) return (GDB_OSABI_UNKNOWN); break; } default: return (GDB_OSABI_UNKNOWN); } /* FreeBSD ELF kernels have an interpreter path of "/red/herring". */ bufp = buf; s = bfd_get_section_by_name(abfd, ".interp"); if (s != NULL && bfd_section_size(s) == sizeof(buf) && bfd_get_full_section_contents(abfd, s, &bufp) && memcmp(buf, KERNEL_INTERP, sizeof(buf)) == 0) return (GDB_OSABI_FREEBSD_KERNEL); return (GDB_OSABI_UNKNOWN); } /* The FreeBSD libkvm target. */ static const target_info fbsd_kvm_target_info = { "vmcore", N_("Kernel core dump file"), N_("Use a vmcore file as a target.\n\ If no filename is specified, /dev/mem is used to examine the running kernel.\n\ target vmcore [-w] [filename]") }; class fbsd_kvm_target final : public process_stratum_target { public: fbsd_kvm_target () = default; const target_info &info () const override { return fbsd_kvm_target_info; } void close () override; void fetch_registers (struct regcache *, int) override; enum target_xfer_status xfer_partial (enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) override; void files_info () override; bool thread_alive (ptid_t ptid) override; std::string pid_to_str (ptid_t) override; const char *extra_thread_info (thread_info *) override; bool has_all_memory () override { return false; } bool has_memory () override; bool has_stack () override; bool has_registers () override; bool has_execution (inferior *inf) override { return false; } }; /* Target ops for libkvm interface. */ static fbsd_kvm_target fbsd_kvm_ops; #ifdef HAVE_KVM_OPEN2 static int kgdb_resolve_symbol(const char *name, kvaddr_t *kva) { struct bound_minimal_symbol ms; ms = lookup_minimal_symbol (name, NULL, NULL); if (ms.minsym == NULL) return (1); *kva = ms.value_address (); return (0); } #endif static void fbsd_kvm_target_open (const char *args, int from_tty) { - struct fbsd_vmcore_ops *ops = get_fbsd_vmcore_ops (target_gdbarch ()); + struct fbsd_vmcore_ops *ops = get_fbsd_vmcore_ops (current_inferior ()->arch ()); char kvm_err[_POSIX2_LINE_MAX]; struct inferior *inf; struct cleanup *old_chain; struct kthr *kt; kvm_t *nkvm; const char *kernel; std::string filename; LONGEST osreldate; bool writeable; if (ops == NULL || ops->supply_pcb == NULL || ops->cpu_pcb_addr == NULL) error ("ABI doesn't support a vmcore target"); target_preopen (from_tty); kernel = get_exec_file (0); if (kernel == NULL) error ("Can't open a vmcore without a kernel"); writeable = false; if (args != NULL) { gdb_argv built_argv (args); for (char **argv = built_argv.get (); *argv != NULL; argv++) { if (**argv == '-') { if (strcmp (*argv, "-w") == 0) writeable = true; else error (_("Invalid argument")); } else { if (!filename.empty ()) error (_("Invalid argument")); filename = gdb_tilde_expand (*argv); if (!IS_ABSOLUTE_PATH (filename)) filename = gdb_abspath (filename.c_str ()); } } } #ifdef HAVE_KVM_OPEN2 nkvm = kvm_open2(kernel, filename.c_str (), writeable ? O_RDWR : O_RDONLY, kvm_err, kgdb_resolve_symbol); #else nkvm = kvm_openfiles(kernel, filename.c_str (), NULL, writeable ? O_RDWR : O_RDONLY, kvm_err); #endif if (nkvm == NULL) { error ("Failed to open vmcore: %s", kvm_err); } /* Don't free the filename now and close any previous vmcore. */ current_inferior ()->unpush_target (&fbsd_kvm_ops); #ifdef HAVE_KVM_DISP /* Relocate kernel objfile if needed. */ struct objfile *symfile_objfile = current_program_space->symfile_object_file; if (symfile_objfile != nullptr && (bfd_get_file_flags(symfile_objfile->obfd.get ()) & (EXEC_P | DYNAMIC)) != 0) { CORE_ADDR displacement = kvm_kerndisp(nkvm); if (displacement != 0) { section_offsets new_offsets (symfile_objfile->section_offsets.size (), displacement); objfile_relocate(symfile_objfile, new_offsets); } } #endif kvm = nkvm; vmcore = std::move(filename); target_unpush_up unpusher; inf = current_inferior(); inf->push_target (&fbsd_kvm_ops); if (inf->pid == 0) { inferior_appeared(inf, 1); inf->fake_pid_p = 1; } /* * Determine the first address in KVA. Newer kernels export * VM_MAXUSER_ADDRESS and the first kernel address can be * determined by adding one. Older kernels do not provide a * symbol that is valid on all platforms, but kernbase is close * for most platforms. */ try { kernstart = parse_and_eval_address("vm_maxuser_address") + 1; } catch (const gdb_exception_error &e) { kernstart = kgdb_lookup("kernbase"); } osreldate = parse_and_eval_long("osreldate"); /* * Look up symbols needed for stoppcbs handling, but don't * fail if they aren't present. */ stoppcbs = kgdb_lookup("stoppcbs"); if (osreldate >= 1400088) { /* stoppcbs is now a pointer rather than an array. */ try { stoppcbs = read_memory_typed_address(stoppcbs, - builtin_type(target_gdbarch())->builtin_data_ptr); + builtin_type(current_inferior ()->arch())->builtin_data_ptr); } catch (const gdb_exception_error &e) { stoppcbs = 0; } } try { pcb_size = parse_and_eval_long("pcb_size"); } catch (const gdb_exception_error &e) { pcb_size = 0; } if (pcb_size == 0) { try { pcb_size = parse_and_eval_long("sizeof(struct pcb)"); } catch (const gdb_exception_error &e) { #ifdef HAVE_KVM_OPEN2 if (kvm_native(nkvm)) pcb_size = sizeof(struct pcb); else pcb_size = 0; #else pcb_size = sizeof(struct pcb); #endif } } kgdb_dmesg(); kt = kgdb_thr_init(ops->cpu_pcb_addr); thread_info *curthr = nullptr; while (kt != NULL) { thread_info *thr = add_thread_silent(&fbsd_kvm_ops, fbsd_vmcore_ptid(kt->tid)); if (kt == curkthr) curthr = thr; kt = kgdb_thr_next(kt); } switch_to_thread (curthr); unpusher.release (); post_create_inferior (from_tty); - target_fetch_registers (get_current_regcache (), -1); + target_fetch_registers (get_thread_regcache (curthr), -1); reinit_frame_cache (); print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1); } void fbsd_kvm_target::close() { if (kvm != NULL) { switch_to_no_thread (); exit_inferior (current_inferior ()); - clear_solib(); + clear_solib (current_program_space); if (kvm_close(kvm) != 0) warning("cannot close \"%s\": %s", vmcore.c_str (), kvm_geterr(kvm)); kvm = NULL; vmcore.clear (); } } #if 0 static void kgdb_trgt_detach(struct target_ops *ops, const char *args, int from_tty) { if (args) error ("Too many arguments"); unpush_target(&kgdb_trgt_ops); reinit_frame_cache(); if (from_tty) gdb_printf("No vmcore file now.\n"); } #endif const char * fbsd_kvm_target::extra_thread_info(thread_info *ti) { return (kgdb_thr_extra_thread_info(ti->ptid.tid())); } bool fbsd_kvm_target::has_memory () { return (kvm != NULL); } bool fbsd_kvm_target::has_stack () { return (kvm != NULL); } bool fbsd_kvm_target::has_registers () { return (kvm != NULL); } void fbsd_kvm_target::files_info() { gdb_printf ("\t`%s', ", vmcore.c_str ()); gdb_stdout->wrap_here (8); gdb_printf ("file type %s.\n", "FreeBSD kernel vmcore"); } std::string fbsd_kvm_target::pid_to_str(ptid_t ptid) { return string_printf (_("Thread %ld"), ptid.tid ()); } bool fbsd_kvm_target::thread_alive(ptid_t ptid) { return (kgdb_thr_lookup_tid(ptid.tid()) != NULL); } void fbsd_kvm_target::fetch_registers(struct regcache *regcache, int regnum) { - struct fbsd_vmcore_ops *ops = get_fbsd_vmcore_ops (target_gdbarch ()); + struct fbsd_vmcore_ops *ops = get_fbsd_vmcore_ops (regcache->arch ()); struct kthr *kt; if (ops->supply_pcb == NULL) return; kt = kgdb_thr_lookup_tid(regcache->ptid().tid()); if (kt == NULL) return; ops->supply_pcb(regcache, kt->pcb); } enum target_xfer_status fbsd_kvm_target::xfer_partial(enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { ssize_t nbytes; gdb_assert(kvm != NULL); switch (object) { case TARGET_OBJECT_MEMORY: nbytes = len; if (readbuf != NULL) #ifdef HAVE_KVM_OPEN2 nbytes = kvm_read2(kvm, offset, readbuf, len); #else nbytes = kvm_read(kvm, offset, readbuf, len); #endif if (writebuf != NULL && len > 0) nbytes = kvm_write(kvm, offset, writebuf, len); if (nbytes < 0) return TARGET_XFER_E_IO; if (nbytes == 0) return TARGET_XFER_EOF; *xfered_len = nbytes; return TARGET_XFER_OK; default: return TARGET_XFER_E_IO; } } static void kgdb_switch_to_thread(const char *arg, int tid) { struct thread_info *tp = fbsd_kvm_ops.find_thread (fbsd_vmcore_ptid (tid)); if (tp == NULL) error ("invalid tid"); thread_select (arg, tp); } static void kgdb_set_proc_cmd (const char *arg, int from_tty) { CORE_ADDR addr; struct kthr *thr; if (!arg) error_no_arg ("proc address for the new context"); if (kvm == NULL) error ("only supported for core file target"); addr = parse_and_eval_address (arg); if (addr < kernstart) { thr = kgdb_thr_lookup_pid((int)addr); if (thr == NULL) error ("invalid pid"); } else { thr = kgdb_thr_lookup_paddr(addr); if (thr == NULL) error("invalid proc address"); } kgdb_switch_to_thread(arg, thr->tid); } static void kgdb_set_tid_cmd (const char *arg, int from_tty) { CORE_ADDR addr; struct kthr *thr; if (!arg) error_no_arg ("TID or thread address for the new context"); addr = (CORE_ADDR) parse_and_eval_address (arg); if (kvm != NULL && addr >= kernstart) { thr = kgdb_thr_lookup_taddr(addr); if (thr == NULL) error("invalid thread address"); addr = thr->tid; } kgdb_switch_to_thread(arg, addr); } void _initialize_kgdb_target (); void _initialize_kgdb_target () { add_target(fbsd_kvm_target_info, fbsd_kvm_target_open, filename_completer); add_com ("proc", class_obscure, kgdb_set_proc_cmd, "Set current process context"); add_com ("tid", class_obscure, kgdb_set_tid_cmd, "Set current thread context"); } CORE_ADDR kgdb_trgt_stop_pcb(u_int cpuid) { if (stoppcbs == 0 || pcb_size == 0) return 0; return (stoppcbs + pcb_size * cpuid); } diff --git a/devel/gdb/files/kgdb/i386fbsd-kern.c b/devel/gdb/files/kgdb/i386fbsd-kern.c index d6e1075db9a3..2dd7bc897a95 100644 --- a/devel/gdb/files/kgdb/i386fbsd-kern.c +++ b/devel/gdb/files/kgdb/i386fbsd-kern.c @@ -1,567 +1,567 @@ /* * 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 "defs.h" #include "frame-unwind.h" #include "gdbcore.h" #include "inferior.h" #include "osabi.h" #include "regcache.h" #include "progspace.h" #include "solib.h" #include "trad-frame.h" #include "i386-tdep.h" #ifdef __i386__ #include #include #include #include #include #endif #include "kgdb.h" struct i386fbsd_info { int ofs_fix; }; /* Per-program-space data key. */ static const registry::key i386fbsd_pspace_data; /* Get the current i386fbsd data. If none is found yet, add it now. This function always returns a valid object. */ static struct i386fbsd_info * get_i386fbsd_info (void) { struct i386fbsd_info *info; info = i386fbsd_pspace_data.get (current_program_space); if (info != nullptr) return info; info = i386fbsd_pspace_data.emplace (current_program_space); /* * In revision 1.117 of i386/i386/exception.S trap handlers * were changed to pass trapframes by reference rather than * by value. Detect this by seeing if the first instruction * at the 'calltrap' label is a "push %esp" which has the * opcode 0x54. */ if (parse_and_eval_long("((char *)calltrap)[0]") == 0x54) info->ofs_fix = 4; else info->ofs_fix = 0; return info; } /* * Even though the pcb contains fields for the segment selectors, only * %gs is updated on each context switch. The other selectors are * saved in stoppcbs[], but we just hardcode their known values rather * than handling that special case. */ static const int i386fbsd_pcb_offset[] = { -1, /* %eax */ -1, /* %ecx */ -1, /* %edx */ 4 * 4, /* %ebx */ 3 * 4, /* %esp */ 2 * 4, /* %ebp */ 1 * 4, /* %esi */ 0 * 4, /* %edi */ 5 * 4, /* %eip */ -1, /* %eflags */ -1, /* %cs */ -1, /* %ss */ -1, /* %ds */ -1, /* %es */ -1, /* %fs */ -1, /* %gs */ }; #define CODE_SEL (4 << 3) #define DATA_SEL (5 << 3) #define PRIV_SEL (1 << 3) static void i386fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[4]; int i; memset(buf, 0, sizeof(buf)); /* * XXX The PCB may have been swapped out. Supply a dummy %eip value * so as to avoid triggering an exception during stack unwinding. */ regcache->raw_supply(I386_EIP_REGNUM, buf); for (i = 0; i < ARRAY_SIZE (i386fbsd_pcb_offset); i++) if (i386fbsd_pcb_offset[i] != -1) { if (target_read_memory(pcb_addr + i386fbsd_pcb_offset[i], buf, sizeof buf) != 0) continue; regcache->raw_supply(i, buf); } regcache->raw_supply_unsigned(I386_CS_REGNUM, CODE_SEL); regcache->raw_supply_unsigned(I386_DS_REGNUM, DATA_SEL); regcache->raw_supply_unsigned(I386_ES_REGNUM, DATA_SEL); regcache->raw_supply_unsigned(I386_FS_REGNUM, PRIV_SEL); regcache->raw_supply_unsigned(I386_GS_REGNUM, DATA_SEL); regcache->raw_supply_unsigned(I386_SS_REGNUM, DATA_SEL); } #ifdef __i386__ /* TODO: Make this cross-debugger friendly. */ static const int i386fbsd_tss_offset[] = { 10 * 4, /* %eax */ 11 * 4, /* %ecx */ 12 * 4, /* %edx */ 13 * 4, /* %ebx */ 14 * 4, /* %esp */ 15 * 4, /* %ebp */ 16 * 4, /* %esi */ 17 * 4, /* %edi */ 8 * 4, /* %eip */ 9 * 4, /* %eflags */ 19 * 4, /* %cs */ 20 * 4, /* %ss */ 21 * 4, /* %ds */ 18 * 4, /* %es */ 22 * 4, /* %fs */ 23 * 4, /* %gs */ }; /* * If the current thread is executing on a CPU, fetch the common_tss * for that CPU. * * This is painful because 'struct pcpu' is variant sized, so we can't * use it. Instead, we lookup the GDT selector for this CPU and * extract the base of the TSS from there. */ static CORE_ADDR i386fbsd_fetch_tss(void) { struct kthr *kt; struct segment_descriptor sd; CORE_ADDR addr, cpu0prvpage, tss; kt = kgdb_thr_lookup_tid(inferior_ptid.tid()); if (kt == NULL || kt->cpu == NOCPU || kt->cpu < 0) return (0); addr = kgdb_lookup("gdt"); if (addr == 0) return (0); addr += (kt->cpu * NGDT + GPROC0_SEL) * sizeof(sd); if (target_read_memory(addr, (gdb_byte *)&sd, sizeof(sd)) != 0) return (0); if (sd.sd_type != SDT_SYS386BSY) { warning ("descriptor is not a busy TSS"); return (0); } tss = sd.sd_hibase << 24 | sd.sd_lobase; /* * In SMP kernels, the TSS is stored as part of the per-CPU * data. On older kernels, the CPU0's private page * is stored at an address that isn't mapped in minidumps. * However, the data is mapped at the alternate cpu0prvpage * address. Thus, if the TSS is at the invalid address, * change it to be relative to cpu0prvpage instead. */ if (trunc_page(tss) == 0xffc00000) { try { cpu0prvpage = parse_and_eval_address("cpu0prvpage"); } catch (const gdb_exception_error &e) { return (0); } tss = cpu0prvpage + (tss & PAGE_MASK); } return (tss); } static struct trad_frame_cache * -i386fbsd_dblfault_cache (frame_info_ptr this_frame, void **this_cache) +i386fbsd_dblfault_cache (const frame_info_ptr &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, tss; int i; if (*this_cache != NULL) return (struct trad_frame_cache *)(*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); tss = i386fbsd_fetch_tss (); for (i = 0; i < ARRAY_SIZE (i386fbsd_tss_offset); i++) if (i386fbsd_tss_offset[i] != -1) trad_frame_set_reg_addr (cache, i, tss + i386fbsd_tss_offset[i]); /* Construct the frame ID using the function start. */ /* XXX: Stack address should be dbfault_stack + PAGE_SIZE. */ trad_frame_set_id (cache, frame_id_build (tss + sizeof(struct i386tss), func)); return cache; } static void -i386fbsd_dblfault_this_id (frame_info_ptr this_frame, +i386fbsd_dblfault_this_id (const frame_info_ptr &this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = i386fbsd_dblfault_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * -i386fbsd_dblfault_prev_register (frame_info_ptr this_frame, +i386fbsd_dblfault_prev_register (const frame_info_ptr &this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = i386fbsd_dblfault_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int i386fbsd_dblfault_sniffer (const struct frame_unwind *self, - frame_info_ptr this_frame, + const frame_info_ptr &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, "dblfault_handler") == 0); } static const struct frame_unwind i386fbsd_dblfault_unwind = { "i386 FreeBSD double fault", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, i386fbsd_dblfault_this_id, i386fbsd_dblfault_prev_register, NULL, i386fbsd_dblfault_sniffer }; #endif static const int i386fbsd_trapframe_offset[] = { 10 * 4, /* %eax */ 9 * 4, /* %ecx */ 8 * 4, /* %edx */ 7 * 4, /* %ebx */ 16 * 4, /* %esp */ 5 * 4, /* %ebp */ 4 * 4, /* %esi */ 3 * 4, /* %edi */ 13 * 4, /* %eip */ 15 * 4, /* %eflags */ 14 * 4, /* %cs */ 17 * 4, /* %ss */ 2 * 4, /* %ds */ 1 * 4, /* %es */ 0 * 4, /* %fs */ -1 /* %gs */ }; #define TRAPFRAME_SIZE 72 static struct trad_frame_cache * -i386fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) +i386fbsd_trapframe_cache (const frame_info_ptr &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; struct i386fbsd_info *info; CORE_ADDR addr, cs, func, pc, sp; const char *name; int i; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); info = get_i386fbsd_info(); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (strcmp(name, "calltrap") == 0 || strcmp(name, "Xlcall_syscall") == 0 || strcmp(name, "Xint0x80_syscall") == 0) /* Traps in later kernels pass the trap frame by reference. */ sp += info->ofs_fix; else if (strcmp(name, "Xtimerint") == 0) /* Timer interrupts also pass the trap frame by reference. */ sp += info->ofs_fix; else if (strcmp(name, "Xcpustop") == 0 || strcmp(name, "Xrendezvous") == 0 || strcmp(name, "Xipi_intr_bitmap_handler") == 0 || strcmp(name, "Xlazypmap") == 0) /* These handlers push a trap frame only. */ ; else if (strcmp(name, "fork_trampoline") == 0) if (get_frame_pc (this_frame) == func) { /* fork_exit hasn't been called (kthread has never run), so %esp in the pcb points to the word above the trapframe. */ sp += 4; } else { /* fork_exit has been called, so %esp in fork_exit's frame is &tf - 12. */ sp += 12; } else { /* Interrupt frames pass the IDT vector in addition to the trap frame. */ sp += info->ofs_fix + 4; } addr = sp + i386fbsd_trapframe_offset[I386_CS_REGNUM]; cs = read_memory_unsigned_integer (addr, 4, byte_order); for (i = 0; i < ARRAY_SIZE (i386fbsd_trapframe_offset); i++) { /* %ss/%esp are only present in the trapframe for a trap from userland. */ if ((cs & I386_SEL_RPL) == I386_SEL_KPL) { if (i == I386_SS_REGNUM) continue; if (i == I386_ESP_REGNUM) { trad_frame_set_reg_value (cache, i, sp + TRAPFRAME_SIZE - 8); continue; } } if (i386fbsd_trapframe_offset[i] != -1) trad_frame_set_reg_addr (cache, i, sp + i386fbsd_trapframe_offset[i]); } /* Read %eip from trap frame. */ addr = sp + i386fbsd_trapframe_offset[I386_EIP_REGNUM]; pc = read_memory_unsigned_integer (addr, 4, 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. */ sp += TRAPFRAME_SIZE; if ((cs & I386_SEL_RPL) == I386_SEL_KPL) sp -= 8; trad_frame_set_id (cache, frame_id_build (sp, func)); } return cache; } static void -i386fbsd_trapframe_this_id (frame_info_ptr this_frame, +i386fbsd_trapframe_this_id (const frame_info_ptr &this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = i386fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * -i386fbsd_trapframe_prev_register (frame_info_ptr this_frame, +i386fbsd_trapframe_prev_register (const frame_info_ptr &this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = i386fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int i386fbsd_trapframe_sniffer (const struct frame_unwind *self, - frame_info_ptr this_frame, + const frame_info_ptr &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) || (name[0] == 'X' && name[1] != '_'))); } static const struct frame_unwind i386fbsd_trapframe_unwind = { "i386 FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, i386fbsd_trapframe_this_id, i386fbsd_trapframe_prev_register, NULL, i386fbsd_trapframe_sniffer }; static void i386fbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) { i386_elf_init_abi(info, gdbarch); #ifdef __i386__ frame_unwind_prepend_unwinder(gdbarch, &i386fbsd_dblfault_unwind); #endif frame_unwind_prepend_unwinder(gdbarch, &i386fbsd_trapframe_unwind); set_gdbarch_so_ops(gdbarch, &kld_so_ops); fbsd_vmcore_set_supply_pcb(gdbarch, i386fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); } void _initialize_i386_kgdb_tdep (); void _initialize_i386_kgdb_tdep () { /* This is used for both i386 and amd64, but amd64 always includes this target, so just include it here. */ gdbarch_register_osabi_sniffer(bfd_arch_i386, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_KERNEL, i386fbsd_kernel_init_abi); #ifdef __i386__ /* * FreeBSD/i386 kernels prior to the introduction of AVX * support used a different layout for the PCB. If gdb is * compiled on these systems, these asserts will fail. The * package builders build packages on older systems which are * then run on newer systems. These binaries trip over these * assertions even when debugging user programs and even * though the running kernel is new enough. To cope, disable * the assertion checks unless gdb is built against a new * enough world. Note that this means kgdb is not going to * parse PCBs correctly on FreeBSD/i386 kernels before AVX was * merged. */ #if __FreeBSD_version >= 1001505 gdb_assert(offsetof(struct pcb, pcb_ebx) == i386fbsd_pcb_offset[I386_EBX_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_esp) == i386fbsd_pcb_offset[I386_ESP_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_ebp) == i386fbsd_pcb_offset[I386_EBP_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_esi) == i386fbsd_pcb_offset[I386_ESI_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_edi) == i386fbsd_pcb_offset[I386_EDI_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_eip) == i386fbsd_pcb_offset[I386_EIP_REGNUM]); #endif gdb_assert(CODE_SEL == GSEL(GCODE_SEL, SEL_KPL)); gdb_assert(DATA_SEL == GSEL(GDATA_SEL, SEL_KPL)); gdb_assert(PRIV_SEL == GSEL(GPRIV_SEL, SEL_KPL)); gdb_assert(sizeof(struct trapframe) == TRAPFRAME_SIZE); gdb_assert(offsetof(struct trapframe, tf_eax) == i386fbsd_trapframe_offset[I386_EAX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ecx) == i386fbsd_trapframe_offset[I386_ECX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_edx) == i386fbsd_trapframe_offset[I386_EDX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ebx) == i386fbsd_trapframe_offset[I386_EBX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_esp) == i386fbsd_trapframe_offset[I386_ESP_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ebp) == i386fbsd_trapframe_offset[I386_EBP_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_esi) == i386fbsd_trapframe_offset[I386_ESI_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_edi) == i386fbsd_trapframe_offset[I386_EDI_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_eip) == i386fbsd_trapframe_offset[I386_EIP_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_eflags) == i386fbsd_trapframe_offset[I386_EFLAGS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_cs) == i386fbsd_trapframe_offset[I386_CS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ss) == i386fbsd_trapframe_offset[I386_SS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ds) == i386fbsd_trapframe_offset[I386_DS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_es) == i386fbsd_trapframe_offset[I386_ES_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_fs) == i386fbsd_trapframe_offset[I386_FS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_eax) == i386fbsd_tss_offset[I386_EAX_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ecx) == i386fbsd_tss_offset[I386_ECX_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_edx) == i386fbsd_tss_offset[I386_EDX_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ebx) == i386fbsd_tss_offset[I386_EBX_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_esp) == i386fbsd_tss_offset[I386_ESP_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ebp) == i386fbsd_tss_offset[I386_EBP_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_esi) == i386fbsd_tss_offset[I386_ESI_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_edi) == i386fbsd_tss_offset[I386_EDI_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_eip) == i386fbsd_tss_offset[I386_EIP_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_eflags) == i386fbsd_tss_offset[I386_EFLAGS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_cs) == i386fbsd_tss_offset[I386_CS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ss) == i386fbsd_tss_offset[I386_SS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ds) == i386fbsd_tss_offset[I386_DS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_es) == i386fbsd_tss_offset[I386_ES_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_fs) == i386fbsd_tss_offset[I386_FS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_gs) == i386fbsd_tss_offset[I386_GS_REGNUM]); #endif } diff --git a/devel/gdb/files/kgdb/kgdb-main.c b/devel/gdb/files/kgdb/kgdb-main.c index 07dbf0a8dccd..e21ce5334ae6 100644 --- a/devel/gdb/files/kgdb/kgdb-main.c +++ b/devel/gdb/files/kgdb/kgdb-main.c @@ -1,374 +1,376 @@ /* * 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 "defs.h" +#include "annotate.h" #include "interps.h" #include "main.h" #include "osabi.h" #include "run-on-main-thread.h" #include "serial.h" +#include "solib.h" #include #include #include "kgdb.h" static int verbose; static char crashdir[PATH_MAX]; static char *dumpnr; static char *kernel; static char *remote; static char *vmcore; static void usage(void) { fprintf(stderr, "usage: %s [-afqvw] [-b rate] [-d crashdir] [-c core | -n dumpnr | -r device]\n" "\t[kernel [core]]\n", getprogname()); exit(1); } static void kernel_from_dumpnr(const char *nr) { char line[PATH_MAX], path[PATH_MAX]; FILE *info; char *dir; struct stat st; int l; /* * If there's a kernel image right here in the crash directory, then * use it. The kernel image is either called kernel. or is in a * subdirectory kernel. and called kernel. The latter allows us * to collect the modules in the same place. */ snprintf(path, sizeof(path), "%s/kernel.%s", crashdir, nr); if (stat(path, &st) == 0) { if (S_ISREG(st.st_mode)) { kernel = strdup(path); return; } if (S_ISDIR(st.st_mode)) { snprintf(path, sizeof(path), "%s/kernel.%s/kernel", crashdir, nr); if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) { kernel = strdup(path); return; } } } /* * No kernel image here. Parse the dump header. The kernel object * directory can be found there and we probably have the kernel * image still in it. The object directory may also have a kernel * with debugging info (called either kernel.full or kernel.debug). * If we have a debug kernel, use it. */ snprintf(path, sizeof(path), "%s/info.%s", crashdir, nr); info = fopen(path, "r"); if (info == NULL) { warn("%s", path); return; } while (fgets(line, sizeof(line), info) != NULL) { l = strlen(line); if (l > 0 && line[l - 1] == '\n') line[--l] = '\0'; if (strncmp(line, " ", 4) == 0) { fclose(info); dir = strchr(line, ':'); dir = (dir == NULL) ? line + 4 : dir + 1; /* * Check for kernel.full first as if it exists * kernel.debug will also exist, but will only * contain debug symbols and not be recognized * as a valid kernel by the osabi sniffer. */ snprintf(path, sizeof(path), "%s/kernel.full", dir); if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) { kernel = strdup(path); return; } snprintf(path, sizeof(path), "%s/kernel.debug", dir); if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) { kernel = strdup(path); return; } snprintf(path, sizeof(path), "%s/kernel", dir); if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) { kernel = strdup(path); return; } return; } } fclose(info); } /* * Remote targets can support any number of syntaxes and we want to * support them all with one addition: we support specifying a device * node for a serial device without the "/dev/" prefix. * * What we do is to stat(2) the existing remote target first. If that * fails, we try it with "/dev/" prepended. If that succeeds we use * the resulting path, otherwise we use the original target. If * either stat(2) succeeds make sure the file is either a character * device or a FIFO. */ static void verify_remote(void) { char path[PATH_MAX]; struct stat st; if (stat(remote, &st) != 0) { snprintf(path, sizeof(path), "/dev/%s", remote); if (stat(path, &st) != 0) return; free(remote); remote = strdup(path); } if (!S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode)) errx(1, "%s: not a special file, FIFO or socket", remote); } static void add_arg(struct captured_main_args *args, char const *arg) { args->argc++; args->argv = (char **)reallocf(args->argv, (args->argc + 1) * sizeof(char *)); if (args->argv == NULL) err(1, "Out of memory building argument list"); args->argv[args->argc] = (char *)arg; } int main(int argc, char *argv[]) { char path[PATH_MAX]; struct stat st; struct captured_main_args args; char *s; int a, ch, writeable; dumpnr = NULL; writeable = 0; strlcpy(crashdir, "/var/crash", sizeof(crashdir)); s = getenv("KGDB_CRASH_DIR"); if (s != NULL) strlcpy(crashdir, s, sizeof(crashdir)); /* Convert long options into short options. */ for (a = 1; a < argc; a++) { s = argv[a]; if (s[0] == '-') { s++; /* Long options take either 1 or 2 dashes. */ if (s[0] == '-') s++; if (strcmp(s, "quiet") == 0) argv[a] = (char *)"-q"; else if (strcmp(s, "fullname") == 0) argv[a] = (char *)"-f"; } } kgdb_quiet = 0; memset (&args, 0, sizeof args); args.interpreter_p = INTERP_CONSOLE; args.argv = (char **)xmalloc(sizeof(char *)); args.argv[0] = argv[0]; while ((ch = getopt(argc, argv, "ab:c:d:fn:qr:vw")) != -1) { switch (ch) { case 'a': annotation_level++; break; case 'b': { int i; char *p; i = strtol(optarg, &p, 0); if (*p != '\0' || p == optarg) warnx("warning: could not set baud rate to `%s'.\n", optarg); else baud_rate = i; break; } case 'c': /* use given core file. */ if (vmcore != NULL) { warnx("option %c: can only be specified once", optopt); usage(); /* NOTREACHED */ } vmcore = strdup(optarg); break; case 'd': /* lookup dumps in given directory. */ strlcpy(crashdir, optarg, sizeof(crashdir)); break; case 'f': annotation_level = 1; break; case 'n': /* use dump with given number. */ dumpnr = optarg; break; case 'q': kgdb_quiet = 1; add_arg(&args, "-q"); break; case 'r': /* use given device for remote session. */ if (remote != NULL) { warnx("option %c: can only be specified once", optopt); usage(); /* NOTREACHED */ } remote = strdup(optarg); break; case 'v': /* increase verbosity. */ verbose++; break; case 'w': /* core file is writeable. */ writeable = 1; break; case '?': default: usage(); } } if (((vmcore != NULL) ? 1 : 0) + ((dumpnr != NULL) ? 1 : 0) + ((remote != NULL) ? 1 : 0) > 1) { warnx("options -c, -n and -r are mutually exclusive"); usage(); /* NOTREACHED */ } if (verbose > 1) warnx("using %s as the crash directory", crashdir); if (argc > optind) kernel = strdup(argv[optind++]); if (argc > optind && (dumpnr != NULL || remote != NULL)) { warnx("options -n and -r do not take a core file. Ignored"); optind = argc; } if (dumpnr != NULL) { snprintf(path, sizeof(path), "%s/vmcore.%s", crashdir, dumpnr); if (stat(path, &st) == -1) err(1, "%s", path); if (!S_ISREG(st.st_mode)) errx(1, "%s: not a regular file", path); vmcore = strdup(path); } else if (remote != NULL) { verify_remote(); } else if (argc > optind) { if (vmcore == NULL) vmcore = strdup(argv[optind++]); if (argc > optind) warnx("multiple core files specified. Ignored"); } else if (vmcore == NULL && kernel == NULL) { vmcore = strdup(_PATH_MEM); kernel = strdup(getbootfile()); } if (verbose) { if (vmcore != NULL) warnx("core file: %s", vmcore); if (remote != NULL) warnx("device file: %s", remote); if (kernel != NULL) warnx("kernel image: %s", kernel); } /* A remote target requires an explicit kernel argument. */ if (remote != NULL && kernel == NULL) { warnx("remote debugging requires a kernel"); usage(); /* NOTREACHED */ } /* If we don't have a kernel image yet, try to find one. */ if (kernel == NULL) { if (dumpnr != NULL) kernel_from_dumpnr(dumpnr); if (kernel == NULL) errx(1, "couldn't find a suitable kernel image"); if (verbose) warnx("kernel image: %s", kernel); } /* Set an alternate prompt. */ add_arg(&args, "-iex"); add_arg(&args, "set prompt (kgdb) "); /* Change osabi to assume a FreeBSD kernel. */ add_arg(&args, "-iex"); add_arg(&args, "set osabi FreeBSD/kernel"); /* Open the vmcore if requested. */ if (vmcore != NULL) { add_arg(&args, "-ex"); if (asprintf(&s, "target vmcore %s%s", writeable ? "-w " : "", vmcore) < 0) err(1, "couldn't build command line"); add_arg(&args, s); } /* Open the remote target if requested. */ if (remote != NULL) { add_arg(&args, "-ex"); if (asprintf(&s, "target remote %s", remote) < 0) err(1, "couldn't build command line"); add_arg(&args, s); } add_arg(&args, kernel); /* The libgdb code uses optind too. Reset it... */ optind = 0; /* Terminate argv list. */ add_arg(&args, NULL); gdb_assert (is_main_thread ()); return (gdb_main(&args)); } diff --git a/devel/gdb/files/kgdb/kgdb.h b/devel/gdb/files/kgdb/kgdb.h index 772e33d4daf5..138177981a96 100644 --- a/devel/gdb/files/kgdb/kgdb.h +++ b/devel/gdb/files/kgdb/kgdb.h @@ -1,64 +1,64 @@ /* * 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. */ #ifndef _KGDB_H_ #define _KGDB_H_ struct kthr { struct kthr *next; CORE_ADDR paddr; CORE_ADDR kaddr; CORE_ADDR pcb; int tid; int pid; int cpu; }; extern struct kthr *curkthr; -extern struct target_so_ops kld_so_ops; +extern solib_ops kld_so_ops; extern int kgdb_quiet; CORE_ADDR kgdb_trgt_stop_pcb(u_int); struct kthr *kgdb_thr_first(void); struct kthr *kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int)); struct kthr *kgdb_thr_lookup_tid(int); struct kthr *kgdb_thr_lookup_pid(int); struct kthr *kgdb_thr_lookup_paddr(uintptr_t); struct kthr *kgdb_thr_lookup_taddr(uintptr_t); struct kthr *kgdb_thr_next(struct kthr *); const char *kgdb_thr_extra_thread_info(int); enum gdb_osabi fbsd_kernel_osabi_sniffer(bfd *abfd); void fbsd_vmcore_set_supply_pcb (struct gdbarch *gdbarch, void (*supply_pcb) (struct regcache *, CORE_ADDR)); void fbsd_vmcore_set_cpu_pcb_addr (struct gdbarch *gdbarch, CORE_ADDR (*cpu_pcb_addr) (u_int)); CORE_ADDR kgdb_lookup(const char *sym); #endif /* _KGDB_H_ */ diff --git a/devel/gdb/files/kgdb/mipsfbsd-kern.c b/devel/gdb/files/kgdb/mipsfbsd-kern.c index 761c969d43dd..d8e950080483 100644 --- a/devel/gdb/files/kgdb/mipsfbsd-kern.c +++ b/devel/gdb/files/kgdb/mipsfbsd-kern.c @@ -1,286 +1,286 @@ /* * Copyright (c) 2007 Juniper Networks, Inc. * 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 "defs.h" #include "frame-unwind.h" #include "osabi.h" #include "regcache.h" #include "solib.h" #include "trad-frame.h" #include "mips-tdep.h" #ifdef __mips__ #include #include #include #endif #include "kgdb.h" /* Size of struct trapframe in registers. */ #define TRAPFRAME_WORDS 74 /* From sys/mips/include/pcb.h. Offsets in the pcb_context[] array. */ #define FBSD_PCB_REG_S0 0 #define FBSD_PCB_REG_S1 1 #define FBSD_PCB_REG_S2 2 #define FBSD_PCB_REG_S3 3 #define FBSD_PCB_REG_S4 4 #define FBSD_PCB_REG_S5 5 #define FBSD_PCB_REG_S6 6 #define FBSD_PCB_REG_S7 7 #define FBSD_PCB_REG_SP 8 #define FBSD_PCB_REG_S8 9 #define FBSD_PCB_REG_RA 10 #define FBSD_PCB_REG_SR 11 #define FBSD_PCB_REG_GP 12 #define FBSD_PCB_REG_PC 13 #ifdef __mips__ _Static_assert(TRAPFRAME_WORDS * sizeof(register_t) == sizeof(struct trapframe), "TRAPFRAME_WORDS mismatch"); _Static_assert(FBSD_PCB_REG_S0 == PCB_REG_S0, "PCB_REG_S0 mismatch"); _Static_assert(FBSD_PCB_REG_S1 == PCB_REG_S1, "PCB_REG_S1 mismatch"); _Static_assert(FBSD_PCB_REG_S2 == PCB_REG_S2, "PCB_REG_S2 mismatch"); _Static_assert(FBSD_PCB_REG_S3 == PCB_REG_S3, "PCB_REG_S3 mismatch"); _Static_assert(FBSD_PCB_REG_S4 == PCB_REG_S4, "PCB_REG_S4 mismatch"); _Static_assert(FBSD_PCB_REG_S5 == PCB_REG_S5, "PCB_REG_S5 mismatch"); _Static_assert(FBSD_PCB_REG_S6 == PCB_REG_S6, "PCB_REG_S6 mismatch"); _Static_assert(FBSD_PCB_REG_S7 == PCB_REG_S7, "PCB_REG_S7 mismatch"); _Static_assert(FBSD_PCB_REG_SP == PCB_REG_SP, "PCB_REG_SP mismatch"); _Static_assert(FBSD_PCB_REG_S8 == PCB_REG_S8, "PCB_REG_S8 mismatch"); _Static_assert(FBSD_PCB_REG_RA == PCB_REG_RA, "PCB_REG_RA mismatch"); _Static_assert(FBSD_PCB_REG_SR == PCB_REG_SR, "PCB_REG_SR mismatch"); _Static_assert(FBSD_PCB_REG_GP == PCB_REG_GP, "PCB_REG_GP mismatch"); _Static_assert(FBSD_PCB_REG_PC == PCB_REG_PC, "PCB_REG_PC mismatch"); #endif static void mipsfbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { struct gdbarch *gdbarch = regcache->arch (); size_t regsize = mips_isa_regsize (gdbarch); gdb_byte buf[regsize * (FBSD_PCB_REG_PC + 1)]; /* Read the entire pcb_context[] array in one go. The pcb_context[] array is after the pcb_regs member which is a trapframe. */ if (target_read_memory (pcb_addr + TRAPFRAME_WORDS * regsize, buf, sizeof(buf)) != 0) return; - regcache->raw_supply_unsigned (MIPS_ZERO_REGNUM, 0); + regcache->raw_supply_zeroed (MIPS_ZERO_REGNUM); regcache->raw_supply (MIPS_S2_REGNUM - 2, buf + (regsize * FBSD_PCB_REG_S0)); regcache->raw_supply (MIPS_S2_REGNUM - 1, buf + (regsize * FBSD_PCB_REG_S1)); regcache->raw_supply (MIPS_S2_REGNUM, buf + (regsize * FBSD_PCB_REG_S2)); regcache->raw_supply (MIPS_S2_REGNUM + 1, buf + (regsize * FBSD_PCB_REG_S3)); regcache->raw_supply (MIPS_S2_REGNUM + 2, buf + (regsize * FBSD_PCB_REG_S4)); regcache->raw_supply (MIPS_S2_REGNUM + 3, buf + (regsize * FBSD_PCB_REG_S5)); regcache->raw_supply (MIPS_S2_REGNUM + 4, buf + (regsize * FBSD_PCB_REG_S6)); regcache->raw_supply (MIPS_S2_REGNUM + 5, buf + (regsize * FBSD_PCB_REG_S7)); regcache->raw_supply (MIPS_SP_REGNUM, buf + (regsize * FBSD_PCB_REG_SP)); regcache->raw_supply (MIPS_S2_REGNUM + 6, buf + (regsize * FBSD_PCB_REG_S8)); regcache->raw_supply (MIPS_RA_REGNUM, buf + (regsize * FBSD_PCB_REG_RA)); regcache->raw_supply (MIPS_PS_REGNUM, buf + (regsize * FBSD_PCB_REG_SR)); regcache->raw_supply (MIPS_GP_REGNUM, buf + (regsize * FBSD_PCB_REG_GP)); regcache->raw_supply (MIPS_EMBED_PC_REGNUM, buf + (regsize * FBSD_PCB_REG_PC)); } static struct trad_frame_cache * -mipsfbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) +mipsfbsd_trapframe_cache (const frame_info_ptr &this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); size_t regsize = mips_isa_regsize (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, func, sp; int regnum; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_signed (this_frame, MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch)); /* Skip over CALLFRAME_SIZ. */ addr = sp; if (regsize == 8) addr += regsize * 4; else addr += regsize * (4 + 2); /* GPRs. Skip zero. */ addr += regsize; for (regnum = MIPS_AT_REGNUM; regnum <= MIPS_RA_REGNUM; regnum++) { trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; } regnum = MIPS_PS_REGNUM; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; /* HI and LO. */ regnum = mips_regnum (gdbarch)->lo; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; regnum = mips_regnum (gdbarch)->hi; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; /* BADVADDR. */ regnum = mips_regnum (gdbarch)->badvaddr; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; /* CAUSE. */ regnum = mips_regnum (gdbarch)->cause; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; /* PC. */ regnum = mips_regnum (gdbarch)->pc; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); trad_frame_set_id (cache, frame_id_build (sp + TRAPFRAME_WORDS * regsize, func)); return cache; } static void -mipsfbsd_trapframe_this_id (frame_info_ptr this_frame, +mipsfbsd_trapframe_this_id (const frame_info_ptr &this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = mipsfbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * -mipsfbsd_trapframe_prev_register (frame_info_ptr this_frame, +mipsfbsd_trapframe_prev_register (const frame_info_ptr &this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = mipsfbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int mipsfbsd_trapframe_sniffer (const struct frame_unwind *self, - frame_info_ptr this_frame, + const frame_info_ptr &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, "MipsKernIntr") == 0) || (strcmp(name, "MipsKernGenException") == 0) || (strcmp(name, "MipsTLBInvalidException") == 0))); } static const struct frame_unwind mipsfbsd_trapframe_unwind = { "mips FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, mipsfbsd_trapframe_this_id, mipsfbsd_trapframe_prev_register, NULL, mipsfbsd_trapframe_sniffer }; static void mipsfbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { enum mips_abi abi = mips_abi (gdbarch); set_gdbarch_software_single_step (gdbarch, mips_software_single_step); switch (abi) { case MIPS_ABI_O32: break; case MIPS_ABI_N32: set_gdbarch_long_double_bit (gdbarch, 128); set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad); break; case MIPS_ABI_N64: set_gdbarch_long_double_bit (gdbarch, 128); set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad); break; } frame_unwind_prepend_unwinder (gdbarch, &mipsfbsd_trapframe_unwind); set_gdbarch_so_ops (gdbarch, &kld_so_ops); fbsd_vmcore_set_supply_pcb (gdbarch, mipsfbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); } void _initialize_mips_kgdb_tdep (); void _initialize_mips_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_mips, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD_KERNEL, mipsfbsd_kernel_init_abi); } diff --git a/devel/gdb/files/kgdb/ppcfbsd-kern.c b/devel/gdb/files/kgdb/ppcfbsd-kern.c index fa04f7762c08..0d51553ea7f6 100644 --- a/devel/gdb/files/kgdb/ppcfbsd-kern.c +++ b/devel/gdb/files/kgdb/ppcfbsd-kern.c @@ -1,259 +1,259 @@ /*- * Copyright (c) 2006 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 "defs.h" #include "frame-unwind.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "solib.h" #include "symtab.h" #include "trad-frame.h" #include "ppc-tdep.h" #include "ppc64-tdep.h" #ifdef __powerpc__ #include #include #endif #include "kgdb.h" #define PCB_OFF_R12 0 #define PCB_OFF_CR 20 #define PCB_OFF_SP 21 #define PCB_OFF_TOC 22 #define PCB_OFF_LR 23 #ifdef __powerpc__ _Static_assert(offsetof(struct pcb, pcb_context) == PCB_OFF_R12 * sizeof(register_t), "r12 offset"); _Static_assert(offsetof(struct pcb, pcb_cr) == PCB_OFF_CR * sizeof(register_t), "cr offset"); _Static_assert(offsetof(struct pcb, pcb_sp) == PCB_OFF_SP * sizeof(register_t), "sp offset"); _Static_assert(offsetof(struct pcb, pcb_toc) == PCB_OFF_TOC * sizeof(register_t), "toc offset"); _Static_assert(offsetof(struct pcb, pcb_lr) == PCB_OFF_LR * sizeof(register_t), "lr offset"); #endif static void ppcfbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { ppc_gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ()); gdb_byte buf[24 * tdep->wordsize]; int i; /* Always give a value for PC in case the PCB isn't readable. */ regcache->raw_supply_zeroed (PPC_PC_REGNUM); if (target_read_memory (pcb_addr, buf, sizeof buf) != 0) return; /* r12 - r31 */ for (i = 0; i < 20; i++) regcache->raw_supply (tdep->ppc_gp0_regnum + 12 + i, buf + tdep->wordsize * i); /* r1 is saved in the sp field */ regcache->raw_supply (tdep->ppc_gp0_regnum + 1, buf + tdep->wordsize * PCB_OFF_SP); if (tdep->wordsize == 8) /* r2 is saved in the toc field */ regcache->raw_supply (tdep->ppc_gp0_regnum + 2, buf + tdep->wordsize * PCB_OFF_TOC); regcache->raw_supply (tdep->ppc_lr_regnum, buf + tdep->wordsize * PCB_OFF_LR); regcache->raw_supply (PPC_PC_REGNUM, buf + tdep->wordsize * PCB_OFF_LR); regcache->raw_supply (tdep->ppc_cr_regnum, buf + tdep->wordsize * PCB_OFF_CR); } #define OFF_FIXREG 0 #define OFF_LR 32 #define OFF_CR 33 #define OFF_XER 34 #define OFF_CTR 35 #define OFF_SRR0 36 #define TRAPFRAME_SIZE 42 #ifdef __powerpc__ _Static_assert(sizeof(struct trapframe) == TRAPFRAME_SIZE * sizeof(register_t), "trapframe size"); _Static_assert(offsetof(struct trapframe, fixreg) == OFF_FIXREG * sizeof(register_t), "fixreg offset"); _Static_assert(offsetof(struct trapframe, lr) == OFF_LR * sizeof(register_t), "lr offset"); _Static_assert(offsetof(struct trapframe, cr) == OFF_CR * sizeof(register_t), "cr offset"); _Static_assert(offsetof(struct trapframe, xer) == OFF_XER * sizeof(register_t), "xer offset"); _Static_assert(offsetof(struct trapframe, ctr) == OFF_CTR * sizeof(register_t), "ctr offset"); _Static_assert(offsetof(struct trapframe, srr0) == OFF_SRR0 * sizeof(register_t), "srr0 offset"); #endif static struct trad_frame_cache * -ppcfbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) +ppcfbsd_trapframe_cache (const frame_info_ptr &this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); ppc_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct trad_frame_cache *cache; CORE_ADDR base; int i; if (*this_cache) return (struct trad_frame_cache *)*this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); if (tdep->wordsize == 8) base += 48; else base += 8; for (i = 0; i < ppc_num_gprs; i++) trad_frame_set_reg_addr (cache, tdep->ppc_gp0_regnum + i, base + (OFF_FIXREG + i) * tdep->wordsize); trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, base + OFF_LR * tdep->wordsize); trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, base + OFF_CR * tdep->wordsize); trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, base + OFF_XER * tdep->wordsize); trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, base + OFF_CTR * tdep->wordsize); /* SRR0? */ trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), base + OFF_SRR0 * tdep->wordsize); /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (base, get_frame_func (this_frame))); return cache; } static void -ppcfbsd_trapframe_this_id (frame_info_ptr this_frame, +ppcfbsd_trapframe_this_id (const frame_info_ptr &this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = ppcfbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * -ppcfbsd_trapframe_prev_register (frame_info_ptr this_frame, +ppcfbsd_trapframe_prev_register (const frame_info_ptr &this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = ppcfbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int ppcfbsd_trapframe_sniffer (const struct frame_unwind *self, - frame_info_ptr this_frame, + const frame_info_ptr &this_frame, void **this_cache) { CORE_ADDR pc; const char *name; pc = get_frame_func (this_frame); find_pc_partial_function (pc, &name, NULL, NULL); if (name && (strcmp(name, "trapagain") == 0 || strcmp(name, "trapexit") == 0 || strcmp(name, "dbtrap") == 0)) return 1; return 0; } static const struct frame_unwind ppcfbsd_trapframe_unwind = { "ppc FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, ppcfbsd_trapframe_this_id, ppcfbsd_trapframe_prev_register, NULL, ppcfbsd_trapframe_sniffer }; static void ppcfbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) { ppc_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); frame_unwind_prepend_unwinder(gdbarch, &ppcfbsd_trapframe_unwind); set_gdbarch_so_ops(gdbarch, &kld_so_ops); fbsd_vmcore_set_supply_pcb(gdbarch, ppcfbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); /* FreeBSD doesn't support the 128-bit `long double' from the psABI. */ set_gdbarch_long_double_bit (gdbarch, 64); set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); if (tdep->wordsize == 4) { set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value); } if (tdep->wordsize == 8) { set_gdbarch_convert_from_func_ptr_addr (gdbarch, ppc64_convert_from_func_ptr_addr); set_gdbarch_elf_make_msymbol_special (gdbarch, ppc64_elf_make_msymbol_special); } } void _initialize_ppc_kgdb_tdep (); void _initialize_ppc_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_powerpc, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc, GDB_OSABI_FREEBSD_KERNEL, ppcfbsd_kernel_init_abi); gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc64, GDB_OSABI_FREEBSD_KERNEL, ppcfbsd_kernel_init_abi); /* Not sure about this one. */ gdbarch_register_osabi_sniffer(bfd_arch_rs6000, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_FREEBSD_KERNEL, ppcfbsd_kernel_init_abi); } diff --git a/devel/gdb/files/kgdb/riscv-fbsd-kern.c b/devel/gdb/files/kgdb/riscv-fbsd-kern.c index 2e77e48a2fa8..7a1de9996ee3 100644 --- a/devel/gdb/files/kgdb/riscv-fbsd-kern.c +++ b/devel/gdb/files/kgdb/riscv-fbsd-kern.c @@ -1,205 +1,205 @@ /*- * Copyright (c) 2018 John Baldwin * 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. */ /* Target-dependent code for FreeBSD/riscv64 kernels. */ #include "defs.h" #include "riscv-tdep.h" #include "frame-unwind.h" #include "gdbarch.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "regset.h" #include "solib.h" #include "target.h" #include "trad-frame.h" #include "kgdb.h" static const struct regcache_map_entry riscv_fbsd_pcbmap[] = { { 1, RISCV_RA_REGNUM, 0 }, { 1, RISCV_SP_REGNUM, 0 }, { 1, RISCV_GP_REGNUM, 0 }, { 1, RISCV_TP_REGNUM, 0 }, { 2, RISCV_FP_REGNUM, 0 }, /* s0 - s1 */ { 10, 18, 0 }, /* s2 - s11 */ { 0 } }; static const struct regset riscv_fbsd_pcbregset = { riscv_fbsd_pcbmap, regcache_supply_regset, regcache_collect_regset }; static void riscv_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[16 * riscv_abi_xlen (regcache->arch ())]; /* Always give a value for PC in case the PCB isn't readable. */ regcache->raw_supply_zeroed (RISCV_PC_REGNUM); regcache->raw_supply_zeroed (RISCV_ZERO_REGNUM); if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) { regcache->supply_regset (&riscv_fbsd_pcbregset, -1, buf, sizeof (buf)); /* Supply the RA as PC as well to simulate the PC as if the thread had just returned. */ regcache->raw_supply (RISCV_PC_REGNUM, buf); } } static const struct regcache_map_entry riscv_fbsd_tfmap[] = { { 1, RISCV_RA_REGNUM, 0 }, { 1, RISCV_SP_REGNUM, 0 }, { 1, RISCV_GP_REGNUM, 0 }, { 1, RISCV_TP_REGNUM, 0 }, { 3, 5, 0 }, /* t0 - t2 */ { 4, 28, 0 }, /* t3 - t6 */ { 2, RISCV_FP_REGNUM, 0 }, /* s0 - s1 */ { 10, 18, 0 }, /* s2 - s11 */ { 8, RISCV_A0_REGNUM, 0 }, /* a0 - a7 */ { 1, RISCV_PC_REGNUM, 0 }, { 1, RISCV_CSR_SSTATUS_REGNUM, 0 }, { 1, RISCV_CSR_STVAL_REGNUM, 0 }, { 1, RISCV_CSR_SCAUSE_REGNUM, 0 }, { 0 } }; static struct trad_frame_cache * -riscv_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) +riscv_fbsd_trapframe_cache (const frame_info_ptr &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 func, pc, sp; const char *name; int xlen; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; sp = get_frame_register_unsigned (this_frame, RISCV_SP_REGNUM); xlen = riscv_isa_xlen (gdbarch); trad_frame_set_reg_regmap (cache, riscv_fbsd_tfmap, sp, 35 * xlen); /* Read $PC from trap frame. */ func = get_frame_func (this_frame); find_pc_partial_function (func, &name, NULL, NULL); pc = read_memory_unsigned_integer (sp + 31 * xlen, xlen, 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 + 35 * xlen, func)); } return cache; } static void -riscv_fbsd_trapframe_this_id (frame_info_ptr this_frame, +riscv_fbsd_trapframe_this_id (const frame_info_ptr &this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = riscv_fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * -riscv_fbsd_trapframe_prev_register (frame_info_ptr this_frame, +riscv_fbsd_trapframe_prev_register (const frame_info_ptr &this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = riscv_fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int riscv_fbsd_trapframe_sniffer (const struct frame_unwind *self, - frame_info_ptr this_frame, + const frame_info_ptr &this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name != NULL && ((strcmp (name, "cpu_exception_handler_user") == 0) || (strcmp (name, "cpu_exception_handler_supervisor") == 0))); } static const struct frame_unwind riscv_fbsd_trapframe_unwind = { "riscv FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, riscv_fbsd_trapframe_this_id, riscv_fbsd_trapframe_prev_register, NULL, riscv_fbsd_trapframe_sniffer }; /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */ static void riscv_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { frame_unwind_prepend_unwinder (gdbarch, &riscv_fbsd_trapframe_unwind); set_gdbarch_so_ops (gdbarch, &kld_so_ops); set_gdbarch_software_single_step (gdbarch, riscv_software_single_step); fbsd_vmcore_set_supply_pcb (gdbarch, riscv_fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); } void _initialize_riscv_kgdb_tdep (); void _initialize_riscv_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_riscv, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_FREEBSD_KERNEL, riscv_fbsd_kernel_init_abi); } diff --git a/devel/gdb/files/kgdb/sparc64fbsd-kern.c b/devel/gdb/files/kgdb/sparc64fbsd-kern.c index 115c934a2c70..90a9d32a56f2 100644 --- a/devel/gdb/files/kgdb/sparc64fbsd-kern.c +++ b/devel/gdb/files/kgdb/sparc64fbsd-kern.c @@ -1,315 +1,315 @@ /* * 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 "defs.h" #include "gdbarch.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "target.h" #include "frame-unwind.h" #include "solib.h" #include "trad-frame.h" #include "sparc-tdep.h" #include "sparc64-tdep.h" #ifdef __sparc64__ #include #include #include #endif #include "kgdb.h" #ifdef __sparc64__ static void sparc64fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { struct pcb pcb; if (target_read_memory(pcb_addr, &pcb, sizeof(pcb)) != 0) memset(&pcb, 0, sizeof(pcb)); regcache_raw_supply(regcache, SPARC_SP_REGNUM, (char *)&pcb.pcb_sp); sparc_supply_rwindow(regcache, pcb.pcb_sp, -1); regcache_raw_supply(regcache, SPARC64_PC_REGNUM, (char *)&pcb.pcb_pc); pcb.pcb_pc += 4; regcache_raw_supply(regcache, SPARC64_NPC_REGNUM, (char *)&pcb.pcb_pc); } #endif #define OFF_TF_SP (14 * 8) #define OFF_TF_TPC (25 * 8) #define OFF_TF_TNPC (24 * 8) #define OFF_TF_OUT (8 * 8) #define TRAPFRAME_SIZE (32 * 8) #ifdef __sparc64__ _Static_assert(sizeof(struct trapframe) == TRAPFRAME_SIZE, "trapframe size"); _Static_assert(offsetof(struct trapframe, tf_sp) == OFF_TF_SP, "tf_sp offset"); _Static_assert(offsetof(struct trapframe, tf_tpc) == OFF_TF_TPC, "tf_tpc offset"); _Static_assert(offsetof(struct trapframe, tf_tnpc) == OFF_TF_TNPC, "tf_tnpc offset"); _Static_assert(offsetof(struct trapframe, tf_out) == OFF_TF_OUT, "tf_out offset"); #endif static struct sparc_frame_cache * -sparc64fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) +sparc64fbsd_trapframe_cache (const frame_info_ptr &this_frame, void **this_cache) { struct sparc_frame_cache *cache; CORE_ADDR fp, sp, trapframe_addr; int regnum; if (*this_cache) return (struct sparc_frame_cache *)*this_cache; cache = sparc_frame_cache (this_frame, this_cache); gdb_assert (cache == *this_cache); fp = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM); trapframe_addr = fp + BIAS - TRAPFRAME_SIZE; sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM); cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); cache->saved_regs[SPARC_SP_REGNUM].set_addr (trapframe_addr + OFF_TF_SP); #ifdef notyet cache->saved_regs[SPARC64_STATE_REGNUM].set_addr (trapframe_addr + OFF_TF_TSTATE); #endif cache->saved_regs[SPARC64_PC_REGNUM].set_addr (trapframe_addr + OFF_TF_TPC); cache->saved_regs[SPARC64_NPC_REGNUM].set_addr (trapframe_addr + OFF_TF_TNPC); for (regnum = SPARC_O0_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++) cache->saved_regs[regnum].set_addr (trapframe_addr + OFF_TF_OUT + (regnum - SPARC_O0_REGNUM) * 8); for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) cache->saved_regs[regnum].set_addr (sp + BIAS + (regnum - SPARC_L0_REGNUM) * 8); return cache; } static void -sparc64fbsd_trapframe_this_id (frame_info_ptr this_frame, +sparc64fbsd_trapframe_this_id (const frame_info_ptr &this_frame, void **this_cache, struct frame_id *this_id) { struct sparc_frame_cache *cache = sparc64fbsd_trapframe_cache (this_frame, this_cache); (*this_id) = frame_id_build (cache->base, cache->pc); } static struct value * -sparc64fbsd_trapframe_prev_register (frame_info_ptr this_frame, +sparc64fbsd_trapframe_prev_register (const frame_info_ptr &this_frame, void **this_cache, int regnum) { struct sparc_frame_cache *cache = sparc64fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum); } static int sparc64fbsd_trapframe_sniffer (const struct frame_unwind *self, - frame_info_ptr this_frame, + const frame_info_ptr &this_frame, void **this_cache) { CORE_ADDR pc; const char *name; pc = get_frame_address_in_block (this_frame); find_pc_partial_function (pc, &name, NULL, NULL); if (name && (strcmp(name, "tl0_intr") == 0 || strcmp(name, "tl0_trap") == 0 || strcmp(name, "tl1_intr") == 0 || strcmp(name, "tl1_trap") == 0)) return 1; return 0; } static const struct frame_unwind sparc64fbsd_trapframe_unwind = { "sparc64 FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, sparc64fbsd_trapframe_this_id, sparc64fbsd_trapframe_prev_register, NULL, sparc64fbsd_trapframe_sniffer }; #if 0 struct kgdb_frame_cache { CORE_ADDR pc; CORE_ADDR sp; CORE_ADDR fp; }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SPARC_SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SPARC_SP_REGNUM)); frame_unwind_register(next_frame, SPARC_FP_REGNUM, buf); cache->fp = extract_unsigned_integer(buf, register_size(current_gdbarch, SPARC_FP_REGNUM)); cache->fp += BIAS - sizeof(struct trapframe); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; cache = kgdb_trgt_frame_cache(next_frame, this_cache); switch (regnum) { case SPARC_SP_REGNUM: ofs = offsetof(struct trapframe, tf_sp); break; case SPARC64_PC_REGNUM: ofs = offsetof(struct trapframe, tf_tpc); break; case SPARC64_NPC_REGNUM: ofs = offsetof(struct trapframe, tf_tnpc); break; case SPARC_O0_REGNUM: case SPARC_O1_REGNUM: case SPARC_O2_REGNUM: case SPARC_O3_REGNUM: case SPARC_O4_REGNUM: case SPARC_O5_REGNUM: case SPARC_O7_REGNUM: ofs = offsetof(struct trapframe, tf_out) + (regnum - SPARC_O0_REGNUM) * 8; break; default: if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) { ofs = (regnum - SPARC_L0_REGNUM) * 8; *addrp = cache->sp + BIAS + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } return; } *addrp = cache->fp + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_func_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strcmp(pname, "tl0_intr") == 0 || strcmp(pname, "tl0_trap") == 0 || strcmp(pname, "tl1_intr") == 0 || strcmp(pname, "tl1_trap") == 0) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %lx =%s\n", __func__, pc, pname); */ return (NULL); } #endif static void sparc64fbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) { sparc64_init_abi(info, gdbarch); frame_unwind_prepend_unwinder(gdbarch, &sparc64fbsd_trapframe_unwind); set_gdbarch_so_ops(gdbarch, &kld_so_ops); #ifdef __sparc64__ fbsd_vmcore_set_supply_pcb(gdbarch, sparc64fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); #endif } void _initialize_sparc64_kgdb_tdep (); void _initialize_sparc64_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_sparc, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, GDB_OSABI_FREEBSD_KERNEL, sparc64fbsd_kernel_init_abi); } diff --git a/devel/gdb/pkg-plist b/devel/gdb/pkg-plist index a25ac1fd9528..7c26ef01f0ab 100644 --- a/devel/gdb/pkg-plist +++ b/devel/gdb/pkg-plist @@ -1,141 +1,146 @@ %%GDB_LINK%%bin/gdb %%GDB_LINK%%%%KGDB%%bin/kgdb bin/gdb%%VER%% %%TUI%%bin/gdbtui%%VER%% %%KGDB%%bin/kgdb%%VER%% %%GDB_LINK%%share/man/man1/gdb.1.gz share/man/man1/gdb%%VER%%.1.gz %%GDB_LINK%%%%KGDB%%share/man/man1/kgdb.1.gz %%KGDB%%share/man/man1/kgdb%%VER%%.1.gz %%LIBCXX%%%%DATADIR%%/auto-load%%LIBCXX_DIR%%/libc++.so.1-gdb.py %%LIBCXX%%%%DATADIR%%/auto-load%%LIBCXX_DIR%%/libc++.so.1-gdb.pyc %%PYTHON%%%%DATADIR%%/python/gdb/__init__.py %%PYTHON%%%%DATADIR%%/python/gdb/__init__.pyc %%PYTHON%%%%DATADIR%%/python/gdb/FrameDecorator.py %%PYTHON%%%%DATADIR%%/python/gdb/FrameDecorator.pyc %%PYTHON%%%%DATADIR%%/python/gdb/FrameIterator.py %%PYTHON%%%%DATADIR%%/python/gdb/FrameIterator.pyc %%PYTHON%%%%DATADIR%%/python/gdb/disassembler.py %%PYTHON%%%%DATADIR%%/python/gdb/disassembler.pyc %%PYTHON%%%%DATADIR%%/python/gdb/frames.py %%PYTHON%%%%DATADIR%%/python/gdb/frames.pyc +%%PYTHON%%%%DATADIR%%/python/gdb/missing_debug.py +%%PYTHON%%%%DATADIR%%/python/gdb/missing_debug.pyc %%PYTHON%%%%DATADIR%%/python/gdb/printing.py %%PYTHON%%%%DATADIR%%/python/gdb/prompt.py %%PYTHON%%%%DATADIR%%/python/gdb/prompt.pyc %%PYTHON%%%%DATADIR%%/python/gdb/printing.pyc %%PYTHON%%%%DATADIR%%/python/gdb/styling.py %%PYTHON%%%%DATADIR%%/python/gdb/styling.pyc %%PYTHON%%%%DATADIR%%/python/gdb/types.py %%PYTHON%%%%DATADIR%%/python/gdb/types.pyc %%PYTHON%%%%DATADIR%%/python/gdb/unwinder.py %%PYTHON%%%%DATADIR%%/python/gdb/unwinder.pyc %%PYTHON%%%%DATADIR%%/python/gdb/xmethod.py %%PYTHON%%%%DATADIR%%/python/gdb/xmethod.pyc %%PYTHON%%%%DATADIR%%/python/gdb/command/__init__.py %%PYTHON%%%%DATADIR%%/python/gdb/command/__init__.pyc %%PYTHON%%%%DATADIR%%/python/gdb/command/explore.py %%PYTHON%%%%DATADIR%%/python/gdb/command/explore.pyc %%PYTHON%%%%DATADIR%%/python/gdb/command/frame_filters.py %%PYTHON%%%%DATADIR%%/python/gdb/command/frame_filters.pyc +%%PYTHON%%%%DATADIR%%/python/gdb/command/missing_debug.py +%%PYTHON%%%%DATADIR%%/python/gdb/command/missing_debug.pyc %%PYTHON%%%%DATADIR%%/python/gdb/command/pretty_printers.py %%PYTHON%%%%DATADIR%%/python/gdb/command/pretty_printers.pyc %%PYTHON%%%%DATADIR%%/python/gdb/command/prompt.py %%PYTHON%%%%DATADIR%%/python/gdb/command/prompt.pyc %%PYTHON%%%%DATADIR%%/python/gdb/command/type_printers.py %%PYTHON%%%%DATADIR%%/python/gdb/command/type_printers.pyc %%PYTHON%%%%DATADIR%%/python/gdb/command/unwinders.py %%PYTHON%%%%DATADIR%%/python/gdb/command/unwinders.pyc %%PYTHON%%%%DATADIR%%/python/gdb/command/xmethods.py %%PYTHON%%%%DATADIR%%/python/gdb/command/xmethods.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/__init__.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/__init__.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/breakpoint.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/breakpoint.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/bt.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/bt.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/disassemble.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/disassemble.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/evaluate.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/evaluate.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/events.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/events.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/frames.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/frames.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/io.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/io.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/launch.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/launch.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/locations.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/locations.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/memory.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/memory.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/modules.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/modules.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/next.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/next.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/pause.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/pause.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/scopes.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/scopes.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/server.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/server.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/sources.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/sources.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/startup.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/startup.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/state.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/state.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/threads.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/threads.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/typecheck.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/typecheck.pyc %%PYTHON%%%%DATADIR%%/python/gdb/dap/varref.py %%PYTHON%%%%DATADIR%%/python/gdb/dap/varref.pyc %%PYTHON%%%%DATADIR%%/python/gdb/function/__init__.py %%PYTHON%%%%DATADIR%%/python/gdb/function/__init__.pyc %%PYTHON%%%%DATADIR%%/python/gdb/function/as_string.py %%PYTHON%%%%DATADIR%%/python/gdb/function/as_string.pyc %%PYTHON%%%%DATADIR%%/python/gdb/function/caller_is.py %%PYTHON%%%%DATADIR%%/python/gdb/function/caller_is.pyc %%PYTHON%%%%DATADIR%%/python/gdb/function/strfns.py %%PYTHON%%%%DATADIR%%/python/gdb/function/strfns.pyc %%PYTHON%%%%DATADIR%%/python/gdb/printer/__init__.py %%PYTHON%%%%DATADIR%%/python/gdb/printer/__init__.pyc %%PYTHON%%%%DATADIR%%/python/gdb/printer/bound_registers.py %%PYTHON%%%%DATADIR%%/python/gdb/printer/bound_registers.pyc %%GUILE%%%%DATADIR%%/guile/gdb.go %%GUILE%%%%DATADIR%%/guile/gdb.scm %%GUILE%%%%DATADIR%%/guile/gdb/boot.scm %%GUILE%%%%DATADIR%%/guile/gdb/experimental.go %%GUILE%%%%DATADIR%%/guile/gdb/experimental.scm %%GUILE%%%%DATADIR%%/guile/gdb/init.scm %%GUILE%%%%DATADIR%%/guile/gdb/iterator.go %%GUILE%%%%DATADIR%%/guile/gdb/iterator.scm %%GUILE%%%%DATADIR%%/guile/gdb/printing.go %%GUILE%%%%DATADIR%%/guile/gdb/printing.scm %%GUILE%%%%DATADIR%%/guile/gdb/support.go %%GUILE%%%%DATADIR%%/guile/gdb/support.scm %%GUILE%%%%DATADIR%%/guile/gdb/types.go %%GUILE%%%%DATADIR%%/guile/gdb/types.scm %%DATADIR%%/syscalls/aarch64-linux.xml %%DATADIR%%/syscalls/amd64-linux.xml %%DATADIR%%/syscalls/arm-linux.xml %%DATADIR%%/syscalls/freebsd.xml %%DATADIR%%/syscalls/gdb-syscalls.dtd %%DATADIR%%/syscalls/i386-linux.xml +%%DATADIR%%/syscalls/loongarch-linux.xml %%DATADIR%%/syscalls/mips-n32-linux.xml %%DATADIR%%/syscalls/mips-n64-linux.xml %%DATADIR%%/syscalls/mips-o32-linux.xml %%DATADIR%%/syscalls/netbsd.xml %%DATADIR%%/syscalls/ppc-linux.xml %%DATADIR%%/syscalls/ppc64-linux.xml %%DATADIR%%/syscalls/s390-linux.xml %%DATADIR%%/syscalls/s390x-linux.xml %%DATADIR%%/syscalls/sparc-linux.xml %%DATADIR%%/syscalls/sparc64-linux.xml %%LIBCXX%%share/libcxx-gdbpy/libcxx/__init__.py %%LIBCXX%%share/libcxx-gdbpy/libcxx/__init__.pyc %%LIBCXX%%share/libcxx-gdbpy/libcxx/printers.py %%LIBCXX%%share/libcxx-gdbpy/libcxx/printers.pyc %%LIBCXX%%share/libcxx-gdbpy/libcxx/xmethods.py %%LIBCXX%%share/libcxx-gdbpy/libcxx/xmethods.pyc