pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

wip/gdb-netbsd-wip: import gdb-8.2.1



Module Name:	pkgsrc-wip
Committed By:	Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By:	kamil
Date:		Wed Apr 1 21:19:50 2020 +0200
Changeset:	7a8786e99d7180134d3edf90cfea14622465bb0a

Added Files:
	gdb-netbsd-wip/DESCR
	gdb-netbsd-wip/Makefile
	gdb-netbsd-wip/PLIST.Linux
	gdb-netbsd-wip/PLIST.common
	gdb-netbsd-wip/distinfo
	gdb-netbsd-wip/options.mk
	gdb-netbsd-wip/patches/patch-bfd_config.bfd
	gdb-netbsd-wip/patches/patch-gdb_Makefile.in
	gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-tdep.h
	gdb-netbsd-wip/patches/patch-gdb_alpha-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_alpha-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_bsd-kvm.c
	gdb-netbsd-wip/patches/patch-gdb_config_aarch64_nbsd.mh
	gdb-netbsd-wip/patches/patch-gdb_config_powerpc_ppc64-nbsd.mh
	gdb-netbsd-wip/patches/patch-gdb_configure
	gdb-netbsd-wip/patches/patch-gdb_configure.host
	gdb-netbsd-wip/patches/patch-gdb_configure.nat
	gdb-netbsd-wip/patches/patch-gdb_configure.tgt
	gdb-netbsd-wip/patches/patch-gdb_gdbserver_Makefile.in
	gdb-netbsd-wip/patches/patch-gdb_gdbserver_configure.srv
	gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-low.c
	gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-low.h
	gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-x86__64-low.c
	gdb-netbsd-wip/patches/patch-gdb_gdbsupport_agent.c
	gdb-netbsd-wip/patches/patch-gdb_gdbsupport_common-defs.h
	gdb-netbsd-wip/patches/patch-gdb_gdbsupport_pathstuff.h
	gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.h
	gdb-netbsd-wip/patches/patch-gdb_i386-bsd-nat.h
	gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_ia64-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_inf-ptrace.c
	gdb-netbsd-wip/patches/patch-gdb_mips-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_mips-tdep.h
	gdb-netbsd-wip/patches/patch-gdb_nat_fork-inferior.c
	gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.h
	gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.h
	gdb-netbsd-wip/patches/patch-gdb_objfiles.c
	gdb-netbsd-wip/patches/patch-gdb_ppc-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.h
	gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.h
	gdb-netbsd-wip/patches/patch-gdb_sparc-tdep.h
	gdb-netbsd-wip/patches/patch-gdb_sparc64-nbsd-nat.c
	gdb-netbsd-wip/patches/patch-gdb_sparc64-nbsd-tdep.c
	gdb-netbsd-wip/patches/patch-gdb_tui_tui-winsource.c
	gdb-netbsd-wip/patches/patch-sim_common_callback.c

Log Message:
wip/gdb-netbsd-wip: import gdb-8.2.1

   The purpose of a debugger such as GDB is to allow you to see what
is going on "inside" another program while it executes--or what
another program was doing at the moment it crashed.

   GDB can do four main kinds of things (plus other things in support
of these) to help you catch bugs in the act:

   * Start your program, specifying anything that might affect its
     behavior.

   * Make your program stop on specified conditions.

   * Examine what has happened, when your program has stopped.

   * Change things in your program, so you can experiment with
     correcting the effects of one bug and go on to learn about
     another.

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=7a8786e99d7180134d3edf90cfea14622465bb0a

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 gdb-netbsd-wip/DESCR                               |   17 +
 gdb-netbsd-wip/Makefile                            |  100 +
 gdb-netbsd-wip/PLIST.Linux                         |    4 +
 gdb-netbsd-wip/PLIST.common                        |   52 +
 gdb-netbsd-wip/distinfo                            |   61 +
 gdb-netbsd-wip/options.mk                          |   13 +
 gdb-netbsd-wip/patches/patch-bfd_config.bfd        |  127 ++
 gdb-netbsd-wip/patches/patch-gdb_Makefile.in       |   13 +
 .../patches/patch-gdb_aarch64-nbsd-nat.c           |  188 ++
 .../patches/patch-gdb_aarch64-nbsd-tdep.c          |  207 ++
 .../patches/patch-gdb_aarch64-nbsd-tdep.h          |   38 +
 gdb-netbsd-wip/patches/patch-gdb_alpha-nbsd-tdep.c |  184 ++
 gdb-netbsd-wip/patches/patch-gdb_alpha-tdep.c      |   36 +
 gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-nat.c  |   81 +
 gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-tdep.c |  219 ++
 gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-nat.c    |  568 ++++++
 gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-tdep.c   |   56 +
 gdb-netbsd-wip/patches/patch-gdb_bsd-kvm.c         |   61 +
 .../patches/patch-gdb_config_aarch64_nbsd.mh       |   10 +
 .../patches/patch-gdb_config_powerpc_ppc64-nbsd.mh |    9 +
 gdb-netbsd-wip/patches/patch-gdb_configure         |   22 +
 gdb-netbsd-wip/patches/patch-gdb_configure.host    |   30 +
 gdb-netbsd-wip/patches/patch-gdb_configure.nat     |  100 +
 gdb-netbsd-wip/patches/patch-gdb_configure.tgt     |   79 +
 .../patches/patch-gdb_gdbserver_Makefile.in        |   12 +
 .../patches/patch-gdb_gdbserver_configure.srv      |   27 +
 .../patches/patch-gdb_gdbserver_netbsd-low.c       | 2089 ++++++++++++++++++++
 .../patches/patch-gdb_gdbserver_netbsd-low.h       |   66 +
 .../patch-gdb_gdbserver_netbsd-x86__64-low.c       |  388 ++++
 .../patches/patch-gdb_gdbsupport_agent.c           |   12 +
 .../patches/patch-gdb_gdbsupport_common-defs.h     |   23 +
 .../patches/patch-gdb_gdbsupport_pathstuff.h       |   11 +
 gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-nat.c   |  112 ++
 gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-tdep.c  |   69 +
 gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.c       |   13 +
 gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.h       |   11 +
 gdb-netbsd-wip/patches/patch-gdb_i386-bsd-nat.h    |   13 +
 gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-nat.c   |   51 +
 gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-tdep.c  |  183 ++
 gdb-netbsd-wip/patches/patch-gdb_ia64-nbsd-tdep.c  |   51 +
 gdb-netbsd-wip/patches/patch-gdb_inf-ptrace.c      |   68 +
 gdb-netbsd-wip/patches/patch-gdb_mips-nbsd-nat.c   |  141 ++
 gdb-netbsd-wip/patches/patch-gdb_mips-tdep.h       |   24 +
 .../patches/patch-gdb_nat_fork-inferior.c          |   13 +
 gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.c        |  533 +++++
 gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.h        |   32 +
 gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.c       |   41 +
 gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.h       |   11 +
 gdb-netbsd-wip/patches/patch-gdb_objfiles.c        |   26 +
 gdb-netbsd-wip/patches/patch-gdb_ppc-nbsd-nat.c    |  130 ++
 gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-nat.c     |   81 +
 gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.c    |  197 ++
 gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.h    |   33 +
 gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-nat.c  |   39 +
 gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.c |   41 +
 gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.h |   40 +
 gdb-netbsd-wip/patches/patch-gdb_sparc-tdep.h      |   25 +
 .../patches/patch-gdb_sparc64-nbsd-nat.c           |   36 +
 .../patches/patch-gdb_sparc64-nbsd-tdep.c          |   12 +
 .../patches/patch-gdb_tui_tui-winsource.c          |   14 +
 gdb-netbsd-wip/patches/patch-sim_common_callback.c |   17 +
 61 files changed, 6960 insertions(+)

