Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Aug 2017 16:07:43 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r448627 - in head/devel/gdb: . files files/kgdb
Message-ID:  <201708231607.v7NG7hVD070875@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb (src,doc committer)
Date: Wed Aug 23 16:07:42 2017
New Revision: 448627
URL: https://svnweb.freebsd.org/changeset/ports/448627

Log:
  Add aarch64 support to GDB.
  
  This includes support for cross-debugging aarch64 process cores and
  kernels as well as native support for aarch64 processes.  Hardware
  single stepping is supported, but hardware watchpoints are not yet
  supported.
  
  Reviewed by:	luca.pizzamiglio@gmail.com (maintainer)
  Approved by:	az (implicit)
  Differential Revision:	https://reviews.freebsd.org/D12074

Added:
  head/devel/gdb/files/kgdb/aarch64-fbsd-kern.c   (contents, props changed)
  head/devel/gdb/files/patch-aarch64-fbsd   (contents, props changed)
Modified:
  head/devel/gdb/Makefile
  head/devel/gdb/files/extrapatch-kgdb
  head/devel/gdb/files/kgdb/fbsd-kvm.c

Modified: head/devel/gdb/Makefile
==============================================================================
--- head/devel/gdb/Makefile	Wed Aug 23 14:54:04 2017	(r448626)
+++ head/devel/gdb/Makefile	Wed Aug 23 16:07:42 2017	(r448627)
@@ -3,7 +3,7 @@
 
 PORTNAME=	gdb
 PORTVERSION=	8.0
-PORTREVISION=	1
+PORTREVISION=	2
 CATEGORIES=	devel
 MASTER_SITES=	GNU
 
