svn commit: r448627 - in head/devel/gdb: . files files/kgdb
John Baldwin
jhb at FreeBSD.org
Wed Aug 23 16:07:44 UTC 2017
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 at 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 at 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) ®s, 0) == -1)
++ perror_with_name (_("Couldn't get registers"));
++
++ regcache_supply_regset (&aarch64_fbsd_gregset, regcache, regnum, ®s,
++ 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) ®s, 0) == -1)
++ perror_with_name (_("Couldn't get registers"));
++
++ regcache_collect_regset (&aarch64_fbsd_gregset, regcache, regnum, ®s,
++ sizeof (regs));
++
++ if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 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 \
More information about the svn-ports-head
mailing list