diffs:
diff --git a/gdb-netbsd-wip/DESCR b/gdb-netbsd-wip/DESCR
new file mode 100644
index 0000000000..c7c2207693
--- /dev/null
+++ b/gdb-netbsd-wip/DESCR
@@ -0,0 +1,17 @@
+   The purpose of a debugger such as GDB is to allow you to see what
+is going on "inside" another program while it executes--or what
+another program was doing at the moment it crashed.
+
+   GDB can do four main kinds of things (plus other things in support
+of these) to help you catch bugs in the act:
+
+   * Start your program, specifying anything that might affect its
+     behavior.
+
+   * Make your program stop on specified conditions.
+
+   * Examine what has happened, when your program has stopped.
+
+   * Change things in your program, so you can experiment with
+     correcting the effects of one bug and go on to learn about
+     another.
diff --git a/gdb-netbsd-wip/Makefile b/gdb-netbsd-wip/Makefile
new file mode 100644
index 0000000000..8c547c4375
--- /dev/null
+++ b/gdb-netbsd-wip/Makefile
@@ -0,0 +1,100 @@
+# $NetBSD: Makefile,v 1.62 2019/04/25 07:32:45 maya Exp $
+
+DISTNAME=	gdb-8.2.1
+CATEGORIES=	devel
+
+MASTER_SITES=		${MASTER_SITE_GITHUB:=bminor/}
+GITHUB_PROJECT=		binutils-gdb
+GITHUB_TAG=		7e24fb63e7db33d3627623629b0e99fe322e26f9
+
+HOMEPAGE=	https://www.gnu.org/software/gdb/gdb.html
+COMMENT=	Symbolic debugger for multiple language frontends
+LICENSE=	gnu-gpl-v3
+
+USE_LANGUAGES=		c c++11
+
+BROKEN_GETTEXT_DETECTION=	yes
+GNU_CONFIGURE=			YES
+USE_PKGLOCALEDIR=		YES
+USE_LIBTOOL=			YES
+USE_TOOLS+=			gmake msgfmt makeinfo perl:build
+REPLACE_LOCALEDIR_PATTERNS+=	Make-in
+INSTALL_TARGET=			install install-info
+TEST_TARGET=			check
+INFO_FILES=			yes
+CONFIGURE_ENV+=			CONFIG_LDFLAGS=${LDFLAGS:M*:Q}
+
+# In gdb/configure, depcomp is parsed with sed.
+SUBST_CLASSES+=			fix-depcomp
+SUBST_STAGE.fix-depcomp+=	pre-configure
+SUBST_MESSAGE.fix-depcomp+=	Read depcomp directly
+SUBST_FILES.fix-depcomp+=	gdb/configure
+SUBST_SED.fix-depcomp+=		-e 's,< ./depcomp,${_OVERRIDE_PATH.depcomp},'
+
+CONFIGURE_ARGS+=	--disable-binutils
+CONFIGURE_ARGS+=	--disable-gprof
+CONFIGURE_ARGS+=	--disable-gold
+CONFIGURE_ARGS+=	--disable-gas
+CONFIGURE_ARGS+=	--disable-ld
+
+CONFIGURE_ARGS+=	--enable-targets=all
+
+AUTO_MKDIRS=		yes
+
+.include "options.mk"
+
+.include "../../mk/bsd.prefs.mk"
+
+PLIST_VARS+=	gcore
+.if (${OPSYS} == "SunOS" || ${OPSYS} == "NetBSD" \
+    || ${OPSYS} == "Linux" || ${OPSYS} == "FreeBSD")
+PLIST.gcore=	yes
+.endif
+
+.if ${OPSYS} == "SunOS"
+# Work around a bug in gdb's configure
+CONFIGURE_ENV+=		ac_cv_header_curses_h=yes
+.elif ${OPSYS} == "NetBSD"
+.include "../../mk/curses.buildlink3.mk"
+CONFIGURE_ARGS+= -with-curses
+CONFIGURE_ENV+= gdb_cv_var_elf=yes
+MAKE_ENV+= gdb_cv_var_elf=yes
+CONFIGURE_ENV+= gdb_cv_struct_lwp=yes
+MAKE_ENV+= gdb_cv_struct_lwp=yes
+
+CONFIGURE_ARGS+=	--with-separate-debug-dir=/usr/libdata/debug
+.elif ${OPSYS} == "DragonFly"
+TARGET_STR=		${MACHINE_ARCH}--dragonfly
+BUILD_DEFS+=		${TARGET_STR}
+## Remove "-pc" string, without this, getting following message:
+##	   *** Gdb does not support native target i386-pc-dragonfly"
+CONFIGURE_ARGS+=	--target=${TARGET_STR}
+TEST_ENV=		DEJAGNU=${WRKDIR}/../files/dragonfly-default.exp
+.endif
+
+post-install:
+	${RM} -f ${DESTDIR}/${PREFIX}/lib/charset.alias
+.if ${OPSYS} == "DragonFly"
+# Following are installed by binutils
+#. for f in ansidecl.h bfdlink.h dis-asm.h symcat.h
+#	(cd ${WRKSRC}/include; ${INSTALL_DATA} ${f}  ${DESTDIR}${PREFIX}/include)
+#. endfor
+	(cd ${DESTDIR}${PREFIX}/bin;               ${LN} ${TARGET_STR}-gdb gdb)
+	(cd ${DESTDIR}${PREFIX}/${PKGMANDIR}/man1; ${LN} ${TARGET_STR}-gdb.1 gdb.1)
+.endif
+#
+# PATH of libiberty.a differs between clang and gcc: (and conflicts to other toolchain)
+# Rename to avoid conflict to native and other toolchain
+# and clang differs its path so, (the same as avr-binutils).
+
+	(cd ${DESTDIR}${PREFIX};				\
+	for d in ${MACHINE_ARCH}/libiberty.a libiberty.a;	\
+	  do if [ -f lib/$$d ]; then				\
+		${MV}	lib/$$d	 lib/gdb/libiberty.a;		\
+		break;						\
+	     fi;						\
+	  done;	)
+
+.include "../../mk/termcap.buildlink3.mk"
+.include "../../devel/gettext-lib/buildlink3.mk"
+.include "../../mk/bsd.pkg.mk"
diff --git a/gdb-netbsd-wip/PLIST.Linux b/gdb-netbsd-wip/PLIST.Linux
new file mode 100644
index 0000000000..e4fe491ac0
--- /dev/null
+++ b/gdb-netbsd-wip/PLIST.Linux
@@ -0,0 +1,4 @@
+@comment $NetBSD: PLIST.Linux,v 1.5 2018/01/31 20:33:11 maya Exp $
+bin/gdbserver
+lib/libinproctrace.so
+man/man1/gcore.1
diff --git a/gdb-netbsd-wip/PLIST.common b/gdb-netbsd-wip/PLIST.common
new file mode 100644
index 0000000000..9e7295ea95
--- /dev/null
+++ b/gdb-netbsd-wip/PLIST.common
@@ -0,0 +1,52 @@
+@comment $NetBSD: PLIST.common,v 1.13 2018/01/31 20:33:11 maya Exp $
+bin/gdb
+bin/gdb-add-index
+include/gdb/jit-reader.h
+info/annotate.info
+info/gdb.info
+info/stabs.info
+man/man1/gdb.1
+man/man1/gdb-add-index.1
+man/man1/gdbserver.1
+man/man5/gdbinit.5
+share/gdb/python/gdb/FrameDecorator.py
+share/gdb/python/gdb/FrameIterator.py
+share/gdb/python/gdb/__init__.py
+share/gdb/python/gdb/command/__init__.py
+share/gdb/python/gdb/command/explore.py
+share/gdb/python/gdb/command/frame_filters.py
+share/gdb/python/gdb/command/pretty_printers.py
+share/gdb/python/gdb/command/prompt.py
+share/gdb/python/gdb/command/type_printers.py
+share/gdb/python/gdb/command/unwinders.py
+share/gdb/python/gdb/command/xmethods.py
+share/gdb/python/gdb/frames.py
+share/gdb/python/gdb/function/__init__.py
+share/gdb/python/gdb/function/as_string.py
+share/gdb/python/gdb/function/caller_is.py
+share/gdb/python/gdb/function/strfns.py
+share/gdb/python/gdb/printer/__init__.py
+share/gdb/python/gdb/printer/bound_registers.py
+share/gdb/python/gdb/printing.py
+share/gdb/python/gdb/prompt.py
+share/gdb/python/gdb/types.py
+share/gdb/python/gdb/unwinder.py
+share/gdb/python/gdb/xmethod.py
+share/gdb/syscalls/aarch64-linux.xml
+share/gdb/syscalls/amd64-linux.xml
+share/gdb/syscalls/arm-linux.xml
+share/gdb/syscalls/freebsd.xml
+share/gdb/syscalls/gdb-syscalls.dtd
+share/gdb/syscalls/i386-linux.xml
+share/gdb/syscalls/mips-n32-linux.xml
+share/gdb/syscalls/mips-n64-linux.xml
+share/gdb/syscalls/mips-o32-linux.xml
+share/gdb/syscalls/ppc-linux.xml
+share/gdb/syscalls/ppc64-linux.xml
+share/gdb/syscalls/s390-linux.xml
+share/gdb/syscalls/s390x-linux.xml
+share/gdb/syscalls/sparc-linux.xml
+share/gdb/syscalls/sparc64-linux.xml
+share/gdb/system-gdbinit/elinos.py
+share/gdb/system-gdbinit/wrs-linux.py
+${PLIST.gcore}bin/gcore
diff --git a/gdb-netbsd-wip/distinfo b/gdb-netbsd-wip/distinfo
new file mode 100644
index 0000000000..699c3b6667
--- /dev/null
+++ b/gdb-netbsd-wip/distinfo
@@ -0,0 +1,61 @@
+$NetBSD$
+
+SHA1 (gdb-8.2.1-7e24fb63e7db33d3627623629b0e99fe322e26f9.tar.gz) = a8ae54700e1f257634da39b48d25c29586f2c263
+RMD160 (gdb-8.2.1-7e24fb63e7db33d3627623629b0e99fe322e26f9.tar.gz) = 96040eb8f7eccd8c7dd157473b781144701754a0
+SHA512 (gdb-8.2.1-7e24fb63e7db33d3627623629b0e99fe322e26f9.tar.gz) = d7a8692ee1b27aecac64bf4176e5fa3e44e315e88da079c24107f3e5318e0e335f35b38426e72c118bd044d547fdd94650781fb1dd1297d33dd5a54c77e78988
+Size (gdb-8.2.1-7e24fb63e7db33d3627623629b0e99fe322e26f9.tar.gz) = 59113538 bytes
+SHA1 (patch-bfd_config.bfd) = 0fd42301a1577e353381a0bf677a7bcb5d32c3d8
+SHA1 (patch-gdb_Makefile.in) = dc465eda202863a23ce660ae5f8065a74e5c8fb4
+SHA1 (patch-gdb_aarch64-nbsd-nat.c) = 04ffc8ed696cb2349a67d302c2f8fa596484a9e6
+SHA1 (patch-gdb_aarch64-nbsd-tdep.c) = 7720b954f12031b60e1fa0a48ce668b104e09d41
+SHA1 (patch-gdb_aarch64-nbsd-tdep.h) = 814627b2b2ce5dc0dc095451183fbe03789f1513
+SHA1 (patch-gdb_alpha-nbsd-tdep.c) = 8fe9d1f08baa252b61b49c2672391c3349768444
+SHA1 (patch-gdb_alpha-tdep.c) = 9030c31dcef6660f58fc27e7979f0dae26e4f970
+SHA1 (patch-gdb_amd64-nbsd-nat.c) = 26ad634a79441949c076cee07e4e5baaaa1402f1
+SHA1 (patch-gdb_amd64-nbsd-tdep.c) = 99328cdd390281ff298c08010907195738a85489
+SHA1 (patch-gdb_arm-nbsd-nat.c) = 09a21d2eed39dc4e74a1f442c6ee59dfbf9c6f54
+SHA1 (patch-gdb_arm-nbsd-tdep.c) = 63009d506e2f92e681529d96150b1c4d04a7afbe
+SHA1 (patch-gdb_bsd-kvm.c) = d04c44fb4c779dd3ecd12c3179ad8a63351e5239
+SHA1 (patch-gdb_config_aarch64_nbsd.mh) = 6d7793009bda1568717ed897c02e77137e47b83b
+SHA1 (patch-gdb_config_powerpc_ppc64-nbsd.mh) = bef62de0ebc162aeac12939d4f4fb220be99efe2
+SHA1 (patch-gdb_configure) = 681e095fdd15432dbc094bf70e5a5b7c67637ad7
+SHA1 (patch-gdb_configure.host) = 427f6dbc2f4373e7e9bede77ccb7a3cd28c74d14
+SHA1 (patch-gdb_configure.nat) = ba5ad6fe4c31b5f5e81bd69c81feb70c36b0f7df
+SHA1 (patch-gdb_configure.tgt) = 6e32066a87234a90c905a0ab17a32ef84a903d0a
+SHA1 (patch-gdb_gdbserver_Makefile.in) = c14e0e580515b849b1ddac65d50b2f757645cea6
+SHA1 (patch-gdb_gdbserver_configure.srv) = d492edda5a6f7e70a2279ebe7409e557672b92aa
+SHA1 (patch-gdb_gdbserver_netbsd-low.c) = 6b79896787cfde6b1c7029e4ad7cd62e274dd23d
+SHA1 (patch-gdb_gdbserver_netbsd-low.h) = 4f4fe50c18f9d10ac842927860ab6418600881f3
+SHA1 (patch-gdb_gdbserver_netbsd-x86__64-low.c) = 487374f6ef2d8943b4b413b86f613411a3811f40
+SHA1 (patch-gdb_gdbsupport_agent.c) = d2ce6030a8c7d4fe84c74f3a44dc5c49f970547e
+SHA1 (patch-gdb_gdbsupport_common-defs.h) = 940d3489c2fac85defff29a0886f1c6d54bee020
+SHA1 (patch-gdb_gdbsupport_pathstuff.h) = 1eef4a97e827bc06fd4c11824435de0ccce076f8
+SHA1 (patch-gdb_hppa-nbsd-nat.c) = eb5fb4b69f0ba69a4a7e8152bc97762a5b2cf1ba
+SHA1 (patch-gdb_hppa-nbsd-tdep.c) = 2b0552b3a8cb820daaf1fa3960cbbf6a31ad1c79
+SHA1 (patch-gdb_hppa-tdep.c) = 57e3a1cc1718aee0f70797804e8859af6c3c7840
+SHA1 (patch-gdb_hppa-tdep.h) = 6cda8a222cd10340ae54878998543e66f4455fd6
+SHA1 (patch-gdb_i386-bsd-nat.h) = f6688e75d80058832bbe12356399eec723f30328
+SHA1 (patch-gdb_i386-nbsd-nat.c) = 12583799f643f31849063acf10cb0dc36c68101f
+SHA1 (patch-gdb_i386-nbsd-tdep.c) = 002ece7989025a4bed1ce1eece9d225faf02c538
+SHA1 (patch-gdb_ia64-nbsd-tdep.c) = 4d1795b806b1b957f7959d57cdab7090c9510fe5
+SHA1 (patch-gdb_inf-ptrace.c) = caef41fb10c585b7b403a3dc6e82a924cc90becb
+SHA1 (patch-gdb_mips-nbsd-nat.c) = 1f71cb0d0c8792bfc80a456d294dad6d75b526b5
+SHA1 (patch-gdb_mips-tdep.h) = 24b3cf83513716492297645b2d5c4281ab12b493
+SHA1 (patch-gdb_nat_fork-inferior.c) = c15d3964c448e010958d8977825d6d46f8708e09
+SHA1 (patch-gdb_nbsd-nat.c) = 60b1b2164206e52254e743cca3de762770f7ab9d
+SHA1 (patch-gdb_nbsd-nat.h) = 4188f1edfb1b0b437c931fa60049221164a6e59e
+SHA1 (patch-gdb_nbsd-tdep.c) = d375084ca0895e71a4f7b837cb633a11eb260884
+SHA1 (patch-gdb_nbsd-tdep.h) = ca419a41fa2e7c41c4a84521700dcfae279f4bfc
+SHA1 (patch-gdb_objfiles.c) = 25bcbc07b2a919db28c1145489e30dcb38b5a230
+SHA1 (patch-gdb_ppc-nbsd-nat.c) = 9986c45717729ffc4db04068296543e3449495a7
+SHA1 (patch-gdb_sh-nbsd-nat.c) = f316feea0192b6926ebe01d0fc83effe632ae063
+SHA1 (patch-gdb_sh-nbsd-tdep.c) = 868d765ebf6c2d4dfb1319653c9312da1ce45a8e
+SHA1 (patch-gdb_sh-nbsd-tdep.h) = 6dca499544ec3e95cd2c10a07926d1e80ab6d109
+SHA1 (patch-gdb_sparc-nbsd-nat.c) = 4aa8d16cf1210125f9117680014f2d8eaa36e681
+SHA1 (patch-gdb_sparc-nbsd-tdep.c) = c61b63a6673402852a2e95b06d382b8eda1653e9
+SHA1 (patch-gdb_sparc-nbsd-tdep.h) = 7520c8d0d465883abc4a302f1efabd9e52492acc
+SHA1 (patch-gdb_sparc-tdep.h) = 74eb0364017aa8b41ef1a06dcb35d8b4a2a31852
+SHA1 (patch-gdb_sparc64-nbsd-nat.c) = d7b9988c09f483d9d57dccc36610cb52751dac0b
+SHA1 (patch-gdb_sparc64-nbsd-tdep.c) = 1e4562ab7f7a2c8b61b2becc70c9d6aa35140598
+SHA1 (patch-gdb_tui_tui-winsource.c) = fc0eb13c8c367bed20630921a6bacce186a80fd8
+SHA1 (patch-sim_common_callback.c) = ac55e639ed6ba51c5daef5fffccc3413abeb1df2
diff --git a/gdb-netbsd-wip/options.mk b/gdb-netbsd-wip/options.mk
new file mode 100644
index 0000000000..3a52d30fcb
--- /dev/null
+++ b/gdb-netbsd-wip/options.mk
@@ -0,0 +1,13 @@
+# $NetBSD: options.mk,v 1.6 2019/04/26 13:13:49 maya Exp $
+
+PKG_OPTIONS_VAR=	PKG_OPTIONS.gdb
+PKG_SUPPORTED_OPTIONS=	python
+PKG_SUGGESTED_OPTIONS=	python
+
+.include "../../mk/bsd.options.mk"
+
+.if !empty(PKG_OPTIONS:Mpython)
+CONFIGURE_ARGS+=	--with-python=${PYTHONBIN}
+PYTHON_VERSIONS_ACCEPTED=	 27
+.include "../../lang/python/application.mk"
+.endif
diff --git a/gdb-netbsd-wip/patches/patch-bfd_config.bfd b/gdb-netbsd-wip/patches/patch-bfd_config.bfd
new file mode 100644
index 0000000000..9f87130cd7
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-bfd_config.bfd
@@ -0,0 +1,127 @@
+$NetBSD$
+
+--- bfd/config.bfd.orig	2019-07-16 00:00:27.000000000 +0000
++++ bfd/config.bfd
+@@ -178,6 +178,7 @@ hppa*)		 targ_archs=bfd_hppa_arch ;;
+ i[3-7]86)	 targ_archs=bfd_i386_arch ;;
+ ia16)		 targ_archs=bfd_i386_arch ;;
+ lm32)	         targ_archs=bfd_lm32_arch ;;
++m5200|m5407)	 targ_archs=bfd_m68k_arch ;;
+ m6811*|m68hc11*) targ_archs="bfd_m68hc11_arch bfd_m68hc12_arch bfd_m9s12x_arch bfd_m9s12xg_arch" ;;
+ m6812*|m68hc12*) targ_archs="bfd_m68hc12_arch bfd_m68hc11_arch bfd_m9s12x_arch bfd_m9s12xg_arch" ;;
+ m68*)		 targ_archs=bfd_m68k_arch ;;
+@@ -241,6 +242,11 @@ case "${targ}" in
+     targ_selvecs="aarch64_elf64_be_vec arm_elf32_le_vec arm_elf32_be_vec"
+     want64=true
+     ;;
++  aarch64-*-netbsd*)
++    targ_defvec=aarch64_elf64_le_vec
++    targ_selvecs="aarch64_elf64_be_vec arm_elf32_le_vec arm_elf32_be_vec"
++    want64=true
++    ;;
+   aarch64-*-fuchsia*)
+     targ_defvec=aarch64_elf64_le_vec
+     targ_selvecs="aarch64_elf64_be_vec arm_elf32_le_vec arm_elf32_be_vec"
+@@ -261,6 +267,16 @@ case "${targ}" in
+     targ_selvecs="aarch64_elf64_le_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_be_vec arm_elf32_le_vec"
+     want64=true
+     ;;
++  aarch64-*-netbsd*)
++    targ_defvec=aarch64_elf64_le_vec
++    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec"
++    want64=true
++    ;;
++  aarch64_be-*-netbsd*)
++    targ_defvec=aarch64_elf64_be_vec
++    targ_selvecs="aarch64_elf64_le_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_be_vec arm_elf32_le_vec"
++    want64=true
++    ;;
+   alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
+     targ_defvec=alpha_elf64_fbsd_vec
+     targ_selvecs="alpha_elf64_vec alpha_ecoff_le_vec"
+@@ -347,11 +363,11 @@ case "${targ}" in
+     targ64_selvecs="x86_64_elf32_nacl_vec x86_64_elf64_nacl_vec"
+     targ_archs="$targ_archs bfd_i386_arch"
+     ;;
+-  armeb-*-netbsdelf*)
++  arm*eb-*-netbsdelf*)
+     targ_defvec=arm_elf32_be_vec
+     targ_selvecs="arm_elf32_le_vec"
+     ;;
+-  arm-*-netbsdelf*)
++  arm*-*-netbsdelf*)
+     targ_defvec=arm_elf32_le_vec
+     targ_selvecs="arm_elf32_be_vec"
+     ;;
+@@ -820,6 +836,10 @@ case "${targ}" in
+   m68*-*-*)
+     targ_defvec=m68k_elf32_vec
+     ;;
++  m68*-*-netbsdelf* | m5407-*-netbsdelf*)
++    targ_defvec=m68k_elf32_vec
++    targ_selvecs="m68k_aout_nbsd_vec m68k_aout_4knbsd_vec m68k_aout_hp300bsd_vec sparc_aout_sunos_be_vec"
++    ;;
+ 
+   s12z-*-*)
+     targ_defvec=s12z_elf32_vec
+@@ -853,14 +873,35 @@ case "${targ}" in
+     targ_selvecs=microblaze_elf32_le_vec
+     ;;
+ 
++  mips*-big-*)
++    targ_defvec=mips_ecoff_be_vec
++    targ_selvecs=mips_ecoff_le_vec
++    ;;
++
++  mips*-dec-* | mips*el-*-ecoff*)
++    targ_defvec=mips_ecoff_le_vec
++    targ_selvecs=mips_ecoff_be_vec
++    ;;
++  mips*-*-ecoff*)
++    targ_defvec=mips_ecoff_be_vec
++    targ_selvecs=mips_ecoff_le_vec
++    ;;
+ #ifdef BFD64
++  mips64*el-*-netbsd*)
++    targ_defvec=mips_elf32_ntrad_le_vec
++    targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec"
++    ;;
++  mips64*-*-netbsd*)
++    targ_defvec=mips_elf32_ntrad_be_vec
++    targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
++    ;;
+   mips*el-*-netbsd*)
+     targ_defvec=mips_elf32_trad_le_vec
+-    targ_selvecs="mips_elf32_trad_be_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec mips_ecoff_le_vec mips_ecoff_be_vec"
++    targ_selvecs="mips_elf32_trad_be_vec mips_elf32_ntrad_le_vec mips_elf32_ntrad_be_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec mips_ecoff_le_vec mips_ecoff_be_vec"
+     ;;
+   mips*-*-netbsd*)
+     targ_defvec=mips_elf32_trad_be_vec
+-    targ_selvecs="mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec mips_ecoff_be_vec mips_ecoff_le_vec"
++    targ_selvecs="mips_elf32_trad_le_vec mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec mips_ecoff_be_vec mips_ecoff_le_vec"
+     ;;
+   mips*-*-irix6*)
+     targ_defvec=mips_elf32_n_be_vec
+@@ -902,6 +943,22 @@ case "${targ}" in
+     targ_defvec=mips_elf32_be_vec
+     targ_selvecs="mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec"
+     ;;
++  mips64*el-*-netbsd*)
++    targ_defvec=mips_elf32_ntrad_le_vec
++    targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec"
++    ;;
++  mips64*-*-netbsd*)
++    targ_defvec=mips_elf32_ntrad_be_vec
++    targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
++    ;;
++  mips*el-*-netbsd*)
++    targ_defvec=mips_elf32_trad_le_vec
++    targ_selvecs="mips_elf32_trad_be_vec mips_elf32_ntrad_le_vec mips_elf32_ntrad_be_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec mips_ecoff_le_vec mips_ecoff_be_vec"
++    ;;
++  mips*-*-netbsd*)
++    targ_defvec=mips_elf32_trad_be_vec
++    targ_selvecs="mips_elf32_trad_le_vec mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec mips_ecoff_be_vec mips_ecoff_le_vec"
++    ;;
+   mips64*-*-openbsd*)
+     targ_defvec=mips_elf64_trad_be_vec
+     targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec"
diff --git a/gdb-netbsd-wip/patches/patch-gdb_Makefile.in b/gdb-netbsd-wip/patches/patch-gdb_Makefile.in
new file mode 100644
index 0000000000..ac5c30eafb
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_Makefile.in
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- gdb/Makefile.in.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/Makefile.in
+@@ -2137,6 +2137,8 @@ ALLDEPFILES = \
+ 	aarch64-fbsd-tdep.c \
+ 	aarch64-linux-nat.c \
+ 	aarch64-linux-tdep.c \
++	aarch64-nbsd-nat.c \
++	aarch64-nbsd-tdep.c \
+ 	aarch64-newlib-tdep.c \
+ 	aarch64-ravenscar-thread.c \
+ 	aarch64-tdep.c \
diff --git a/gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-nat.c
new file mode 100644
index 0000000000..80bbd2fb9f
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-nat.c
@@ -0,0 +1,188 @@
+$NetBSD$
+
+--- gdb/aarch64-nbsd-nat.c.orig	2019-09-02 20:02:23.493799588 +0000
++++ gdb/aarch64-nbsd-nat.c
+@@ -0,0 +1,183 @@
++/* Native-dependent code for NetBSD/aarch64.
++
++   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include "defs.h"
++#include "target.h"
++
++#include <sys/types.h>
++#include <sys/ptrace.h>
++
++#include <machine/frame.h>
++#include <machine/pcb.h>
++
++#include "nbsd-nat.h"
++#include "aarch64-tdep.h"
++#include "aarch64-nbsd-tdep.h"
++#include "regcache.h"
++#include "gdbcore.h"
++#include "bsd-kvm.h"
++#include "inf-ptrace.h"
++
++/* Determine if PT_GETREGS fetches REGNUM.  */
++
++struct aarch64_nbsd_nat_target final : public nbsd_nat_target
++{
++  void fetch_registers (struct regcache *, int) override;
++  void store_registers (struct regcache *, int) override;
++};
++
++static aarch64_nbsd_nat_target the_aarch64_nbsd_nat_target;
++
++static bool
++getregs_supplies (struct gdbarch *gdbarch, int regnum)
++{
++  return (regnum >= AARCH64_X0_REGNUM && regnum <= AARCH64_CPSR_REGNUM);
++}
++
++/* Determine if PT_GETFPREGS fetches REGNUM.  */
++
++static bool
++getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
++{
++  return (regnum >= AARCH64_V0_REGNUM && regnum <= AARCH64_FPCR_REGNUM);
++}
++
++void
++aarch64_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
++{
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
++
++  struct gdbarch *gdbarch = regcache->arch ();
++  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
++    {
++      struct reg regs;
++
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
++	perror_with_name (_("Couldn't get registers"));
++
++      regcache_supply_regset (&aarch64_nbsd_gregset, regcache, regnum, &regs,
++			       sizeof (regs));
++    }
++
++  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
++    {
++      struct fpreg fpregs;
++
++      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
++	perror_with_name (_("Couldn't get floating point status"));
++
++      regcache_supply_regset (&aarch64_nbsd_fpregset, regcache, regnum, &fpregs,
++			       sizeof (fpregs));
++    }
++}
++
++/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
++   this for all registers.  */
++
++void
++aarch64_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
++{
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
++
++  struct gdbarch *gdbarch = regcache->arch ();
++  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
++    {
++      struct reg regs;
++
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
++	perror_with_name (_("Couldn't get registers"));
++
++      regcache_collect_regset (&aarch64_nbsd_gregset, regcache,regnum, &regs,
++			       sizeof (regs));
++
++      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
++	perror_with_name (_("Couldn't write registers"));
++    }
++
++  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
++    {
++      struct fpreg fpregs;
++
++      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
++	perror_with_name (_("Couldn't get floating point status"));
++
++      regcache_collect_regset (&aarch64_nbsd_fpregset, regcache,regnum, &fpregs,
++				sizeof (fpregs));
++
++      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
++	perror_with_name (_("Couldn't write floating point status"));
++    }
++}
++
++static int
++aarch64_nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
++{
++  struct trapframe tf;
++  int i;
++
++  /* The following is true for NetBSD/arm64:
++
++     The pcb contains the frame pointer at the point of the context
++     switch in cpu_switchto().  At that point we have a stack frame as
++     described by `struct trapframe', which has the following layout:
++
++     x0..x30
++     sp
++     pc
++     spsr
++     tpidr
++
++     This accounts for all callee-saved registers specified by the psABI.
++     From this information we reconstruct the register state as it would
++     look when we just returned from cpu_switchto().
++
++     For kernel core dumps, dumpsys() builds a fake trapframe for us. */
++
++  /* The trapframe pointer shouldn't be zero.  */
++  if (pcb->pcb_tf == 0)
++    return 0;
++
++  /* Read the stack frame, and check its validity.  */
++  read_memory ((uintptr_t)pcb->pcb_tf, (gdb_byte *) &tf, sizeof tf);
++
++  for (i = 0; i <= 30; i++)
++    {
++      regcache->raw_supply (AARCH64_X0_REGNUM + i, &tf.tf_reg[i]);
++    }
++  regcache->raw_supply (AARCH64_SP_REGNUM, &tf.tf_sp);
++  regcache->raw_supply (AARCH64_PC_REGNUM, &tf.tf_pc);
++
++  regcache->raw_supply (AARCH64_FPCR_REGNUM, &pcb->pcb_fpregs.fpcr);
++  regcache->raw_supply (AARCH64_FPSR_REGNUM, &pcb->pcb_fpregs.fpsr);
++
++  return 1;
++}
++
++void
++_initialize_aarch64_nbsd_nat (void)
++{
++  add_inf_child_target (&the_aarch64_nbsd_nat_target);
++
++  /* Support debugging kernel virtual memory images.  */
++  bsd_kvm_add_target (aarch64_nbsd_supply_pcb);
++}
diff --git a/gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-tdep.c
new file mode 100644
index 0000000000..8bf92eb260
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-tdep.c
@@ -0,0 +1,207 @@
+$NetBSD$
+
+--- gdb/aarch64-nbsd-tdep.c.orig	2019-09-02 20:02:23.494088395 +0000
++++ gdb/aarch64-nbsd-tdep.c
+@@ -0,0 +1,202 @@
++/* Target-dependent code for NetBSD/aarch64.
++
++   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include "defs.h"
++
++#include "gdbarch.h"
++#include "nbsd-tdep.h"
++#include "aarch64-tdep.h"
++#include "aarch64-nbsd-tdep.h"
++#include "osabi.h"
++#include "solib-svr4.h"
++#include "target.h"
++#include "tramp-frame.h"
++#include "trad-frame.h"
++
++/* In a signal frame, sp points to a 'struct sigframe' which is
++   defined as:
++
++   struct sigframe {
++	   siginfo_t	sf_si;
++	   ucontext_t	sf_uc;
++   };
++
++   ucontext_t is defined as:
++
++   struct __ucontext {
++	   sigset_t	uc_sigmask;
++	   mcontext_t	uc_mcontext;
++	   ...
++   };
++
++   The mcontext_t contains the general purpose register set followed
++   by the floating point register set.  The floating point register
++   set is only valid if the _MC_FP_VALID flag is set in mc_flags.  */
++
++#define AARCH64_MCONTEXT_REG_SIZE               8
++#define AARCH64_MCONTEXT_FPREG_SIZE             16
++#define AARCH64_SIGFRAME_UCONTEXT_OFFSET	80
++#define AARCH64_UCONTEXT_MCONTEXT_OFFSET	16
++#define	AARCH64_MCONTEXT_FPREGS_OFFSET		272
++#define	AARCH64_MCONTEXT_FLAGS_OFFSET		800
++#define AARCH64_MCONTEXT_FLAG_FP_VALID		0x1
++
++/* Implement the "init" method of struct tramp_frame.  */
++
++static void
++aarch64_nbsd_sigframe_init (const struct tramp_frame *self,
++			     struct frame_info *this_frame,
++			     struct trad_frame_cache *this_cache,
++			     CORE_ADDR func)
++{
++  struct gdbarch *gdbarch = get_frame_arch (this_frame);
++  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
++  CORE_ADDR sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM);
++  CORE_ADDR mcontext_addr =
++    sp
++    + AARCH64_SIGFRAME_UCONTEXT_OFFSET
++    + AARCH64_UCONTEXT_MCONTEXT_OFFSET;
++  gdb_byte buf[4];
++  int i;
++
++  for (i = 0; i < 30; i++)
++    {
++      trad_frame_set_reg_addr (this_cache,
++			       AARCH64_X0_REGNUM + i,
++			       mcontext_addr + i * AARCH64_MCONTEXT_REG_SIZE);
++    }
++  trad_frame_set_reg_addr (this_cache, AARCH64_LR_REGNUM,
++			   mcontext_addr + 30 * AARCH64_MCONTEXT_REG_SIZE);
++  trad_frame_set_reg_addr (this_cache, AARCH64_SP_REGNUM,
++			   mcontext_addr + 31 * AARCH64_MCONTEXT_REG_SIZE);
++  trad_frame_set_reg_addr (this_cache, AARCH64_PC_REGNUM,
++			   mcontext_addr + 32 * AARCH64_MCONTEXT_REG_SIZE);
++  trad_frame_set_reg_addr (this_cache, AARCH64_CPSR_REGNUM,
++			   mcontext_addr + 33 * AARCH64_MCONTEXT_REG_SIZE);
++
++  if (target_read_memory (mcontext_addr + AARCH64_MCONTEXT_FLAGS_OFFSET, buf,
++			  4) == 0
++      && (extract_unsigned_integer (buf, 4, byte_order)
++	  & AARCH64_MCONTEXT_FLAG_FP_VALID))
++    {
++      for (i = 0; i < 32; i++)
++	{
++	  trad_frame_set_reg_addr (this_cache, AARCH64_V0_REGNUM + i,
++				   mcontext_addr
++				   + AARCH64_MCONTEXT_FPREGS_OFFSET
++				   + i * AARCH64_MCONTEXT_FPREG_SIZE);
++	}
++      trad_frame_set_reg_addr (this_cache, AARCH64_FPSR_REGNUM,
++			       mcontext_addr + AARCH64_MCONTEXT_FPREGS_OFFSET
++			       + 32 * AARCH64_MCONTEXT_FPREG_SIZE);
++      trad_frame_set_reg_addr (this_cache, AARCH64_FPCR_REGNUM,
++			       mcontext_addr + AARCH64_MCONTEXT_FPREGS_OFFSET
++			       + 32 * AARCH64_MCONTEXT_FPREG_SIZE + 4);
++    }
++
++  trad_frame_set_id (this_cache, frame_id_build (sp, func));
++}
++
++static const struct tramp_frame aarch64_nbsd_sigframe =
++{
++  SIGTRAMP_FRAME,
++  4,
++  {
++    {0x910003e0, ULONGEST_MAX},		/* mov  x0, sp  */
++    {0x91014000, ULONGEST_MAX},		/* add  x0, x0, #SF_UC  */
++    {0xd2803428, ULONGEST_MAX},		/* mov  x8, #SYS_sigreturn  */
++    {0xd4000001, ULONGEST_MAX},		/* svc  0x0  */
++    {(ULONGEST)TRAMP_SENTINEL_INSN, ULONGEST_MAX}
++  },
++  aarch64_nbsd_sigframe_init
++};
++
++/* Register maps.  */
++
++static const struct regcache_map_entry aarch64_nbsd_gregmap[] =
++  {
++    { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */
++    { 1, AARCH64_LR_REGNUM, 8 },
++    { 1, AARCH64_SP_REGNUM, 8 },
++    { 1, AARCH64_PC_REGNUM, 8 },
++    { 1, AARCH64_CPSR_REGNUM, 4 },
++    { 0 }
++  };
++
++static const struct regcache_map_entry aarch64_nbsd_fpregmap[] =
++  {
++    { 32, AARCH64_V0_REGNUM, 16 }, /* v0 ... v31 */
++    { 1, AARCH64_FPSR_REGNUM, 4 },
++    { 1, AARCH64_FPCR_REGNUM, 4 },
++    { 0 }
++  };
++
++/* Register set definitions.  */
++
++const struct regset aarch64_nbsd_gregset =
++  {
++    aarch64_nbsd_gregmap,
++    regcache_supply_regset, regcache_collect_regset
++  };
++
++const struct regset aarch64_nbsd_fpregset =
++  {
++    aarch64_nbsd_fpregmap,
++    regcache_supply_regset, regcache_collect_regset
++  };
++
++/* Implement the "regset_from_core_section" gdbarch method.  */
++
++static void
++aarch64_nbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
++					   iterate_over_regset_sections_cb *cb,
++					   void *cb_data,
++					   const struct regcache *regcache)
++{
++  cb (".reg", AARCH64_NBSD_SIZEOF_GREGSET, AARCH64_NBSD_SIZEOF_GREGSET,
++      &aarch64_nbsd_gregset, NULL, cb_data);
++  cb (".reg2", AARCH64_NBSD_SIZEOF_FPREGSET, AARCH64_NBSD_SIZEOF_FPREGSET,
++      &aarch64_nbsd_fpregset, NULL, cb_data);
++}
++
++/* Implement the 'init_osabi' method of struct gdb_osabi_handler.  */
++
++static void
++aarch64_nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++
++  set_solib_svr4_fetch_link_map_offsets (gdbarch,
++					 svr4_lp64_fetch_link_map_offsets);
++
++  tramp_frame_prepend_unwinder (gdbarch, &aarch64_nbsd_sigframe);
++
++  /* Enable longjmp.  */
++  tdep->jb_pc = 13;
++
++  set_gdbarch_iterate_over_regset_sections
++    (gdbarch, aarch64_nbsd_iterate_over_regset_sections);
++}
++
++void
++_initialize_aarch64_nbsd_tdep (void)
++{
++  gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_NETBSD,
++			  aarch64_nbsd_init_abi);
++}
diff --git a/gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-tdep.h b/gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-tdep.h
new file mode 100644
index 0000000000..3ae9a0e0e4
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_aarch64-nbsd-tdep.h
@@ -0,0 +1,38 @@
+$NetBSD$
+
+--- gdb/aarch64-nbsd-tdep.h.orig	2019-09-02 20:02:23.494326453 +0000
++++ gdb/aarch64-nbsd-tdep.h
+@@ -0,0 +1,33 @@
++/* NetBSD/aarch64 target support, prototypes.
++
++   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include "regset.h"
++
++/* The general-purpose regset consists of 31 registers (30 X , plus LR), SP,
++   ELR (PC), SPSR register, and TPIDR.  SPSR is 32 bits but the structure is
++   passed to 64 bit alignment.  */
++#define AARCH64_NBSD_SIZEOF_GREGSET  (35 * X_REGISTER_SIZE)
++
++/* The fp regset consists of 32 V registers, plus FPSR and FPCR which
++   are 4 bytes wide each, and the whole structure is padded to 128 bit
++   alignment.  */
++#define AARCH64_NBSD_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
++
++extern const struct regset aarch64_nbsd_gregset;
++extern const struct regset aarch64_nbsd_fpregset;
diff --git a/gdb-netbsd-wip/patches/patch-gdb_alpha-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_alpha-nbsd-tdep.c
new file mode 100644
index 0000000000..e7dfeeb9b2
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_alpha-nbsd-tdep.c
@@ -0,0 +1,184 @@
+$NetBSD$
+
+--- gdb/alpha-nbsd-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/alpha-nbsd-tdep.c
+@@ -28,13 +28,18 @@
+ #include "value.h"
+ 
+ #include "alpha-tdep.h"
+-#include "alpha-bsd-tdep.h"
+ #include "nbsd-tdep.h"
+ #include "solib-svr4.h"
++#include "trad-frame.h"
++#include "frame-unwind.h"
++#include "tramp-frame.h"
+ #include "target.h"
+ 
+ /* Core file support.  */
+ 
++/* Even though NetBSD/alpha used ELF since day one, it used the
++   traditional a.out-style core dump format before NetBSD 1.6.  */
++
+ /* Sizeof `struct reg' in <machine/reg.h>.  */
+ #define ALPHANBSD_SIZEOF_GREGS	(32 * 8)
+ 
+@@ -170,31 +175,95 @@ alphanbsd_iterate_over_regset_sections (
+ 
+ /* Signal trampolines.  */
+ 
++static void
++alphanbsd_sigtramp_cache_init (const struct tramp_frame *,
++			       struct frame_info *,
++			       struct trad_frame_cache *,
++			       CORE_ADDR);
+ /* Under NetBSD/alpha, signal handler invocations can be identified by the
+    designated code sequence that is used to return from a signal handler.
+    In particular, the return address of a signal handler points to the
+-   following code sequence:
++   following code sequences: */
++static const struct tramp_frame alphanbsd_sigtramp_sc1 = {
++  SIGTRAMP_FRAME,
++  4,
++  {
++    { 0xa61e0000, 0xffffffff },		/* ldq a0, 0(sp) */
++    { 0x23de0010, 0xffffffff },		/* lda sp, 16(sp) */
++    { 0x201f0127, 0xffffffff },		/* lda v0, 295 */
++    { 0x00000083, 0xffffffff },		/* call_pal callsys */
++    { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
++  },
++  alphanbsd_sigtramp_cache_init
++};
+ 
+-	ldq	a0, 0(sp)
+-	lda	sp, 16(sp)
+-	lda	v0, 295(zero)	# __sigreturn14
+-	call_pal callsys
+-
+-   Each instruction has a unique encoding, so we simply attempt to match
+-   the instruction the PC is pointing to with any of the above instructions.
+-   If there is a hit, we know the offset to the start of the designated
+-   sequence and can then check whether we really are executing in the
+-   signal trampoline.  If not, -1 is returned, otherwise the offset from the
+-   start of the return sequence is returned.  */
+-static const gdb_byte sigtramp_retcode[] =
+-{
+-  0x00, 0x00, 0x1e, 0xa6,	/* ldq a0, 0(sp) */
+-  0x10, 0x00, 0xde, 0x23,	/* lda sp, 16(sp) */
+-  0x27, 0x01, 0x1f, 0x20,	/* lda v0, 295(zero) */
+-  0x83, 0x00, 0x00, 0x00,	/* call_pal callsys */
++/* The siginfo signal trampoline for NetBSD/alpha introduced in 2.0 */
++static const struct tramp_frame alphanbsd_sigtramp_si2 =
++{
++  SIGTRAMP_FRAME,
++  4,
++  {
++    { 0x221e0080, ULONGEST_MAX },		/* lda	a0,128(sp) */
++    { 0x201f0134, ULONGEST_MAX },		/* lda	v0,308 */
++    { 0x00000083, ULONGEST_MAX },		/* callsys */
++    { 0x47e00410, ULONGEST_MAX },		/* mov	v0,a0 */
++    { 0x201f0001, ULONGEST_MAX },		/* lda	v0,1 */
++    { 0x00000083, ULONGEST_MAX },		/* callsys */
++    { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
++  },
++  alphanbsd_sigtramp_cache_init
++};
++/* The siginfo signal trampoline for NetBSD/alpha introduced in 4.0 */
++static const struct tramp_frame alphanbsd_sigtramp_si4 =
++{
++  SIGTRAMP_FRAME,
++  4,
++  {
++    { 0x27ba0000, 0xffff0000 },
++    { 0x23bd0000, 0xffff0000 },			/* ldgp	gp,0(ra) */
++    { 0x221e0080, ULONGEST_MAX },		/* lda	a0,128(sp) */
++    { 0x201f0134, ULONGEST_MAX },		/* lda	v0,308 */
++    { 0x00000083, ULONGEST_MAX },		/* callsys */
++    { 0x221fffff, ULONGEST_MAX },		/* lda	a0,-1 */
++    { 0x201f0001, ULONGEST_MAX },		/* lda	v0,1 */
++    { 0x00000083, ULONGEST_MAX },		/* callsys */
++    { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
++  },
++  alphanbsd_sigtramp_cache_init
+ };
+-#define RETCODE_NWORDS		4
+-#define RETCODE_SIZE		(RETCODE_NWORDS * 4)
++
++static void
++alphanbsd_sigtramp_cache_init (const struct tramp_frame *self,
++			       struct frame_info *this_frame,
++			       struct trad_frame_cache *this_cache,
++			       CORE_ADDR func)
++{
++  struct gdbarch *gdbarch = get_frame_arch (this_frame);
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  CORE_ADDR addr, sp;
++  int i;
++
++  sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
++
++  if (self == &alphanbsd_sigtramp_sc1) {
++    addr = sp;
++  } else {
++    addr = sp + 128 + 56;
++  }
++ 
++  for (i = 0; i < 32; i++, addr += ALPHA_REGISTER_SIZE)
++    {
++      trad_frame_set_reg_addr (this_cache, i, addr);
++    }
++  trad_frame_set_reg_addr (this_cache, ALPHA_PC_REGNUM, addr);
++
++  /* Construct the frame ID using the function start.  */
++  trad_frame_set_id (this_cache, frame_id_build (sp, func));
++}
++
++#ifdef notyet
++#define RETCODE_NWORDS          4
++#define RETCODE_SIZE            (RETCODE_NWORDS * 4)
+ 
+ static LONGEST
+ alphanbsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
+@@ -244,6 +313,7 @@ alphanbsd_sigcontext_addr (struct frame_
+     return 0;
+   return get_frame_base (get_next_frame (frame));
+ }
++#endif
+ 
+ 
+ static void
+@@ -261,18 +331,24 @@ alphanbsd_init_abi (struct gdbarch_info 
+   /* NetBSD/alpha does not provide single step support via ptrace(2); we
+      must use software single-stepping.  */
+   set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
+-
+   /* NetBSD/alpha has SVR4-style shared libraries.  */
+   set_solib_svr4_fetch_link_map_offsets
+     (gdbarch, svr4_lp64_fetch_link_map_offsets);
++  set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
+ 
++#ifdef notyet
+   tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
+   tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp;
+   tdep->sigcontext_addr = alphanbsd_sigcontext_addr;
++#endif
+ 
+   tdep->jb_pc = 2;
+   tdep->jb_elt_size = 8;
+ 
++  tramp_frame_prepend_unwinder (gdbarch, &alphanbsd_sigtramp_sc1);
++  tramp_frame_prepend_unwinder (gdbarch, &alphanbsd_sigtramp_si2);
++  tramp_frame_prepend_unwinder (gdbarch, &alphanbsd_sigtramp_si4);
++
+   set_gdbarch_iterate_over_regset_sections
+     (gdbarch, alphanbsd_iterate_over_regset_sections);
+ }
+@@ -281,9 +357,6 @@ alphanbsd_init_abi (struct gdbarch_info 
+ void
+ _initialize_alphanbsd_tdep (void)
+ {
+-  /* Even though NetBSD/alpha used ELF since day one, it used the
+-     traditional a.out-style core dump format before NetBSD 1.6, but
+-     we don't support those.  */
+   gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_NETBSD,
+                           alphanbsd_init_abi);
+ }
diff --git a/gdb-netbsd-wip/patches/patch-gdb_alpha-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_alpha-tdep.c
new file mode 100644
index 0000000000..7082f1dcba
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_alpha-tdep.c
@@ -0,0 +1,36 @@
+$NetBSD$
+
+--- gdb/alpha-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/alpha-tdep.c
+@@ -754,6 +754,31 @@ alpha_skip_prologue (struct gdbarch *gdb
+   return pc + offset;
+ }
+ 
++/* GNU ld for alpha is so clever that the redundant GP load in function
++   entrypoint is skipped.  We must therefore skip initial GP loads; otherwise
++   breakpoints in function entrypoints can also be skipped.  */
++
++static CORE_ADDR
++alpha_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR pc)
++{
++  unsigned long inst;
++  gdb_byte buf[ALPHA_INSN_SIZE];
++
++  /* Refer to the comment in alpha_skip_prologue above.  */
++  if (target_read_memory (pc, buf, sizeof (buf)))
++    return pc;
++
++  /* Skip a GP load in the first two words in the function entrypoint.  */
++  inst = alpha_read_insn (gdbarch, pc);
++  if ((inst & 0xffff0000) != 0x27bb0000)	/* ldah $gp,n($t12) */
++    return pc;
++  inst = alpha_read_insn (gdbarch, pc + ALPHA_INSN_SIZE);
++  if ((inst & 0xffff0000) != 0x23bd0000)	/* lda $gp,n($gp) */
++    return pc;
++
++  return pc + 2 * ALPHA_INSN_SIZE;
++}
++
+ 
+ static const int ldl_l_opcode = 0x2a;
+ static const int ldq_l_opcode = 0x2b;
diff --git a/gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-nat.c
new file mode 100644
index 0000000000..72202df156
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-nat.c
@@ -0,0 +1,81 @@
+$NetBSD$
+
+--- gdb/amd64-nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/amd64-nbsd-nat.c
+@@ -24,6 +24,13 @@
+ #include "amd64-tdep.h"
+ #include "amd64-bsd-nat.h"
+ #include "amd64-nat.h"
++#include "regcache.h"
++#include "gdbcore.h"
++#include "bsd-kvm.h"
++
++#include <machine/frame.h>
++#include <machine/pcb.h>
++#include <machine/reg.h>
+ 
+ /* Mapping between the general-purpose registers in NetBSD/amd64
+    `struct reg' format and GDB's register cache layout for
+@@ -54,6 +61,55 @@ static int amd64nbsd32_r_reg_offset[] =
+   15 * 8			/* %gs */
+ };
+ 
++static int
++amd64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
++{
++  struct switchframe sf;
++
++  /* The following is true for NetBSD/amd64:
++
++     The pcb contains the stack pointer at the point of the context
++     switch in cpu_switchto().  At that point we have a stack frame as
++     described by `struct switchframe', which for NetBSD/amd64 has the
++     following layout:
++
++     interrupt level
++     %r15
++     %r14
++     %r13
++     %r12
++     %rbx
++     return address
++
++     Together with %rsp in the pcb, this accounts for all callee-saved
++     registers specified by the psABI.  From this information we
++     reconstruct the register state as it would look when we just
++     returned from cpu_switchto().
++
++     For kernel core dumps, dumpsys() builds a fake switchframe for us. */
++
++  /* The stack pointer shouldn't be zero.  */
++  if (pcb->pcb_rsp == 0)
++    return 0;
++
++  /* Read the stack frame, and check its validity.  */
++  read_memory (pcb->pcb_rsp, (gdb_byte *) &sf, sizeof sf);
++  pcb->pcb_rsp += sizeof (struct switchframe);
++  regcache->raw_supply (12, &sf.sf_r12);
++  regcache->raw_supply (13, &sf.sf_r13);
++  regcache->raw_supply (14, &sf.sf_r14);
++  regcache->raw_supply (15, &sf.sf_r15);
++  regcache->raw_supply (AMD64_RBX_REGNUM, &sf.sf_rbx);
++  regcache->raw_supply (AMD64_RIP_REGNUM, &sf.sf_rip);
++
++  regcache->raw_supply (AMD64_RSP_REGNUM, &pcb->pcb_rsp);
++  regcache->raw_supply (AMD64_RBP_REGNUM, &pcb->pcb_rbp);
++  regcache->raw_supply (AMD64_FS_REGNUM, &pcb->pcb_fs);
++  regcache->raw_supply (AMD64_GS_REGNUM, &pcb->pcb_gs);
++
++  return 1;
++}
++
+ static amd64_bsd_nat_target<nbsd_nat_target> the_amd64_nbsd_nat_target;
+ 
+ void
+@@ -64,4 +120,6 @@ _initialize_amd64nbsd_nat (void)
+   amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset;
+ 
+   add_inf_child_target (&the_amd64_nbsd_nat_target);
++
++  bsd_kvm_add_target (amd64nbsd_supply_pcb);
+ }
diff --git a/gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-tdep.c
new file mode 100644
index 0000000000..dd95f1084a
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_amd64-nbsd-tdep.c
@@ -0,0 +1,219 @@
+$NetBSD$
+
+--- gdb/amd64-nbsd-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/amd64-nbsd-tdep.c
+@@ -28,6 +28,8 @@
+ #include "gdbsupport/x86-xstate.h"
+ #include "nbsd-tdep.h"
+ #include "solib-svr4.h"
++#include "trad-frame.h"
++#include "frame-unwind.h"
+ 
+ /* Support for signal handlers.  */
+ 
+@@ -94,6 +96,196 @@ int amd64nbsd_r_reg_offset[] =
+   15 * 8			/* %gs */
+ };
+ 
++/* Kernel debugging support */
++static const int amd64nbsd_tf_reg_offset[] =
++{
++  18 * 8,			/* %rax */
++  17 * 8,			/* %rbx */
++  10 * 8,			/* %rcx */
++  2 * 8,			/* %rdx */
++  1 * 8,			/* %rsi */
++  0 * 8,			/* %rdi */
++  16 * 8,			/* %rbp */
++  28 * 8,			/* %rsp */
++  4 * 8,			/* %r8 .. */
++  5 * 8,			
++  3 * 8,			
++  11 * 8,			
++  12 * 8,			
++  13 * 8,			
++  14 * 8,			
++  15 * 8,			/* ... %r15 */
++  25 * 8,			/* %rip */
++  27 * 8,			/* %eflags */
++  26 * 8,			/* %cs */
++  29 * 8,			/* %ss */
++  22 * 8,			/* %ds */
++  21 * 8,			/* %es */
++  20 * 8,			/* %fs */
++  19 * 8,			/* %gs */
++};
++
++static struct trad_frame_cache *
++amd64nbsd_trapframe_cache(struct frame_info *this_frame, void **this_cache)
++{
++  struct trad_frame_cache *cache;
++  CORE_ADDR func, sp, addr;
++  ULONGEST cs = 0, rip = 0;
++  const char *name;
++  int i;
++  struct gdbarch *gdbarch = get_frame_arch (this_frame);
++  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
++
++  if (*this_cache)
++    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);
++
++  /* There is an extra 'call' in the interrupt sequence - ignore the extra
++   * return address */
++
++  addr = sp;
++  if (name) {
++	if (strncmp (name, "Xintr", 5) == 0
++	 || strncmp (name, "Xhandle", 7) == 0) {
++		addr += 8;		/* It's an interrupt frame.  */
++	}
++  }
++
++#ifdef DEBUG_TRAPFRAME
++  for (i = 0; i < 50; i++) {
++    cs = read_memory_unsigned_integer (addr + i * 8, 8, byte_order);
++    printf("%s i=%d r=%#jx\n", name, i, (intmax_t)cs);
++  }
++#endif
++
++  for (i = 0; i < ARRAY_SIZE (amd64nbsd_tf_reg_offset); i++)
++    if (amd64nbsd_tf_reg_offset[i] != -1)
++      trad_frame_set_reg_addr (cache, i, addr + amd64nbsd_tf_reg_offset[i]);
++
++  /* Read %cs and %rip when we have the addresses to hand */
++  cs = read_memory_unsigned_integer (addr
++    + amd64nbsd_tf_reg_offset[AMD64_CS_REGNUM], 8, byte_order);
++  rip = read_memory_unsigned_integer (addr
++    + amd64nbsd_tf_reg_offset[AMD64_RIP_REGNUM], 8, byte_order);
++
++#ifdef DEBUG_TRAPFRAME
++  printf("%s cs=%#jx rip=%#jx\n", name, (intmax_t)cs, (intmax_t)rip);
++#endif
++
++  /* The trap frame layout was changed lf the %rip value is less than 2^16 it
++   * is almost certainly the %ss of the old format. */
++  if (rip < (1 << 16))
++    {
++
++      for (i = 0; i < ARRAY_SIZE (amd64nbsd_tf_reg_offset); i++)
++        {
++
++          if (amd64nbsd_tf_reg_offset[i] == -1)
++            continue;
++
++          trad_frame_set_reg_addr (cache, i, addr + amd64nbsd_r_reg_offset[i]);
++
++          /* Read %cs when we have the address to hand */
++          if (i == AMD64_CS_REGNUM)
++	    cs = read_memory_unsigned_integer (addr + amd64nbsd_r_reg_offset[i],
++	    8, byte_order);
++        }
++    }
++
++  if ((cs & I386_SEL_RPL) == I386_SEL_UPL ||
++	(name && strncmp(name, "Xsoft", 5) == 0))
++    {
++      /* Trap from user space or soft interrupt; 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 + 16, func));
++    }
++
++  return cache;
++}
++
++static void
++amd64nbsd_trapframe_this_id (struct frame_info *this_frame,
++			     void **this_cache,
++			     struct frame_id *this_id)
++{
++  struct trad_frame_cache *cache =
++    amd64nbsd_trapframe_cache (this_frame, this_cache);
++  
++  trad_frame_get_id (cache, this_id);
++}
++
++static struct value *
++amd64nbsd_trapframe_prev_register (struct frame_info *this_frame,
++				   void **this_cache, int regnum) 
++{
++  struct trad_frame_cache *cache =
++    amd64nbsd_trapframe_cache (this_frame, this_cache);
++
++  return trad_frame_get_register (cache, this_frame, regnum);
++}
++
++static int
++amd64nbsd_trapframe_sniffer (const struct frame_unwind *self,
++			     struct frame_info *this_frame,
++			     void **this_prologue_cache)
++{
++  ULONGEST cs = 0;
++  const char *name;
++
++  try
++    {
++      cs = get_frame_register_unsigned (this_frame, AMD64_CS_REGNUM);
++    }
++  catch (gdb_exception_error &except)
++    {
++      if (except.reason < 0 && except.error != NOT_AVAILABLE_ERROR)
++	throw_exception (std::move (except));
++    }
++
++  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
++    return 0;
++
++  find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
++  return (name && ((strcmp (name, "alltraps") == 0)
++	        || (strcmp (name, "calltrap") == 0)
++	        || (strcmp (name, "handle_syscall") == 0)
++		|| (strcmp (name, "Xdoreti") == 0)
++		|| (strcmp (name, "Xspllower") == 0)
++		|| (strncmp (name, "Xhandle", 7) == 0)
++		|| (strncmp (name, "Xintr", 5) == 0)
++		|| (strncmp (name, "Xpreempt", 8) == 0)
++		|| (strncmp (name, "Xrecurse", 8) == 0)
++		|| (strncmp (name, "Xresume", 7) == 0)
++		|| (strncmp (name, "Xsoft", 5) == 0)
++		|| (strncmp (name, "Xstray", 6) == 0)
++		|| (strncmp (name, "Xsyscall", 8) == 0)
++		|| (strncmp (name, "Xtrap", 5) == 0)
++	    ));
++}
++
++static const struct frame_unwind amd64nbsd_trapframe_unwind = {
++  /* FIXME: kettenis/20051219: This really is more like an interrupt
++     frame, but SIGTRAMP_FRAME would print <signal handler called>,
++     which really is not what we want here.  */
++  NORMAL_FRAME,
++  default_frame_unwind_stop_reason,
++  amd64nbsd_trapframe_this_id,
++  amd64nbsd_trapframe_prev_register,
++  NULL,
++  amd64nbsd_trapframe_sniffer
++};
++
+ static void
+ amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+ {
+@@ -118,6 +310,8 @@ amd64nbsd_init_abi (struct gdbarch_info 
+   /* NetBSD uses SVR4-style shared libraries.  */
+   set_solib_svr4_fetch_link_map_offsets
+     (gdbarch, svr4_lp64_fetch_link_map_offsets);
++  /* Unwind kernel trap frames correctly.  */
++  frame_unwind_prepend_unwinder (gdbarch, &amd64nbsd_trapframe_unwind);
+ }
+ 
+ void
diff --git a/gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-nat.c
new file mode 100644
index 0000000000..c5e5fc280a
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-nat.c
@@ -0,0 +1,568 @@
+$NetBSD$
+
+--- gdb/arm-nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/arm-nbsd-nat.c
+@@ -1,5 +1,4 @@
+-/* Native-dependent code for BSD Unix running on ARM's, for GDB.
+-
++/*
+    Copyright (C) 1988-2019 Free Software Foundation, Inc.
+ 
+    This file is part of GDB.
+@@ -17,20 +16,30 @@
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
++#ifndef _KERNTYPES
++#define _KERNTYPES
++#endif
+ #include "defs.h"
+ #include "gdbcore.h"
+ #include "inferior.h"
+ #include "regcache.h"
+ #include "target.h"
++
++#include "nbsd-nat.h"
+ #include <sys/types.h>
+ #include <sys/ptrace.h>
+ #include <machine/reg.h>
+ #include <machine/frame.h>
++#include <arm/arm32/frame.h>
++
++/* Support for debugging kernel virtual memory images.  */
++#include <machine/pcb.h>
+ 
+ #include "arm-tdep.h"
+ #include "inf-ptrace.h"
++#include "bsd-kvm.h"
+ 
+-class arm_netbsd_nat_target final : public inf_ptrace_target
++class arm_nbsd_nat_target final : public nbsd_nat_target
+ {
+ public:
+   /* Add our register access methods.  */
+@@ -38,10 +47,60 @@ public:
+   void store_registers (struct regcache *, int) override;
+ };
+ 
+-static arm_netbsd_nat_target the_arm_netbsd_nat_target;
++static arm_nbsd_nat_target the_arm_nbsd_nat_target;
+ 
+ extern int arm_apcs_32;
+ 
++#define FPSCR(r) ((char *) &(r)->fpr_vfp.vfp_fpscr)
++#define FPREG(r, regno) \
++    ((char *) (r)->fpr_vfp.vfp_regs + 8 * ((regno) - ARM_D0_REGNUM))
++
++static int
++armnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
++{
++  struct switchframe sf;
++
++  /* The following is true for NetBSD/arm32 in 5.0 and after:
++
++     The pcb contains r8-r13 (sp) at the point of context switch in
++     cpu_switchto() or call of dumpsys(). At that point we have a
++     stack frame as described by `struct switchframe', which for
++     NetBSD/arm32 has the following layout:
++
++	r4   ascending.
++	r5        |
++	r6        |
++	r7       \|/
++	old sp
++	pc
++
++     we reconstruct the register state as it would look when we just
++     returned from cpu_switchto() or dumpsys().  */
++
++  if (!arm_apcs_32)
++    return 0;
++
++  /* The stack pointer shouldn't be zero.  */
++  if (pcb->pcb_sp == 0)
++    return 0;
++
++  read_memory (pcb->pcb_sp, (gdb_byte *) &sf, sizeof sf);
++
++  regcache->raw_supply (ARM_PC_REGNUM, &sf.sf_pc);
++  regcache->raw_supply (ARM_SP_REGNUM, &pcb->pcb_sp);
++  regcache->raw_supply (12, &pcb->pcb_r12);
++  regcache->raw_supply (11, &pcb->pcb_r11);
++  regcache->raw_supply (10, &pcb->pcb_r10);
++  regcache->raw_supply (9, &pcb->pcb_r9);
++  regcache->raw_supply (8, &pcb->pcb_r8);
++  regcache->raw_supply (7, &sf.sf_r7);
++  regcache->raw_supply (6, &sf.sf_r6);
++  regcache->raw_supply (5, &sf.sf_r5);
++  regcache->raw_supply (4, &sf.sf_r4);
++
++  return 1;
++}
++
+ static void
+ arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
+ {
+@@ -65,25 +124,26 @@ arm_supply_gregset (struct regcache *reg
+ }
+ 
+ static void
+-arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
++arm_supply_vfpregset (struct regcache *regcache, struct fpreg *vfpregset)
+ {
+   int regno;
+ 
+-  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+-    regcache->raw_supply (regno,
+-			  (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
++  for (regno = ARM_D0_REGNUM; regno < 16 + ARM_D0_REGNUM; regno++)
++    regcache->raw_supply (regno, FPREG(vfpregset, regno));
+ 
+-  regcache->raw_supply (ARM_FPS_REGNUM, (char *) &fparegset->fpr_fpsr);
++  regcache->raw_supply (ARM_FPSCR_REGNUM, FPSCR(vfpregset));
+ }
+ 
+ static void
+ fetch_register (struct regcache *regcache, int regno)
+ {
+-  struct reg inferior_registers;
++  struct reg regs;
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+   int ret;
+ 
+-  ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_registers, 0);
++  ret = ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp);
+ 
+   if (ret < 0)
+     {
+@@ -94,32 +154,28 @@ fetch_register (struct regcache *regcach
+   switch (regno)
+     {
+     case ARM_SP_REGNUM:
+-      regcache->raw_supply (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
++      regcache->raw_supply (ARM_SP_REGNUM, (char *) &regs.r_sp);
+       break;
+ 
+     case ARM_LR_REGNUM:
+-      regcache->raw_supply (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
++      regcache->raw_supply (ARM_LR_REGNUM, (char *) &regs.r_lr);
+       break;
+ 
+     case ARM_PC_REGNUM:
+       /* This is ok: we're running native...  */
+-      inferior_registers.r_pc = gdbarch_addr_bits_remove
+-				  (regcache->arch (),
+-				   inferior_registers.r_pc);
+-      regcache->raw_supply (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
++      regs.r_pc = gdbarch_addr_bits_remove (regcache->arch (), regs.r_pc);
++      regcache->raw_supply (ARM_PC_REGNUM, (char *) &regs.r_pc);
+       break;
+ 
+     case ARM_PS_REGNUM:
+       if (arm_apcs_32)
+-	regcache->raw_supply (ARM_PS_REGNUM,
+-			      (char *) &inferior_registers.r_cpsr);
++	regcache->raw_supply (ARM_PS_REGNUM, (char *) &regs.r_cpsr);
+       else
+-	regcache->raw_supply (ARM_PS_REGNUM,
+-			      (char *) &inferior_registers.r_pc);
++	regcache->raw_supply (ARM_PS_REGNUM, (char *) &regs.r_pc);
+       break;
+ 
+     default:
+-      regcache->raw_supply (regno, (char *) &inferior_registers.r[regno]);
++      regcache->raw_supply (regno, (char *) &regs.r[regno]);
+       break;
+     }
+ }
+@@ -127,12 +183,14 @@ fetch_register (struct regcache *regcach
+ static void
+ fetch_regs (struct regcache *regcache)
+ {
+-  struct reg inferior_registers;
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
++  struct reg regs;
+   int ret;
+   int regno;
+ 
+-  ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_registers, 0);
++  ret = ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp);
+ 
+   if (ret < 0)
+     {
+@@ -140,17 +198,19 @@ fetch_regs (struct regcache *regcache)
+       return;
+     }
+ 
+-  arm_supply_gregset (regcache, &inferior_registers);
++  arm_supply_gregset (regcache, &regs);
+ }
+ 
+ static void
+ fetch_fp_register (struct regcache *regcache, int regno)
+ {
+-  struct fpreg inferior_fp_registers;
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
++  struct fpreg fpregs;
+   int ret;
+ 
+-  ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
++  ret = ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp); 
+ 
+   if (ret < 0)
+     {
+@@ -160,14 +220,13 @@ fetch_fp_register (struct regcache *regc
+ 
+   switch (regno)
+     {
+-    case ARM_FPS_REGNUM:
+-      regcache->raw_supply (ARM_FPS_REGNUM,
+-			    (char *) &inferior_fp_registers.fpr_fpsr);
++    case ARM_FPSCR_REGNUM:
++      regcache->raw_supply (ARM_FPSCR_REGNUM, FPSCR(&fpregs));
+       break;
+ 
+     default:
+-      regcache->raw_supply
+-	(regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
++      regno += ARM_D0_REGNUM;
++      regcache->raw_supply (regno, FPREG(&fpregs, regno));
+       break;
+     }
+ }
+@@ -175,20 +234,21 @@ fetch_fp_register (struct regcache *regc
+ static void
+ fetch_fp_regs (struct regcache *regcache)
+ {
+-  struct fpreg inferior_fp_registers;
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
++  struct fpreg fpregs;
+   int ret;
+-  int regno;
+ 
+-  ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
++  ret = ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp);
+ 
+   if (ret < 0)
+     {
+-      warning (_("unable to fetch general registers"));
++      warning (_("unable to fetch floating-point registers"));
+       return;
+     }
+ 
+-  arm_supply_fparegset (regcache, &inferior_fp_registers);
++  arm_supply_vfpregset (regcache, &fpregs);
+ }
+ 
+ void
+@@ -196,10 +256,10 @@ arm_nbsd_nat_target::fetch_registers (st
+ {
+   if (regno >= 0)
+     {
+-      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+-	fetch_register (regcache, regno);
+-      else
++      if (regno >= ARM_D0_REGNUM && regno <= ARM_FPSCR_REGNUM)
+ 	fetch_fp_register (regcache, regno);
++      else
++	fetch_register (regcache, regno);
+     }
+   else
+     {
+@@ -213,11 +273,13 @@ static void
+ store_register (const struct regcache *regcache, int regno)
+ {
+   struct gdbarch *gdbarch = regcache->arch ();
+-  struct reg inferior_registers;
++  struct reg regs;
+   int ret;
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+ 
+-  ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_registers, 0);
++  ret = ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp); 
+ 
+   if (ret < 0)
+     {
+@@ -228,17 +290,16 @@ store_register (const struct regcache *r
+   switch (regno)
+     {
+     case ARM_SP_REGNUM:
+-      regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
++      regcache->raw_collect (ARM_SP_REGNUM, (char *) &regs.r_sp);
+       break;
+ 
+     case ARM_LR_REGNUM:
+-      regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
++      regcache->raw_collect (ARM_LR_REGNUM, (char *) &regs.r_lr);
+       break;
+ 
+     case ARM_PC_REGNUM:
+       if (arm_apcs_32)
+-	regcache->raw_collect (ARM_PC_REGNUM,
+-			       (char *) &inferior_registers.r_pc);
++	regcache->raw_collect (ARM_PC_REGNUM, (char *) &regs.r_pc);
+       else
+ 	{
+ 	  unsigned pc_val;
+@@ -246,16 +307,14 @@ store_register (const struct regcache *r
+ 	  regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
+ 	  
+ 	  pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
+-	  inferior_registers.r_pc ^= gdbarch_addr_bits_remove
+-				       (gdbarch, inferior_registers.r_pc);
+-	  inferior_registers.r_pc |= pc_val;
++	  regs.r_pc ^= gdbarch_addr_bits_remove (gdbarch, regs.r_pc);
++	  regs.r_pc |= pc_val;
+ 	}
+       break;
+ 
+     case ARM_PS_REGNUM:
+       if (arm_apcs_32)
+-	regcache->raw_collect (ARM_PS_REGNUM,
+-			       (char *) &inferior_registers.r_cpsr);
++	regcache->raw_collect (ARM_PS_REGNUM, (char *) &regs.r_cpsr);
+       else
+ 	{
+ 	  unsigned psr_val;
+@@ -263,19 +322,17 @@ store_register (const struct regcache *r
+ 	  regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
+ 
+ 	  psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
+-	  inferior_registers.r_pc = gdbarch_addr_bits_remove
+-				      (gdbarch, inferior_registers.r_pc);
+-	  inferior_registers.r_pc |= psr_val;
++	  regs.r_pc = gdbarch_addr_bits_remove (gdbarch, regs.r_pc);
++	  regs.r_pc |= psr_val;
+ 	}
+       break;
+ 
+     default:
+-      regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
++      regcache->raw_collect (regno, (char *) &regs.r[regno]);
+       break;
+     }
+ 
+-  ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_registers, 0);
++  ret = ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp);
+ 
+   if (ret < 0)
+     warning (_("unable to write register %d to inferior"), regno);
+@@ -285,22 +342,24 @@ static void
+ store_regs (const struct regcache *regcache)
+ {
+   struct gdbarch *gdbarch = regcache->arch ();
+-  struct reg inferior_registers;
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
++  struct reg regs;
+   int ret;
+   int regno;
+ 
+ 
+   for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
+-    regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
++    regcache->raw_collect (regno, (char *) &regs.r[regno]);
+ 
+-  regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
+-  regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
++  regcache->raw_collect (ARM_SP_REGNUM, (char *) &regs.r_sp);
++  regcache->raw_collect (ARM_LR_REGNUM, (char *) &regs.r_lr);
+ 
+   if (arm_apcs_32)
+     {
+-      regcache->raw_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
+-      regcache->raw_collect (ARM_PS_REGNUM,
+-			     (char *) &inferior_registers.r_cpsr);
++      regcache->raw_collect (ARM_PC_REGNUM, (char *) &regs.r_pc);
++      regcache->raw_collect (ARM_PS_REGNUM, (char *) &regs.r_cpsr);
+     }
+   else
+     {
+@@ -313,11 +372,10 @@ store_regs (const struct regcache *regca
+       pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
+       psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
+ 
+-      inferior_registers.r_pc = pc_val | psr_val;
++      regs.r_pc = pc_val | psr_val;
+     }
+ 
+-  ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_registers, 0);
++  ret = ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp); 
+ 
+   if (ret < 0)
+     warning (_("unable to store general registers"));
+@@ -326,11 +384,13 @@ store_regs (const struct regcache *regca
+ static void
+ store_fp_register (const struct regcache *regcache, int regno)
+ {
+-  struct fpreg inferior_fp_registers;
++  struct fpreg fpregs;
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+   int ret;
+ 
+-  ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
++  ret = ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp); 
+ 
+   if (ret < 0)
+     {
+@@ -341,18 +401,15 @@ store_fp_register (const struct regcache
+   switch (regno)
+     {
+     case ARM_FPS_REGNUM:
+-      regcache->raw_collect (ARM_FPS_REGNUM,
+-			     (char *) &inferior_fp_registers.fpr_fpsr);
++      regcache->raw_collect (ARM_FPS_REGNUM, FPSCR(&fpregs));
+       break;
+ 
+     default:
+-      regcache->raw_collect
+-	(regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
++      regcache->raw_collect (regno, FPREG(&fpregs, regno));
+       break;
+     }
+ 
+-  ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
++  ret = ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp); 
+ 
+   if (ret < 0)
+     warning (_("unable to write register %d to inferior"), regno);
+@@ -361,20 +418,20 @@ store_fp_register (const struct regcache
+ static void
+ store_fp_regs (const struct regcache *regcache)
+ {
+-  struct fpreg inferior_fp_registers;
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
++  struct fpreg fpregs;
+   int ret;
+   int regno;
+ 
+ 
+-  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+-    regcache->raw_collect
+-      (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
++  for (regno = ARM_D0_REGNUM; regno < 16 + ARM_D0_REGNUM; regno++)
++    regcache->raw_collect (regno, FPREG(&fpregs, regno));
+ 
+-  regcache->raw_collect (ARM_FPS_REGNUM,
+-			 (char *) &inferior_fp_registers.fpr_fpsr);
++  regcache->raw_collect (ARM_FPSCR_REGNUM, FPSCR(&fpregs));
+ 
+-  ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
+-		(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
++  ret = ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp);
+ 
+   if (ret < 0)
+     warning (_("unable to store floating-point registers"));
+@@ -385,10 +442,10 @@ arm_nbsd_nat_target::store_registers (st
+ {
+   if (regno >= 0)
+     {
+-      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+-	store_register (regcache, regno);
+-      else
++      if (regno >= ARM_D0_REGNUM && regno <= ARM_FPSCR_REGNUM)
+ 	store_fp_register (regcache, regno);
++      else
++	store_register (regcache, regno);
+     }
+   else
+     {
+@@ -397,13 +454,32 @@ arm_nbsd_nat_target::store_registers (st
+     }
+ }
+ 
++struct md_core
++{
++  struct reg intreg;
++  struct fpreg freg;
++};
++
++static void
++fetch_core_registers (struct regcache *regcache,
++		      char *core_reg_sect, unsigned core_reg_size,
++		      int which, CORE_ADDR ignore)
++{
++  struct md_core *core_reg = (struct md_core *) core_reg_sect;
++  int regno;
++  CORE_ADDR r_pc;
++
++  arm_supply_gregset (regcache, &core_reg->intreg);
++  arm_supply_vfpregset (regcache, &core_reg->freg);
++}
++
+ static void
+ fetch_elfcore_registers (struct regcache *regcache,
+ 			 char *core_reg_sect, unsigned core_reg_size,
+ 			 int which, CORE_ADDR ignore)
+ {
+   struct reg gregset;
+-  struct fpreg fparegset;
++  struct fpreg vfpregset;
+ 
+   switch (which)
+     {
+@@ -426,8 +502,8 @@ fetch_elfcore_registers (struct regcache
+ 	{
+ 	  /* The memcpy may be unnecessary, but we can't really be sure
+ 	     of the alignment of the data in the core file.  */
+-	  memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
+-	  arm_supply_fparegset (regcache, &fparegset);
++	  memcpy (&vfpregset, core_reg_sect, sizeof (vfpregset));
++	  arm_supply_vfpregset (regcache, &vfpregset);
+ 	}
+       break;
+ 
+@@ -437,9 +513,18 @@ fetch_elfcore_registers (struct regcache
+     }
+ }
+ 
++static struct core_fns arm_netbsd_core_fns =
++{
++  bfd_target_unknown_flavour,		/* core_flavour.  */
++  default_check_format,			/* check_format.  */
++  default_core_sniffer,			/* core_sniffer.  */
++  fetch_core_registers,			/* core_read_registers.  */
++  NULL
++};
++
+ static struct core_fns arm_netbsd_elfcore_fns =
+ {
+-  bfd_target_elf_flavour,		/* core_flovour.  */
++  bfd_target_elf_flavour,		/* core_flavour.  */
+   default_check_format,			/* check_format.  */
+   default_core_sniffer,			/* core_sniffer.  */
+   fetch_elfcore_registers,		/* core_read_registers.  */
+@@ -449,7 +534,8 @@ static struct core_fns arm_netbsd_elfcor
+ void
+ _initialize_arm_netbsd_nat (void)
+ {
+-  add_inf_child_target (&the_arm_netbsd_nat_target);
++  add_inf_child_target (&the_arm_nbsd_nat_target);
+ 
++  deprecated_add_core_fns (&arm_netbsd_core_fns);
+   deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
+ }
diff --git a/gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-tdep.c
new file mode 100644
index 0000000000..6a60cb73e9
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_arm-nbsd-tdep.c
@@ -0,0 +1,56 @@
+$NetBSD$
+
+--- gdb/arm-nbsd-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/arm-nbsd-tdep.c
+@@ -22,6 +22,7 @@
+ 
+ #include "arch/arm.h"
+ #include "arm-tdep.h"
++#include "nbsd-tdep.h"
+ #include "solib-svr4.h"
+ 
+ /* Description of the longjmp buffer.  */
+@@ -42,7 +43,7 @@ arm_netbsd_init_abi_common (struct gdbar
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ 
+   tdep->lowest_pc = 0x8000;
+-  switch (info.byte_order)
++  switch (info.byte_order_for_code)
+     {
+     case BFD_ENDIAN_LITTLE:
+       tdep->arm_breakpoint = arm_nbsd_arm_le_breakpoint;
+@@ -68,8 +69,23 @@ arm_netbsd_init_abi_common (struct gdbar
+ 
+   /* Single stepping.  */
+   set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
++  /* Core support */
++  set_gdbarch_iterate_over_regset_sections
++    (gdbarch, armbsd_iterate_over_regset_sections);
++
+ }
+-  
++
++static void
++arm_netbsd_aout_init_abi (struct gdbarch_info info,
++			  struct gdbarch *gdbarch)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++
++  arm_netbsd_init_abi_common (info, gdbarch);
++  if (tdep->fp_model == ARM_FLOAT_AUTO)
++    tdep->fp_model = ARM_FLOAT_SOFT_FPA;
++}
++
+ static void
+ arm_netbsd_elf_init_abi (struct gdbarch_info info,
+ 			 struct gdbarch *gdbarch)
+@@ -83,6 +99,9 @@ arm_netbsd_elf_init_abi (struct gdbarch_
+   /* NetBSD ELF uses SVR4-style shared libraries.  */
+   set_solib_svr4_fetch_link_map_offsets
+     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
++
++  /* for single stepping; see PR/50773 */
++  set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
+ }
+ 
+ void
diff --git a/gdb-netbsd-wip/patches/patch-gdb_bsd-kvm.c b/gdb-netbsd-wip/patches/patch-gdb_bsd-kvm.c
new file mode 100644
index 0000000000..55f22ca045
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_bsd-kvm.c
@@ -0,0 +1,61 @@
+$NetBSD$
+
+--- gdb/bsd-kvm.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/bsd-kvm.c
+@@ -29,6 +29,7 @@
+ #include "gdbcore.h"
+ #include "inferior.h"          /* for get_exec_file */
+ #include "gdbthread.h"
++#include "arch-utils.h"
+ 
+ #include <fcntl.h>
+ #include <kvm.h>
+@@ -108,6 +109,7 @@ bsd_kvm_target_open (const char *arg, in
+   char errbuf[_POSIX2_LINE_MAX];
+   char *execfile = NULL;
+   kvm_t *temp_kd;
++  struct inferior *inf;
+   char *filename = NULL;
+ 
+   target_preopen (from_tty);
+@@ -136,6 +138,12 @@ bsd_kvm_target_open (const char *arg, in
+   core_kd = temp_kd;
+   push_target (&bsd_kvm_ops);
+ 
++  inf = add_inferior_silent (bsd_kvm_ptid.pid ());
++  inf->aspace = maybe_new_address_space ();
++  inf->pspace = new program_space (inf->aspace);
++
++  inf->gdbarch = get_current_arch ();
++
+   add_thread_silent (bsd_kvm_ptid);
+   inferior_ptid = bsd_kvm_ptid;
+ 
+@@ -273,6 +281,27 @@ bsd_kvm_target::fetch_registers (struct 
+       return;
+     }
+ 
++#if 1 /* TODO: HAVE_STRUCT_LWP_L_ADDR */
++  memset (nl, 0, sizeof nl);
++  nl[0].n_name = "_lwp0";
++
++  if (kvm_nlist (core_kd, nl) == -1)
++    error (("%s"), kvm_geterr (core_kd));
++
++  if (nl[0].n_value != 0)
++    {
++      struct pcb *paddr;
++
++      /* Found lwp0.  */
++      nl[0].n_value += offsetof (struct lwp, l_addr);
++      if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
++	error (("%s"), kvm_geterr (core_kd));
++
++      bsd_kvm_fetch_pcb (regcache, paddr);
++      return;
++    }
++#endif
++
+ #ifdef HAVE_STRUCT_THREAD_TD_PCB
+   /* In FreeBSD kernels for 5.0-RELEASE and later, the PCB no longer
+      lives in `struct proc' but in `struct thread'.  The `struct
diff --git a/gdb-netbsd-wip/patches/patch-gdb_config_aarch64_nbsd.mh b/gdb-netbsd-wip/patches/patch-gdb_config_aarch64_nbsd.mh
new file mode 100644
index 0000000000..fdfc4dedf1
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_config_aarch64_nbsd.mh
@@ -0,0 +1,10 @@
+$NetBSD$
+
+--- gdb/config/aarch64/nbsd.mh.orig	2019-09-02 20:02:23.496700950 +0000
++++ gdb/config/aarch64/nbsd.mh
+@@ -0,0 +1,5 @@
++# Host: NetBSD/arm64
++NATDEPFILES= fork-child.o inf-ptrace.o nbsd-nat.o aarch64-nbsd-nat.o \
++	bsd-kvm.o
++
++LOADLIBES= -lkvm
diff --git a/gdb-netbsd-wip/patches/patch-gdb_config_powerpc_ppc64-nbsd.mh b/gdb-netbsd-wip/patches/patch-gdb_config_powerpc_ppc64-nbsd.mh
new file mode 100644
index 0000000000..7ef6d88a89
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_config_powerpc_ppc64-nbsd.mh
@@ -0,0 +1,9 @@
+$NetBSD$
+
+--- gdb/config/powerpc/ppc64-nbsd.mh.orig	2019-09-02 20:02:23.496966514 +0000
++++ gdb/config/powerpc/ppc64-nbsd.mh
+@@ -0,0 +1,4 @@
++# Host: NetBSD/powerpc64
++NATDEPFILES= fork-child.o inf-ptrace.o nbsd-nat.o ppc-nbsd-nat.o bsd-kvm.o
++
++LOADLIBES= -lkvm
diff --git a/gdb-netbsd-wip/patches/patch-gdb_configure b/gdb-netbsd-wip/patches/patch-gdb_configure
new file mode 100644
index 0000000000..6d56e67e2a
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_configure
@@ -0,0 +1,22 @@
+$NetBSD$
+
+--- gdb/configure.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/configure
+@@ -13532,6 +13532,9 @@ if ${am_cv_langinfo_codeset+:} false; th
+ else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
++#include <sys/param.h>
++#define _KMEMUSER
++#include <sys/lwp.h>
+ #include <langinfo.h>
+ int
+ main ()
+@@ -13998,6 +14001,7 @@ if ${gdb_cv_struct_lwp+:} false; then :
+ else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
++#define _KMEMUSER
+ #include <sys/param.h>
+ #define _KMEMUSER
+ #include <sys/lwp.h>
diff --git a/gdb-netbsd-wip/patches/patch-gdb_configure.host b/gdb-netbsd-wip/patches/patch-gdb_configure.host
new file mode 100644
index 0000000000..9f7c50a62f
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_configure.host
@@ -0,0 +1,30 @@
+$NetBSD$
+
+--- gdb/configure.host.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/configure.host
+@@ -84,6 +84,7 @@ case "${host}" in
+ *-*-darwin*)		gdb_host=darwin ;;
+ 
+ aarch64*-*-linux*)	gdb_host=linux ;;
++aarch64*-*-netbsd*)	gdb_host=nbsd ;;
+ aarch64*-*-freebsd*)	gdb_host=fbsd ;;
+ 
+ alpha*-*-linux*)	gdb_host=alpha-linux ;;
+@@ -121,7 +122,7 @@ i[34567]86-*-cygwin*)	gdb_host=cygwin ;;
+ ia64-*-linux*)		gdb_host=linux ;;
+ 
+ m68*-*-linux*)		gdb_host=linux ;;
+-m68*-*-netbsdelf* | m68*-*-knetbsd*-gnu)
++m68*-*-netbsdelf* | m68*-*-knetbsd*-gnu | m5407-*-netbsdelf*)
+ 			gdb_host=nbsdelf ;;
+ m68*-*-openbsd*)	gdb_host=obsd ;;
+ 
+@@ -138,6 +139,8 @@ powerpc-*-aix* | rs6000-*-* | powerpc64-
+ powerpc*-*-freebsd*)	gdb_host=fbsd ;;
+ powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
+ 			gdb_host=nbsd ;;
++powerpc64-*-netbsd* | powerpc64-*-knetbsd*-gnu)
++			gdb_host=ppc64-nbsd ;;
+ powerpc-*-openbsd*)	gdb_host=obsd ;;
+ 
+ powerpc64*-*-linux*)	gdb_host=ppc64-linux
diff --git a/gdb-netbsd-wip/patches/patch-gdb_configure.nat b/gdb-netbsd-wip/patches/patch-gdb_configure.nat
new file mode 100644
index 0000000000..599f31082b
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_configure.nat
@@ -0,0 +1,100 @@
+$NetBSD$
+
+--- gdb/configure.nat.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/configure.nat
+@@ -329,11 +329,16 @@ case ${gdb_host} in
+ 	esac
+ 	;;
+     nbsd)
++	NATDEPFILES="${NATDEPFILES} nbsd-nat.o bsd-kvm.o"
++	LOADLIBES='-lkvm'
+ 	case ${gdb_host_cpu} in
++	    aarch64)
++		# Host: NetBSD/aarch64
++		NATDEPFILES="${NATDEPFILES} aarch64-nbsd-nat.o"
++		;;
+ 	    alpha)
+ 		# Host: NetBSD/alpha
+-		NATDEPFILES="${NATDEPFILES} alpha-bsd-nat.o bsd-kvm.o"
+-		LOADLIBES='-lkvm'
++		NATDEPFILES="${NATDEPFILES} alpha-bsd-nat.o"
+ 		;;
+ 	    mips)
+ 		# Host: NetBSD/mips
+@@ -341,12 +346,11 @@ case ${gdb_host} in
+ 		;;
+ 	    pa)
+ 		# Host: NetBSD/hppa
+-		NATDEPFILES="${NATDEPFILES} nbsd-nat.o hppa-nbsd-nat.o"
++		NATDEPFILES="${NATDEPFILES} hppa-nbsd-nat.o"
+ 		;;
+ 	    powerpc)
+ 		# Host: NetBSD/powerpc
+-		NATDEPFILES="${NATDEPFILES} ppc-nbsd-nat.o bsd-kvm.o"
+-		LOADLIBES='-lkvm'
++		NATDEPFILES="${NATDEPFILES} ppc-nbsd-nat.o"
+ 		;;
+ 	    sh)
+ 		# Host: NetBSD/sh
+@@ -356,22 +360,24 @@ case ${gdb_host} in
+ 	esac
+ 	;;
+     nbsd64)
++	NATDEPFILES="${NATDEPFILES} nbsd-nat.o bsd-kvm.o"
++	LOADLIBES='-lkvm'
+ 	case ${gdb_host_cpu} in
+ 	    i386)
+ 		# Host: NetBSD/amd64
+-		NATDEPFILES="${NATDEPFILES} nbsd-nat.o amd64-nat.o x86-nat.o \
+-		nat/x86-dregs.o x86-bsd-nat.o amd64-bsd-nat.o amd64-nbsd-nat.o"
++		NATDEPFILES="${NATDEPFILES} amd64-nbsd-nat.o amd64-bsd-nat.o \
++		amd64-nat.o x86-bsd-nat.o x86-nat.o nat/x86-dregs.o"
+ 		;;
+ 	    sparc)
+ 		# Host: NetBSD/sparc64
+-		NATDEPFILES="${NATDEPFILES} sparc64-nbsd-nat.o sparc-nat.o \
+-		bsd-kvm.o"
+-		LOADLIBES='-lkvm'
++		NATDEPFILES="${NATDEPFILES} sparc64-nbsd-nat.o sparc-nat.o"
+ 		;;
+ 
+ 	esac
+ 	;;
+     nbsdelf)
++	NATDEPFILES="${NATDEPFILES} nbsd-nat.o bsd-kvm.o"
++	LOADLIBES='-lkvm'
+ 	case ${gdb_host_cpu} in
+ 	    arm)
+ 		# Host: NetBSD/arm
+@@ -379,26 +385,20 @@ case ${gdb_host} in
+ 		;;
+ 	    i386)
+ 		# Host: NetBSD/i386 ELF
+-		NATDEPFILES="${NATDEPFILES} nbsd-nat.o x86-nat.o \
+-		nat/x86-dregs.o \
+-		x86-bsd-nat.o i386-bsd-nat.o i386-nbsd-nat.o bsd-kvm.o"
+-		LOADLIBES='-lkvm'
++		NATDEPFILES="${NATDEPFILES} i386-nbsd-nat.o i386-bsd-nat.o \
++		x86-bsd-nat.o x86-nat.o nat/x86-dregs.o"
+ 		;;
+ 	    m68k)
+ 		# Host: NetBSD/m68k ELF
+-		NATDEPFILES="${NATDEPFILES} m68k-bsd-nat.o bsd-kvm.o"
+-		LOADLIBES='-lkvm'
++		NATDEPFILES="${NATDEPFILES} m68k-bsd-nat.o"
+ 		;;
+ 	    sparc)
+ 		# Host: NetBSD/sparc ELF
+-		NATDEPFILES="${NATDEPFILES} sparc-nat.o sparc-nbsd-nat.o \
+-		bsd-kvm.o"
+-		LOADLIBES='-lkvm'
++		NATDEPFILES="${NATDEPFILES} sparc-nat.o sparc-nbsd-nat.o"
+ 		;;
+ 	    vax)
+ 		# Host: NetBSD/vax ELF
+-		NATDEPFILES="${NATDEPFILES} vax-bsd-nat.o bsd-kvm.o"
+-		LOADLIBES='-lkvm'
++		NATDEPFILES="${NATDEPFILES} vax-bsd-nat.o"
+ 		;;
+ 
+ 	esac
diff --git a/gdb-netbsd-wip/patches/patch-gdb_configure.tgt b/gdb-netbsd-wip/patches/patch-gdb_configure.tgt
new file mode 100644
index 0000000000..b4d0e35b70
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_configure.tgt
@@ -0,0 +1,79 @@
+$NetBSD$
+
+--- gdb/configure.tgt.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/configure.tgt
+@@ -128,6 +128,16 @@ aarch64*-*-linux*)
+ 	build_gdbserver=yes
+ 	;;
+ 
++aarch64*-*-netbsd*)
++	# Target: AArch64 NetBSD
++	gdb_target_obs="aarch64-tdep.o aarch64-nbsd-tdep.o \
++			arch/aarch64-insn.o"
++	;;
++
++alpha*-*-osf*)
++	# Target: Little-endian Alpha running OSF/1
++	gdb_target_obs="alpha-tdep.o alpha-osf1-tdep.o alpha-mdebug-tdep.o"
++	;;
+ alpha*-*-linux*)
+ 	# Target: Little-endian Alpha running Linux
+ 	gdb_target_obs="alpha-mdebug-tdep.o alpha-linux-tdep.o \
+@@ -172,7 +182,7 @@ arm*-*-freebsd*)
+ 	;;
+ arm*-*-netbsd* | arm*-*-knetbsd*-gnu)
+ 	# Target: NetBSD/arm
+-	gdb_target_obs="arm-nbsd-tdep.o"
++	gdb_target_obs="arm-bsd-tdep.o arm-nbsd-tdep.o"
+ 	;;
+ arm*-*-openbsd*)
+ 	# Target: OpenBSD/arm
+@@ -246,11 +256,11 @@ hppa*-*-linux*)
+ 	;;
+ hppa*-*-netbsd*)
+ 	# Target: NetBSD/hppa
+-	gdb_target_obs="hppa-bsd-tdep.o hppa-nbsd-tdep.o solib-svr4.o"
++	gdb_target_obs="hppa-bsd-tdep.o hppa-nbsd-tdep.o"
+ 	;;
+ hppa*-*-openbsd*)
+ 	# Target: OpenBSD/hppa
+-	gdb_target_obs="hppa-bsd-tdep.o hppa-obsd-tdep.o solib-svr4.o"
++	gdb_target_obs="hppa-bsd-tdep.o hppa-obsd-tdep.o"
+ 	;;
+ 
+ i[34567]86-*-darwin*)
+@@ -380,7 +390,7 @@ m68*-*-linux*)
+ 			linux-tdep.o glibc-tdep.o symfile-mem.o"
+ 	build_gdbserver=yes
+ 	;;
+-m68*-*-netbsd* | m68*-*-knetbsd*-gnu)
++m68*-*-netbsd* | m68*-*-knetbsd*-gnu | m5407-*-netbsdelf*)
+ 	# Target: NetBSD/m68k
+ 	gdb_target_obs="m68k-tdep.o m68k-bsd-tdep.o"
+ 	;;
+@@ -492,7 +502,7 @@ powerpc*-*-freebsd*)
+ 			ravenscar-thread.o ppc-ravenscar-thread.o"
+ 	;;
+ 
+-powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
++powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu | powerpc64-*-netbsd*)
+ 	# Target: NetBSD/powerpc
+ 	gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc-nbsd-tdep.o \
+ 			ravenscar-thread.o ppc-ravenscar-thread.o"
+@@ -714,7 +724,7 @@ v850*-*-elf | v850*-*-rtems*)
+ 
+ vax-*-netbsd* | vax-*-knetbsd*-gnu)
+ 	# Target: NetBSD/vax
+-	gdb_target_obs="vax-tdep.o solib-svr4.o"
++	gdb_target_obs="vax-tdep.o"
+ 	;;
+ vax-*-openbsd*)
+ 	# Target: OpenBSD/vax
+@@ -762,6 +772,7 @@ x86_64-*-mingw* | x86_64-*-cygwin*)
+ x86_64-*-netbsd* | x86_64-*-knetbsd*-gnu)
+ 	# Target: NetBSD/amd64
+ 	gdb_target_obs="amd64-nbsd-tdep.o ${i386_tobjs}"
++	build_gdbserver=yes
+ 	;;
+ x86_64-*-openbsd*)
+ 	# Target: OpenBSD/amd64
diff --git a/gdb-netbsd-wip/patches/patch-gdb_gdbserver_Makefile.in b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_Makefile.in
new file mode 100644
index 0000000000..e5e6768ea4
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_Makefile.in
@@ -0,0 +1,12 @@
+$NetBSD$
+
+--- gdb/gdbserver/Makefile.in.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/gdbserver/Makefile.in
+@@ -179,6 +179,7 @@ SFILES = \
+ 	$(srcdir)/linux-x86-low.c \
+ 	$(srcdir)/linux-xtensa-low.c \
+ 	$(srcdir)/mem-break.c \
++	$(srcdir)/netbsd-low.c \
+ 	$(srcdir)/proc-service.c \
+ 	$(srcdir)/proc-service.list \
+ 	$(srcdir)/regcache.c \
diff --git a/gdb-netbsd-wip/patches/patch-gdb_gdbserver_configure.srv b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_configure.srv
new file mode 100644
index 0000000000..a7f03f5cf3
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_configure.srv
@@ -0,0 +1,27 @@
+$NetBSD$
+
+--- gdb/gdbserver/configure.srv.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/gdbserver/configure.srv
+@@ -30,6 +30,10 @@ ipa_ppc_linux_regobj="powerpc-32l-ipa.o 
+ # these files over and over again.
+ srv_linux_obj="linux-low.o linux-osdata.o linux-procfs.o linux-ptrace.o linux-waitpid.o linux-personality.o linux-namespaces.o fork-child.o fork-inferior.o"
+ 
++# NetBSD object files.  This is so we don't have to repeat
++# these files over and over again.
++srv_netbsd_obj="netbsd-low.o fork-child.o fork-inferior.o"
++
+ # Input is taken from the "${target}" variable.
+ 
+ case "${target}" in
+@@ -378,6 +382,11 @@ case "${target}" in
+ 			ipa_obj="linux-amd64-ipa.o linux-x86-tdesc-ipa.o"
+ 			ipa_obj="${ipa_obj} arch/amd64-ipa.o"
+ 			;;
++  x86_64-*-netbsd*)	srv_regobj=""
++			srv_tgtobj="netbsd-low.o netbsd-x86_64-low.o fork-child.o fork-inferior.o"
++			srv_tgtobj="${srv_tgtobj} arch/amd64.o"
++			srv_netbsd=yes
++			;;
+   x86_64-*-mingw*)	srv_regobj=""
+ 			srv_tgtobj="x86-low.o x86-dregs.o i387-fp.o win32-low.o win32-i386-low.o"
+ 			srv_tgtobj="${srv_tgtobj} arch/amd64.o"
diff --git a/gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-low.c b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-low.c
new file mode 100644
index 0000000000..df5ad2f4ca
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-low.c
@@ -0,0 +1,2089 @@
+$NetBSD$
+
+--- gdb/gdbserver/netbsd-low.c.orig	2019-09-02 20:02:23.503085722 +0000
++++ gdb/gdbserver/netbsd-low.c
+@@ -0,0 +1,2084 @@
++/* Copyright (C) 2019 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include "server.h"
++#include "target.h"
++#include "netbsd-low.h"
++
++#include <sys/param.h>
++#include <sys/types.h>
++
++#include <sys/ptrace.h>
++#include <sys/sysctl.h>
++
++#include <limits.h>
++#include <unistd.h>
++#include <signal.h>
++
++#include <elf.h>
++
++#include "gdbsupport/gdb_wait.h"
++#include "gdbsupport/filestuff.h"
++#include "gdbsupport/common-inferior.h"
++#include "nat/fork-inferior.h"
++#include "hostio.h"
++
++int using_threads = 1;
++
++const struct target_desc *netbsd_tdesc;
++
++/* Per-process private data.  */
++
++struct process_info_private
++{
++  /* The PTID obtained from the last wait performed on this process.
++     Initialized to null_ptid until the first wait is performed.  */
++  ptid_t last_wait_event_ptid;
++
++  /* &_r_debug.  0 if not yet determined.  -1 if no PT_DYNAMIC in Phdrs.  */
++  CORE_ADDR r_debug;
++};
++
++/* Print a debug trace on standard output if debug_threads is set.  */
++
++static void
++netbsd_debug (const char *string, ...)
++{
++  va_list args;
++
++  if (!debug_threads)
++    return;
++
++  va_start (args, string);
++  fprintf (stderr, "[pid=%d] DEBUG(netbsd): ", getpid());
++  vfprintf (stderr, string, args);
++  va_end (args);
++}
++
++/* Build a ptid_t given a PID and a NetBSD TID.  */
++
++static ptid_t
++netbsd_ptid_t (pid_t pid, lwpid_t tid)
++{
++  return ptid_t (pid, tid, 0);
++}
++
++/* Return a string image of the ptrace REQUEST number.  */
++
++static const char *
++ptrace_request_to_str (int request)
++{
++#define CASE(X) case X: return #X
++  switch (request)
++    {
++      CASE(PT_TRACE_ME);
++      CASE(PT_READ_I);
++      CASE(PT_READ_D);
++      CASE(PT_WRITE_I);
++      CASE(PT_WRITE_D);
++      CASE(PT_CONTINUE);
++      CASE(PT_KILL);
++      CASE(PT_ATTACH);
++      CASE(PT_DETACH);
++      CASE(PT_IO);
++      CASE(PT_DUMPCORE);
++      CASE(PT_LWPINFO);
++      CASE(PT_SYSCALL);
++      CASE(PT_SYSCALLEMU);
++      CASE(PT_SET_EVENT_MASK);
++      CASE(PT_GET_EVENT_MASK);
++      CASE(PT_GET_PROCESS_STATE);
++      CASE(PT_SET_SIGINFO);
++      CASE(PT_GET_SIGINFO);
++      CASE(PT_RESUME);
++      CASE(PT_SUSPEND);
++
++#ifdef PT_STEP
++      CASE(PT_STEP);
++#endif
++#ifdef PT_GETREGS
++      CASE(PT_GETREGS);
++#endif
++#ifdef PT_SETREGS
++      CASE(PT_SETREGS);
++#endif
++#ifdef PT_GETFPREGS
++      CASE(PT_GETFPREGS);
++#endif
++#ifdef PT_SETFPREGS
++      CASE(PT_SETFPREGS);
++#endif
++#ifdef PT_GETDBREGS
++      CASE(PT_GETDBREGS);
++#endif
++#ifdef PT_SETDBREGS
++      CASE(PT_SETDBREGS);
++#endif
++#ifdef PT_SETSTEP
++      CASE(PT_SETSTEP);
++#endif
++#ifdef PT_CLEARSTEP
++      CASE(PT_CLEARSTEP);
++#endif
++#ifdef PT_GETXSTATE
++      CASE(PT_GETXSTATE);
++#endif
++#ifdef PT_SETXSTATE
++      CASE(PT_SETXSTATE);
++#endif
++#ifdef PT_GETXMMREGS
++      CASE(PT_GETXMMREGS);
++#endif
++#ifdef PT_SETXMMREGS
++      CASE(PT_SETXMMREGS);
++#endif
++#ifdef PT_GETVECREGS
++      CASE(PT_GETVECREGS);
++#endif
++#ifdef PT_SETVECREGS
++      CASE(PT_SETVECREGS);
++#endif
++    }
++#undef CASE
++
++  return "<unknown-request>";
++}
++
++static const char *
++ptrace_ptio_request_to_str (int request)
++{
++#define CASE(X) case X: return #X
++  switch (request)
++    {
++      CASE(PIOD_READ_D);
++      CASE(PIOD_WRITE_D);
++      CASE(PIOD_READ_I);
++      CASE(PIOD_WRITE_I);
++      CASE(PIOD_READ_AUXV);
++    }
++#undef CASE
++
++  return "<unknown-request>";
++}
++
++/* Return a string image of the ptrace REQUEST number.  */
++
++static const char *
++sigcode_to_str (int signo, int sigcode)
++{
++#define CASE(X) case X: return #X
++  switch (signo)
++    {
++      case SIGILL:
++      switch (sigcode)
++        {
++          CASE(ILL_ILLOPC);
++          CASE(ILL_ILLOPN);
++          CASE(ILL_ILLADR);
++          CASE(ILL_ILLTRP);
++          CASE(ILL_PRVOPC);
++          CASE(ILL_PRVREG);
++          CASE(ILL_COPROC);
++          CASE(ILL_BADSTK);
++        }
++        break;
++
++      case SIGFPE:
++      switch (sigcode)
++        {
++          CASE(FPE_INTDIV);
++          CASE(FPE_INTOVF);
++          CASE(FPE_FLTDIV);
++          CASE(FPE_FLTOVF);
++          CASE(FPE_FLTUND);
++          CASE(FPE_FLTRES);
++          CASE(FPE_FLTINV);
++          CASE(FPE_FLTSUB);
++        }
++        break;
++
++      case SIGSEGV:
++      switch (sigcode)
++        {
++          CASE(SEGV_MAPERR);
++          CASE(SEGV_ACCERR);
++        }
++        break;
++
++      case SIGBUS:
++      switch (sigcode)
++        {
++          CASE(BUS_ADRALN);
++          CASE(BUS_ADRERR);
++          CASE(BUS_OBJERR);
++        }
++        break;
++
++      case SIGTRAP:
++      switch (sigcode)
++        {
++          CASE(TRAP_BRKPT);
++          CASE(TRAP_TRACE);
++          CASE(TRAP_EXEC);
++          CASE(TRAP_CHLD);
++          CASE(TRAP_LWP);
++          CASE(TRAP_DBREG);
++          CASE(TRAP_SCE);
++          CASE(TRAP_SCX);
++        }
++        break;
++
++      case SIGCHLD:
++      switch (sigcode)
++        {
++          CASE(CLD_EXITED);
++          CASE(CLD_KILLED);
++          CASE(CLD_DUMPED);
++          CASE(CLD_TRAPPED);
++          CASE(CLD_STOPPED);
++          CASE(CLD_CONTINUED);
++        }
++        break;
++
++      case SIGIO:
++      switch (sigcode)
++        {
++          CASE(POLL_IN);
++          CASE(POLL_OUT);
++          CASE(POLL_MSG);
++          CASE(POLL_ERR);
++          CASE(POLL_PRI);
++          CASE(POLL_HUP);
++        }
++        break;
++    }
++
++  switch (sigcode)
++    {
++      CASE(SI_USER);
++      CASE(SI_QUEUE);
++      CASE(SI_TIMER);
++      CASE(SI_ASYNCIO);
++      CASE(SI_MESGQ);
++      CASE(SI_LWP);
++      CASE(SI_NOINFO);
++    }
++#undef CASE
++
++  return "<unknown-sigcode>";
++}
++
++/* A wrapper around waitpid that handles the various idiosyncrasies
++   of NetBSD waitpid.  */
++
++static int
++netbsd_waitpid (int pid, int *stat_loc, int options)
++{
++  int ret;
++
++  do
++    {
++      ret = waitpid (pid, stat_loc, options);
++    }
++  while (ret == -1 && errno == EINTR);
++
++  return ret;
++}
++
++static const char *
++netbsd_wait_kind_to_str (int kind)
++{
++#define CASE(X) case X: return #X
++  switch (kind)
++    {
++      CASE(TARGET_WAITKIND_EXITED);
++      CASE(TARGET_WAITKIND_STOPPED);
++      CASE(TARGET_WAITKIND_SIGNALLED);
++      CASE(TARGET_WAITKIND_LOADED);
++      CASE(TARGET_WAITKIND_FORKED);
++      CASE(TARGET_WAITKIND_VFORKED);
++      CASE(TARGET_WAITKIND_EXECD);
++      CASE(TARGET_WAITKIND_VFORK_DONE);
++      CASE(TARGET_WAITKIND_SYSCALL_ENTRY);
++      CASE(TARGET_WAITKIND_SYSCALL_RETURN);
++      CASE(TARGET_WAITKIND_IGNORE);
++      CASE(TARGET_WAITKIND_NO_HISTORY);
++      CASE(TARGET_WAITKIND_NO_RESUMED);
++      CASE(TARGET_WAITKIND_THREAD_CREATED);
++      CASE(TARGET_WAITKIND_THREAD_EXITED);
++    }
++#undef CASE
++
++  return "<unknown-request>";
++}
++
++/* A wrapper around ptrace that allows us to print debug traces of
++   ptrace calls if debug traces are activated.  */
++
++static int
++netbsd_ptrace (int request, pid_t pid, void *addr, int data)
++{
++  int result;
++  int saved_errno;
++
++  netbsd_debug ("PTRACE (%s, pid=%d, addr=%p, data=%#x)\n",
++              ptrace_request_to_str (request), pid, addr, data);
++
++  if (request == PT_IO)
++    {
++      struct ptrace_io_desc *pio = (struct ptrace_io_desc *)addr;
++      netbsd_debug (":: { .piod_op=%s, .piod_offs=%p, .piod_addr=%p, "
++                    ".piod_len=%zu }\n",
++                    ptrace_ptio_request_to_str (pio->piod_op),
++                    pio->piod_offs, pio->piod_addr, pio->piod_len);
++      if (pio->piod_op == PT_WRITE_I || pio->piod_op == PT_WRITE_D)
++        {
++          for (size_t i = 0; i < pio->piod_len; i++)
++            netbsd_debug (" :: [%02zu] = %#02x\n", i, (unsigned char)((char *)pio->piod_addr)[i]);
++        }
++    }
++
++  saved_errno = errno;
++  errno = 0;
++  result = ptrace (request, pid, addr, data);
++
++  netbsd_debug (" -> %d (=%#x errno=%d)\n", result, result, errno);
++  if (request == PT_IO)
++    {
++      struct ptrace_io_desc *pio = (struct ptrace_io_desc *)addr;
++      netbsd_debug (" -> :: { .piod_op=%s, .piod_offs=%p, .piod_addr=%p, "
++                    ".piod_len=%zu }\n",
++                    ptrace_ptio_request_to_str (pio->piod_op),
++                    pio->piod_offs, pio->piod_addr, pio->piod_len);
++      if (pio->piod_op == PT_READ_I || pio->piod_op == PT_READ_D)
++        {
++          for (size_t i = 0; i < pio->piod_len; i++)
++            netbsd_debug (" :: [%02zu] = %#02x\n", i, (unsigned char)((char *)pio->piod_addr)[i]);
++        }
++    }
++
++  errno = saved_errno;
++  return result;
++}
++
++/* A wrapper around ptrace that allows us to print debug traces of
++   ptrace calls if debug traces are activated.  */
++
++static int
++netbsd_sysctl (const int *name, u_int namelen, void *oldp, size_t *oldlenp,
++  const void *newp, size_t newlen)
++{
++  int result;
++
++  gdb_assert(name);
++  gdb_assert(namelen > 0);
++
++  std::string str = "[" + std::to_string(name[0]);
++  for (u_int i = 1; i < namelen; i++)
++    str += ", " + std::to_string(name[i]);
++  str += "]";
++
++  netbsd_debug ("SYSCTL (name=%s, namelen=%u, oldp=%p, oldlenp=%p, newp=%p, "
++                "newlen=%zu)\n",
++                str.c_str(), namelen, oldp, oldlenp, newp, newlen);
++  result = sysctl(name, namelen, oldp, oldlenp, newp, newlen);
++
++  netbsd_debug (" -> %d (=%#x errno=%d)\n", result, result, errno);
++
++  return result;
++}
++
++/* Call add_process with the given parameters, and initializes
++   the process' private data.  */
++
++static struct process_info *
++netbsd_add_process (int pid, int attached)
++{
++  struct process_info *proc;
++
++  proc = add_process (pid, attached);
++  proc->tdesc = netbsd_tdesc;
++  proc->priv = XCNEW (struct process_info_private);
++  proc->priv->last_wait_event_ptid = null_ptid;
++
++  return proc;
++}
++
++/* Callback used by fork_inferior to start tracing the inferior.  */
++
++static void
++netbsd_ptrace_fun ()
++{
++  /* Switch child to its own process group so that signals won't
++     directly affect GDBserver. */
++  if (setpgid (0, 0) < 0)
++    trace_start_error_with_name ("setpgid");
++
++  if (netbsd_ptrace (PT_TRACE_ME, 0, NULL, 0) < 0)
++    trace_start_error_with_name ("netbsd_ptrace");
++
++  /* If GDBserver is connected to gdb via stdio, redirect the inferior's
++     stdout to stderr so that inferior i/o doesn't corrupt the connection.
++     Also, redirect stdin to /dev/null.  */
++  if (remote_connection_is_stdio ())
++    {
++      if (close (0) < 0)
++        trace_start_error_with_name ("close");
++      if (open ("/dev/null", O_RDONLY) < 0)
++        trace_start_error_with_name ("open");
++      if (dup2 (2, 1) < 0)
++        trace_start_error_with_name ("dup2");
++      if (write (2, "stdin/stdout redirected\n",
++                 sizeof ("stdin/stdout redirected\n") - 1) < 0)
++        {
++          /* Errors ignored.  */;
++        }
++    }
++}
++
++static void
++netbsd_add_threads_sysctl (pid_t pid)
++{
++  struct kinfo_lwp *kl;
++  int mib[5];
++  size_t i, nlwps;
++  size_t size;
++
++  mib[0] = CTL_KERN;
++  mib[1] = KERN_LWP;
++  mib[2] = pid;
++  mib[3] = sizeof(struct kinfo_lwp);
++  mib[4] = 0;
++
++  if (netbsd_sysctl (mib, 5, NULL, &size, NULL, 0) == -1 || size == 0)
++    trace_start_error_with_name ("sysctl");
++
++  mib[4] = size / sizeof(size_t);
++
++  kl = (struct kinfo_lwp *) xmalloc (size);
++  if (kl == NULL)
++    trace_start_error_with_name ("malloc");
++
++  if (netbsd_sysctl (mib, 5, kl, &size, NULL, 0) == -1 || size == 0)
++    trace_start_error_with_name ("sysctl");
++
++  nlwps = size / sizeof(struct kinfo_lwp);
++
++  for (i = 0; i < nlwps; i++) {
++    ptid_t ptid = netbsd_ptid_t (pid, kl[i].l_lid);
++    netbsd_debug ("Registering thread (pid=%d, lwpid=%d)\n", pid, kl[i].l_lid);
++    add_thread (ptid, NULL);
++  }
++
++  xfree(kl);
++}
++
++static void
++netbsd_wait_stopped_noreap (pid_t pid)
++{
++  int status;
++
++  gdb_assert (pid > 0);
++
++repeat:
++  pid_t wpid = netbsd_waitpid (pid, &status, WNOWAIT);
++
++  if (wpid == -1 || wpid != pid)
++    internal_error (__FILE__, __LINE__, _("unexpected waitpid return value %d"), wpid);
++
++  if (WIFSTOPPED (status))
++    return;
++
++  if (WIFSIGNALED (status) || WIFEXITED (status))
++    internal_error (__FILE__, __LINE__, _("tracee died"));
++
++  // Should not happen
++  if (WIFCONTINUED (status))
++    goto repeat;
++
++  __unreachable();
++}
++
++/* Assuming we've just attached to a stopped and waited inferior whose pid is PID */
++
++static void
++netbsd_add_threads_after_attach (pid_t pid)
++{
++  struct ptrace_lwpinfo pl;
++
++  pl.pl_lwpid = 0;
++  while (netbsd_ptrace(PT_LWPINFO, pid, (void *)&pl, sizeof(pl)) != -1 &&
++    pl.pl_lwpid != 0)
++    {
++      ptid_t thread_ptid = netbsd_ptid_t (pid, pl.pl_lwpid);
++
++      if (!find_thread_ptid (thread_ptid))
++	{
++	  netbsd_debug ("New thread: (pid = %d, tid = %d)\n",
++		      pid, pl.pl_lwpid);
++	  add_thread (thread_ptid, NULL);
++	}
++    }
++}
++
++/* Implement the create_inferior method of the target_ops vector.  */
++
++static int
++netbsd_create_inferior (const char *program,
++		      const std::vector<char *> &program_args)
++{
++  pid_t pid;
++  std::string str_program_args = stringify_argv (program_args);
++
++  netbsd_debug ("%s(program='%s', args=%s)\n",
++                __func__, program, str_program_args.c_str());
++
++  pid = fork_inferior (program,
++		       str_program_args.c_str (),
++		       get_environ ()->envp (), netbsd_ptrace_fun,
++		       NULL, NULL, NULL, NULL);
++
++  netbsd_add_process (pid, 0);
++
++  netbsd_wait_stopped_noreap (pid);
++
++  netbsd_add_threads_sysctl (pid);
++
++  post_fork_inferior (pid, program);
++
++  return pid;
++}
++
++/* Implement the attach target_ops method.  */
++
++static int
++netbsd_attach (unsigned long pid)
++{
++
++  netbsd_debug ("%s(pid=%d)\n", __func__, pid);
++
++  if (netbsd_ptrace (PT_ATTACH, pid, NULL, 0) != 0)
++    error ("Cannot attach to process %lu: %s (%d)\n", pid,
++	   strerror (errno), errno);
++
++  netbsd_add_process (pid, 1);
++  netbsd_add_threads_after_attach (pid);
++
++  return 0;
++}
++
++#if 0
++/* Resume the execution of the given PTID.  */
++
++static void
++netbsd_continue (ptid_t ptid)
++{
++  struct thread_resume resume_info;
++
++  resume_info.thread = ptid;
++  resume_info.kind = resume_continue;
++  resume_info.sig = 0;
++
++  netbsd_resume (&resume_info, 1);
++}
++#endif
++
++/* Implement the resume target_ops method.  */
++
++static void
++netbsd_resume (struct thread_resume *resume_info, size_t n)
++{
++
++  netbsd_debug ("%s()\n", __func__);
++
++  ptid_t ptid = resume_info[0].thread;
++  const int signal = resume_info[0].sig;
++
++  if (ptid == minus_one_ptid)
++    ptid = ptid_of (current_thread);
++
++  regcache_invalidate_pid (ptid.pid ());
++
++  if (resume_info[0].kind == resume_step)
++    {
++      if (n == 1)
++        {
++          struct ptrace_lwpinfo pl;
++          int val;
++          pl.pl_lwpid = 0;
++          while ((val = netbsd_ptrace(PT_LWPINFO, ptid.pid(), (void *)&pl,
++            sizeof(pl))) != -1 && pl.pl_lwpid != 0)
++           {
++              if (pl.pl_lwpid == ptid.lwp())
++                {
++                  netbsd_ptrace (PT_SETSTEP, ptid.pid(), NULL, pl.pl_lwpid);
++                  netbsd_ptrace (PT_RESUME, ptid.pid(), NULL, pl.pl_lwpid);
++                }
++              else
++                {
++                  netbsd_ptrace (PT_CLEARSTEP, ptid.pid(), NULL, pl.pl_lwpid);
++                  netbsd_ptrace (PT_SUSPEND, ptid.pid(), NULL, pl.pl_lwpid);
++                }
++           }
++        }
++      else
++        {
++          struct ptrace_lwpinfo pl;
++          int val;
++          pl.pl_lwpid = 0;
++          while ((val = netbsd_ptrace(PT_LWPINFO, ptid.pid(), (void *)&pl,
++            sizeof(pl))) != -1 && pl.pl_lwpid != 0)
++           {
++              netbsd_ptrace (PT_SETSTEP, ptid.pid(), NULL, pl.pl_lwpid);
++              netbsd_ptrace (PT_RESUME, ptid.pid(), NULL, pl.pl_lwpid);
++           }
++        }
++    }
++  else
++    {
++      struct ptrace_lwpinfo pl;
++      int val;
++      pl.pl_lwpid = 0;
++      while ((val = netbsd_ptrace(PT_LWPINFO, ptid.pid(), (void *)&pl, sizeof(pl))) != -1 &&
++        pl.pl_lwpid != 0)
++        {
++          netbsd_ptrace (PT_CLEARSTEP, ptid.pid(), NULL, pl.pl_lwpid);
++          netbsd_ptrace (PT_RESUME, ptid.pid(), NULL, pl.pl_lwpid);
++        }
++    }
++
++  errno = 0;
++  netbsd_ptrace (PT_CONTINUE, ptid.pid(), (void *)1, signal);
++  if (errno)
++    perror_with_name ("ptrace");
++}
++
++static char *
++pid_to_exec_file (pid_t pid)
++{
++  static const int name[] = {
++    CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_PATHNAME,
++  };
++  static char path[MAXPATHLEN];
++  size_t len;
++
++  len = sizeof(path);
++  if (netbsd_sysctl (name, __arraycount(name), path, &len, NULL, 0) == -1)
++    return NULL;
++
++  return path;
++}
++
++static void
++netbsd_enable_event_reporting (pid_t pid)
++{
++  ptrace_event_t event;
++
++  ptrace (PT_GET_EVENT_MASK, pid, &event, sizeof(event));
++
++  event.pe_set_event |= PTRACE_FORK;
++  event.pe_set_event |= PTRACE_VFORK;
++  event.pe_set_event |= PTRACE_VFORK_DONE;
++  event.pe_set_event |= PTRACE_LWP_CREATE;
++  event.pe_set_event |= PTRACE_LWP_EXIT;
++  event.pe_set_event |= PTRACE_POSIX_SPAWN;
++
++  netbsd_ptrace (PT_SET_EVENT_MASK, pid, &event, sizeof(event));
++}
++
++/* Implement the wait target_ops method.  */
++
++static ptid_t
++netbsd_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, int target_options)
++{
++  pid_t pid;
++  int status;
++
++  if (ptid == minus_one_ptid)
++    ptid = ptid_of (current_thread);
++
++  pid = ptid.pid();
++
++  int options = 0;
++  if (target_options & TARGET_WNOHANG)
++    options |= WNOHANG;
++
++  pid_t wpid = netbsd_waitpid (pid, &status, options);
++
++  if (wpid == 0)
++    {
++      gdb_assert (target_options & TARGET_WNOHANG);
++      ourstatus->kind = TARGET_WAITKIND_IGNORE;
++      return null_ptid;
++    }
++
++  gdb_assert (wpid != -1);
++
++  if (WIFEXITED (status))
++    {
++      ourstatus->kind = TARGET_WAITKIND_EXITED;
++      ourstatus->value.integer = WEXITSTATUS (status);
++      return ptid;
++    }
++
++  if (WIFSIGNALED (status))
++    {
++      ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
++      ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (status));
++      return ptid;
++    }
++
++  if (WIFCONTINUED(status))
++    {
++      ourstatus->kind = TARGET_WAITKIND_IGNORE;
++      return null_ptid;
++    }
++
++
++  if (WIFSTOPPED (status))
++    {
++      ptrace_state_t pst;
++      ptrace_siginfo_t psi, child_psi;
++      pid_t child, wchild;
++      ptid_t child_ptid;
++      lwpid_t lwp;
++
++      {
++        struct process_info *proc;
++
++      /* Architecture-specific setup after inferior is running.  */
++      proc = find_process_pid (wpid);
++      if (proc->tdesc == NULL)
++        {
++              /* This needs to happen after we have attached to the
++                 inferior and it is stopped for the first time, but
++                 before we access any inferior registers.  */
++              the_low_target.arch_setup ();
++        }
++      }
++
++      ourstatus->kind = TARGET_WAITKIND_STOPPED;
++      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (status));
++
++      // Find the lwp that caused the wait status change
++      if (netbsd_ptrace (PT_GET_SIGINFO, wpid, &psi, sizeof(psi)) == -1)
++        perror_with_name (("ptrace"));
++
++      /* For whole-process signals pick random thread */
++      if (psi.psi_lwpid == 0)
++        {
++          // XXX: Is this always valid?
++          lwp = lwpid_of (current_thread);
++        }
++      else
++        {
++          lwp = psi.psi_lwpid;
++        }
++
++      ptid_t wptid = netbsd_ptid_t (wpid, lwp);
++
++      if (!find_thread_ptid (wptid))
++        {
++          add_thread (wptid, NULL);
++        }
++
++      switch (psi.psi_siginfo.si_signo)
++        {
++        case SIGTRAP:
++          switch (psi.psi_siginfo.si_code)
++            {
++            case TRAP_BRKPT:
++#ifdef PTRACE_BREAKPOINT_ADJ
++              {
++                CORE_ADDR pc;
++                struct reg r;
++                netbsd_ptrace (PT_GETREGS, wpid, &r, psi.psi_lwpid);
++                pc = PTRACE_REG_PC (&r);
++                PTRACE_REG_SET_PC (&r, pc - PTRACE_BREAKPOINT_ADJ);
++                netbsd_ptrace (PT_SETREGS, wpid, &r, psi.psi_lwpid);
++              }
++#endif
++            case TRAP_DBREG:
++            case TRAP_TRACE:
++              /* These stop reasons return STOPPED and are distinguished later */
++              break;
++            case TRAP_SCE:
++              ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY;
++              ourstatus->value.syscall_number = psi.psi_siginfo.si_sysnum;
++              break;
++            case TRAP_SCX:
++              ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN;
++              ourstatus->value.syscall_number = psi.psi_siginfo.si_sysnum;
++              break;
++#if 0
++            case TRAP_EXEC:
++              ourstatus->kind = TARGET_WAITKIND_EXECD;
++              ourstatus->value.execd_pathname = xstrdup(pid_to_exec_file (wpid));
++              break;
++#endif
++            case TRAP_LWP:
++            case TRAP_CHLD:
++              if (netbsd_ptrace (PT_GET_PROCESS_STATE, wpid, &pst, sizeof(pst)) == -1)
++                perror_with_name (("ptrace"));
++              switch (pst.pe_report_event)
++                {
++                case PTRACE_FORK:
++                case PTRACE_VFORK:
++                  if (pst.pe_report_event == PTRACE_FORK)
++                    ourstatus->kind = TARGET_WAITKIND_FORKED;
++                  else
++                    ourstatus->kind = TARGET_WAITKIND_VFORKED;
++                  child = pst.pe_other_pid;
++
++                  wchild = netbsd_waitpid (child, &status, 0);
++
++                  if (wchild == -1)
++                    perror_with_name (("waitpid"));
++
++                  gdb_assert (wchild == child);
++
++                  if (!WIFSTOPPED(status))
++                    {
++                      /* Abnormal situation (SIGKILLed?).. bail out */
++                      ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
++                      return wptid;
++                    }
++
++                  if (netbsd_ptrace (PT_GET_SIGINFO, child, &child_psi, sizeof(child_psi)) == -1)
++                    perror_with_name (("ptrace"));
++
++                  if (child_psi.psi_siginfo.si_signo != SIGTRAP)
++                    {
++                      /* Abnormal situation.. bail out */
++                      ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
++                      return wptid;
++                    }
++
++                  if (child_psi.psi_siginfo.si_code != TRAP_CHLD)
++                    {
++                      /* Abnormal situation.. bail out */
++                      ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
++                      return wptid;
++                    }
++
++                  child_ptid = netbsd_ptid_t (child, child_psi.psi_lwpid);
++                  netbsd_enable_event_reporting (child_ptid.pid ());
++                  ourstatus->value.related_pid = child_ptid;
++                  break;
++                case PTRACE_VFORK_DONE:
++                  ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
++                  break;
++                case PTRACE_LWP_CREATE:
++                  wptid = netbsd_ptid_t (wpid, pst.pe_lwp);
++                  if (!find_thread_ptid (wptid))
++                    {
++                      add_thread (wptid, NULL);
++                    }
++                  ourstatus->kind = TARGET_WAITKIND_THREAD_CREATED;
++                  break;
++                case PTRACE_LWP_EXIT:
++                  wptid = netbsd_ptid_t (wpid, pst.pe_lwp);
++                  thread_info *thread = find_thread_ptid (wptid);
++                  if (!thread)
++                    {
++                      /* Dead child reported after attach? */
++                      ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
++                      return wptid;
++                    }
++                  remove_thread (thread);
++                  ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
++
++#if 0
++                  if (netbsd_ptrace (PT_CONTINUE, pid, (void *)1, 0) == -1)
++                    perror_with_name (("ptrace"));
++#endif
++                  break;
++                }
++              break;
++            }
++          break;
++        }
++      return wptid;
++    }
++
++  return null_ptid;
++}
++
++/* A wrapper around netbsd_wait_1 that also prints debug traces when
++   such debug traces have been activated.  */
++
++static ptid_t
++netbsd_wait (ptid_t ptid, struct target_waitstatus *status, int options)
++{
++  ptid_t new_ptid;
++
++  netbsd_debug ("%s (pid = %d, options=%s)\n", __func__,
++                ptid.pid(), options & TARGET_WNOHANG ? "WNOHANG" : "0" );
++  new_ptid = netbsd_wait_1 (ptid, status, options);
++  netbsd_debug ("          -> (pid=%d, status->kind = %s)\n",
++	        new_ptid.pid(), netbsd_wait_kind_to_str(status->kind));
++  if (status->kind == TARGET_WAITKIND_EXECD)
++    {
++        netbsd_debug ("          -> (execd_pathname='%s')\n",
++                      status->value.execd_pathname);
++    }
++
++  return new_ptid;
++}
++
++/* Implement the kill target_ops method.  */
++
++static int
++netbsd_kill (process_info *process)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  pid_t pid = process->pid;
++  ptid_t ptid = netbsd_ptid_t (pid, 0);
++  struct target_waitstatus status;
++
++  netbsd_ptrace (PT_KILL, pid, NULL, 0);
++  netbsd_wait (ptid, &status, 0);
++  the_target->mourn (process);
++  return 0;
++}
++
++/* Implement the detach target_ops method.  */
++
++static int
++netbsd_detach (process_info *process)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  pid_t pid = process->pid;
++
++  netbsd_ptrace (PT_DETACH, pid, (void *)1, 0);
++  the_target->mourn (process);
++  return 0;
++}
++
++/* Implement the mourn target_ops method.  */
++
++static void
++netbsd_mourn (struct process_info *proc)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  for_each_thread (proc->pid, remove_thread);
++
++  /* Free our private data.  */
++  free (proc->priv);
++  proc->priv = NULL;
++
++  remove_process (proc);
++}
++
++/* Implement the join target_ops method.  */
++
++static void
++netbsd_join (int pid)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  /* The PTRACE_DETACH is sufficient to detach from the process.
++     So no need to do anything extra.  */
++}
++
++/* Implement the thread_alive target_ops method.  */
++
++static int
++netbsd_thread_alive (ptid_t ptid)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  /* The list of threads is updated at the end of each wait, so it
++     should be up to date.  No need to re-fetch it.  */
++  return (find_thread_ptid (ptid) != NULL);
++}
++
++/* Implement the fetch_registers target_ops method.  */
++
++static void
++netbsd_fetch_registers (struct regcache *regcache, int regno)
++{
++  netbsd_debug ("%s(regno=%d)\n", __func__, regno);
++
++  struct netbsd_regset_info *regset = netbsd_target_regsets;
++  ptid_t inferior_ptid = ptid_of (current_thread);
++
++  while (regset->size >= 0)
++    {
++      char *buf;
++      int res;
++
++      buf = (char *)xmalloc (regset->size);
++      res = netbsd_ptrace (regset->get_request, inferior_ptid.pid(), buf, inferior_ptid.lwp());
++      if (res < 0)
++        perror ("ptrace");
++      regset->store_function (regcache, buf);
++      free (buf);
++      regset++;
++    }
++}
++
++/* Implement the store_registers target_ops method.  */
++
++static void
++netbsd_store_registers (struct regcache *regcache, int regno)
++{
++  netbsd_debug ("%s(regno=%d)\n", __func__, regno);
++
++  struct netbsd_regset_info *regset = netbsd_target_regsets;
++  ptid_t inferior_ptid = ptid_of (current_thread);
++
++  while (regset->size >= 0)
++    {
++      char *buf;
++      int res;
++
++      buf = (char *)xmalloc (regset->size);
++      res = netbsd_ptrace (regset->get_request, inferior_ptid.pid(), buf, inferior_ptid.lwp());
++      if (res == 0)
++        {
++	  /* Then overlay our cached registers on that.  */
++	  regset->fill_function (regcache, buf);
++	  /* Only now do we write the register set.  */
++	  res = netbsd_ptrace (regset->set_request, inferior_ptid.pid(), buf, inferior_ptid.lwp());
++        }
++      if (res < 0)
++        perror ("ptrace");
++      free (buf);
++      regset++;
++    }
++}
++
++/* Implement the read_memory target_ops method.  */
++
++static int
++netbsd_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int size)
++{
++  netbsd_debug ("%s(memaddr=%p, myaddr=%p, size=%d)\n",
++                __func__, memaddr, myaddr, size);
++
++  struct ptrace_io_desc io;
++  io.piod_op = PIOD_READ_D;
++  io.piod_len = size;
++
++  ptid_t inferior_ptid = ptid_of (current_thread);
++
++  int bytes_read = 0;
++
++  if (size == 0)
++    {
++      /* Zero length write always succeeds.  */
++      return 0;
++    }
++  do
++    {
++      io.piod_offs = (void *)(memaddr + bytes_read);
++      io.piod_addr = myaddr + bytes_read;
++
++      int rv = netbsd_ptrace (PT_IO, inferior_ptid.pid(), &io, 0);
++      if (rv == -1)
++        return errno;
++      if (io.piod_len == 0)
++        return 0;
++
++      bytes_read += io.piod_len;
++      io.piod_len = size - bytes_read;
++    }
++  while (bytes_read < size);
++
++  return 0;
++}
++
++/* Implement the write_memory target_ops method.  */
++
++static int
++netbsd_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int size)
++{
++  netbsd_debug ("%s(memaddr=%p, myaddr=%p, size=%d)\n",
++                __func__, memaddr, myaddr, size);
++
++  struct ptrace_io_desc io;
++  io.piod_op = PIOD_WRITE_D;
++  io.piod_len = size;
++
++  ptid_t inferior_ptid = ptid_of (current_thread);
++
++  int bytes_written = 0;
++
++  if (size == 0)
++    {
++      /* Zero length write always succeeds.  */
++      return 0;
++    }
++
++  do
++    {
++      io.piod_addr = (void *)(myaddr + bytes_written);
++      io.piod_offs = (void *)(memaddr + bytes_written);
++
++      int rv = netbsd_ptrace (PT_IO, inferior_ptid.pid(), &io, 0);
++      if (rv == -1)
++        return errno;
++      if (io.piod_len == 0)
++        return 0;
++
++      bytes_written += io.piod_len;
++      io.piod_len = size - bytes_written;
++    }
++  while (bytes_written < size);
++
++  return 0;
++}
++
++/* Implement the kill_request target_ops method.  */
++
++static void
++netbsd_request_interrupt (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  ptid_t inferior_ptid = ptid_of (get_first_thread ());
++
++  kill (inferior_ptid.pid(), SIGINT);
++}
++
++/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
++   to debugger memory starting at MYADDR.  */
++
++static int
++netbsd_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
++{
++  netbsd_debug ("%s(offset=%p, myaddr=%p, size=%u)\n",
++                __func__, offset, myaddr, len);
++
++  struct ptrace_io_desc pio;
++  pid_t pid = pid_of (current_thread);
++
++  pio.piod_op = PIOD_READ_AUXV;
++  pio.piod_offs = (void *)(intptr_t)offset;
++  pio.piod_addr = myaddr;
++  pio.piod_len = len;
++
++  if (netbsd_ptrace (PT_IO, pid, &pio, 0) == -1)
++    return 0;
++
++  return pio.piod_len;
++}
++
++static int
++netbsd_supports_z_point_type (char z_type)
++{
++  netbsd_debug ("%s(z_type='%c')\n", __func__, z_type);
++
++  switch (z_type)
++    {
++    case Z_PACKET_SW_BP:
++#if 0
++    case Z_PACKET_HW_BP:
++    case Z_PACKET_WRITE_WP:
++    case Z_PACKET_READ_WP:
++    case Z_PACKET_ACCESS_WP:
++#endif
++      return 1;
++    default:
++      return 0;
++    }
++}
++
++/* Insert {break/watch}point at address ADDR.  SIZE is not used.  */
++
++static int
++netbsd_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
++                     int size, struct raw_breakpoint *bp)
++{
++  netbsd_debug ("%s type:%#x addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size);
++
++  switch (type)
++    {
++    case raw_bkpt_type_sw:
++      return insert_memory_breakpoint (bp);
++    case raw_bkpt_type_hw:
++    case raw_bkpt_type_write_wp:
++    case raw_bkpt_type_read_wp:
++    case raw_bkpt_type_access_wp:
++    default:
++      return 1; /* Not supported.  */
++    }
++}
++
++/* Remove {break/watch}point at address ADDR.  SIZE is not used.  */
++
++static int
++netbsd_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
++                     int size, struct raw_breakpoint *bp)
++{
++  netbsd_debug ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size);
++
++  switch (type)
++    {
++    case raw_bkpt_type_sw:
++      return remove_memory_breakpoint (bp);
++    case raw_bkpt_type_hw:
++    case raw_bkpt_type_write_wp:
++    case raw_bkpt_type_read_wp:
++    case raw_bkpt_type_access_wp:
++    default:
++      return 1; /* Not supported.  */
++    }
++}
++
++/* Implement the to_stopped_by_sw_breakpoint target_ops
++   method.  */
++
++static int
++netbsd_stopped_by_sw_breakpoint (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  ptrace_siginfo_t psi;
++  pid_t pid = pid_of (current_thread);
++
++  if (netbsd_ptrace (PT_GET_SIGINFO, pid, &psi, sizeof(psi)) == -1)
++    return -1; // XXX
++
++  netbsd_debug (" -> psi_lwpid = %d, psi_siginfo.si_signo=SIG%s, "
++                "psi_siginfo.si_code=%s\n", psi.psi_lwpid,
++                signalname(psi.psi_siginfo.si_signo),
++                sigcode_to_str(psi.psi_siginfo.si_signo, psi.psi_siginfo.si_code));
++
++  return psi.psi_siginfo.si_signo == SIGTRAP &&
++         psi.psi_siginfo.si_code == TRAP_BRKPT;
++}
++
++/* Implement the to_supports_stopped_by_sw_breakpoint target_ops
++   method.  */
++
++static int
++netbsd_supports_stopped_by_sw_breakpoint (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  return 1;
++}
++
++static int
++netbsd_qxfer_siginfo (const char *annex, unsigned char *readbuf,
++                     unsigned const char *writebuf, CORE_ADDR offset, int len)
++{
++  netbsd_debug ("%s(annex=%p, readbuf=%p, writebuf=%p, offset=%p len=%d)\n",
++                __func__, annex, readbuf, writebuf, offset, len);
++
++  if (current_thread == NULL)
++    return -1;
++
++  pid_t pid = pid_of (current_thread);
++
++  netbsd_debug ("%s siginfo for lwp %d.\n",
++                readbuf != NULL ? "Reading" : "Writing",
++                pid);
++
++  if (offset >= sizeof (siginfo))
++    return -1;
++
++  struct ptrace_siginfo psi;
++  if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof(psi)) != 0)
++    return -1;
++
++  if (offset + len > sizeof (siginfo))
++    len = sizeof (siginfo) - offset;
++
++  if (readbuf != NULL)
++    memcpy (readbuf, (char *)&psi.psi_siginfo + offset, len);
++  else
++    {
++      memcpy ((char *)&psi.psi_siginfo + offset, writebuf, len);
++
++      if (ptrace (PT_SET_SIGINFO, pid, &psi, sizeof(psi)) != 0)
++        return -1;
++    }
++
++  return len;
++}
++
++static int
++netbsd_supports_non_stop (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  return 0;
++}
++
++static int
++netbsd_supports_multi_process (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  return 0; /* XXX */
++}
++
++/* Check if fork events are supported.  */
++
++static int
++netbsd_supports_fork_events (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  return 1;
++}
++
++/* Check if vfork events are supported.  */
++
++static int
++netbsd_supports_vfork_events (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  return 1;
++}
++
++/* Check if exec events are supported.  */
++
++static int
++netbsd_supports_exec_events (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  return 1;
++}
++
++static int
++netbsd_supports_disable_randomization (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  return 0;
++}
++
++/* Extract &phdr and num_phdr in the inferior.  Return 0 on success.  */
++
++static int
++get_phdr_phnum_from_proc_auxv (const int pid, const int is_elf64,
++                               CORE_ADDR *phdr_memaddr, int *num_phdr)
++{
++  struct ptrace_io_desc pio;
++  const int auxv_size = is_elf64
++    ? sizeof (Aux64Info) : sizeof (Aux32Info);
++  char *auxv_buf;
++  char *buf;
++  const size_t auxv_buf_size = 100 * sizeof(Aux64Info);
++
++  auxv_buf = (char *)xmalloc(auxv_buf_size);
++
++  pio.piod_op = PIOD_READ_AUXV;
++  pio.piod_offs = 0;
++  pio.piod_addr = auxv_buf;
++  pio.piod_len = auxv_buf_size;
++
++  netbsd_ptrace (PT_IO, pid, &pio, 0);
++
++  *phdr_memaddr = 0;
++  *num_phdr = 0;
++
++  for (buf = auxv_buf; buf < (auxv_buf + auxv_buf_size); buf += auxv_size)
++    {
++      if (is_elf64)
++        {
++          Aux64Info *const aux = (Aux64Info *) buf;
++
++          switch (aux->a_type)
++            {
++            case AT_PHDR:
++              *phdr_memaddr = aux->a_v;
++              break;
++            case AT_PHNUM:
++              *num_phdr = aux->a_v;
++              break;
++            }
++        }
++      else
++        {
++          Aux32Info *const aux = (Aux32Info *) buf;
++
++          switch (aux->a_type)
++            {
++            case AT_PHDR:
++              *phdr_memaddr = aux->a_v;
++              break;
++            case AT_PHNUM:
++              *num_phdr = aux->a_v;
++              break;
++            }
++        }
++
++      if (*phdr_memaddr != 0 && *num_phdr != 0)
++        break;
++    }
++
++  xfree (auxv_buf);
++
++  if (*phdr_memaddr == 0 || *num_phdr == 0)
++    {
++      warning ("Unexpected missing AT_PHDR and/or AT_PHNUM: "
++               "phdr_memaddr = %ld, phdr_num = %d",
++               (long) *phdr_memaddr, *num_phdr);
++      return 2;
++    }
++
++  return 0;
++}
++
++/* Return &_DYNAMIC (via PT_DYNAMIC) in the inferior, or 0 if not present.  */
++
++static CORE_ADDR
++get_dynamic (const int pid, const int is_elf64)
++{
++  CORE_ADDR phdr_memaddr, relocation;
++  int num_phdr, i;
++  unsigned char *phdr_buf;
++  const int phdr_size = is_elf64 ? sizeof (Elf64_Phdr) : sizeof (Elf32_Phdr);
++
++  if (get_phdr_phnum_from_proc_auxv (pid, is_elf64, &phdr_memaddr, &num_phdr))
++    return 0;
++
++  gdb_assert (num_phdr < 100);  /* Basic sanity check.  */
++  phdr_buf = (unsigned char *) alloca (num_phdr * phdr_size);
++
++  if (netbsd_read_memory (phdr_memaddr, phdr_buf, num_phdr * phdr_size))
++    return 0;
++
++  /* Compute relocation: it is expected to be 0 for "regular" executables,
++     non-zero for PIE ones.  */
++  relocation = -1;
++  for (i = 0; relocation == -1 && i < num_phdr; i++)
++    if (is_elf64)
++      {
++        Elf64_Phdr *const p = (Elf64_Phdr *) (phdr_buf + i * phdr_size);
++
++        if (p->p_type == PT_PHDR)
++          relocation = phdr_memaddr - p->p_vaddr;
++      }
++    else
++      {
++        Elf32_Phdr *const p = (Elf32_Phdr *) (phdr_buf + i * phdr_size);
++
++        if (p->p_type == PT_PHDR)
++          relocation = phdr_memaddr - p->p_vaddr;
++      }
++
++  if (relocation == -1)
++    {
++      /* PT_PHDR is optional, but necessary for PIE in general.  Fortunately
++         any real world executables, including PIE executables, have always
++         PT_PHDR present.  PT_PHDR is not present in some shared libraries or
++         in fpc (Free Pascal 2.4) binaries but neither of those have a need for
++         or present DT_DEBUG anyway (fpc binaries are statically linked).
++
++         Therefore if there exists DT_DEBUG there is always also PT_PHDR.
++
++         GDB could find RELOCATION also from AT_ENTRY - e_entry.  */
++
++      return 0;
++    }
++
++  for (i = 0; i < num_phdr; i++)
++    {
++      if (is_elf64)
++        {
++          Elf64_Phdr *const p = (Elf64_Phdr *) (phdr_buf + i * phdr_size);
++
++          if (p->p_type == PT_DYNAMIC)
++            return p->p_vaddr + relocation;
++        }
++      else
++        {
++          Elf32_Phdr *const p = (Elf32_Phdr *) (phdr_buf + i * phdr_size);
++
++          if (p->p_type == PT_DYNAMIC)
++            return p->p_vaddr + relocation;
++        }
++    }
++
++  return 0;
++}
++
++/* Return &_r_debug in the inferior, or -1 if not present.  Return value
++   can be 0 if the inferior does not yet have the library list initialized.
++   We look for DT_MIPS_RLD_MAP first.  MIPS executables use this instead of
++   DT_DEBUG, although they sometimes contain an unused DT_DEBUG entry too.  */
++
++static CORE_ADDR
++get_r_debug (const int pid, const int is_elf64)
++{
++  CORE_ADDR dynamic_memaddr;
++  const int dyn_size = is_elf64 ? sizeof (Elf64_Dyn) : sizeof (Elf32_Dyn);
++  unsigned char buf[sizeof (Elf64_Dyn)];  /* The larger of the two.  */
++  CORE_ADDR map = -1;
++
++  dynamic_memaddr = get_dynamic (pid, is_elf64);
++  if (dynamic_memaddr == 0)
++    return map;
++
++  while (netbsd_read_memory (dynamic_memaddr, buf, dyn_size) == 0)
++    {
++      if (is_elf64)
++        {
++          Elf64_Dyn *const dyn = (Elf64_Dyn *) buf;
++#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL
++          union
++            {
++              Elf64_Xword map;
++              unsigned char buf[sizeof (Elf64_Xword)];
++            }
++          rld_map;
++#endif
++#ifdef DT_MIPS_RLD_MAP
++          if (dyn->d_tag == DT_MIPS_RLD_MAP)
++            {
++              if (netbsd_read_memory (dyn->d_un.d_val,
++                                     rld_map.buf, sizeof (rld_map.buf)) == 0)
++                return rld_map.map;
++              else
++                break;
++            }
++#endif  /* DT_MIPS_RLD_MAP */
++#ifdef DT_MIPS_RLD_MAP_REL
++          if (dyn->d_tag == DT_MIPS_RLD_MAP_REL)
++            {
++              if (netbsd_read_memory (dyn->d_un.d_val + dynamic_memaddr,
++                                     rld_map.buf, sizeof (rld_map.buf)) == 0)
++                return rld_map.map;
++              else
++                break;
++            }
++#endif  /* DT_MIPS_RLD_MAP_REL */
++
++          if (dyn->d_tag == DT_DEBUG && map == -1)
++            map = dyn->d_un.d_val;
++
++          if (dyn->d_tag == DT_NULL)
++            break;
++        }
++      else
++        {
++          Elf32_Dyn *const dyn = (Elf32_Dyn *) buf;
++#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL
++          union
++            {
++              Elf32_Word map;
++              unsigned char buf[sizeof (Elf32_Word)];
++            }
++          rld_map;
++#endif
++#ifdef DT_MIPS_RLD_MAP
++          if (dyn->d_tag == DT_MIPS_RLD_MAP)
++            {
++              if (netbsd_read_memory (dyn->d_un.d_val,
++                                     rld_map.buf, sizeof (rld_map.buf)) == 0)
++                return rld_map.map;
++              else
++                break;
++            }
++#endif  /* DT_MIPS_RLD_MAP */
++#ifdef DT_MIPS_RLD_MAP_REL
++          if (dyn->d_tag == DT_MIPS_RLD_MAP_REL)
++            {
++              if (netbsd_read_memory (dyn->d_un.d_val + dynamic_memaddr,
++                                     rld_map.buf, sizeof (rld_map.buf)) == 0)
++                return rld_map.map;
++              else
++                break;
++            }
++#endif  /* DT_MIPS_RLD_MAP_REL */
++
++          if (dyn->d_tag == DT_DEBUG && map == -1)
++            map = dyn->d_un.d_val;
++
++          if (dyn->d_tag == DT_NULL)
++            break;
++        }
++
++      dynamic_memaddr += dyn_size;
++    }
++
++  return map;
++}
++
++/* Read one pointer from MEMADDR in the inferior.  */
++
++static int
++read_one_ptr (CORE_ADDR memaddr, CORE_ADDR *ptr, int ptr_size)
++{
++  int ret;
++
++  /* Go through a union so this works on either big or little endian
++     hosts, when the inferior's pointer size is smaller than the size
++     of CORE_ADDR.  It is assumed the inferior's endianness is the
++     same of the superior's.  */
++
++  union
++  {
++    CORE_ADDR core_addr;
++    unsigned int ui;
++    unsigned char uc;
++  } addr;
++
++  ret = netbsd_read_memory (memaddr, &addr.uc, ptr_size);
++  if (ret == 0)
++    {
++      if (ptr_size == sizeof (CORE_ADDR))
++        *ptr = addr.core_addr;
++      else if (ptr_size == sizeof (unsigned int))
++        *ptr = addr.ui;
++      else
++        gdb_assert_not_reached ("unhandled pointer size");
++    }
++  return ret;
++}
++
++struct link_map_offsets
++  {
++    /* Offset and size of r_debug.r_version.  */
++    int r_version_offset;
++
++    /* Offset and size of r_debug.r_map.  */
++    int r_map_offset;
++
++    /* Offset to l_addr field in struct link_map.  */
++    int l_addr_offset;
++
++    /* Offset to l_name field in struct link_map.  */
++    int l_name_offset;
++
++    /* Offset to l_ld field in struct link_map.  */
++    int l_ld_offset;
++
++    /* Offset to l_next field in struct link_map.  */
++    int l_next_offset;
++
++    /* Offset to l_prev field in struct link_map.  */
++    int l_prev_offset;
++  };
++
++/* Return non-zero if HEADER is a 64-bit ELF file.  */
++
++static int
++elf_64_header_p (const Elf64_Ehdr *header, unsigned int *machine)
++{
++  if (header->e_ident[EI_MAG0] == ELFMAG0
++      && header->e_ident[EI_MAG1] == ELFMAG1
++      && header->e_ident[EI_MAG2] == ELFMAG2
++      && header->e_ident[EI_MAG3] == ELFMAG3)
++    {
++      *machine = header->e_machine;
++      return header->e_ident[EI_CLASS] == ELFCLASS64;
++
++    }
++  *machine = EM_NONE;
++  return -1;
++}
++
++/* Return non-zero if FILE is a 64-bit ELF file,
++   zero if the file is not a 64-bit ELF file,
++   and -1 if the file is not accessible or doesn't exist.  */
++
++static int
++elf_64_file_p (const char *file, unsigned int *machine)
++{
++  Elf64_Ehdr header;
++  int fd;
++
++  fd = open (file, O_RDONLY);
++  if (fd < 0)
++    return -1;
++
++  if (read (fd, &header, sizeof (header)) != sizeof (header))
++    {
++      close (fd);
++      return 0;
++    }
++  close (fd);
++
++  int is64 = elf_64_header_p (&header, machine);
++
++  netbsd_debug ("%s(): file='%s' is64=%d\n", __func__, file, is64);
++
++  return is64;
++}
++
++/* Construct qXfer:libraries-svr4:read reply.  */
++
++static int
++netbsd_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
++                            unsigned const char *writebuf,
++                            CORE_ADDR offset, int len)
++{
++  netbsd_debug ("%s(annex=%s, readbuf=%p, writebuf=%p, offset=%p, len=%d)\n",
++                __func__, annex, readbuf, writebuf, offset, len);
++
++  struct process_info_private *const priv = current_process ()->priv;
++  int pid, is_elf64;
++
++  static const struct link_map_offsets lmo_32bit_offsets =
++    {
++      0,     /* r_version offset. */
++      4,     /* r_debug.r_map offset.  */
++      0,     /* l_addr offset in link_map.  */
++      4,     /* l_name offset in link_map.  */
++      8,     /* l_ld offset in link_map.  */
++      12,    /* l_next offset in link_map.  */
++      16     /* l_prev offset in link_map.  */
++    };
++
++  static const struct link_map_offsets lmo_64bit_offsets =
++    {
++      0,     /* r_version offset. */
++      8,     /* r_debug.r_map offset.  */
++      0,     /* l_addr offset in link_map.  */
++      8,     /* l_name offset in link_map.  */
++      16,    /* l_ld offset in link_map.  */
++      24,    /* l_next offset in link_map.  */
++      32     /* l_prev offset in link_map.  */
++    };
++  const struct link_map_offsets *lmo;
++  unsigned int machine;
++  int ptr_size;
++  CORE_ADDR lm_addr = 0, lm_prev = 0;
++  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
++  int header_done = 0;
++
++  if (writebuf != NULL)
++    return -2;
++  if (readbuf == NULL)
++    return -1;
++
++  pid = pid_of (current_thread);
++  is_elf64 = elf_64_file_p (pid_to_exec_file(pid), &machine);
++  lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
++  ptr_size = is_elf64 ? 8 : 4;
++
++  while (annex[0] != '\0')
++    {
++      const char *sep;
++      CORE_ADDR *addrp;
++      int name_len;
++
++      sep = strchr (annex, '=');
++      if (sep == NULL)
++        break;
++
++      name_len = sep - annex;
++      if (name_len == 5 && startswith (annex, "start"))
++        addrp = &lm_addr;
++      else if (name_len == 4 && startswith (annex, "prev"))
++        addrp = &lm_prev;
++      else
++        {
++          annex = strchr (sep, ';');
++          if (annex == NULL)
++            break;
++          annex++;
++          continue;
++        }
++
++      annex = decode_address_to_semicolon (addrp, sep + 1);
++    }
++
++  if (lm_addr == 0)
++    {
++      int r_version = 0;
++
++      if (priv->r_debug == 0)
++        priv->r_debug = get_r_debug (pid, is_elf64);
++
++      /* We failed to find DT_DEBUG.  Such situation will not change
++         for this inferior - do not retry it.  Report it to GDB as
++         E01, see for the reasons at the GDB solib-svr4.c side.  */
++      if (priv->r_debug == (CORE_ADDR) -1)
++        return -1;
++
++      if (priv->r_debug != 0)
++        {
++          if (netbsd_read_memory (priv->r_debug + lmo->r_version_offset,
++                                 (unsigned char *) &r_version,
++                                 sizeof (r_version)) != 0
++              || r_version != 1)
++            {
++              warning ("unexpected r_debug version %d", r_version);
++            }
++          else if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
++                                 &lm_addr, ptr_size) != 0)
++            {
++              warning ("unable to read r_map from 0x%lx",
++                       (long) priv->r_debug + lmo->r_map_offset);
++            }
++        }
++    }
++
++  std::string document = "<library-list-svr4 version=\"1.0\"";
++
++  while (lm_addr
++         && read_one_ptr (lm_addr + lmo->l_name_offset,
++                          &l_name, ptr_size) == 0
++         && read_one_ptr (lm_addr + lmo->l_addr_offset,
++                          &l_addr, ptr_size) == 0
++         && read_one_ptr (lm_addr + lmo->l_ld_offset,
++                          &l_ld, ptr_size) == 0
++         && read_one_ptr (lm_addr + lmo->l_prev_offset,
++                          &l_prev, ptr_size) == 0
++         && read_one_ptr (lm_addr + lmo->l_next_offset,
++                          &l_next, ptr_size) == 0)
++    {
++      unsigned char libname[PATH_MAX];
++
++      if (lm_prev != l_prev)
++        {
++          warning ("Corrupted shared library list: 0x%lx != 0x%lx",
++                   (long) lm_prev, (long) l_prev);
++          break;
++        }
++
++      /* Ignore the first entry even if it has valid name as the first entry
++         corresponds to the main executable.  The first entry should not be
++         skipped if the dynamic loader was loaded late by a static executable
++         (see solib-svr4.c parameter ignore_first).  But in such case the main
++         executable does not have PT_DYNAMIC present and this function already
++         exited above due to failed get_r_debug.  */
++      if (lm_prev == 0)
++        string_appendf (document, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
++      else
++        {
++          /* Not checking for error because reading may stop before
++             we've got PATH_MAX worth of characters.  */
++          libname[0] = '\0';
++          netbsd_read_memory (l_name, libname, sizeof (libname) - 1);
++          libname[sizeof (libname) - 1] = '\0';
++          if (libname[0] != '\0')
++            {
++              if (!header_done)
++                {
++                  /* Terminate `<library-list-svr4'.  */
++                  document += '>';
++                  header_done = 1;
++                }
++
++              string_appendf (document, "<library name=\"");
++              xml_escape_text_append (&document, (char *) libname);
++              string_appendf (document, "\" lm=\"0x%lx\" "
++                              "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
++                              (unsigned long) lm_addr, (unsigned long) l_addr,
++                              (unsigned long) l_ld);
++            }
++        }
++
++      lm_prev = lm_addr;
++      lm_addr = l_next;
++    }
++
++  if (!header_done)
++    {
++      /* Empty list; terminate `<library-list-svr4'.  */
++      document += "/>";
++    }
++  else
++    document += "</library-list-svr4>";
++
++  int document_len = document.length ();
++  if (offset < document_len)
++    document_len -= offset;
++  else
++    document_len = 0;
++  if (len > document_len)
++    len = document_len;
++
++  memcpy (readbuf, document.data () + offset, len);
++
++  return len;
++}
++
++/* Return the name of a file that can be opened to get the symbols for
++   the child process identified by PID.  */
++
++static char *
++netbsd_pid_to_exec_file (pid_t pid)
++{
++  netbsd_debug ("%s(pid=%d)\n", __func__, pid);
++
++  return pid_to_exec_file(pid);
++}
++
++
++/* Implementation of the target_ops method "sw_breakpoint_from_kind".  */
++
++static const gdb_byte *
++netbsd_sw_breakpoint_from_kind (int kind, int *size)
++{
++  netbsd_debug ("%s(kind=%d)\n", __func__, kind);
++
++  static gdb_byte brkpt[PTRACE_BREAKPOINT_SIZE];
++
++  *size = PTRACE_BREAKPOINT_SIZE;
++
++  memcpy(brkpt, PTRACE_BREAKPOINT, PTRACE_BREAKPOINT_SIZE);
++
++  return brkpt;
++}
++
++const char *
++netbsd_thread_name (ptid_t ptid)
++{
++  netbsd_debug ("%s(ptid=(%d, %d, %d))\n",
++                __func__, ptid.pid(), ptid.lwp(), ptid.tid());
++
++  struct kinfo_lwp *kl;
++  pid_t pid = ptid.pid ();
++  lwpid_t lwp = ptid.lwp ();
++  static char buf[KI_LNAMELEN];
++  int mib[5];
++  size_t i, nlwps;
++  size_t size;
++
++  mib[0] = CTL_KERN;
++  mib[1] = KERN_LWP;
++  mib[2] = pid;
++  mib[3] = sizeof(struct kinfo_lwp);
++  mib[4] = 0;
++
++  if (netbsd_sysctl (mib, 5, NULL, &size, NULL, 0) == -1 || size == 0)
++    perror_with_name (("sysctl"));
++
++  mib[4] = size / sizeof(size_t);
++
++  kl = (struct kinfo_lwp *) xmalloc (size);
++  if (kl == NULL)
++    perror_with_name (("malloc"));
++
++  if (netbsd_sysctl (mib, 5, kl, &size, NULL, 0) == -1 || size == 0)
++    perror_with_name (("sysctl"));
++
++  nlwps = size / sizeof(struct kinfo_lwp);
++  buf[0] = '\0';
++  for (i = 0; i < nlwps; i++) {
++    if (kl[i].l_lid == lwp) {
++      xsnprintf (buf, sizeof buf, "%s", kl[i].l_name);
++      break;
++    }
++  }
++  xfree(kl);
++
++  return buf;
++}
++
++static int
++netbsd_supports_catch_syscall (void)
++{
++  netbsd_debug ("%s()\n", __func__);
++
++  return 1;
++}
++
++/* The NetBSD target_ops vector.  */
++
++static struct target_ops netbsd_target_ops = {
++  netbsd_create_inferior,
++  NULL,  /* post_create_inferior */
++  netbsd_attach,
++  netbsd_kill,
++  netbsd_detach,
++  netbsd_mourn,
++  netbsd_join,
++  netbsd_thread_alive,
++  netbsd_resume,
++  netbsd_wait,
++  netbsd_fetch_registers,
++  netbsd_store_registers,
++  NULL,  /* prepare_to_access_memory */
++  NULL,  /* done_accessing_memory */
++  netbsd_read_memory,
++  netbsd_write_memory,
++  NULL,  /* look_up_symbols */
++  netbsd_request_interrupt,
++  netbsd_read_auxv,
++  netbsd_supports_z_point_type,
++  netbsd_insert_point,
++  netbsd_remove_point,
++  netbsd_stopped_by_sw_breakpoint,
++  netbsd_supports_stopped_by_sw_breakpoint,
++  NULL,  /* stopped_by_hw_breakpoint */
++  NULL,  /* supports_stopped_by_hw_breakpoint */
++  target_can_do_hardware_single_step,
++  NULL,  /* stopped_by_watchpoint */
++  NULL,  /* stopped_data_address */
++  NULL,  /* read_offsets */
++  NULL,  /* get_tls_address */
++  NULL,  /* qxfer_spu */
++  hostio_last_error_from_errno,
++  NULL,  /* qxfer_osdata */
++  netbsd_qxfer_siginfo,
++  netbsd_supports_non_stop,
++  NULL,  /* async */
++  NULL,  /* start_non_stop */
++  netbsd_supports_multi_process,
++  netbsd_supports_fork_events,
++  netbsd_supports_vfork_events,
++  netbsd_supports_exec_events,
++  NULL,  /* handle_new_gdb_connection */
++  NULL,  /* handle_monitor_command */
++  NULL,  /* core_of_thread */
++  NULL,  /* read_loadmap */
++  NULL,  /* process_qsupported */
++  NULL,  /* supports_tracepoints */
++  NULL,  /* read_pc */
++  NULL,  /* write_pc */
++  NULL,  /* thread_stopped */
++  NULL,  /* get_tib_address */
++  NULL,  /* pause_all */
++  NULL,  /* unpause_all */
++  NULL,  /* stabilize_threads */
++  NULL,  /* install_fast_tracepoint_jump_pad */
++  NULL,  /* emit_ops */
++  netbsd_supports_disable_randomization,
++  NULL,  /* get_min_fast_tracepoint_insn_len */
++  netbsd_qxfer_libraries_svr4,
++  NULL,  /* supports_agent */
++  NULL,  /* enable_btrace */
++  NULL,  /* disable_btrace */
++  NULL,  /* read_btrace */
++  NULL,  /* read_btrace_conf */
++  NULL,  /* supports_range_stepping */
++  netbsd_pid_to_exec_file,
++  NULL,  /* multifs_open */
++  NULL,  /* multifs_unlink */
++  NULL,  /* multifs_readlink */
++  NULL,  /* breakpoint_kind_from_pc */
++  netbsd_sw_breakpoint_from_kind,
++  netbsd_thread_name,
++  NULL,  /* breakpoint_kind_from_current_state */
++  NULL,  /* supports_software_single_step */
++  netbsd_supports_catch_syscall,
++  NULL,  /* get_ipa_tdesc_idx */
++  NULL,  /* thread_handle */
++};
++
++void
++initialize_low (void)
++{
++  set_target_ops (&netbsd_target_ops);
++  the_low_target.arch_setup ();
++}
diff --git a/gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-low.h b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-low.h
new file mode 100644
index 0000000000..a325013c0b
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-low.h
@@ -0,0 +1,66 @@
+$NetBSD$
+
+--- gdb/gdbserver/netbsd-low.h.orig	2019-09-02 20:02:23.503235772 +0000
++++ gdb/gdbserver/netbsd-low.h
+@@ -0,0 +1,61 @@
++/* Copyright (C) 2010-2019 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#ifndef GDBSERVER_NETBSD_LOW_H
++#define GDBSERVER_NETBSD_LOW_H
++
++struct regcache;
++struct target_desc;
++
++/*  Some information relative to a given register set.   */
++
++struct netbsd_regset_info
++{
++  /* The ptrace request needed to get/set registers of this set.  */
++  int get_request, set_request;
++  /* The size of the register set.  */
++  int size;
++  /* Fill the buffer BUF from the contents of the given REGCACHE.  */
++  void (*fill_function) (struct regcache *regcache, char *buf);
++  /* Store the register value in BUF in the given REGCACHE.  */
++  void (*store_function) (struct regcache *regcache, const char *buf);
++};
++
++/* A list of regsets for the target being debugged, terminated by an entry
++   where the size is negative.
++
++   This list should be created by the target-specific code.  */
++
++extern struct netbsd_regset_info netbsd_target_regsets[];
++
++/* The target-specific operations for NetBSD support.  */
++
++struct netbsd_target_ops
++{
++  /* Architecture-specific setup.  */
++  void (*arch_setup) (void);
++
++  /* Hook to support target specific qSupported.  */
++  void (*process_qsupported) (char **, int count);
++};
++
++extern struct netbsd_target_ops the_low_target;
++
++/* XXX: multilib */
++extern const struct target_desc *netbsd_tdesc;
++
++#endif /* GDBSERVER_NETBSD_LOW_H */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-x86__64-low.c b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-x86__64-low.c
new file mode 100644
index 0000000000..55fc14c1f5
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_gdbserver_netbsd-x86__64-low.c
@@ -0,0 +1,388 @@
+$NetBSD$
+
+--- gdb/gdbserver/netbsd-x86_64-low.c.orig	2019-09-02 20:02:23.503455942 +0000
++++ gdb/gdbserver/netbsd-x86_64-low.c
+@@ -0,0 +1,383 @@
++/* Copyright (C) 2010-2019 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include "server.h"
++#include "netbsd-low.h"
++#include <limits.h>
++#include <sys/ptrace.h>
++#include "gdbsupport/x86-xstate.h"
++#include "arch/amd64.h"
++#include "x86-tdesc.h"
++#include "tdesc.h"
++
++static int use_xml;
++
++/* The index of various registers inside the regcache.  */
++
++enum netbsd_x86_64_gdb_regnum
++{
++  AMD64_RAX_REGNUM,             /* %rax */
++  AMD64_RBX_REGNUM,             /* %rbx */
++  AMD64_RCX_REGNUM,             /* %rcx */
++  AMD64_RDX_REGNUM,             /* %rdx */
++  AMD64_RSI_REGNUM,             /* %rsi */
++  AMD64_RDI_REGNUM,             /* %rdi */
++  AMD64_RBP_REGNUM,             /* %rbp */
++  AMD64_RSP_REGNUM,             /* %rsp */
++  AMD64_R8_REGNUM,              /* %r8 */
++  AMD64_R9_REGNUM,              /* %r9 */
++  AMD64_R10_REGNUM,             /* %r10 */
++  AMD64_R11_REGNUM,             /* %r11 */
++  AMD64_R12_REGNUM,             /* %r12 */
++  AMD64_R13_REGNUM,             /* %r13 */
++  AMD64_R14_REGNUM,             /* %r14 */
++  AMD64_R15_REGNUM,             /* %r15 */
++  AMD64_RIP_REGNUM,             /* %rip */
++  AMD64_EFLAGS_REGNUM,          /* %eflags */
++  AMD64_CS_REGNUM,              /* %cs */
++  AMD64_SS_REGNUM,              /* %ss */
++  AMD64_DS_REGNUM,              /* %ds */
++  AMD64_ES_REGNUM,              /* %es */
++  AMD64_FS_REGNUM,              /* %fs */
++  AMD64_GS_REGNUM,              /* %gs */
++  AMD64_ST0_REGNUM = 24,        /* %st0 */
++  AMD64_ST1_REGNUM,             /* %st1 */
++  AMD64_FCTRL_REGNUM = AMD64_ST0_REGNUM + 8,
++  AMD64_FSTAT_REGNUM = AMD64_ST0_REGNUM + 9,
++  AMD64_FTAG_REGNUM = AMD64_ST0_REGNUM + 10,
++  AMD64_XMM0_REGNUM = 40,       /* %xmm0 */
++  AMD64_XMM1_REGNUM,            /* %xmm1 */
++  AMD64_MXCSR_REGNUM = AMD64_XMM0_REGNUM + 16,
++  AMD64_YMM0H_REGNUM,           /* %ymm0h */
++  AMD64_YMM15H_REGNUM = AMD64_YMM0H_REGNUM + 15,
++  AMD64_BND0R_REGNUM = AMD64_YMM15H_REGNUM + 1,
++  AMD64_BND3R_REGNUM = AMD64_BND0R_REGNUM + 3,
++  AMD64_BNDCFGU_REGNUM,
++  AMD64_BNDSTATUS_REGNUM,
++  AMD64_XMM16_REGNUM,
++  AMD64_XMM31_REGNUM = AMD64_XMM16_REGNUM + 15,
++  AMD64_YMM16H_REGNUM,
++  AMD64_YMM31H_REGNUM = AMD64_YMM16H_REGNUM + 15,
++  AMD64_K0_REGNUM,
++  AMD64_K7_REGNUM = AMD64_K0_REGNUM + 7,
++  AMD64_ZMM0H_REGNUM,
++  AMD64_ZMM31H_REGNUM = AMD64_ZMM0H_REGNUM + 31,
++  AMD64_PKRU_REGNUM,
++  AMD64_FSBASE_REGNUM,
++  AMD64_GSBASE_REGNUM
++};
++
++/* The fill_function for the general-purpose register set.  */
++
++static void
++netbsd_x86_64_fill_gregset (struct regcache *regcache, char *buf)
++{
++  struct reg *r;
++
++  r = (struct reg *)buf;
++
++#define netbsd_x86_64_collect_gp(regnum, fld) do { \
++  collect_register (regcache, regnum, &r->regs[_REG_##fld]); \
++  printf("collect_register(%p, %d, %p -> %lx)\n", regcache, regnum, &r->regs[_REG_##fld], r->regs[_REG_##fld]); \
++  } while (0)
++
++  netbsd_x86_64_collect_gp (AMD64_RAX_REGNUM, RAX);
++  netbsd_x86_64_collect_gp (AMD64_RBX_REGNUM, RBX);
++  netbsd_x86_64_collect_gp (AMD64_RCX_REGNUM, RCX);
++  netbsd_x86_64_collect_gp (AMD64_RDX_REGNUM, RDX);
++  netbsd_x86_64_collect_gp (AMD64_RSI_REGNUM, RSI);
++  netbsd_x86_64_collect_gp (AMD64_RDI_REGNUM, RDI);
++  netbsd_x86_64_collect_gp (AMD64_RBP_REGNUM, RBP);
++  netbsd_x86_64_collect_gp (AMD64_RSP_REGNUM, RSP);
++  netbsd_x86_64_collect_gp (AMD64_R8_REGNUM, R8);
++  netbsd_x86_64_collect_gp (AMD64_R9_REGNUM, R9);
++  netbsd_x86_64_collect_gp (AMD64_R10_REGNUM, R10);
++  netbsd_x86_64_collect_gp (AMD64_R11_REGNUM, R11);
++  netbsd_x86_64_collect_gp (AMD64_R12_REGNUM, R12);
++  netbsd_x86_64_collect_gp (AMD64_R13_REGNUM, R13);
++  netbsd_x86_64_collect_gp (AMD64_R14_REGNUM, R14);
++  netbsd_x86_64_collect_gp (AMD64_R15_REGNUM, R15);
++  netbsd_x86_64_collect_gp (AMD64_RIP_REGNUM, RIP);
++  netbsd_x86_64_collect_gp (AMD64_EFLAGS_REGNUM, RFLAGS);
++  netbsd_x86_64_collect_gp (AMD64_CS_REGNUM, CS);
++  netbsd_x86_64_collect_gp (AMD64_SS_REGNUM, SS);
++  netbsd_x86_64_collect_gp (AMD64_DS_REGNUM, DS);
++  netbsd_x86_64_collect_gp (AMD64_ES_REGNUM, ES);
++  netbsd_x86_64_collect_gp (AMD64_FS_REGNUM, FS);
++  netbsd_x86_64_collect_gp (AMD64_GS_REGNUM, GS);
++}
++
++/* The store_function for the general-purpose register set.  */
++
++static void
++netbsd_x86_64_store_gregset (struct regcache *regcache, const char *buf)
++{
++  struct reg *r;
++
++  r = (struct reg *)buf;
++
++#define netbsd_x86_64_supply_gp(regnum, fld) do { \
++  supply_register (regcache, regnum, &r->regs[_REG_##fld]); \
++  printf("supply_register(%p, %d, %p -> %lx)\n", regcache, regnum, &r->regs[_REG_##fld], r->regs[_REG_##fld]); \
++  } while(0)
++
++  netbsd_x86_64_supply_gp (AMD64_RAX_REGNUM, RAX);
++  netbsd_x86_64_supply_gp (AMD64_RBX_REGNUM, RBX);
++  netbsd_x86_64_supply_gp (AMD64_RCX_REGNUM, RCX);
++  netbsd_x86_64_supply_gp (AMD64_RDX_REGNUM, RDX);
++  netbsd_x86_64_supply_gp (AMD64_RSI_REGNUM, RSI);
++  netbsd_x86_64_supply_gp (AMD64_RDI_REGNUM, RDI);
++  netbsd_x86_64_supply_gp (AMD64_RBP_REGNUM, RBP);
++  netbsd_x86_64_supply_gp (AMD64_RSP_REGNUM, RSP);
++  netbsd_x86_64_supply_gp (AMD64_R8_REGNUM, R8);
++  netbsd_x86_64_supply_gp (AMD64_R9_REGNUM, R9);
++  netbsd_x86_64_supply_gp (AMD64_R10_REGNUM, R10);
++  netbsd_x86_64_supply_gp (AMD64_R11_REGNUM, R11);
++  netbsd_x86_64_supply_gp (AMD64_R12_REGNUM, R12);
++  netbsd_x86_64_supply_gp (AMD64_R13_REGNUM, R13);
++  netbsd_x86_64_supply_gp (AMD64_R14_REGNUM, R14);
++  netbsd_x86_64_supply_gp (AMD64_R15_REGNUM, R15);
++  netbsd_x86_64_supply_gp (AMD64_RIP_REGNUM, RIP);
++  netbsd_x86_64_supply_gp (AMD64_EFLAGS_REGNUM, RFLAGS);
++  netbsd_x86_64_supply_gp (AMD64_CS_REGNUM, CS);
++  netbsd_x86_64_supply_gp (AMD64_SS_REGNUM, SS);
++  netbsd_x86_64_supply_gp (AMD64_DS_REGNUM, DS);
++  netbsd_x86_64_supply_gp (AMD64_ES_REGNUM, ES);
++  netbsd_x86_64_supply_gp (AMD64_FS_REGNUM, FS);
++  netbsd_x86_64_supply_gp (AMD64_GS_REGNUM, GS);
++}
++
++#if 0
++/* Extract the first 16 bits of register REGNUM in the REGCACHE,
++   and store these 2 bytes at DEST.
++
++   This is useful to collect certain 16bit registers which are known
++   by GDBserver as 32bit registers (such as the Control Register
++   for instance).  */
++
++static void
++collect_16bit_register (struct regcache *regcache, int regnum, char *dest)
++{
++  gdb_byte word[4];
++
++  collect_register (regcache, regnum, word);
++  memcpy (dest, word, 2);
++}
++#endif
++
++#if 0
++/* The fill_function for the floating-point register set.  */
++
++static void
++netbsd_x86_64_fill_fpregset (struct regcache *regcache, char *buf)
++{
++  int i;
++
++  /* Collect %st0 .. %st7.  */
++  for (i = 0; i < 8; i++)
++    collect_register (regcache, I386_ST0_REGNUM + i,
++                      buf + offsetof (usr_fcontext_t, ufc_reg)
++		      + i * sizeof (struct ufp387_real));
++
++  /* Collect the other FPU registers.  */
++  collect_16bit_register (regcache, x86_64_FCTRL_REGNUM,
++                          buf + offsetof (usr_fcontext_t, ufc_control));
++  collect_16bit_register (regcache, I386_FSTAT_REGNUM,
++                          buf + offsetof (usr_fcontext_t, ufc_status));
++  collect_16bit_register (regcache, I386_FTAG_REGNUM,
++                          buf + offsetof (usr_fcontext_t, ufc_tag));
++  collect_register (regcache, I386_FISEG_REGNUM,
++                    buf + offsetof (usr_fcontext_t, ufc_inst_sel));
++  collect_register (regcache, I386_FIOFF_REGNUM,
++                    buf + offsetof (usr_fcontext_t, ufc_inst_off));
++  collect_register (regcache, I386_FOSEG_REGNUM,
++                    buf + offsetof (usr_fcontext_t, ufc_data_sel));
++  collect_register (regcache, I386_FOOFF_REGNUM,
++                    buf + offsetof (usr_fcontext_t, ufc_data_off));
++#if !defined(netbsdOS_178)
++  collect_16bit_register (regcache, I386_FOP_REGNUM,
++                          buf + offsetof (usr_fcontext_t, ufc_opcode));
++
++  /* Collect the XMM registers.  */
++  for (i = 0; i < 8; i++)
++    collect_register (regcache, I386_XMM0_REGNUM + i,
++                      buf + offsetof (usr_fcontext_t, uxmm_reg)
++		      + i * sizeof (struct uxmm_register));
++  collect_register (regcache, I386_MXCSR_REGNUM,
++                    buf + offsetof (usr_fcontext_t, usse_mxcsr));
++#endif
++}
++#endif
++
++#if 0
++/* This is the supply counterpart for collect_16bit_register:
++   It extracts a 2byte value from BUF, and uses that value to
++   set REGNUM's value in the regcache.
++
++   This is useful to supply the value of certain 16bit registers
++   which are known by GDBserver as 32bit registers (such as the Control
++   Register for instance).  */
++
++static void
++supply_16bit_register (struct regcache *regcache, int regnum, const char *buf)
++{
++  gdb_byte word[4];
++
++  memcpy (word, buf, 2);
++  memset (word + 2, 0, 2);
++  supply_register (regcache, regnum, word);
++}
++#endif
++
++#if 0
++/* The store_function for the floating-point register set.  */
++
++static void
++netbsd_x86_64_store_fpregset (struct regcache *regcache, const char *buf)
++{
++  int i;
++
++  /* Store the %st0 .. %st7 registers.  */
++  for (i = 0; i < 8; i++)
++    supply_register (regcache, I386_ST0_REGNUM + i,
++                     buf + offsetof (usr_fcontext_t, ufc_reg)
++		     + i * sizeof (struct ufp387_real));
++
++  /* Store the other FPU registers.  */
++  supply_16bit_register (regcache, I386_FCTRL_REGNUM,
++                         buf + offsetof (usr_fcontext_t, ufc_control));
++  supply_16bit_register (regcache, I386_FSTAT_REGNUM,
++                         buf + offsetof (usr_fcontext_t, ufc_status));
++  supply_16bit_register (regcache, I386_FTAG_REGNUM,
++                         buf + offsetof (usr_fcontext_t, ufc_tag));
++  supply_register (regcache, I386_FISEG_REGNUM,
++                   buf + offsetof (usr_fcontext_t, ufc_inst_sel));
++  supply_register (regcache, I386_FIOFF_REGNUM,
++                   buf + offsetof (usr_fcontext_t, ufc_inst_off));
++  supply_register (regcache, I386_FOSEG_REGNUM,
++                   buf + offsetof (usr_fcontext_t, ufc_data_sel));
++  supply_register (regcache, I386_FOOFF_REGNUM,
++                   buf + offsetof (usr_fcontext_t, ufc_data_off));
++#if !defined(LYNXOS_178)
++  supply_16bit_register (regcache, I386_FOP_REGNUM,
++                         buf + offsetof (usr_fcontext_t, ufc_opcode));
++
++  /* Store the XMM registers.  */
++  for (i = 0; i < 8; i++)
++    supply_register (regcache, I386_XMM0_REGNUM + i,
++                     buf + offsetof (usr_fcontext_t, uxmm_reg)
++		     + i * sizeof (struct uxmm_register));
++  supply_register (regcache, I386_MXCSR_REGNUM,
++                   buf + offsetof (usr_fcontext_t, usse_mxcsr));
++#endif
++}
++#endif
++
++/* Implements the netbsd_target_ops.arch_setup routine.  */
++
++static void
++netbsd_x86_64_arch_setup (void)
++{
++  struct target_desc *tdesc
++    = amd64_create_target_description (X86_XSTATE_SSE_MASK, false, false, false);
++
++  init_target_desc (tdesc, amd64_expedite_regs);
++
++  netbsd_tdesc = tdesc;
++}
++
++/* Update all the target description of all processes; a new GDB
++   connected, and it may or not support xml target descriptions.  */
++
++static void
++x86_64_netbsd_update_xmltarget (void)
++{
++  struct thread_info *saved_thread = current_thread;
++
++  /* Before changing the register cache's internal layout, flush the
++     contents of the current valid caches back to the threads, and
++     release the current regcache objects.  */
++  regcache_release ();
++
++  for_each_process ([] (process_info *proc) {
++    int pid = proc->pid;
++
++    /* Look up any thread of this process.  */
++    current_thread = find_any_thread_of_pid (pid);
++
++    the_low_target.arch_setup ();
++  });
++
++  current_thread = saved_thread;
++}
++
++/* Process qSupported query, "xmlRegisters=". */
++
++static void
++netbsd_x86_64_process_qsupported (char **features, int count)
++{
++  int i;
++
++  /* Return if gdb doesn't support XML.  If gdb sends "xmlRegisters="
++     with "i386" in qSupported query, it supports x86 XML target
++     descriptions.  */
++  use_xml = 0;
++  for (i = 0; i < count; i++)
++    {
++      const char *feature = features[i];
++
++      if (startswith (feature, "xmlRegisters="))
++        {
++          char *copy = xstrdup (feature + 13);
++          char *p;
++
++          for (p = strtok (copy, ","); p != NULL; p = strtok (NULL, ","))
++            {
++              if (strcmp (p, "i386") == 0)
++                {
++                  use_xml = 1;
++                  break;
++                }
++            }
++
++          free (copy);
++        }
++    }
++  x86_64_netbsd_update_xmltarget ();
++}
++
++/* Description of all the x86-netbsd register sets.  */
++
++struct netbsd_regset_info netbsd_target_regsets[] = {
++  /* General Purpose Registers.  */
++  {PT_GETREGS, PT_SETREGS, sizeof(struct reg),
++   netbsd_x86_64_fill_gregset, netbsd_x86_64_store_gregset},
++  /* Floating Point Registers.  */
++#if 0
++  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof(usr_fcontext_t),
++    netbsd_x86_64_fill_fpregset, netbsd_x86_64_store_fpregset },
++#endif
++  /* End of list marker.  */
++  {0, 0, -1, NULL, NULL }
++};
++
++/* The netbsd_target_ops vector for x86-netbsd.  */
++
++struct netbsd_target_ops the_low_target = {
++  netbsd_x86_64_arch_setup,
++  netbsd_x86_64_process_qsupported,
++};
diff --git a/gdb-netbsd-wip/patches/patch-gdb_gdbsupport_agent.c b/gdb-netbsd-wip/patches/patch-gdb_gdbsupport_agent.c
new file mode 100644
index 0000000000..6b405a5c66
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_gdbsupport_agent.c
@@ -0,0 +1,12 @@
+$NetBSD$
+
+--- gdb/gdbsupport/agent.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/gdbsupport/agent.c
+@@ -155,6 +155,7 @@ gdb_connect_sync_socket (int pid)
+       return -1;
+     }
+ 
++  memset(&addr, 0, sizeof(addr));
+   addr.sun_family = AF_UNIX;
+ 
+   res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
diff --git a/gdb-netbsd-wip/patches/patch-gdb_gdbsupport_common-defs.h b/gdb-netbsd-wip/patches/patch-gdb_gdbsupport_common-defs.h
new file mode 100644
index 0000000000..5ac7452fc5
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_gdbsupport_common-defs.h
@@ -0,0 +1,23 @@
+$NetBSD$
+
+--- gdb/gdbsupport/common-defs.h.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/gdbsupport/common-defs.h
+@@ -96,9 +96,9 @@
+ #include <strings.h>	/* for strcasecmp and strncasecmp */
+ #endif
+ #include <errno.h>
+-#include <alloca.h>
+ 
+ #include "ansidecl.h"
++#ifndef __NetBSD__
+ /* This is defined by ansidecl.h, but we prefer gnulib's version.  On
+    MinGW, gnulib might enable __USE_MINGW_ANSI_STDIO, which may or not
+    require use of attribute gnu_printf instead of printf.  gnulib
+@@ -106,6 +106,7 @@
+    is compatible with ATTRIBUTE_PRINTF, simply use it.  */
+ #undef ATTRIBUTE_PRINTF
+ #define ATTRIBUTE_PRINTF _GL_ATTRIBUTE_FORMAT_PRINTF
++#endif
+ 
+ #if GCC_VERSION >= 3004
+ #define ATTRIBUTE_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
diff --git a/gdb-netbsd-wip/patches/patch-gdb_gdbsupport_pathstuff.h b/gdb-netbsd-wip/patches/patch-gdb_gdbsupport_pathstuff.h
new file mode 100644
index 0000000000..42515c202b
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_gdbsupport_pathstuff.h
@@ -0,0 +1,11 @@
+$NetBSD$
+
+--- gdb/gdbsupport/pathstuff.h.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/gdbsupport/pathstuff.h
+@@ -92,4 +92,6 @@ extern const char *get_shell ();
+ 
+ extern gdb::char_vector make_temp_filename (const std::string &f);
+ 
++extern "C" char *canonicalize_file_name (const char *path);
++
+ #endif /* COMMON_PATHSTUFF_H */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-nat.c
new file mode 100644
index 0000000000..a744537642
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-nat.c
@@ -0,0 +1,112 @@
+$NetBSD$
+
+--- gdb/hppa-nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/hppa-nbsd-nat.c
+@@ -58,8 +58,7 @@ hppanbsd_fpregset_supplies_p (int regnum
+ static void
+ hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+ {
+-  const char *regs = gregs;
+-  const int *r = gregs;
++  const char *regs = (const char *) gregs;
+   int regnum;
+ 
+   for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
+@@ -83,7 +82,7 @@ hppanbsd_supply_gregset (struct regcache
+ static void
+ hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
+ {
+-  const char *regs = fpregs;
++  const char *regs = (const char *) fpregs;
+   int regnum;
+ 
+   for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
+@@ -101,8 +100,7 @@ static void
+ hppanbsd_collect_gregset (const struct regcache *regcache,
+ 			  void *gregs, int regnum)
+ {
+-  char *regs = gregs;
+-  int *r = gregs;
++  char *regs = (char *) gregs;
+   int i;
+ 
+   for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
+@@ -146,10 +144,10 @@ hppanbsd_collect_gregset (const struct r
+    in FPREGS.  */
+ 
+ static void
+-hppanbsd_collect_fpregset (struct regcache *regcache,
++hppanbsd_collect_fpregset (const struct regcache *regcache,
+ 			  void *fpregs, int regnum)
+ {
+-  char *regs = fpregs;
++  char *regs = (char *) fpregs;
+   int i;
+ 
+   for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
+@@ -170,13 +168,15 @@ void
+ hppa_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
+ 
+ {
+-  pid_t pid = regcache->ptid ().pid ();
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+ 
+   if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
+     {
+       struct reg regs;
+ 
+-      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get registers"));
+ 
+       hppanbsd_supply_gregset (regcache, &regs);
+@@ -186,7 +186,7 @@ hppa_nbsd_nat_target::fetch_registers (s
+     {
+       struct fpreg fpregs;
+ 
+-      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get floating point status"));
+ 
+       hppanbsd_supply_fpregset (regcache, &fpregs);
+@@ -199,18 +199,20 @@ hppa_nbsd_nat_target::fetch_registers (s
+ void
+ hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
+ {
+-  pid_t pid = regcache->ptid ().pid ();
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+ 
+   if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
+     {
+       struct reg regs;
+ 
+-      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+         perror_with_name (_("Couldn't get registers"));
+ 
+       hppanbsd_collect_gregset (regcache, &regs, regnum);
+ 
+-      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+         perror_with_name (_("Couldn't write registers"));
+     }
+ 
+@@ -218,12 +220,12 @@ hppa_nbsd_nat_target::store_registers (s
+     {
+       struct fpreg fpregs;
+ 
+-      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get floating point status"));
+ 
+       hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
+ 
+-      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ 	perror_with_name (_("Couldn't write floating point status"));
+     }
+ }
diff --git a/gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-tdep.c
new file mode 100644
index 0000000000..3ca179efbf
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_hppa-nbsd-tdep.c
@@ -0,0 +1,69 @@
+$NetBSD$
+
+--- gdb/hppa-nbsd-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/hppa-nbsd-tdep.c
+@@ -25,8 +25,8 @@
+ #include "trad-frame.h"
+ #include "tramp-frame.h"
+ 
+-#include "hppa-tdep.h"
+ #include "hppa-bsd-tdep.h"
++#include "hppa-tdep.h"
+ #include "gdbarch.h"
+ 
+ /* From <machine/mcontext.h>.  */
+@@ -58,6 +58,19 @@ static int hppanbsd_mc_reg_offset[] =
+   38 * 4,	/* sr1 */
+   39 * 4,	/* sr2 */
+   40 * 4,	/* sr3 */
++  -1,		/* 48 */
++  -1,		/* 49 */
++  -1,		/* 50 */
++  -1,		/* 51 */
++  -1,		/* 52 */
++  -1,		/* 53 */
++  -1,		/* 54 */
++  -1,		/* 55 */
++  -1,		/* 56 */
++  -1,		/* 57 CR24 */
++  -1,		/* 58 CR25 */
++  -1,		/* 59 CR26 */
++  43 * 4,	/* HPPA_CR27_REGNUM */
+ 
+   /* more tbd */
+ };
+@@ -129,7 +142,7 @@ hppanbsd_sigtramp_cache_init (const stru
+ /* Core file support.  */
+ 
+ /* Sizeof `struct reg' in <machine/reg.h>.  */
+-#define HPPANBSD_SIZEOF_GREGS	(44 * 4)
++#define HPPANBSD_SIZEOF_GREGS	(47 * 4)
+ 
+ static int hppanbsd_reg_offset[] =
+ {
+@@ -153,6 +166,25 @@ static int hppanbsd_reg_offset[] =
+   -1,		/* HPPA_ISR_REGNUM */
+   -1,		/* HPPA_IOR_REGNUM */
+   0 * 4,	/* HPPA_IPSW_REGNUM */
++  -1,		/* spare? */
++  41 * 4,	/* HPPA_SR4_REGNUM */
++  37 * 4,	/* sr0 */
++  38 * 4,	/* sr1 */
++  39 * 4,	/* sr2 */
++  40 * 4,	/* sr3 */
++  -1,		/* 48 */
++  -1,		/* 49 */
++  -1,		/* 50 */
++  -1,		/* 51 */
++  -1,		/* 52 */
++  -1,		/* 53 */
++  -1,		/* 54 */
++  -1,		/* 55 */
++  -1,		/* 56 */
++  -1,		/* 57 */
++  -1,		/* 58 */
++  -1,		/* 59 */
++  46 * 4,	/* HPPA_CR27_REGNUM */
+ };
+ 
+ /* Supply register REGNUM from the buffer specified by GREGS and LEN
diff --git a/gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.c
new file mode 100644
index 0000000000..7586c4df3a
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- gdb/hppa-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/hppa-tdep.c
+@@ -624,7 +624,7 @@ hppa32_register_name (struct gdbarch *gd
+     "sr5",    "sr6",     "sr7",    "cr0",
+     "cr8",    "cr9",     "ccr",    "cr12",
+     "cr13",   "cr24",    "cr25",   "cr26",
+-    "mpsfu_high","mpsfu_low","mpsfu_ovflo","pad",
++    "cr27",   "cr28",    "cr29",   "cr30",
+     "fpsr",    "fpe1",   "fpe2",   "fpe3",
+     "fpe4",   "fpe5",    "fpe6",   "fpe7",
+     "fr4",     "fr4R",   "fr5",    "fr5R",
diff --git a/gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.h b/gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.h
new file mode 100644
index 0000000000..fd68417d82
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_hppa-tdep.h
@@ -0,0 +1,11 @@
+$NetBSD$
+
+--- gdb/hppa-tdep.h.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/hppa-tdep.h
+@@ -215,4 +215,6 @@ extern int hppa_in_solib_call_trampoline
+ 					  CORE_ADDR pc);
+ extern CORE_ADDR hppa_skip_trampoline_code (struct frame_info *, CORE_ADDR pc);
+ 
++void _initialize_hppabsd_tdep (void);
++
+ #endif  /* hppa-tdep.h */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_i386-bsd-nat.h b/gdb-netbsd-wip/patches/patch-gdb_i386-bsd-nat.h
new file mode 100644
index 0000000000..f2d85b382e
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_i386-bsd-nat.h
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- gdb/i386-bsd-nat.h.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/i386-bsd-nat.h
+@@ -20,6 +20,8 @@
+ #ifndef I386_BSD_NAT_H
+ #define I386_BSD_NAT_H
+ 
++#include "x86-bsd-nat.h"
++
+ /* Helper functions.  See definitions.  */
+ extern void i386bsd_fetch_inferior_registers (struct regcache *regcache,
+ 					      int regnum);
diff --git a/gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-nat.c
new file mode 100644
index 0000000000..e2047a0b12
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-nat.c
@@ -0,0 +1,51 @@
+$NetBSD$
+
+--- gdb/i386-nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/i386-nbsd-nat.c
+@@ -23,11 +23,13 @@
+ #include "target.h"
+ 
+ #include "i386-tdep.h"
++#include "i387-tdep.h"
+ #include "i386-bsd-nat.h"
+ 
+ /* Support for debugging kernel virtual memory images.  */
+ 
+ #include <sys/types.h>
++#include <machine/reg.h>
+ #include <machine/frame.h>
+ #include <machine/pcb.h>
+ 
+@@ -39,21 +41,25 @@ i386nbsd_supply_pcb (struct regcache *re
+ {
+   struct switchframe sf;
+ 
+-  /* The following is true for NetBSD 1.6.2:
++  /* The following is true for NetBSD 1.6.2 and after:
+ 
+      The pcb contains %esp and %ebp at the point of the context switch
+-     in cpu_switch().  At that point we have a stack frame as
+-     described by `struct switchframe', which for NetBSD 1.6.2 has the
+-     following layout:
++     in cpu_switch()/cpu_switchto().  At that point we have a stack frame as
++     described by `struct switchframe', which for NetBSD (2.0 and later) has
++     the following layout:
+ 
+-     interrupt level
+      %edi
+      %esi
+      %ebx
+-     %eip
++     return address
+ 
+      we reconstruct the register state as it would look when we just
+-     returned from cpu_switch().  */
++     returned from cpu_switch()/cpu_switchto().
++
++     For core dumps the pcb is saved by savectx()/dumpsys() and contains the
++     stack pointer and frame pointer.  A new dumpsys() fakes a switchframe
++     whereas older code isn't reliable so use an iffy heuristic to detect this
++     and use the frame pointer to recover enough state.  */
+ 
+   /* The stack pointer shouldn't be zero.  */
+   if (pcb->pcb_esp == 0)
diff --git a/gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-tdep.c
new file mode 100644
index 0000000000..bc79bac8d5
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_i386-nbsd-tdep.c
@@ -0,0 +1,183 @@
+$NetBSD$
+
+--- gdb/i386-nbsd-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/i386-nbsd-tdep.c
+@@ -33,6 +33,11 @@
+ #include "nbsd-tdep.h"
+ #include "solib-svr4.h"
+ 
++#include "elf-bfd.h"		/* for header hack */
++#include "trad-frame.h"		/* signal trampoline/kernel frame support */
++#include "frame-unwind.h"	/* kernel frame support */
++#include "tramp-frame.h"	/* signal trampoline/kernel frame support */
++
+ /* From <machine/reg.h>.  */
+ static int i386nbsd_r_reg_offset[] =
+ {
+@@ -369,6 +374,156 @@ i386nbsd_sigtramp_cache_init (const stru
+ }
+ 
+ 
++/* From <machine/frame.h>.  Note that %esp and %ess are only saved in
++   a trap frame when entering the kernel from user space.  */
++static int i386nbsd_tf_reg_offset[] =
++{
++  10 * 4,			/* %eax */
++   9 * 4,			/* %ecx */
++   8 * 4,			/* %edx */
++   7 * 4,			/* %ebx */
++  -1,				/* %esp */
++   6 * 4,			/* %ebp */
++   5 * 4,			/* %esi */
++   4 * 4,			/* %edi */
++  13 * 4,			/* %eip */
++  15 * 4,			/* %eflags */
++  14 * 4,			/* %cs */
++  -1,				/* %ss */
++   3 * 4,			/* %ds */
++   2 * 4,			/* %es */
++   1 * 4,			/* %fs */
++   0 * 4			/* %gs */
++};
++ 
++static struct trad_frame_cache *
++i386nbsd_trapframe_cache(struct frame_info *this_frame, void **this_cache)
++{
++  struct trad_frame_cache *cache;
++  CORE_ADDR func, sp, addr, tmp;
++  ULONGEST cs;
++  const char *name;
++  int i;
++  struct gdbarch *gdbarch = get_frame_arch (this_frame);
++  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
++
++  if (*this_cache)
++    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, I386_ESP_REGNUM);
++
++  find_pc_partial_function (func, &name, NULL, NULL);
++  if (name && (strncmp (name, "Xintr", 5) == 0 ||
++               strncmp (name, "Xhandle", 7) == 0))
++    {
++      /* It's an interrupt frame. */
++      tmp = read_memory_unsigned_integer (sp + 4, 4, byte_order);
++      if (tmp < 15)
++        {
++          /* Reasonable value for 'ppl': already on interrupt stack. */
++          addr = sp + 8;
++        }
++      else
++        {
++          /* Switch to previous stack. */
++          addr = tmp + 4;
++        }
++    }
++  else
++    {
++      /* It's a trap frame. */
++      addr = sp + 4;
++    }
++
++  for (i = 0; i < ARRAY_SIZE (i386nbsd_tf_reg_offset); i++)
++    if (i386nbsd_tf_reg_offset[i] != -1)
++      trad_frame_set_reg_addr (cache, i, addr + i386nbsd_tf_reg_offset[i]);
++
++  /* Read %cs from trap frame.  */
++  addr += i386nbsd_tf_reg_offset[I386_CS_REGNUM];
++  cs = read_memory_unsigned_integer (addr, 4, byte_order); 
++  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
++    {
++      /* Trap from user space; 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 + 8, func));
++    }
++
++  return cache;
++}
++
++static void
++i386nbsd_trapframe_this_id (struct frame_info *this_frame,
++			    void **this_cache, struct frame_id *this_id)
++{
++  struct trad_frame_cache *cache =
++    i386nbsd_trapframe_cache (this_frame, this_cache);
++  
++  trad_frame_get_id (cache, this_id);
++}
++
++static struct value *
++i386nbsd_trapframe_prev_register (struct frame_info *this_frame,
++				  void **this_cache, int regnum)
++{
++  struct trad_frame_cache *cache =
++    i386nbsd_trapframe_cache (this_frame, this_cache);
++
++  return trad_frame_get_register (cache, this_frame, regnum);
++}
++
++static int
++i386nbsd_trapframe_sniffer (const struct frame_unwind *self,
++			    struct frame_info *this_frame,
++			    void **this_prologue_cache)
++{
++  ULONGEST cs;
++  const char *name;
++
++  /* Check Current Privilege Level and bail out if we're not executing
++     in kernel space.  */
++  cs = get_frame_register_unsigned (this_frame, I386_CS_REGNUM);
++  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
++    return 0;
++
++
++  find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
++  return (name && ((strcmp (name, "alltraps") == 0)
++	        || (strcmp (name, "calltrap") == 0)
++		|| (strcmp (name, "syscall1") == 0)
++		|| (strcmp (name, "Xdoreti") == 0)
++		|| (strncmp (name, "Xintr", 5) == 0)
++		|| (strncmp (name, "Xhandle", 7) == 0)
++		|| (strncmp (name, "Xpreempt", 8) == 0)
++		|| (strncmp (name, "Xrecurse", 8) == 0)
++		|| (strncmp (name, "Xresume", 7) == 0)
++		|| (strncmp (name, "Xsoft", 5) == 0)
++		|| (strncmp (name, "Xstray", 6) == 0)
++		|| (strncmp (name, "Xsyscall", 8) == 0)
++		|| (strncmp (name, "Xtrap", 5) == 0)
++	    ));
++}
++
++const struct frame_unwind i386nbsd_trapframe_unwind = {
++  /* FIXME: kettenis/20051219: This really is more like an interrupt
++     frame, but SIGTRAMP_FRAME would print <signal handler called>,
++     which really is not what we want here.  */
++  NORMAL_FRAME,
++  default_frame_unwind_stop_reason,
++  i386nbsd_trapframe_this_id,
++  i386nbsd_trapframe_prev_register,
++  NULL,
++  i386nbsd_trapframe_sniffer
++};
++
+ static void 
+ i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+ {
+@@ -398,6 +553,9 @@ i386nbsd_init_abi (struct gdbarch_info i
+   tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si2);
+   tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si31);
+   tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si4);
++
++  /* Unwind kernel trap frames correctly.  */
++  frame_unwind_prepend_unwinder (gdbarch, &i386nbsd_trapframe_unwind);
+ }
+ 
+ /* NetBSD ELF.  */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_ia64-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_ia64-nbsd-tdep.c
new file mode 100644
index 0000000000..0ba4f1f1ed
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_ia64-nbsd-tdep.c
@@ -0,0 +1,51 @@
+$NetBSD$
+
+--- gdb/ia64-nbsd-tdep.c.orig	2019-09-02 20:02:23.506067905 +0000
++++ gdb/ia64-nbsd-tdep.c
+@@ -0,0 +1,46 @@
++/* Target-dependent code for NetBSD/ia64.
++
++   Copyright (C) 2004-2017 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include "defs.h"
++#include "arch-utils.h"
++#include "osabi.h"
++
++#include "ia64-tdep.h"
++#include "solib-svr4.h"
++
++/* NetBSD ELF.  */
++
++static void
++ia64nbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
++{
++  /* NetBSD ELF uses SVR4-style shared libraries.  */
++  set_solib_svr4_fetch_link_map_offsets
++    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
++}
++
++
++/* Provide a prototype to silence -Wmissing-prototypes.  */
++void _initialize_ia64nbsd_tdep (void);
++
++void
++_initialize_ia64nbsd_tdep (void)
++{
++  gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_NETBSD,
++			  ia64nbsd_elf_init_abi);
++}
diff --git a/gdb-netbsd-wip/patches/patch-gdb_inf-ptrace.c b/gdb-netbsd-wip/patches/patch-gdb_inf-ptrace.c
new file mode 100644
index 0000000000..7460c33c7f
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_inf-ptrace.c
@@ -0,0 +1,68 @@
+$NetBSD$
+
+--- gdb/inf-ptrace.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/inf-ptrace.c
+@@ -322,10 +322,12 @@ get_ptrace_pid (ptid_t ptid)
+ {
+   pid_t pid;
+ 
++#ifndef __NetBSD__
+   /* If we have an LWPID to work with, use it.  Otherwise, we're
+      dealing with a non-threaded program/target.  */
+   pid = ptid.lwp ();
+   if (pid == 0)
++#endif
+     pid = ptid.pid ();
+   return pid;
+ }
+@@ -338,7 +340,7 @@ void
+ inf_ptrace_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
+ {
+   pid_t pid;
+-  int request;
++  int request, sig;
+ 
+   if (minus_one_ptid == ptid)
+     /* Resume all threads.  Traditionally ptrace() only supports
+@@ -360,13 +362,23 @@ inf_ptrace_target::resume (ptid_t ptid, 
+          all possible successor instructions), so we don't have to
+          worry about that here.  */
+       request = PT_STEP;
+-    }
++#if __NetBSD__
++      /*
++       * On NetBSD the data field of PT_STEP contains the thread
++       * to be stepped; all other threads are continued if this value is > 0
++       */
++      sig = ptid.lwp ();
++#else
++      sig = 0;
++#endif
++    } else
++      sig = gdb_signal_to_host (signal);
+ 
+   /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
+      where it was.  If GDB wanted it to start some other way, we have
+      already written a new program counter value to the child.  */
+   errno = 0;
+-  ptrace (request, pid, (PTRACE_TYPE_ARG3)1, gdb_signal_to_host (signal));
++  ptrace (request, pid, (PTRACE_TYPE_ARG3)1, sig);
+   if (errno != 0)
+     perror_with_name (("ptrace"));
+ }
+@@ -562,6 +574,15 @@ inf_ptrace_target::xfer_partial (enum ta
+ 	/* If the PT_IO request is somehow not supported, fallback on
+ 	   using PT_WRITE_D/PT_READ_D.  Otherwise we will return zero
+ 	   to indicate failure.  */
++	if (errno == EACCES)
++	  {
++	    fprintf_unfiltered (gdb_stderr, "Cannot %s process at %p (%s). "
++				"Is PaX MPROTECT active? See security(7), "
++				"sysctl(7), paxctl(8)\n", writebuf ? "write to" :
++				"read from", piod.piod_offs,
++				strerror(errno));
++	    return TARGET_XFER_E_IO;	/* Some other error perhaps? */
++	  }
+ 	if (errno != EINVAL)
+ 	  return TARGET_XFER_EOF;
+       }
diff --git a/gdb-netbsd-wip/patches/patch-gdb_mips-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_mips-nbsd-nat.c
new file mode 100644
index 0000000000..87b19b600e
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_mips-nbsd-nat.c
@@ -0,0 +1,141 @@
+$NetBSD$
+
+--- gdb/mips-nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/mips-nbsd-nat.c
+@@ -16,7 +16,9 @@
+ 
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+-
++#ifndef _KERNTYPES
++#define _KERNTYPES
++#endif
+ #include "defs.h"
+ #include "inferior.h"
+ #include "regcache.h"
+@@ -27,10 +29,14 @@
+ #include <machine/reg.h>
+ 
+ #include "mips-tdep.h"
++#include "nbsd-nat.h"
+ #include "mips-nbsd-tdep.h"
+ #include "inf-ptrace.h"
++#include "bsd-kvm.h"
++
++#include "machine/pcb.h"
+ 
+-class mips_nbsd_nat_target final : public inf_ptrace_target
++class mips_nbsd_nat_target final : public nbsd_nat_target
+ {
+   void fetch_registers (struct regcache *, int) override;
+   void store_registers (struct regcache *, int) override;
+@@ -49,14 +55,16 @@ getregs_supplies (struct gdbarch *gdbarc
+ void
+ mips_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
+ {
+-  pid_t pid = regcache->ptid ().pid ();
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+ 
+   struct gdbarch *gdbarch = regcache->arch ();
+   if (regno == -1 || getregs_supplies (gdbarch, regno))
+     {
+       struct reg regs;
+ 
+-      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get registers"));
+       
+       mipsnbsd_supply_reg (regcache, (char *) &regs, regno);
+@@ -69,7 +77,7 @@ mips_nbsd_nat_target::fetch_registers (s
+     {
+       struct fpreg fpregs;
+ 
+-      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get floating point status"));
+ 
+       mipsnbsd_supply_fpreg (regcache, (char *) &fpregs, regno);
+@@ -79,19 +87,21 @@ mips_nbsd_nat_target::fetch_registers (s
+ void
+ mips_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
+ {
+-  pid_t pid = regcache->ptid ().pid ();
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+ 
+   struct gdbarch *gdbarch = regcache->arch ();
+   if (regno == -1 || getregs_supplies (gdbarch, regno))
+     {
+       struct reg regs;
+ 
+-      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get registers"));
+ 
+       mipsnbsd_fill_reg (regcache, (char *) &regs, regno);
+ 
+-      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+ 	perror_with_name (_("Couldn't write registers"));
+ 
+       if (regno != -1)
+@@ -103,18 +113,54 @@ mips_nbsd_nat_target::store_registers (s
+     {
+       struct fpreg fpregs; 
+ 
+-      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get floating point status"));
+ 
+       mipsnbsd_fill_fpreg (regcache, (char *) &fpregs, regno);
+ 
+-      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ 	perror_with_name (_("Couldn't write floating point status"));
+     }
+ }
+ 
++static int
++mipsnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
++{
++  struct label_t sf;
++
++  sf = pcb->pcb_context;
++
++  /* really should test for n{32,64} abi for this register
++     unless this is purely the "n" ABI */
++
++  regcache->raw_supply (MIPS_S0_REGNUM, &sf.val[_L_S0]);
++  regcache->raw_supply (MIPS_S1_REGNUM, &sf.val[_L_S1]);
++  regcache->raw_supply (MIPS_S2_REGNUM, &sf.val[_L_S2]);
++  regcache->raw_supply (MIPS_S3_REGNUM, &sf.val[_L_S3]);
++  regcache->raw_supply (MIPS_S4_REGNUM, &sf.val[_L_S4]);
++  regcache->raw_supply (MIPS_S5_REGNUM, &sf.val[_L_S5]);
++  regcache->raw_supply (MIPS_S6_REGNUM, &sf.val[_L_S6]);
++  regcache->raw_supply (MIPS_S7_REGNUM, &sf.val[_L_S7]);
++
++  regcache->raw_supply (MIPS_S8_REGNUM, &sf.val[_L_S8]);
++
++  regcache->raw_supply (MIPS_T8_REGNUM, &sf.val[_L_T8]);
++
++  regcache->raw_supply (MIPS_GP_REGNUM, &sf.val[_L_GP]);
++
++  regcache->raw_supply (MIPS_SP_REGNUM, &sf.val[_L_SP]);
++  regcache->raw_supply (MIPS_RA_REGNUM, &sf.val[_L_RA]);
++  regcache->raw_supply (MIPS_PS_REGNUM, &sf.val[_L_SR]);
++
++  /* provide the return address of the savectx as the current pc */
++  regcache->raw_supply (MIPS_EMBED_PC_REGNUM, &sf.val[_L_RA]);
++
++  return 0;
++}
++
+ void
+ _initialize_mipsnbsd_nat (void)
+ {
+   add_inf_child_target (&the_mips_nbsd_nat_target);
++  bsd_kvm_add_target (mipsnbsd_supply_pcb);
+ }
diff --git a/gdb-netbsd-wip/patches/patch-gdb_mips-tdep.h b/gdb-netbsd-wip/patches/patch-gdb_mips-tdep.h
new file mode 100644
index 0000000000..ad5893e27e
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_mips-tdep.h
@@ -0,0 +1,24 @@
+$NetBSD$
+
+--- gdb/mips-tdep.h.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/mips-tdep.h
+@@ -126,10 +126,19 @@ enum
+   MIPS_AT_REGNUM = 1,
+   MIPS_V0_REGNUM = 2,		/* Function integer return value.  */
+   MIPS_A0_REGNUM = 4,		/* Loc of first arg during a subr call.  */
++  MIPS_S0_REGNUM = 16,
++  MIPS_S1_REGNUM = 17,
+   MIPS_S2_REGNUM = 18,		/* Contains return address in MIPS16 thunks. */
++  MIPS_S3_REGNUM = 19,
++  MIPS_S4_REGNUM = 20,
++  MIPS_S5_REGNUM = 21,
++  MIPS_S6_REGNUM = 22,
++  MIPS_S7_REGNUM = 23,
++  MIPS_T8_REGNUM = 24,
+   MIPS_T9_REGNUM = 25,		/* Contains address of callee in PIC.  */
+   MIPS_GP_REGNUM = 28,
+   MIPS_SP_REGNUM = 29,
++  MIPS_S8_REGNUM = 30,
+   MIPS_RA_REGNUM = 31,
+   MIPS_PS_REGNUM = 32,		/* Contains processor status.  */
+   MIPS_EMBED_LO_REGNUM = 33,
diff --git a/gdb-netbsd-wip/patches/patch-gdb_nat_fork-inferior.c b/gdb-netbsd-wip/patches/patch-gdb_nat_fork-inferior.c
new file mode 100644
index 0000000000..8367613e19
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_nat_fork-inferior.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- gdb/nat/fork-inferior.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/nat/fork-inferior.c
+@@ -525,7 +525,7 @@ startup_inferior (pid_t pid, int ntraps,
+ 
+ 	  case TARGET_WAITKIND_EXECD:
+ 	    /* Handle EXEC signals as if they were SIGTRAP signals.  */
+-	    xfree (ws.value.execd_pathname);
++//	    xfree (ws.value.execd_pathname);
+ 	    resume_signal = GDB_SIGNAL_TRAP;
+ 	    switch_to_thread (event_ptid);
+ 	    break;
diff --git a/gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.c
new file mode 100644
index 0000000000..c32c6812d7
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.c
@@ -0,0 +1,533 @@
+$NetBSD$
+
+--- gdb/nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/nbsd-nat.c
+@@ -1,4 +1,4 @@
+-/* Native-dependent code for NetBSD.
++/* Native-dependent code for NetBSD
+ 
+    Copyright (C) 2006-2019 Free Software Foundation, Inc.
+ 
+@@ -18,7 +18,21 @@
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #include "defs.h"
++#include "gdbcore.h"
++#include "inferior.h"
++#include "regcache.h"
++#include "regset.h"
++#include "gdbcmd.h"
++#include "gdbthread.h"
++#include "gdbsupport/gdb_wait.h"
++#include <sys/types.h>
++#include <sys/ptrace.h>
++#include <sys/sysctl.h>
++#ifdef HAVE_KINFO_GETVMMAP
++#include <util.h>
++#endif
+ 
++#include "elf-bfd.h"
+ #include "nbsd-nat.h"
+ 
+ /* Return the name of a file that can be opened to get the symbols for
+@@ -31,6 +45,17 @@ nbsd_nat_target::pid_to_exec_file (int p
+   static char buf[PATH_MAX];
+   char name[PATH_MAX];
+ 
++  size_t buflen;
++  int mib[4];
++
++  mib[0] = CTL_KERN;
++  mib[1] = KERN_PROC_ARGS;
++  mib[2] = pid;
++  mib[3] = KERN_PROC_PATHNAME;
++  buflen = sizeof buf;
++  if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0)
++    return buf;
++
+   xsnprintf (name, PATH_MAX, "/proc/%d/exe", pid);
+   len = readlink (name, buf, PATH_MAX - 1);
+   if (len != -1)
+@@ -41,3 +66,482 @@ nbsd_nat_target::pid_to_exec_file (int p
+ 
+   return NULL;
+ }
++
++/* Iterate over all the memory regions in the current inferior,
++   calling FUNC for each memory region.  OBFD is passed as the last
++   argument to FUNC.  */
++
++int
++nbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
++					   void *obfd)
++{
++  pid_t pid = inferior_ptid.pid ();
++  struct kinfo_vmentry *vmentl, *kve;
++  uint64_t size;
++  int i;
++  size_t nitems;
++
++  vmentl = kinfo_getvmmap (pid, &nitems);
++  if (vmentl == NULL)
++    perror_with_name (_("Couldn't fetch VM map entries."));
++
++  for (i = 0; i < nitems; i++)
++    {
++      kve = &vmentl[i];
++
++      /* Skip unreadable segments and those where MAP_NOCORE has been set.  */
++      if (!(kve->kve_protection & KVME_PROT_READ)
++	  || kve->kve_flags & KVME_FLAG_NOCOREDUMP)
++	continue;
++
++      /* Skip segments with an invalid type.  */
++      switch (kve->kve_type) {
++	case KVME_TYPE_VNODE:
++	case KVME_TYPE_ANON:
++	case KVME_TYPE_SUBMAP:
++	case KVME_TYPE_OBJECT:
++	  break;
++	default:
++	  continue;
++      }
++
++      size = kve->kve_end - kve->kve_start;
++      if (info_verbose)
++	{
++	  fprintf_filtered (gdb_stdout, 
++			    "Save segment, %ld bytes at %llx (%c%c%c)\n",
++			    (long) size,
++			    (long long int)kve->kve_start,
++			    kve->kve_protection & KVME_PROT_READ ? 'r' : '-',
++			    kve->kve_protection & KVME_PROT_WRITE ? 'w' : '-',
++			    kve->kve_protection & KVME_PROT_EXEC ? 'x' : '-');
++	}
++
++      /* Invoke the callback function to create the corefile segment.
++	 Pass MODIFIED as true, we do not know the real modification state.  */
++      func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ,
++	    kve->kve_protection & KVME_PROT_WRITE,
++	    kve->kve_protection & KVME_PROT_EXEC, 1, obfd);
++    }
++  free(vmentl);
++  return 0;
++}
++
++static int debug_nbsd_lwp;
++
++static void
++show_nbsd_lwp_debug (struct ui_file *file, int from_tty,
++		     struct cmd_list_element *c, const char *value)
++{
++  fprintf_filtered (file, _("Debugging of NetBSD lwp module is %s.\n"), value);
++}
++
++/* Return true if PTID is still active in the inferior.  */
++
++bool
++nbsd_nat_target::thread_alive (ptid_t ptid)
++{
++  if (ptid.lwp_p ())
++    {
++      struct ptrace_lwpinfo pl;
++
++      pl.pl_lwpid = ptid.lwp ();
++      if (ptrace (PT_LWPINFO, ptid.pid (), (caddr_t) &pl, sizeof pl)
++	  == -1)
++	return 0;
++    }
++
++  return 1;
++}
++
++/* Convert PTID to a string.  Returns the string in a static
++   buffer.  */
++
++std::string
++nbsd_nat_target::pid_to_str (ptid_t ptid)
++{
++  lwpid_t lwp;
++
++  lwp = ptid.lwp ();
++  if (lwp != 0)
++    {
++      static char buf[64];
++      int pid = ptid.pid ();
++
++      xsnprintf (buf, sizeof buf, "LWP %d of process %d", lwp, pid);
++      return buf;
++    }
++
++  return normal_pid_to_str (ptid);
++}
++
++/* Return the name assigned to a thread by an application.  Returns
++   the string in a static buffer.  */
++
++const char *
++nbsd_nat_target::thread_name (struct thread_info *thr)
++{
++  struct kinfo_lwp *kl;
++  pid_t pid = thr->ptid.pid ();
++  lwpid_t lwp = thr->ptid.lwp ();
++  static char buf[KI_LNAMELEN];
++  int mib[5];
++  size_t i, nlwps;
++  size_t size;
++
++  mib[0] = CTL_KERN;
++  mib[1] = KERN_LWP;
++  mib[2] = pid;
++  mib[3] = sizeof(struct kinfo_lwp);
++  mib[4] = 0;
++
++  if (sysctl(mib, 5, NULL, &size, NULL, 0) == -1 || size == 0)
++    perror_with_name (("sysctl"));
++
++  mib[4] = size / sizeof(size_t);
++
++  kl = (struct kinfo_lwp *) xmalloc (size);
++  if (kl == NULL)
++    perror_with_name (("malloc"));
++
++  if (sysctl(mib, 5, kl, &size, NULL, 0) == -1 || size == 0)
++    perror_with_name (("sysctl"));
++
++  nlwps = size / sizeof(struct kinfo_lwp);
++  buf[0] = '\0';
++  for (i = 0; i < nlwps; i++) {
++    if (kl[i].l_lid == lwp) {
++      xsnprintf (buf, sizeof buf, "%s", kl[i].l_name);
++      break;
++    }
++  }
++  xfree(kl);
++
++  return buf;
++}
++
++/* Enable additional event reporting on new processes. */
++
++static void
++nbsd_enable_proc_events (pid_t pid)
++{
++  int events;
++
++  if (ptrace (PT_GET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events,
++	      sizeof (events)) == -1)
++    perror_with_name (("ptrace"));
++  events |= PTRACE_FORK;
++  events |= PTRACE_VFORK;
++  events |= PTRACE_VFORK_DONE;
++  events |= PTRACE_LWP_CREATE;
++  events |= PTRACE_LWP_EXIT;
++#if notyet
++  events |= PTRACE_POSIX_SPAWN;
++#endif
++  if (ptrace (PT_SET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events,
++	      sizeof (events)) == -1)
++    perror_with_name (("ptrace"));
++}
++
++/* Add threads for any new LWPs in a process.
++
++   When LWP events are used, this function is only used to detect existing
++   threads when attaching to a process.  On older systems, this function is
++   called to discover new threads each time the thread list is updated.  */
++
++static void
++nbsd_add_threads (pid_t pid)
++{
++  int val;
++  struct ptrace_lwpinfo pl;
++
++  pl.pl_lwpid = 0;
++  while ((val = ptrace (PT_LWPINFO, pid, (void *)&pl, sizeof(pl))) != -1
++    && pl.pl_lwpid != 0)
++    {
++      ptid_t ptid = ptid_t (pid, pl.pl_lwpid, 0);
++      if (!in_thread_list (ptid))
++	{
++	  if (inferior_ptid.lwp () == 0)
++	    thread_change_ptid (inferior_ptid, ptid);
++	  else
++	    add_thread (ptid);
++	}
++    }
++}
++
++/* Implement the "to_update_thread_list" target_ops method.  */
++
++void
++nbsd_nat_target::update_thread_list ()
++{
++  prune_threads ();
++
++  nbsd_add_threads (inferior_ptid.pid ());
++}
++
++
++struct nbsd_fork_info
++{
++  struct nbsd_fork_info *next;
++  ptid_t ptid;
++};
++
++void
++nbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
++{
++  if (debug_nbsd_lwp)
++    fprintf_unfiltered (gdb_stdlog,
++			"NLWP: nbsd_resume for ptid (%d, %ld, %ld)\n",
++			ptid.pid (), ptid.lwp (), ptid.tid ());
++  if (ptid.pid () == -1)
++    ptid = inferior_ptid;
++  inf_ptrace_target::resume (ptid, step, signo);
++}
++
++/* Wait for the child specified by PTID to do something.  Return the
++   process ID of the child, or MINUS_ONE_PTID in case of error; store
++   the status in *OURSTATUS.  */
++
++ptid_t
++nbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
++		       int target_options)
++{
++  ptid_t wptid;
++
++  /*
++   * Always perform polling on exact PID, overwrite the default polling on
++   * WAIT_ANY.
++   *
++   * This avoids events reported in random order reported for FORK / VFORK.
++   *
++   * Polling on traced parent always simplifies the code.
++   */
++  ptid = inferior_ptid;
++
++  if (debug_nbsd_lwp)
++    fprintf_unfiltered (gdb_stdlog, "NLWP: calling super_wait (%d, %ld, %ld) target_options=%#x\n",
++                        ptid.pid (), ptid.lwp (), ptid.tid (), target_options);
++
++  wptid = inf_ptrace_target::wait (ptid, ourstatus, target_options);
++
++  if (debug_nbsd_lwp)
++    fprintf_unfiltered (gdb_stdlog, "NLWP: returned from super_wait (%d, %ld, %ld) target_options=%#x with ourstatus->kind=%d\n",
++                        ptid.pid (), ptid.lwp (), ptid.tid (),
++			target_options, ourstatus->kind);
++
++  if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
++    {
++      ptrace_state_t pst;
++      ptrace_siginfo_t psi, child_psi;
++      int status;
++      pid_t pid, child, wchild;
++      ptid_t child_ptid;
++      lwpid_t lwp;
++
++      pid = wptid.pid ();
++      // Find the lwp that caused the wait status change
++      if (ptrace(PT_GET_SIGINFO, pid, &psi, sizeof(psi)) == -1)
++        perror_with_name (("ptrace"));
++
++      /* For whole-process signals pick random thread */
++      if (psi.psi_lwpid == 0) {
++        // XXX: Is this always valid?
++        lwp = inferior_ptid.lwp ();
++      } else {
++        lwp = psi.psi_lwpid;
++      }
++
++      wptid = ptid_t (pid, lwp, 0);
++
++      /* Set LWP in the process */
++      if (in_thread_list (ptid_t (pid))) {
++          if (debug_nbsd_lwp)
++            fprintf_unfiltered (gdb_stdlog,
++                                "NLWP: using LWP %d for first thread\n",
++                                lwp);
++          thread_change_ptid (ptid_t (pid), wptid);                                                                                                 
++      }
++
++      if (debug_nbsd_lwp)
++         fprintf_unfiltered (gdb_stdlog,
++                             "NLWP: received signal=%d si_code=%d in process=%d lwp=%d\n",
++                             psi.psi_siginfo.si_signo, psi.psi_siginfo.si_code, pid, lwp);
++
++      switch (psi.psi_siginfo.si_signo) {
++      case SIGTRAP:
++        switch (psi.psi_siginfo.si_code) {
++        case TRAP_BRKPT:
++//          lp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
++          break;
++        case TRAP_DBREG:
++//          if (hardware_breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
++//            lp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
++//          else
++//            lp->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
++          break;
++        case TRAP_TRACE:
++//          lp->stop_reason = TARGET_STOPPED_BY_SINGLE_STEP;
++          break;
++        case TRAP_SCE:
++          ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY;
++          ourstatus->value.syscall_number = psi.psi_siginfo.si_sysnum;
++          break;
++        case TRAP_SCX:
++          ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN;
++          ourstatus->value.syscall_number = psi.psi_siginfo.si_sysnum;
++          break;
++        case TRAP_EXEC:
++          ourstatus->kind = TARGET_WAITKIND_EXECD;
++          ourstatus->value.execd_pathname = xstrdup(pid_to_exec_file (pid));
++          break;
++        case TRAP_LWP:
++        case TRAP_CHLD:
++          if (ptrace(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst)) == -1)
++            perror_with_name (("ptrace"));
++          switch (pst.pe_report_event) {
++          case PTRACE_FORK:
++          case PTRACE_VFORK:
++            if (pst.pe_report_event == PTRACE_FORK)
++              ourstatus->kind = TARGET_WAITKIND_FORKED;
++            else
++              ourstatus->kind = TARGET_WAITKIND_VFORKED;
++            child = pst.pe_other_pid;
++
++            if (debug_nbsd_lwp)
++              fprintf_unfiltered (gdb_stdlog,
++                                  "NLWP: registered %s event for PID %d\n",
++                                  (pst.pe_report_event == PTRACE_FORK) ? "FORK" : "VFORK", child);
++
++            wchild = waitpid (child, &status, 0);
++
++            if (wchild == -1)
++              perror_with_name (("waitpid"));
++
++            gdb_assert (wchild == child);
++
++            if (!WIFSTOPPED(status)) {
++              /* Abnormal situation (SIGKILLed?).. bail out */
++              ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
++              return wptid;
++            }
++
++            if (ptrace(PT_GET_SIGINFO, child, &child_psi, sizeof(child_psi)) == -1)
++              perror_with_name (("ptrace"));
++
++            if (child_psi.psi_siginfo.si_signo != SIGTRAP) {
++              /* Abnormal situation.. bail out */
++              ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
++              return wptid;
++            }
++
++            if (child_psi.psi_siginfo.si_code != TRAP_CHLD) {
++              /* Abnormal situation.. bail out */
++              ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
++              return wptid;
++            }
++
++            child_ptid = ptid_t (child, child_psi.psi_lwpid, 0);
++            nbsd_enable_proc_events (child_ptid.pid ());
++            ourstatus->value.related_pid = child_ptid;
++            break;
++          case PTRACE_VFORK_DONE:
++            ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
++            if (debug_nbsd_lwp)
++              fprintf_unfiltered (gdb_stdlog, "NLWP: reported VFORK_DONE parent=%d child=%d\n", pid, pst.pe_other_pid);
++            break;
++          case PTRACE_LWP_CREATE:
++            wptid = ptid_t (pid, pst.pe_lwp, 0);
++            if (in_thread_list (wptid)) {
++              /* Newborn reported after attach? */
++              ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
++              return wptid;
++            }
++	    if (inferior_ptid.lwp () == 0)
++	      thread_change_ptid (inferior_ptid, wptid);
++	    else
++	      add_thread (wptid);
++            ourstatus->kind = TARGET_WAITKIND_THREAD_CREATED;
++            if (debug_nbsd_lwp)
++              fprintf_unfiltered (gdb_stdlog, "NLWP: created LWP %d\n", pst.pe_lwp);
++            break;
++          case PTRACE_LWP_EXIT:
++            wptid = ptid_t (pid, pst.pe_lwp, 0);
++            if (!in_thread_list (wptid)) {
++              /* Dead child reported after attach? */
++              ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
++              return wptid;
++            }
++            delete_thread (find_thread_ptid (wptid));
++            ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
++            if (debug_nbsd_lwp)
++              fprintf_unfiltered (gdb_stdlog, "NLWP: exited LWP %d\n", pst.pe_lwp);
++            if (ptrace (PT_CONTINUE, pid, (void *)1, 0) == -1)
++              perror_with_name (("ptrace"));
++            break;
++          }
++          break;
++        }
++        break;
++      }
++
++      if (debug_nbsd_lwp)
++	fprintf_unfiltered (gdb_stdlog,
++		"NLWP: nbsd_wait returned (%d, %ld, %ld)\n",
++		wptid.pid (), wptid.lwp (),
++		wptid.tid ());
++      inferior_ptid = wptid;
++
++    }
++    return wptid;
++}
++
++/* Target hook for follow_fork.  On entry and at return inferior_ptid is
++   the ptid of the followed inferior.  */
++
++int
++nbsd_nat_target::follow_fork (int follow_child, int detach_fork)
++{
++  if (!follow_child && detach_fork)
++    {
++      struct thread_info *tp = inferior_thread ();
++      pid_t child_pid = tp->pending_follow.value.related_pid.pid ();
++
++      /* Breakpoints have already been detached from the child by
++	 infrun.c.  */
++
++      if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
++	perror_with_name (("ptrace"));
++    }
++
++  return 0;
++}
++
++void
++nbsd_nat_target::post_startup_inferior (ptid_t pid)
++{
++  nbsd_enable_proc_events (pid.pid ());
++}
++
++void
++nbsd_nat_target::post_attach (int pid)
++{
++  nbsd_enable_proc_events (pid);
++  nbsd_add_threads (pid);
++}
++
++/* Provide a prototype to silence -Wmissing-prototypes.  */
++extern initialize_file_ftype _initialize_nbsd_nat;
++
++void
++_initialize_nbsd_nat (void)
++{
++  add_setshow_boolean_cmd ("nbsd-lwp", class_maintenance,
++			   &debug_nbsd_lwp, _("\
++Set debugging of NetBSD lwp module."), _("\
++Show debugging of NetBSD lwp module."), _("\
++Enables printf debugging output."),
++			   NULL,
++			   &show_nbsd_lwp_debug,
++			   &setdebuglist, &showdebuglist);
++}
diff --git a/gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.h b/gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.h
new file mode 100644
index 0000000000..4bd269081b
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_nbsd-nat.h
@@ -0,0 +1,32 @@
+$NetBSD$
+
+--- gdb/nbsd-nat.h.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/nbsd-nat.h
+@@ -27,6 +27,27 @@
+ struct nbsd_nat_target : public inf_ptrace_target
+ {
+   char *pid_to_exec_file (int pid) override;
++  int find_memory_regions (find_memory_region_ftype func, void *data) override;
++
++  bool thread_alive (ptid_t ptid) override;
++  std::string pid_to_str (ptid_t) override;
++
++  const char *thread_name (struct thread_info *) override;
++
++  void update_thread_list () override;
++
++  thread_control_capabilities get_thread_control_capabilities () override
++  { return tc_schedlock; }
++
++  void resume (ptid_t, int, enum gdb_signal) override;
++
++  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
++
++  void post_startup_inferior (ptid_t) override;
++  void post_attach (int) override;
++
++  int follow_fork (int, int) override;
++
+ };
+ 
+ #endif /* nbsd-nat.h */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.c
new file mode 100644
index 0000000000..2b307d0017
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.c
@@ -0,0 +1,41 @@
+$NetBSD$
+
+--- gdb/nbsd-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/nbsd-tdep.c
+@@ -3,9 +3,9 @@
+    Copyright (C) 2002-2019 Free Software Foundation, Inc.
+ 
+    Contributed by Wasabi Systems, Inc.
+-  
++
+    This file is part of GDB.
+-  
++
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+@@ -20,6 +20,7 @@
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #include "defs.h"
++#include "objfiles.h"
+ #include "solib-svr4.h"
+ #include "nbsd-tdep.h"
+ 
+@@ -47,3 +48,16 @@ nbsd_pc_in_sigtramp (CORE_ADDR pc, const
+   return (func_name != NULL
+ 	  && startswith (func_name, "__sigtramp"));
+ }
++
++CORE_ADDR
++nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
++{
++  struct bound_minimal_symbol msym;
++
++  msym = lookup_minimal_symbol("_rtld_bind_start", NULL, NULL);
++  if (msym.minsym && BMSYMBOL_VALUE_ADDRESS (msym) == pc)
++    return frame_unwind_caller_pc (get_current_frame ());
++  else
++    return find_solib_trampoline_target (get_current_frame (), pc);
++}
++
diff --git a/gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.h b/gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.h
new file mode 100644
index 0000000000..6df845d3de
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_nbsd-tdep.h
@@ -0,0 +1,11 @@
+$NetBSD$
+
+--- gdb/nbsd-tdep.h.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/nbsd-tdep.h
+@@ -25,4 +25,6 @@ struct link_map_offsets *nbsd_lp64_solib
+ 
+ int nbsd_pc_in_sigtramp (CORE_ADDR, const char *);
+ 
++CORE_ADDR nbsd_skip_solib_resolver (struct gdbarch *gdbarch,
++				    CORE_ADDR pc);
+ #endif /* NBSD_TDEP_H */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_objfiles.c b/gdb-netbsd-wip/patches/patch-gdb_objfiles.c
new file mode 100644
index 0000000000..10df850cc9
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_objfiles.c
@@ -0,0 +1,26 @@
+$NetBSD$
+
+--- gdb/objfiles.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/objfiles.c
+@@ -1123,6 +1123,13 @@ static int
+ insert_section_p (const struct bfd *abfd,
+ 		  const struct bfd_section *section)
+ {
++#ifndef __NetBSD__
++  /*
++   * On NetBSD we don't typically have overlay sections and in some of
++   * our kernels (i386 vma = lma | 0xc0000000), so the following test
++   * makes kernels not load any symbols. There must be a better way to
++   * detect overlays.
++   */
+   const bfd_vma lma = bfd_section_lma (abfd, section);
+ 
+   if (overlay_debugging && lma != 0 && lma != bfd_section_vma (abfd, section)
+@@ -1131,6 +1138,7 @@ insert_section_p (const struct bfd *abfd
+        discarding sections from the "system supplied DSO" (aka vdso)
+        on some Linux systems (e.g. Fedora 11).  */
+     return 0;
++#endif
+   if ((bfd_get_section_flags (abfd, section) & SEC_THREAD_LOCAL) != 0)
+     /* This is a TLS section.  */
+     return 0;
diff --git a/gdb-netbsd-wip/patches/patch-gdb_ppc-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_ppc-nbsd-nat.c
new file mode 100644
index 0000000000..ac03c8e043
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_ppc-nbsd-nat.c
@@ -0,0 +1,130 @@
+$NetBSD$
+
+--- gdb/ppc-nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/ppc-nbsd-nat.c
+@@ -19,6 +19,7 @@
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
++#define _KMEMUSER
+ #include "defs.h"
+ 
+ #include <sys/types.h>
+@@ -31,12 +32,15 @@
+ #include "inferior.h"
+ #include "regcache.h"
+ 
++#include "common/gdb_assert.h"
++
++#include "nbsd-nat.h"
+ #include "ppc-tdep.h"
+ #include "ppc-nbsd-tdep.h"
+ #include "bsd-kvm.h"
+ #include "inf-ptrace.h"
+ 
+-struct ppc_nbsd_nat_target final : public inf_ptrace_target
++struct ppc_nbsd_nat_target final : public nbsd_nat_target
+ {
+   void fetch_registers (struct regcache *, int) override;
+   void store_registers (struct regcache *, int) override;
+@@ -88,13 +92,15 @@ void
+ ppc_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
+ {
+   struct gdbarch *gdbarch = regcache->arch ();
+-  pid_t pid = regcache->ptid ().pid ();
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+ 
+   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
+     {
+       struct reg regs;
+ 
+-      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+         perror_with_name (_("Couldn't get registers"));
+ 
+       ppc_supply_gregset (&ppcnbsd_gregset, regcache,
+@@ -105,7 +111,7 @@ ppc_nbsd_nat_target::fetch_registers (st
+     {
+       struct fpreg fpregs;
+ 
+-      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get FP registers"));
+ 
+       ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
+@@ -117,19 +123,21 @@ void
+ ppc_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
+ {
+   struct gdbarch *gdbarch = regcache->arch ();
+-  pid_t pid = regcache->ptid ().pid ();
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+ 
+   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
+     {
+       struct reg regs;
+ 
+-      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get registers"));
+ 
+       ppc_collect_gregset (&ppcnbsd_gregset, regcache,
+ 			   regnum, &regs, sizeof regs);
+ 
+-      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+ 	perror_with_name (_("Couldn't write registers"));
+     }
+ 
+@@ -137,13 +145,13 @@ ppc_nbsd_nat_target::store_registers (st
+     {
+       struct fpreg fpregs;
+ 
+-      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get FP registers"));
+ 
+       ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
+ 			    regnum, &fpregs, sizeof fpregs);
+ 
+-      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ 	perror_with_name (_("Couldn't set FP registers"));
+     }
+ }
+@@ -161,20 +169,20 @@ ppcnbsd_supply_pcb (struct regcache *reg
+   if (pcb->pcb_sp == 0)
+     return 0;
+ 
+-  read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
+-  regcache->raw_supply (tdep->ppc_cr_regnum, &sf.cr);
+-  regcache->raw_supply (tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
++  read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof(sf));
++  regcache->raw_supply (tdep->ppc_cr_regnum, &sf.sf_cr);
++  regcache->raw_supply (tdep->ppc_gp0_regnum + 2, &sf.sf_fixreg2);
+   for (i = 0 ; i < 19 ; i++)
+-    regcache->raw_supply (tdep->ppc_gp0_regnum + 13 + i, &sf.fixreg[i]);
++    regcache->raw_supply (tdep->ppc_gp0_regnum + 13 + i, &sf.sf_fixreg[i]);
+ 
+-  read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
+-  regcache->raw_supply (tdep->ppc_gp0_regnum + 30, &cf.r30);
+-  regcache->raw_supply (tdep->ppc_gp0_regnum + 31, &cf.r31);
+-  regcache->raw_supply (tdep->ppc_gp0_regnum + 1, &cf.sp);
+-
+-  read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
+-  regcache->raw_supply (tdep->ppc_lr_regnum, &cf.lr);
+-  regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &cf.lr);
++  read_memory(sf.sf_sp, (gdb_byte *)&cf, sizeof(cf));
++  regcache->raw_supply (tdep->ppc_gp0_regnum + 30, &cf.cf_r30);
++  regcache->raw_supply (tdep->ppc_gp0_regnum + 31, &cf.cf_r31);
++  regcache->raw_supply (tdep->ppc_gp0_regnum + 1, &cf.cf_sp);
++
++  read_memory(cf.cf_sp, (gdb_byte *)&cf, sizeof(cf));
++  regcache->raw_supply (tdep->ppc_lr_regnum, &cf.cf_lr);
++  regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &cf.cf_lr);
+ 
+   return 1;
+ }
diff --git a/gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-nat.c
new file mode 100644
index 0000000000..dcd9a534ec
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-nat.c
@@ -0,0 +1,81 @@
+$NetBSD$
+
+--- gdb/sh-nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/sh-nbsd-nat.c
+@@ -29,8 +29,10 @@
+ #include "sh-tdep.h"
+ #include "inf-ptrace.h"
+ #include "regcache.h"
++#include "inf-ptrace.h"
++#include "nbsd-nat.h"
+ 
+-struct sh_nbsd_nat_target final : public inf_ptrace_target
++struct sh_nbsd_nat_target final : public nbsd_nat_target
+ {
+   void fetch_registers (struct regcache *, int) override;
+   void store_registers (struct regcache *, int) override;
+@@ -43,26 +45,27 @@ static sh_nbsd_nat_target the_sh_nbsd_na
+   (((regno) >= R0_REGNUM && (regno) <= (R0_REGNUM + 15)) \
+ || (regno) == gdbarch_pc_regnum (gdbarch) || (regno) == PR_REGNUM \
+ || (regno) == MACH_REGNUM || (regno) == MACL_REGNUM \
+-|| (regno) == SR_REGNUM)
++|| (regno) == SR_REGNUM || (regno) == GBR_REGNUM)
+ 
+ /* Sizeof `struct reg' in <machine/reg.h>.  */
+-#define SHNBSD_SIZEOF_GREGS	(21 * 4)
++#define SHNBSD_SIZEOF_GREGS	(22 * 4)
+ 
+ void
+ sh_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
+ {
+-  pid_t pid = regcache->ptid ().pid ();
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+ 
+   if (regno == -1 || GETREGS_SUPPLIES (regcache->arch (), regno))
+     {
+-      struct reg inferior_registers;
++      struct reg regs;
+ 
+-      if (ptrace (PT_GETREGS, pid,
+-		  (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get registers"));
+ 
+       sh_corefile_supply_regset (&sh_corefile_gregset, regcache, regno,
+-				 (char *) &inferior_registers,
++				 (char *) &regs,
+ 				 SHNBSD_SIZEOF_GREGS);
+ 
+       if (regno != -1)
+@@ -73,22 +76,22 @@ sh_nbsd_nat_target::fetch_registers (str
+ void
+ sh_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
+ {
+-  pid_t pid = regcache->ptid ().pid ();
++  ptid_t ptid = regcache->ptid ();
++  pid_t pid = ptid.pid ();
++  int lwp = ptid.lwp ();
+ 
+   if (regno == -1 || GETREGS_SUPPLIES (regcache->arch (), regno))
+     {
+-      struct reg inferior_registers;
++      struct reg regs;
+ 
+-      if (ptrace (PT_GETREGS, pid,
+-		  (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+ 	perror_with_name (_("Couldn't get registers"));
+ 
+       sh_corefile_collect_regset (&sh_corefile_gregset, regcache, regno,
+-				  (char *) &inferior_registers,
++				  (char *) &regs,
+ 				  SHNBSD_SIZEOF_GREGS);
+ 
+-      if (ptrace (PT_SETREGS, pid,
+-		  (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
++      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
+ 	perror_with_name (_("Couldn't set registers"));
+ 
+       if (regno != -1)
diff --git a/gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.c
new file mode 100644
index 0000000000..eeba3725fa
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.c
@@ -0,0 +1,197 @@
+$NetBSD$
+
+--- gdb/sh-nbsd-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/sh-nbsd-tdep.c
+@@ -21,17 +21,26 @@
+ 
+ #include "defs.h"
+ #include "gdbcore.h"
++#include "inferior.h"
++#include "regcache.h"
+ #include "regset.h"
+ #include "value.h"
+ #include "osabi.h"
+ 
+-#include "sh-tdep.h"
++#include "trad-frame.h"
++#include "tramp-frame.h"
++
++#include "common/gdb_assert.h"
+ #include "solib-svr4.h"
++#include "sh-tdep.h"
++#include "sh-nbsd-tdep.h"
++#include "nbsd-tdep.h"
++
+ #include "gdbarch.h"
+ 
+ /* Convert a register number into an offset into a ptrace
+    register structure.  */
+-static const struct sh_corefile_regmap regmap[] =
++static const struct sh_corefile_regmap gregs_table[] =
+ {
+   {R0_REGNUM,      20 * 4},
+   {R0_REGNUM + 1,  19 * 4},
+@@ -54,9 +63,136 @@ static const struct sh_corefile_regmap r
+   {PR_REGNUM,	    2 * 4},
+   {MACH_REGNUM,	    3 * 4},
+   {MACL_REGNUM,	    4 * 4},
++  {GBR_REGNUM,	   21 * 4},
+   {-1 /* Terminator.  */, 0}
+ };
++
++
++#define REGSx16(base) \
++  {(base),      0}, \
++  {(base) +  1, 4}, \
++  {(base) +  2, 8}, \
++  {(base) +  3, 12}, \
++  {(base) +  4, 16}, \
++  {(base) +  5, 20}, \
++  {(base) +  6, 24}, \
++  {(base) +  7, 28}, \
++  {(base) +  8, 32}, \
++  {(base) +  9, 36}, \
++  {(base) + 10, 40}, \
++  {(base) + 11, 44}, \
++  {(base) + 12, 48}, \
++  {(base) + 13, 52}, \
++  {(base) + 14, 56}, \
++  {(base) + 15, 60}
++
++/* Convert an FPU register number into an offset into a ptrace
++   register structure.  */
++static const struct sh_corefile_regmap fpregs_table[] =
++{
++  REGSx16 (FR0_REGNUM),
++  /* XXX: REGSx16(XF0_REGNUM) omitted.  */
++  {FPSCR_REGNUM, 128},
++  {FPUL_REGNUM,  132},
++  {-1 /* Terminator.  */, 0}
++};
++
++
++/* From <machine/mcontext.h>.  */
++static const int shnbsd_mc_reg_offset[] =
++{
++  (20 * 4),	/* r0 */
++  (19 * 4),	/* r1 */
++  (18 * 4),	/* r2 */ 
++  (17 * 4),	/* r3 */ 
++  (16 * 4),	/* r4 */
++  (15 * 4),	/* r5 */
++  (14 * 4),	/* r6 */
++  (13 * 4),	/* r7 */
++  (12 * 4),	/* r8 */ 
++  (11 * 4),	/* r9 */
++  (10 * 4),	/* r10 */
++  ( 9 * 4),	/* r11 */
++  ( 8 * 4),	/* r12 */
++  ( 7 * 4),	/* r13 */
++  ( 6 * 4),	/* r14 */
++  (21 * 4),	/* r15/sp */
++  ( 1 * 4),	/* pc */
++  ( 5 * 4),	/* pr */
++  ( 0 * 4),	/* gbr */
++  -1,
++  ( 4 * 4),	/* mach */
++  ( 3 * 4),	/* macl */
++  ( 2 * 4),	/* sr */
++};
++
++/* SH register sets.  */
++
+ 
++static void
++shnbsd_sigtramp_cache_init (const struct tramp_frame *,
++			     struct frame_info *,
++			     struct trad_frame_cache *,
++			     CORE_ADDR);
++
++/* The siginfo signal trampoline for NetBSD/sh3 versions 2.0 and later */
++static const struct tramp_frame shnbsd_sigtramp_si2 =
++{
++  SIGTRAMP_FRAME,
++  2,
++  {
++    { 0x64f3, ULONGEST_MAX },			/* mov     r15,r4 */
++    { 0xd002, ULONGEST_MAX },			/* mov.l   .LSYS_setcontext */
++    { 0xc380, ULONGEST_MAX },			/* trapa   #-128 */
++    { 0xa003, ULONGEST_MAX },			/* bra     .Lskip1 */
++    { 0x0009, ULONGEST_MAX },			/* nop */
++    { 0x0009, ULONGEST_MAX },			/* nop */
++ /* .LSYS_setcontext */
++    { 0x0134, ULONGEST_MAX }, { 0x0000, ULONGEST_MAX },     /* 0x134 */
++ /* .Lskip1 */
++    { 0x6403, ULONGEST_MAX },			/* mov     r0,r4 */
++    { 0xd002, ULONGEST_MAX },			/* mov.l   .LSYS_exit  */
++    { 0xc380, ULONGEST_MAX },			/* trapa   #-128 */
++    { 0xa003, ULONGEST_MAX },			/* bra     .Lskip2 */
++    { 0x0009, ULONGEST_MAX },			/* nop */
++    { 0x0009, ULONGEST_MAX },			/* nop */
++ /* .LSYS_exit */
++    { 0x0001, ULONGEST_MAX }, { 0x0000, ULONGEST_MAX },     /* 0x1 */
++/* .Lskip2 */
++    { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
++  },
++  shnbsd_sigtramp_cache_init
++};
++
++static void
++shnbsd_sigtramp_cache_init (const struct tramp_frame *self,
++			    struct frame_info *next_frame,
++			    struct trad_frame_cache *this_cache,
++			    CORE_ADDR func)
++{
++  struct gdbarch *gdbarch = get_frame_arch (next_frame);
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  int sp_regnum = gdbarch_sp_regnum (gdbarch);
++  CORE_ADDR sp = get_frame_register_unsigned (next_frame, sp_regnum);
++  CORE_ADDR base;
++  const int *reg_offset;
++  int num_regs;
++  int i;
++
++  reg_offset = shnbsd_mc_reg_offset;
++  num_regs = ARRAY_SIZE (shnbsd_mc_reg_offset);
++  /* SP already points at the ucontext. */
++  base = sp;
++  /* offsetof(ucontext_t, uc_mcontext) == 36 */
++  base += 36;
++
++  for (i = 0; i < num_regs; i++)
++    if (reg_offset[i] != -1)
++      trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
++
++  /* Construct the frame ID using the function start.  */
++  trad_frame_set_id (this_cache, frame_id_build (sp, func));
++}
+ 
+ static void
+ shnbsd_init_abi (struct gdbarch_info info,
+@@ -64,11 +200,16 @@ shnbsd_init_abi (struct gdbarch_info inf
+ {
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ 
+-  tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
+-  tdep->sizeof_gregset = 84;
++  tdep->core_gregmap = (struct sh_corefile_regmap *)gregs_table;
++  tdep->sizeof_gregset = 88;
++
++  tdep->core_fpregmap = (struct sh_corefile_regmap *)fpregs_table;
++  tdep->sizeof_fpregset = 0;	/* XXX */
+ 
+   set_solib_svr4_fetch_link_map_offsets
+-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
++    (gdbarch, nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
++
++  tramp_frame_prepend_unwinder (gdbarch, &shnbsd_sigtramp_si2);
+ }
+ 
+ void
+@@ -76,6 +217,4 @@ _initialize_shnbsd_tdep (void)
+ {
+   gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD,
+ 			  shnbsd_init_abi);
+-  gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD,
+-			  shnbsd_init_abi);
+ }
diff --git a/gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.h b/gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.h
new file mode 100644
index 0000000000..765138b2b3
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_sh-nbsd-tdep.h
@@ -0,0 +1,33 @@
+$NetBSD$
+
+--- gdb/sh-nbsd-tdep.h.orig	2019-09-02 20:02:23.509331057 +0000
++++ gdb/sh-nbsd-tdep.h
+@@ -0,0 +1,28 @@
++/* Target-dependent definitions for SuperH running NetBSD, for GDB.
++   Copyright (C) 2002 Free Software Foundation, Inc.
++   Contributed by Wasabi Systems, Inc.
++
++   This file is part of GDB.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 2 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 51 Franklin Street, Fifth Floor,
++   Boston, MA 02110-1301, USA.  */
++
++#ifndef SH_NBSD_TDEP_H
++#define SH_NBSD_TDEP_H
++
++void shnbsd_supply_reg (struct regcache *, const char *, int);
++void shnbsd_fill_reg (const struct regcache *, char *, int);
++
++#endif /* SH_NBSD_TDEP_H */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-nat.c
new file mode 100644
index 0000000000..22540751c7
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-nat.c
@@ -0,0 +1,39 @@
+$NetBSD$
+
+--- gdb/sparc-nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/sparc-nbsd-nat.c
+@@ -21,13 +21,16 @@
+ #include "regcache.h"
+ #include "target.h"
+ 
++#include "nbsd-nat.h"
+ #include "sparc-tdep.h"
++#include "sparc-nbsd-tdep.h"
+ #include "sparc-nat.h"
+ 
+ /* Support for debugging kernel virtual memory images.  */
+ 
+ #include <sys/types.h>
+ #include <machine/pcb.h>
++#include <machine/reg.h>
+ 
+ #include "bsd-kvm.h"
+ 
+@@ -55,7 +58,7 @@ sparc32nbsd_supply_pcb (struct regcache 
+   return 1;
+ }
+ 
+-static sparc_target<inf_ptrace_target> the_sparc_nbsd_nat_target;
++static sparc_target<nbsd_nat_target> the_sparc_nbsd_nat_target;
+ 
+ void
+ _initialize_sparcnbsd_nat (void)
+@@ -63,7 +66,7 @@ _initialize_sparcnbsd_nat (void)
+   sparc_gregmap = &sparc32nbsd_gregmap;
+   sparc_fpregmap = &sparc32_bsd_fpregmap;
+ 
+-  add_inf_child_target (&sparc_nbsd_nat_target);
++  add_inf_child_target (&the_sparc_nbsd_nat_target);
+ 
+   /* Support debugging kernel virtual memory images.  */
+   bsd_kvm_add_target (sparc32nbsd_supply_pcb);
diff --git a/gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.c
new file mode 100644
index 0000000000..2c7e45d722
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.c
@@ -0,0 +1,41 @@
+$NetBSD$
+
+--- gdb/sparc-nbsd-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/sparc-nbsd-tdep.c
+@@ -32,6 +32,7 @@
+ #include "gdbarch.h"
+ 
+ #include "sparc-tdep.h"
++#include "sparc-nbsd-tdep.h"
+ #include "nbsd-tdep.h"
+ 
+ /* Macros to extract fields from SPARC instructions.  */
+@@ -291,7 +292,7 @@ static const struct regset sparc32nbsd_f
+     NULL, sparc32nbsd_supply_fpregset, NULL
+   };
+ 
+-void
++static void
+ sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+ {
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+@@ -310,6 +311,12 @@ sparc32nbsd_init_abi (struct gdbarch_inf
+   tdep->step_trap = sparcnbsd_step_trap;
+ 
+   frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
++}
++
++void
++sparc32nbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
++{
++  sparc32nbsd_init_abi (info, gdbarch);
+ 
+   set_solib_svr4_fetch_link_map_offsets
+     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+@@ -319,5 +326,5 @@ void
+ _initialize_sparcnbsd_tdep (void)
+ {
+   gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD,
+-			  sparc32nbsd_init_abi);
++			  sparc32nbsd_elf_init_abi);
+ }
diff --git a/gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.h b/gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.h
new file mode 100644
index 0000000000..5a0b8bd0f8
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_sparc-nbsd-tdep.h
@@ -0,0 +1,40 @@
+$NetBSD$
+
+--- gdb/sparc-nbsd-tdep.h.orig	2019-09-02 20:02:23.510217820 +0000
++++ gdb/sparc-nbsd-tdep.h
+@@ -0,0 +1,35 @@
++/* Target-dependent definitions for sparc running NetBSD, for GDB.
++   Copyright (C) 2017 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 2 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 51 Franklin Street, Fifth Floor,
++   Boston, MA 02110-1301, USA.  */
++
++#ifndef SPARC_NBSD_TDEP_H
++#define SPARC_NBSD_TDEP_H
++
++/* Register offsets for NetBSD.  */
++extern const struct sparc_gregmap sparc32nbsd_gregmap;
++
++/* Return the address of a system call's alternative return
++   address.  */
++extern CORE_ADDR sparcnbsd_step_trap (struct frame_info *frame,
++				      unsigned long insn);
++
++extern struct trad_frame_saved_reg *
++  sparc32nbsd_sigcontext_saved_regs (struct frame_info *next_frame);
++
++#endif /* SPARC_NBSD_TDEP_H */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_sparc-tdep.h b/gdb-netbsd-wip/patches/patch-gdb_sparc-tdep.h
new file mode 100644
index 0000000000..b43c35da85
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_sparc-tdep.h
@@ -0,0 +1,25 @@
+$NetBSD$
+
+--- gdb/sparc-tdep.h.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/sparc-tdep.h
+@@ -252,20 +252,4 @@ extern const char *sparc_sol2_static_tra
+ extern void sparc32_sol2_init_abi (struct gdbarch_info info,
+ 				   struct gdbarch *gdbarch);
+ 
+-/* Functions and variables exported from sparcnbsd-tdep.c.  */
+-
+-/* Register offsets for NetBSD.  */
+-extern const struct sparc_gregmap sparc32nbsd_gregmap;
+-
+-/* Return the address of a system call's alternative return
+-   address.  */
+-extern CORE_ADDR sparcnbsd_step_trap (struct frame_info *frame,
+-				      unsigned long insn);
+-
+-extern void sparc32nbsd_init_abi (struct gdbarch_info info,
+-				  struct gdbarch *gdbarch);
+-
+-extern struct trad_frame_saved_reg *
+-  sparc32nbsd_sigcontext_saved_regs (struct frame_info *next_frame);
+-
+ #endif /* sparc-tdep.h */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_sparc64-nbsd-nat.c b/gdb-netbsd-wip/patches/patch-gdb_sparc64-nbsd-nat.c
new file mode 100644
index 0000000000..bb2066b0a2
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_sparc64-nbsd-nat.c
@@ -0,0 +1,36 @@
+$NetBSD$
+
+--- gdb/sparc64-nbsd-nat.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/sparc64-nbsd-nat.c
+@@ -20,9 +20,13 @@
+ #include "defs.h"
+ #include "gdbcore.h"
+ #include "regcache.h"
++#include "inferior.h"
++#include "inf-ptrace.h"
+ #include "target.h"
+ 
++#include "nbsd-nat.h"
+ #include "sparc64-tdep.h"
++#include "sparc-nbsd-tdep.h"
+ #include "sparc-nat.h"
+ 
+ /* NetBSD is different from the other OSes that support both SPARC and
+@@ -106,8 +110,6 @@ sparc64nbsd_gregset_supplies_p (struct g
+   return 0;
+ }
+ 
+-/* Determine whether `fpregset_t' contains register REGNUM.  */
+-
+ static int
+ sparc64nbsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
+ {
+@@ -168,7 +170,7 @@ sparc64nbsd_supply_pcb (struct regcache 
+ }
+ 
+ /* We've got nothing to add to the generic SPARC target.  */
+-static sparc_target<inf_ptrace_target> the_sparc64_nbsd_nat_target;
++static sparc_target<nbsd_nat_target> the_sparc64_nbsd_nat_target;
+ 
+ void
+ _initialize_sparc64nbsd_nat (void)
diff --git a/gdb-netbsd-wip/patches/patch-gdb_sparc64-nbsd-tdep.c b/gdb-netbsd-wip/patches/patch-gdb_sparc64-nbsd-tdep.c
new file mode 100644
index 0000000000..16168be83f
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_sparc64-nbsd-tdep.c
@@ -0,0 +1,12 @@
+$NetBSD$
+
+--- gdb/sparc64-nbsd-tdep.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/sparc64-nbsd-tdep.c
+@@ -31,6 +31,7 @@
+ #include "trad-frame.h"
+ 
+ #include "sparc64-tdep.h"
++#include "sparc-nbsd-tdep.h"
+ #include "nbsd-tdep.h"
+ 
+ /* From <machine/reg.h>.  */
diff --git a/gdb-netbsd-wip/patches/patch-gdb_tui_tui-winsource.c b/gdb-netbsd-wip/patches/patch-gdb_tui_tui-winsource.c
new file mode 100644
index 0000000000..c801c96bf6
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-gdb_tui_tui-winsource.c
@@ -0,0 +1,14 @@
+$NetBSD$
+
+--- gdb/tui/tui-winsource.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ gdb/tui/tui-winsource.c
+@@ -545,6 +545,9 @@ tui_erase_exec_info_content (struct tui_
+ {
+   struct tui_gen_win_info *exec_info = win_info->execution_info;
+ 
++  if (exec_info->handle == NULL)
++    return;
++
+   werase (exec_info->handle);
+   exec_info->refresh_window ();
+ }
diff --git a/gdb-netbsd-wip/patches/patch-sim_common_callback.c b/gdb-netbsd-wip/patches/patch-sim_common_callback.c
new file mode 100644
index 0000000000..391bb030c1
--- /dev/null
+++ b/gdb-netbsd-wip/patches/patch-sim_common_callback.c
@@ -0,0 +1,17 @@
+$NetBSD$
+
+--- sim/common/callback.c.orig	2019-07-16 00:00:27.000000000 +0000
++++ sim/common/callback.c
+@@ -424,7 +424,11 @@ os_system (host_callback *p, const char 
+ static long
+ os_time (host_callback *p, long *t)
+ {
+-  return wrap (p, time (t));
++  long v = (long)time(NULL);
++
++  if (t != NULL)
++    *t = v;
++  return wrap (p, v);
+ }
+ 
+ 



Home | Main Index | Thread Index | Old Index