@@ -55,7 +55,7 @@ VER=		${PORTVERSION:S/.//g}
 PLIST_SUB=	VER=${VER}
 
 # untested elsewhere, might work
-ONLY_FOR_ARCHS=		amd64 armv6 i386 mips powerpc powerpc64	
+ONLY_FOR_ARCHS=	aarch64 amd64 armv6 i386 mips powerpc powerpc64	
 
 OPTIONS_DEFINE=	DEBUG GDB_LINK GUILE KGDB PYTHON TUI
 

Modified: head/devel/gdb/files/extrapatch-kgdb
==============================================================================
--- head/devel/gdb/files/extrapatch-kgdb	Wed Aug 23 14:54:04 2017	(r448626)
+++ head/devel/gdb/files/extrapatch-kgdb	Wed Aug 23 16:07:42 2017	(r448627)
@@ -1,5 +1,5 @@
 diff --git gdb/Makefile.in gdb/Makefile.in
-index 6e96a88a98..98c5fd2664 100644
+index cf59ae7143..0dd72d35d1 100644
 --- gdb/Makefile.in
 +++ gdb/Makefile.in
 @@ -227,7 +227,8 @@ INCGNU = -I$(srcdir)/gnulib/import -I$(GNULIB_BUILDDIR)/import
@@ -12,7 +12,15 @@ index 6e96a88a98..98c5fd2664 100644
  
  #
  # CLI sub directory definitons
-@@ -758,6 +759,7 @@ ALL_64_TARGET_OBS = \
+@@ -745,6 +746,7 @@ TARGET_OBS = @TARGET_OBS@
+ # All target-dependent objects files that require 64-bit CORE_ADDR
+ # (used with --enable-targets=all --enable-64-bit-bfd).
+ ALL_64_TARGET_OBS = \
++	aarch64-fbsd-kern.o \
+ 	aarch64-fbsd-tdep.o \
+ 	aarch64-insn.o \
+ 	aarch64-linux-tdep.o \
+@@ -759,6 +761,7 @@ ALL_64_TARGET_OBS = \
  	amd64-darwin-tdep.o \
  	amd64-dicos-tdep.o \
  	amd64-fbsd-tdep.o \
@@ -20,7 +28,7 @@ index 6e96a88a98..98c5fd2664 100644
  	amd64-linux-tdep.o \
  	amd64-nbsd-tdep.o \
  	amd64-obsd-tdep.o \
-@@ -769,6 +771,7 @@ ALL_64_TARGET_OBS = \
+@@ -770,6 +773,7 @@ ALL_64_TARGET_OBS = \
  	ia64-vms-tdep.o \
  	mips64-obsd-tdep.o \
  	sparc64-fbsd-tdep.o \
@@ -28,7 +36,7 @@ index 6e96a88a98..98c5fd2664 100644
  	sparc64-linux-tdep.o \
  	sparc64-nbsd-tdep.o \
  	sparc64-obsd-tdep.o \
-@@ -796,6 +799,9 @@ ALL_TARGET_OBS = \
+@@ -797,6 +801,9 @@ ALL_TARGET_OBS = \
  	cris-linux-tdep.o \
  	cris-tdep.o \
  	dicos-tdep.o \
@@ -38,7 +46,7 @@ index 6e96a88a98..98c5fd2664 100644
  	fbsd-tdep.o \
  	frv-linux-tdep.o \
  	frv-tdep.o \
-@@ -812,6 +818,7 @@ ALL_TARGET_OBS = \
+@@ -813,6 +820,7 @@ ALL_TARGET_OBS = \
  	i386-darwin-tdep.o \
  	i386-dicos-tdep.o \
  	i386-fbsd-tdep.o \
@@ -46,7 +54,7 @@ index 6e96a88a98..98c5fd2664 100644
  	i386-gnu-tdep.o \
  	i386-go32-tdep.o \
  	i386-linux-tdep.o \
-@@ -836,6 +843,7 @@ ALL_TARGET_OBS = \
+@@ -837,6 +845,7 @@ ALL_TARGET_OBS = \
  	mep-tdep.o \
  	microblaze-linux-tdep.o \
  	microblaze-tdep.o \
@@ -54,7 +62,7 @@ index 6e96a88a98..98c5fd2664 100644
  	mips-fbsd-tdep.o \
  	mips-linux-tdep.o \
  	mips-nbsd-tdep.o \
-@@ -853,6 +861,7 @@ ALL_TARGET_OBS = \
+@@ -854,6 +863,7 @@ ALL_TARGET_OBS = \
  	nto-tdep.o \
  	obsd-tdep.o \
  	ppc-fbsd-tdep.o \
@@ -62,7 +70,7 @@ index 6e96a88a98..98c5fd2664 100644
  	ppc-linux-tdep.o \
  	ppc-nbsd-tdep.o \
  	ppc-obsd-tdep.o \
-@@ -1870,7 +1879,7 @@ generated_files = \
+@@ -1871,7 +1881,7 @@ generated_files = \
  # Flags needed to compile Python code
  PYTHON_CFLAGS = @PYTHON_CFLAGS@
  
@@ -71,7 +79,7 @@ index 6e96a88a98..98c5fd2664 100644
  	@$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do
  
  # Rule for compiling .c files in the top-level gdb directory.
-@@ -2209,6 +2218,12 @@ gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
+@@ -2210,6 +2220,12 @@ gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
  		-o gdb$(EXEEXT) gdb.o $(LIBGDB_OBS) \
  		$(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES)
  
@@ -84,7 +92,7 @@ index 6e96a88a98..98c5fd2664 100644
  # Convenience rule to handle recursion.
  $(LIBGNU) $(GNULIB_H): all-lib
  all-lib: $(GNULIB_BUILDDIR)/Makefile
-@@ -2253,7 +2268,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
+@@ -2254,7 +2270,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
  	@$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(CLEANDIRS)" subdir_do
  	rm -f *.o *.a $(ADD_FILES) *~ init.c-tmp init.l-tmp version.c-tmp
  	rm -f init.c version.c observer.h observer.inc
@@ -93,7 +101,15 @@ index 6e96a88a98..98c5fd2664 100644
  	rm -f gdb[0-9]$(EXEEXT)
  	rm -f test-cp-name-parser$(EXEEXT)
  	rm -f xml-builtin.c stamp-xml
-@@ -2475,6 +2490,7 @@ ALLDEPFILES = \
+@@ -2461,6 +2477,7 @@ MAKEOVERRIDES =
+ 
+ ALLDEPFILES = \
+ 	aarch64-fbsd-nat.c \
++	aarch64-fbsd-kern.c \
+ 	aarch64-fbsd-tdep.c \
+ 	aarch64-linux-nat.c \
+ 	aarch64-linux-tdep.c \
+@@ -2478,6 +2495,7 @@ ALLDEPFILES = \
  	amd64-bsd-nat.c \
  	amd64-darwin-tdep.c \
  	amd64-dicos-tdep.c \
@@ -101,7 +117,7 @@ index 6e96a88a98..98c5fd2664 100644
  	amd64-fbsd-nat.c \
  	amd64-fbsd-tdep.c \
  	amd64-linux-nat.c \
-@@ -2510,6 +2526,9 @@ ALLDEPFILES = \
+@@ -2513,6 +2531,9 @@ ALLDEPFILES = \
  	dcache.c \
  	dicos-tdep.c \
  	exec.c \
@@ -111,7 +127,7 @@ index 6e96a88a98..98c5fd2664 100644
  	fbsd-nat.c \
  	fbsd-tdep.c \
  	fork-child.c \
-@@ -2531,6 +2550,7 @@ ALLDEPFILES = \
+@@ -2534,6 +2555,7 @@ ALLDEPFILES = \
  	i386-darwin-nat.c \
  	i386-darwin-tdep.c \
  	i386-dicos-tdep.c \
@@ -119,7 +135,7 @@ index 6e96a88a98..98c5fd2664 100644
  	i386-fbsd-nat.c \
  	i386-fbsd-tdep.c \
  	i386-gnu-nat.c \
-@@ -2572,6 +2592,7 @@ ALLDEPFILES = \
+@@ -2575,6 +2597,7 @@ ALLDEPFILES = \
  	mingw-hdep.c \
  	mips-fbsd-nat.c \
  	mips-fbsd-tdep.c \
@@ -127,7 +143,7 @@ index 6e96a88a98..98c5fd2664 100644
  	mips-linux-nat.c \
  	mips-linux-tdep.c \
  	mips-nbsd-nat.c \
-@@ -2589,6 +2610,7 @@ ALLDEPFILES = \
+@@ -2592,6 +2615,7 @@ ALLDEPFILES = \
  	obsd-nat.c \
  	obsd-tdep.c \
  	posix-hdep.c \
@@ -135,7 +151,7 @@ index 6e96a88a98..98c5fd2664 100644
  	ppc-fbsd-nat.c \
  	ppc-fbsd-tdep.c \
  	ppc-linux-nat.c \
-@@ -2633,6 +2655,7 @@ ALLDEPFILES = \
+@@ -2636,6 +2660,7 @@ ALLDEPFILES = \
  	sparc-sol2-nat.c \
  	sparc-sol2-tdep.c \
  	sparc-tdep.c \
@@ -143,7 +159,7 @@ index 6e96a88a98..98c5fd2664 100644
  	sparc64-fbsd-nat.c \
  	sparc64-fbsd-tdep.c \
  	sparc64-linux-nat.c \
-@@ -2664,6 +2687,12 @@ ALLDEPFILES = \
+@@ -2667,6 +2692,12 @@ ALLDEPFILES = \
  	xtensa-linux-tdep.c \
  	xtensa-tdep.c \
  	xtensa-xtregs.c \
@@ -156,7 +172,7 @@ index 6e96a88a98..98c5fd2664 100644
  	common/mingw-strerror.c \
  	common/posix-strerror.c
  
-@@ -2925,7 +2954,7 @@ endif
+@@ -2928,7 +2959,7 @@ endif
  
  # A list of all the objects we might care about in this build, for
  # dependency tracking.
@@ -277,10 +293,10 @@ index 50f6f592ba..89cdc9cc8e 100644
  
  # GDB may fork/exec the iconv program to get the list of supported character
 diff --git gdb/configure.tgt gdb/configure.tgt
-index fdcb7b1d69..d99aa325ab 100644
+index f72a0dbbc1..2d73300961 100644
 --- gdb/configure.tgt
 +++ gdb/configure.tgt
-@@ -198,7 +198,13 @@ i[34567]86-*-dicos*)
+@@ -203,7 +203,13 @@ i[34567]86-*-dicos*)
  i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
  	# Target: FreeBSD/i386
  	gdb_target_obs="i386-tdep.o i387-tdep.o i386-bsd-tdep.o i386-fbsd-tdep.o \
@@ -295,7 +311,7 @@ index fdcb7b1d69..d99aa325ab 100644
  	;;
  i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
  	# Target: NetBSD/i386
-@@ -372,7 +378,8 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
+@@ -377,7 +383,8 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
  	;;
  mips*-*-freebsd*)
  	# Target: MIPS running FreeBSD
@@ -305,7 +321,7 @@ index fdcb7b1d69..d99aa325ab 100644
  	gdb_sim=../sim/mips/libsim.a
  	;;
  mips64*-*-openbsd*)
-@@ -431,7 +438,8 @@ powerpc*-*-freebsd*)
+@@ -436,7 +443,8 @@ powerpc*-*-freebsd*)
  	# Target: FreeBSD/powerpc
  	gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
  		        ppc-fbsd-tdep.o fbsd-tdep.o solib-svr4.o \
@@ -315,7 +331,7 @@ index fdcb7b1d69..d99aa325ab 100644
  	;;
  
  powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
-@@ -555,7 +563,8 @@ sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
+@@ -560,7 +568,8 @@ sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
  	# Target: FreeBSD/sparc64
  	gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64-fbsd-tdep.o \
  			fbsd-tdep.o solib-svr4.o \
@@ -325,7 +341,7 @@ index fdcb7b1d69..d99aa325ab 100644
  	;;
  sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
  	# Target: NetBSD/sparc
-@@ -686,7 +695,9 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
+@@ -691,7 +700,9 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
  	# Target: FreeBSD/amd64
  	gdb_target_obs="amd64-tdep.o amd64-fbsd-tdep.o i386-tdep.o \
  			i387-tdep.o i386-bsd-tdep.o i386-fbsd-tdep.o \

Added: head/devel/gdb/files/kgdb/aarch64-fbsd-kern.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/gdb/files/kgdb/aarch64-fbsd-kern.c	Wed Aug 23 16:07:42 2017	(r448627)
@@ -0,0 +1,196 @@
+/*-
+ * Copyright (c) 2017 John Baldwin <jhb@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* Target-dependent code for FreeBSD/aarch64 kernels.  */
+
+#include "defs.h"
+
+#include "aarch64-tdep.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "solib.h"
+#include "target.h"
+#include "trad-frame.h"
+
+#include "kgdb.h"
+
+static const struct regcache_map_entry aarch64_fbsd_pcbmap[] =
+  {
+    { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */
+    { 1, AARCH64_LR_REGNUM, 8 },
+    { 1, AARCH64_SP_REGNUM, 8 },
+    { 1, AARCH64_PC_REGNUM, 8 },
+    { 0 }
+  };
+
+static const struct regset aarch64_fbsd_pcbregset =
+  {
+    aarch64_fbsd_pcbmap,
+    regcache_supply_regset, regcache_collect_regset
+  };
+
+static void
+aarch64_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr)
+{
+  gdb_byte buf[8 * 33];
+
+  if (target_read_memory (pcb_addr, buf, sizeof buf) == 0)
+    regcache_supply_regset (&aarch64_fbsd_pcbregset, regcache, -1, buf,
+			    sizeof (buf));
+}
+
+static struct trad_frame_cache *
+aarch64_fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  struct trad_frame_cache *cache;
+  CORE_ADDR addr, func, pc, sp;
+  const char *name;
+  int i;
+
+  if (*this_cache != NULL)
+    return ((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, AARCH64_SP_REGNUM);
+
+  find_pc_partial_function (func, &name, NULL, NULL);
+  if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func)
+    {
+      /* fork_exit hasn't been called (kthread has never run), so SP
+	 hasn't been initialized yet.  The stack pointer is stored in
+	 the X2 in the pcb.  */
+      sp = get_frame_register_unsigned (this_frame, AARCH64_X0_REGNUM + 2);
+    }
+
+  trad_frame_set_reg_addr (cache, AARCH64_SP_REGNUM, sp);
+  trad_frame_set_reg_addr (cache, AARCH64_LR_REGNUM, sp + 8);
+  trad_frame_set_reg_addr (cache, AARCH64_PC_REGNUM, sp + 16);
+  trad_frame_set_reg_addr (cache, AARCH64_CPSR_REGNUM, sp + 24);
+  for (i = 0; i < 30; i++)
+    trad_frame_set_reg_addr (cache, AARCH64_X0_REGNUM + 1, sp + 32 + i * 8);
+
+  /* Read $PC from trap frame.  */
+  pc = read_memory_unsigned_integer (sp + 16, 8, byte_order);
+
+  if (pc == 0 && strcmp(name, "fork_trampoline") == 0)
+    {
+      /* Initial frame of a kthread; terminate backtrace.  */
+      trad_frame_set_id (cache, outer_frame_id);
+    }
+  else
+    {
+      /* Construct the frame ID using the function start.  */
+      trad_frame_set_id (cache, frame_id_build (sp + 8 * 34, func));
+    }
+
+  return cache;
+}
+
+static void
+aarch64_fbsd_trapframe_this_id (struct frame_info *this_frame,
+			     void **this_cache, struct frame_id *this_id)
+{
+  struct trad_frame_cache *cache =
+    aarch64_fbsd_trapframe_cache (this_frame, this_cache);
+  
+  trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+aarch64_fbsd_trapframe_prev_register (struct frame_info *this_frame,
+				   void **this_cache, int regnum)
+{
+  struct trad_frame_cache *cache =
+    aarch64_fbsd_trapframe_cache (this_frame, this_cache);
+
+  return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static int
+aarch64_fbsd_trapframe_sniffer (const struct frame_unwind *self,
+				struct frame_info *this_frame,
+				void **this_prologue_cache)
+{
+  const char *name;
+
+  find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL);
+  return (name && ((strcmp (name, "handle_el1h_sync") == 0)
+		   || (strcmp (name, "handle_el1h_irq") == 0)
+		   || (strcmp (name, "handle_el0h_sync") == 0)
+		   || (strcmp (name, "handle_el0h_irq") == 0)
+		   || (strcmp (name, "handle_el0h_error") == 0)
+		   || (strcmp (name, "fork_trampoline") == 0)));
+}
+
+static const struct frame_unwind aarch64_fbsd_trapframe_unwind = {
+  SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
+  aarch64_fbsd_trapframe_this_id,
+  aarch64_fbsd_trapframe_prev_register,
+  NULL,
+  aarch64_fbsd_trapframe_sniffer
+};
+
+/* Implement the 'init_osabi' method of struct gdb_osabi_handler.  */
+
+static void
+aarch64_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  frame_unwind_prepend_unwinder (gdbarch, &aarch64_fbsd_trapframe_unwind);
+
+  set_solib_ops (gdbarch, &kld_so_ops);
+
+  /* Enable longjmp.  */
+  tdep->jb_pc = 13;
+
+  fbsd_vmcore_set_supply_pcb (gdbarch, aarch64_fbsd_supply_pcb);
+  fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_aarch64_kgdb_tdep;
+
+void
+_initialize_aarch64_kgdb_tdep (void)
+{
+  gdbarch_register_osabi_sniffer(bfd_arch_aarch64,
+				 bfd_target_elf_flavour,
+				 fbsd_kernel_osabi_sniffer);
+  gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_FREEBSD_KERNEL,
+			  aarch64_fbsd_kernel_init_abi);
+}

Modified: head/devel/gdb/files/kgdb/fbsd-kvm.c
==============================================================================
--- head/devel/gdb/files/kgdb/fbsd-kvm.c	Wed Aug 23 14:54:04 2017	(r448626)
+++ head/devel/gdb/files/kgdb/fbsd-kvm.c	Wed Aug 23 16:07:42 2017	(r448627)
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <inferior.h>
 #include <language.h>
 #include "objfiles.h"
+#include "osabi.h"
 #include <regcache.h>
 #include <solib.h>
 #include <target.h>
@@ -185,9 +186,30 @@ fbsd_kernel_osabi_sniffer(bfd *abfd)
 	bfd_byte buf[sizeof(KERNEL_INTERP)];
 	bfd_byte *bufp;
 
-	/* FreeBSD ELF kernels have a FreeBSD/ELF OS ABI. */
-	if (elf_elfheader(abfd)->e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
+	/* First, determine if this is a FreeBSD/ELF binary. */
+	switch (elf_elfheader(abfd)->e_ident[EI_OSABI]) {
+	case ELFOSABI_FREEBSD:
+		break;
+	case ELFOSABI_NONE: {
+		enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+		bfd_map_over_sections (abfd,
+		    generic_elf_osabi_sniff_abi_tag_sections,
+		    &osabi);
+
+		/*
+		 * aarch64 kernels don't have the right note tag for
+		 * kernels so just look for /red/herring anyway.
+		 */
+		if (osabi == GDB_OSABI_UNKNOWN &&
+		    elf_elfheader(abfd)->e_machine == EM_AARCH64)
+			break;
+		if (osabi != GDB_OSABI_FREEBSD)
+			return (GDB_OSABI_UNKNOWN);
+	}
+	default:
 		return (GDB_OSABI_UNKNOWN);
+	}
 
 	/* FreeBSD ELF kernels have an interpreter path of "/red/herring". */
 	bufp = buf;

Added: head/devel/gdb/files/patch-aarch64-fbsd
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/gdb/files/patch-aarch64-fbsd	Wed Aug 23 16:07:42 2017	(r448627)
@@ -0,0 +1,470 @@
+diff --git gdb/Makefile.in gdb/Makefile.in
+index 1d2dbaf3f7..d8e2b49523 100644
+--- gdb/Makefile.in
++++ gdb/Makefile.in
+@@ -745,6 +745,7 @@ TARGET_OBS = @TARGET_OBS@
+ # All target-dependent objects files that require 64-bit CORE_ADDR
+ # (used with --enable-targets=all --enable-64-bit-bfd).
+ ALL_64_TARGET_OBS = \
++	aarch64-fbsd-tdep.o \
+ 	aarch64-insn.o \
+ 	aarch64-linux-tdep.o \
+ 	aarch64-newlib-tdep.o \
+@@ -2458,6 +2459,8 @@ force_update:
+ MAKEOVERRIDES =
+ 
+ ALLDEPFILES = \
++	aarch64-fbsd-nat.c \
++	aarch64-fbsd-tdep.c \
+ 	aarch64-linux-nat.c \
+ 	aarch64-linux-tdep.c \
+ 	aarch64-newlib-tdep.c \
+diff --git gdb/aarch64-fbsd-nat.c gdb/aarch64-fbsd-nat.c
+new file mode 100644
+index 0000000000..f7855b9c0b
+--- /dev/null
++++ gdb/aarch64-fbsd-nat.c
+@@ -0,0 +1,133 @@
++/* Native-dependent code for FreeBSD/aarch64.
++
++   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 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/reg.h>
++
++#include "fbsd-nat.h"
++#include "aarch64-tdep.h"
++#include "aarch64-fbsd-tdep.h"
++#include "inf-ptrace.h"
++
++/* Determine if PT_GETREGS fetches REGNUM.  */
++
++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);
++}
++
++/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
++   for all registers.  */
++
++static void
++aarch64_fbsd_fetch_inferior_registers (struct target_ops *ops,
++				       struct regcache *regcache, int regnum)
++{
++  pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
++
++  struct gdbarch *gdbarch = get_regcache_arch (regcache);
++  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
++    {
++      struct reg regs;
++
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++	perror_with_name (_("Couldn't get registers"));
++
++      regcache_supply_regset (&aarch64_fbsd_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, 0) == -1)
++	perror_with_name (_("Couldn't get floating point status"));
++
++      regcache_supply_regset (&aarch64_fbsd_fpregset, regcache, regnum, &fpregs,
++			      sizeof (fpregs));
++    }
++}
++
++/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
++   this for all registers.  */
++
++static void
++aarch64_fbsd_store_inferior_registers (struct target_ops *ops,
++				       struct regcache *regcache, int regnum)
++{
++  pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
++
++  struct gdbarch *gdbarch = get_regcache_arch (regcache);
++  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
++    {
++      struct reg regs;
++
++      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
++	perror_with_name (_("Couldn't get registers"));
++
++      regcache_collect_regset (&aarch64_fbsd_gregset, regcache, regnum, &regs,
++			       sizeof (regs));
++
++      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -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, 0) == -1)
++	perror_with_name (_("Couldn't get floating point status"));
++
++      regcache_collect_regset (&aarch64_fbsd_fpregset, regcache, regnum, &fpregs,
++			       sizeof (fpregs));
++
++      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
++	perror_with_name (_("Couldn't write floating point status"));
++    }
++}
++
++
++/* Provide a prototype to silence -Wmissing-prototypes.  */
++void _initialize_aarch64_fbsd_nat (void);
++
++void
++_initialize_aarch64_fbsd_nat (void)
++{
++  struct target_ops *t;
++
++  t = inf_ptrace_target ();
++  t->to_fetch_registers = aarch64_fbsd_fetch_inferior_registers;
++  t->to_store_registers = aarch64_fbsd_store_inferior_registers;
++  fbsd_nat_add_target (t);
++}
+diff --git gdb/aarch64-fbsd-tdep.c gdb/aarch64-fbsd-tdep.c
+new file mode 100644
+index 0000000000..f8ce627282
+--- /dev/null
++++ gdb/aarch64-fbsd-tdep.c
+@@ -0,0 +1,208 @@
++/* Target-dependent code for FreeBSD/aarch64.
++
++   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 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 "fbsd-tdep.h"
++#include "aarch64-tdep.h"
++#include "aarch64-fbsd-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_fbsd_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_fbsd_sigframe =
++{
++  SIGTRAMP_FRAME,
++  4,
++  {
++    {0x910003e0, -1},		/* mov  x0, sp  */
++    {0x91014000, -1},		/* add  x0, x0, #SF_UC  */
++    {0xd2803428, -1},		/* mov  x8, #SYS_sigreturn  */
++    {0xd4000001, -1},		/* svc  0x0  */
++    {TRAMP_SENTINEL_INSN, -1}
++  },
++  aarch64_fbsd_sigframe_init
++};
++
++/* Register maps.  */
++
++static const struct regcache_map_entry aarch64_fbsd_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_fbsd_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_fbsd_gregset =
++  {
++    aarch64_fbsd_gregmap,
++    regcache_supply_regset, regcache_collect_regset
++  };
++
++const struct regset aarch64_fbsd_fpregset =
++  {
++    aarch64_fbsd_fpregmap,
++    regcache_supply_regset, regcache_collect_regset
++  };
++
++/* Implement the "regset_from_core_section" gdbarch method.  */
++
++static void
++aarch64_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
++					   iterate_over_regset_sections_cb *cb,
++					   void *cb_data,
++					   const struct regcache *regcache)
++{
++  cb (".reg", AARCH64_FBSD_SIZEOF_GREGSET, &aarch64_fbsd_gregset,
++      NULL, cb_data);
++  cb (".reg2", AARCH64_FBSD_SIZEOF_FPREGSET, &aarch64_fbsd_fpregset,
++      NULL, cb_data);
++}
++
++/* Implement the 'init_osabi' method of struct gdb_osabi_handler.  */
++
++static void
++aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++
++  /* Generic FreeBSD support.  */
++  fbsd_init_abi (info, gdbarch);
++
++  set_solib_svr4_fetch_link_map_offsets (gdbarch,
++					 svr4_lp64_fetch_link_map_offsets);
++
++  tramp_frame_prepend_unwinder (gdbarch, &aarch64_fbsd_sigframe);
++
++  /* Enable longjmp.  */
++  tdep->jb_pc = 13;
++
++  set_gdbarch_iterate_over_regset_sections
++    (gdbarch, aarch64_fbsd_iterate_over_regset_sections);
++}
++
++/* Provide a prototype to silence -Wmissing-prototypes.  */
++extern initialize_file_ftype _initialize_aarch64_fbsd_tdep;
++
++void
++_initialize_aarch64_fbsd_tdep (void)
++{
++  gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_FREEBSD,
++			  aarch64_fbsd_init_abi);
++}
+diff --git gdb/aarch64-fbsd-tdep.h gdb/aarch64-fbsd-tdep.h
+new file mode 100644
+index 0000000000..0f66dd3925
+--- /dev/null
++++ gdb/aarch64-fbsd-tdep.h
+@@ -0,0 +1,33 @@
++/* FreeBSD/aarch64 target support, prototypes.
++
++   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 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 30 X registers, plus LR, SP,
++   ELR, and SPSR registers.  SPSR is 32 bits but the structure is
++   passed to 64 bit alignment.  */
++#define AARCH64_FBSD_SIZEOF_GREGSET  (34 * 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_FBSD_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
++
++extern const struct regset aarch64_fbsd_gregset;
++extern const struct regset aarch64_fbsd_fpregset;
+diff --git gdb/config/aarch64/fbsd.mh gdb/config/aarch64/fbsd.mh
+new file mode 100644
+index 0000000000..4171987bc9
+--- /dev/null
++++ gdb/config/aarch64/fbsd.mh
+@@ -0,0 +1,23 @@
++#  Host: Freebsd/aarch64
++#
++#  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 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/>.
++
++NATDEPFILES= inf-ptrace.o fork-child.o aarch64-fbsd-nat.o fbsd-nat.o 
++HAVE_NATIVE_GCORE_HOST = 1
++
++LOADLIBES= -lkvm
+diff --git gdb/configure.host gdb/configure.host
+index d74fd04934..304675f137 100644
+--- gdb/configure.host
++++ gdb/configure.host
+@@ -84,6 +84,7 @@ case "${host}" in
+ *-*-darwin*)		gdb_host=darwin ;;
+ 
+ aarch64*-*-linux*)	gdb_host=linux ;;
++aarch64*-*-freebsd*)	gdb_host=fbsd ;;
+ 
+ alpha*-*-linux*)	gdb_host=alpha-linux ;;
+ alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu)
+diff --git gdb/configure.tgt gdb/configure.tgt
+index fdcb7b1d69..f72a0dbbc1 100644
+--- gdb/configure.tgt
++++ gdb/configure.tgt
+@@ -44,6 +44,11 @@ aarch64*-*-elf | aarch64*-*-rtems*)
+ 	gdb_target_obs="aarch64-tdep.o aarch64-newlib-tdep.o aarch64-insn.o"
+ 	;;
+ 
++aarch64*-*-freebsd*)
++	# Target: FreeBSD/aarch64
++	gdb_target_obs="aarch64-tdep.o aarch64-fbsd-tdep.o aarch64-insn.o"
++	;;
++
+ aarch64*-*-linux*)
+ 	# Target: AArch64 linux
+ 	gdb_target_obs="aarch64-tdep.o aarch64-linux-tdep.o aarch64-insn.o \



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201708231607.v7NG7hVD070875>