Here is a cleaned-up version of a diff that Dale made to support OpenBSD/arm64 in gdb. Single-stepping doesn't work yet, which means that stepping through the code doesn't really work. But setting breakpoints and inspecting state or looking at core files should work.
I'm not sure what to do with the lang/ocaml comment in the Makefile. ok? Index: devel/gdb/Makefile =================================================================== RCS file: /cvs/ports/devel/gdb/Makefile,v retrieving revision 1.54 diff -u -p -r1.54 Makefile --- devel/gdb/Makefile 18 Jun 2018 14:53:12 -0000 1.54 +++ devel/gdb/Makefile 10 Jul 2018 09:44:47 -0000 @@ -1,13 +1,12 @@ # $OpenBSD: Makefile,v 1.54 2018/06/18 14:53:12 kettenis Exp $ # adjust lang/ocaml if gdb is ported to aarch64 -NOT_FOR_ARCHS= aarch64 COMMENT= GNU debugger CATEGORIES= devel DISTNAME= gdb-7.12.1 -REVISION= 2 +REVISION= 3 HOMEPAGE= https://www.gnu.org/software/gdb/ Index: devel/gdb/patches/patch-bfd_config_bfd =================================================================== RCS file: devel/gdb/patches/patch-bfd_config_bfd diff -N devel/gdb/patches/patch-bfd_config_bfd --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ devel/gdb/patches/patch-bfd_config_bfd 10 Jul 2018 09:44:47 -0000 @@ -0,0 +1,15 @@ +$OpenBSD$ +--- bfd/config.bfd.orig Sat Jan 21 05:48:42 2017 ++++ bfd/config.bfd Tue Mar 7 22:55:11 2017 +@@ -202,6 +202,11 @@ case "${targ}" in + 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-*-openbsd*) ++ targ_defvec=aarch64_elf64_le_vec ++ targ_selvecs="aarch64_elf32_le_vec arm_elf32_le_vec" ++ want64=true ++ ;; + aarch64_be-*-linux*) + 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" Index: devel/gdb/patches/patch-gdb_Makefile_in =================================================================== RCS file: devel/gdb/patches/patch-gdb_Makefile_in diff -N devel/gdb/patches/patch-gdb_Makefile_in --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ devel/gdb/patches/patch-gdb_Makefile_in 10 Jul 2018 09:44:47 -0000 @@ -0,0 +1,24 @@ +$OpenBSD$ +Index: gdb/Makefile.in +--- gdb/Makefile.in.orig ++++ gdb/Makefile.in +@@ -644,7 +644,8 @@ 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-tdep.o aarch64-linux-tdep.o aarch64-newlib-tdep.o aarch64-insn.o \ ++ aarch64-tdep.o aarch64-linux-tdep.o \ ++ aarch64-newlib-tdep.o aarch64obsd-tdep.o aarch64-insn.o \ + alphabsd-tdep.o alphafbsd-tdep.o alpha-linux-tdep.o alpha-mdebug-tdep.o \ + alphanbsd-tdep.o alphaobsd-tdep.o alpha-tdep.o \ + amd64fbsd-tdep.o amd64-darwin-tdep.o amd64-dicos-tdep.o \ +@@ -1663,7 +1664,8 @@ MAKEOVERRIDES= + + ALLDEPFILES = \ + aarch64-tdep.c aarch64-linux-tdep.c aarch64-newlib-tdep.c \ +- aarch64-linux-nat.c \ ++ aarch64obsd-tdep.c \ ++ aarch64-linux-nat.c aarch64obsd-nat.c \ + aix-thread.c \ + alphabsd-nat.c alpha-linux-nat.c \ + alpha-tdep.c alpha-mdebug-tdep.c \ Index: devel/gdb/patches/patch-gdb_aarch64obsd-nat_c =================================================================== RCS file: devel/gdb/patches/patch-gdb_aarch64obsd-nat_c diff -N devel/gdb/patches/patch-gdb_aarch64obsd-nat_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ devel/gdb/patches/patch-gdb_aarch64obsd-nat_c 10 Jul 2018 09:44:47 -0000 @@ -0,0 +1,210 @@ +$OpenBSD$ +Index: gdb/aarch64obsd-nat.c +--- gdb/aarch64obsd-nat.c.orig ++++ gdb/aarch64obsd-nat.c +@@ -0,0 +1,205 @@ ++/* Native-dependent code for OpenBSD/arm64 (AArch64) ++ ++ Copyright (C) 2011-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 "gdbcore.h" ++#include "inferior.h" ++#include "regcache.h" ++#include <sys/types.h> ++#include <sys/ptrace.h> ++#include <machine/reg.h> ++ ++#include "aarch64-tdep.h" ++#include "inf-ptrace.h" ++ ++/* Fill GDB's register array with the general-purpose register values ++ from the current thread. */ ++ ++static void ++fetch_gregs_from_thread (struct regcache *regcache) ++{ ++ struct reg regs; ++ pid_t pid; ++ int regno; ++ int ret; ++ ++ pid = ptid_get_pid (inferior_ptid); ++ ++ ret = ptrace(PT_GETREGS, pid, (caddr_t)®s, 0); ++ if (ret < 0) ++ perror_with_name (_("Unable to fetch general registers.")); ++ ++ for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_FP_REGNUM; regno++) ++ regcache_raw_supply (regcache, regno, ®s.r_reg[regno]); ++ regcache_raw_supply (regcache, AARCH64_LR_REGNUM, ®s.r_lr); ++ regcache_raw_supply (regcache, AARCH64_SP_REGNUM, ®s.r_sp); ++ regcache_raw_supply (regcache, AARCH64_PC_REGNUM, ®s.r_pc); ++ regcache_raw_supply (regcache, AARCH64_CPSR_REGNUM, ®s.r_spsr); ++} ++ ++/* Store to the current thread the valid general-purpose register ++ values in the GDB's register array. */ ++ ++static void ++store_gregs_to_thread (const struct regcache *regcache) ++{ ++ struct reg regs; ++ pid_t pid; ++ int regno; ++ int ret; ++ ++ pid = ptid_get_pid (inferior_ptid); ++ ++ // fetch old values as only 'valid' entries will be replaced. ++ ret = ptrace(PT_GETREGS, pid, (caddr_t)®s, 0); ++ if (ret < 0) { ++ perror_with_name (_("Unable to store general registers.")); ++ return; ++ } ++ ++ for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_FP_REGNUM; regno++) ++ if (REG_VALID == regcache_register_status (regcache, regno)) ++ regcache_raw_collect (regcache, regno, ®s.r_reg[regno]); ++ if (REG_VALID == regcache_register_status (regcache, AARCH64_LR_REGNUM)) ++ regcache_raw_collect (regcache, AARCH64_LR_REGNUM, ®s.r_lr); ++ if (REG_VALID == regcache_register_status (regcache, AARCH64_SP_REGNUM)) ++ regcache_raw_collect (regcache, AARCH64_SP_REGNUM, ®s.r_sp); ++ if (REG_VALID == regcache_register_status (regcache, AARCH64_PC_REGNUM)) ++ regcache_raw_collect (regcache, AARCH64_PC_REGNUM, ®s.r_pc); ++ if (REG_VALID == regcache_register_status (regcache, AARCH64_CPSR_REGNUM)) ++ regcache_raw_collect (regcache, AARCH64_CPSR_REGNUM, ®s.r_spsr); ++ ++ ret = ptrace(PT_SETREGS, pid, (caddr_t)®s, 0); ++ if (ret < 0) ++ perror_with_name (_("Unable to store general registers.")); ++} ++ ++/* Fill GDB's register array with the fp/simd register values ++ from the current thread. */ ++ ++static void ++fetch_fpregs_from_thread (struct regcache *regcache) ++{ ++ int ret; ++ pid_t pid; ++ int regno; ++ struct fpreg fpregs; ++ ++ pid = ptid_get_pid (inferior_ptid); ++ ++ ret = ptrace(PT_GETFPREGS, pid, (caddr_t)&fpregs, 0); ++ if (ret < 0) { ++ perror_with_name (_("Unable to fetch general registers.")); ++ return; ++ } ++ ++ for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++) ++ regcache_raw_supply (regcache, regno, &fpregs.fp_reg[regno]); ++ ++ regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM, &fpregs.fp_sr); ++ regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM, &fpregs.fp_cr); ++} ++ ++/* Store to the current thread the valid fp/simd register ++ values in the GDB's register array. */ ++ ++static void ++store_fpregs_to_thread (const struct regcache *regcache) ++{ ++ int ret; ++ pid_t pid; ++ int regno; ++ struct fpreg fpregs; ++ ++ pid = ptid_get_pid (inferior_ptid); ++ ++ ret = ptrace(PT_GETFPREGS, pid, (caddr_t)&fpregs, 0); ++ if (ret < 0) { ++ perror_with_name (_("Unable to store general registers.")); ++ return; ++ } ++ ++ for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++) ++ if (REG_VALID == regcache_register_status (regcache, regno)) ++ regcache_raw_collect (regcache, regno, &fpregs.fp_reg[regno]); ++ ++ if (REG_VALID == regcache_register_status (regcache, AARCH64_FPSR_REGNUM)) ++ regcache_raw_collect (regcache, AARCH64_FPSR_REGNUM, &fpregs.fp_sr); ++ if (REG_VALID == regcache_register_status (regcache, AARCH64_FPCR_REGNUM)) ++ regcache_raw_collect (regcache, AARCH64_FPCR_REGNUM, &fpregs.fp_cr); ++ ++ ret = ptrace(PT_SETFPREGS, pid, (caddr_t)&fpregs, 0); ++ if (ret < 0) ++ perror_with_name (_("Unable to store general registers.")); ++} ++ ++/* Implement the "to_fetch_register" target_ops method. */ ++ ++static void ++aarch64_obsd_fetch_inferior_registers (struct target_ops *ops, ++ struct regcache *regcache, ++ int regno) ++{ ++ if (regno == -1) ++ { ++ fetch_gregs_from_thread (regcache); ++ fetch_fpregs_from_thread (regcache); ++ } ++ else if (regno < AARCH64_V0_REGNUM) ++ fetch_gregs_from_thread (regcache); ++ else ++ fetch_fpregs_from_thread (regcache); ++} ++ ++/* Implement the "to_store_register" target_ops method. */ ++ ++static void ++aarch64_obsd_store_inferior_registers (struct target_ops *ops, ++ struct regcache *regcache, ++ int regno) ++{ ++ if (regno == -1) ++ { ++ store_gregs_to_thread (regcache); ++ store_fpregs_to_thread (regcache); ++ } ++ else if (regno < AARCH64_V0_REGNUM) ++ store_gregs_to_thread (regcache); ++ else ++ store_fpregs_to_thread (regcache); ++} ++ ++ ++/* -Wmissing-prototypes. */ ++void _initialize_aarch64_obsd_nat (void); ++ ++void ++_initialize_aarch64_obsd_nat (void) ++{ ++ struct target_ops *t; ++ ++ t = inf_ptrace_target (); ++ ++ /* Add our register access methods. */ ++ t->to_fetch_registers = aarch64_obsd_fetch_inferior_registers; ++ t->to_store_registers = aarch64_obsd_store_inferior_registers; ++ ++ /* Register the target. */ ++ add_target (t); ++} Index: devel/gdb/patches/patch-gdb_aarch64obsd-tdep_c =================================================================== RCS file: devel/gdb/patches/patch-gdb_aarch64obsd-tdep_c diff -N devel/gdb/patches/patch-gdb_aarch64obsd-tdep_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ devel/gdb/patches/patch-gdb_aarch64obsd-tdep_c 10 Jul 2018 09:44:47 -0000 @@ -0,0 +1,116 @@ +$OpenBSD$ +Index: gdb/aarch64obsd-tdep.c +--- gdb/aarch64obsd-tdep.c.orig ++++ gdb/aarch64obsd-tdep.c +@@ -0,0 +1,111 @@ ++/* Target-dependent code for OpenBSD/aarch64. ++ ++ Copyright (C) 2006-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 "osabi.h" ++#include "regset.h" ++#include "trad-frame.h" ++#include "tramp-frame.h" ++ ++#include "aarch64-tdep.h" ++#include "obsd-tdep.h" ++#include "solib-svr4.h" ++ ++/* The general-purpose regset consists of 31 X registers, plus SP, PC, ++ and SPSR and TPIDR registers. */ ++#define AARCH64_OBSD_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_OBSD_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE) ++ ++/* Register maps. */ ++ ++static const struct regcache_map_entry aarch64_obsd_gregmap[] = ++ { ++ { 31, AARCH64_X0_REGNUM, 8 }, /* x0 ... x30 */ ++ { 1, AARCH64_SP_REGNUM, 8 }, ++ { 1, AARCH64_PC_REGNUM, 8 }, ++ { 1, AARCH64_CPSR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++static const struct regcache_map_entry aarch64_obsd_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_obsd_gregset = ++ { ++ aarch64_obsd_gregmap, ++ regcache_supply_regset, regcache_collect_regset ++ }; ++ ++const struct regset aarch64_obsd_fpregset = ++ { ++ aarch64_obsd_fpregmap, ++ regcache_supply_regset, regcache_collect_regset ++ }; ++ ++static void ++aarch64_obsd_iterate_over_regset_sections (struct gdbarch *gdbarch, ++ iterate_over_regset_sections_cb *cb, ++ void *cb_data, ++ const struct regcache *regcache) ++{ ++ cb (".reg", AARCH64_OBSD_SIZEOF_GREGSET, &aarch64_obsd_gregset, ++ NULL, cb_data); ++ cb (".reg2", AARCH64_OBSD_SIZEOF_FPREGSET, &aarch64_obsd_fpregset, ++ NULL, cb_data); ++} ++ ++ ++static void ++aarch64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ /* OpenBSD/aarch64 uses SVR4-style shared libraries. */ ++ set_solib_svr4_fetch_link_map_offsets ++ (gdbarch, svr4_lp64_fetch_link_map_offsets); ++ set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver); ++ ++ /* Enable longjmp. */ ++ tdep->jb_pc = 13; ++ ++ set_gdbarch_iterate_over_regset_sections ++ (gdbarch, aarch64_obsd_iterate_over_regset_sections); ++} ++ ++ ++/* Provide a prototype to silence -Wmissing-prototypes. */ ++extern initialize_file_ftype _initialize_aarch64obsd_tdep; ++ ++void ++_initialize_aarch64obsd_tdep (void) ++{ ++ gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_OPENBSD_ELF, ++ aarch64obsd_init_abi); ++} Index: devel/gdb/patches/patch-gdb_config_aarch64_obsd_mh =================================================================== RCS file: devel/gdb/patches/patch-gdb_config_aarch64_obsd_mh diff -N devel/gdb/patches/patch-gdb_config_aarch64_obsd_mh --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ devel/gdb/patches/patch-gdb_config_aarch64_obsd_mh 10 Jul 2018 09:44:47 -0000 @@ -0,0 +1,10 @@ +$OpenBSD$ +Index: gdb/config/aarch64/obsd.mh +--- gdb/config/aarch64/obsd.mh.orig ++++ gdb/config/aarch64/obsd.mh +@@ -0,0 +1,5 @@ ++# Host: OpenBSD/arm64 ++NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o \ ++ aarch64obsd-nat.o bsd-kvm.o ++ ++LOADLIBES= -lkvm Index: devel/gdb/patches/patch-gdb_configure_host =================================================================== RCS file: devel/gdb/patches/patch-gdb_configure_host diff -N devel/gdb/patches/patch-gdb_configure_host --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ devel/gdb/patches/patch-gdb_configure_host 10 Jul 2018 09:44:47 -0000 @@ -0,0 +1,11 @@ +$OpenBSD$ +--- gdb/configure.host.orig Sat Jan 21 05:48:42 2017 ++++ gdb/configure.host Tue Mar 7 23:52:43 2017 +@@ -82,6 +82,7 @@ case "${host}" in + *-*-darwin*) gdb_host=darwin ;; + + aarch64*-*-linux*) gdb_host=linux ;; ++aarch64*-*-openbsd*) gdb_host=obsd ;; + + alpha*-*-linux*) gdb_host=alpha-linux ;; + alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu) Index: devel/gdb/patches/patch-gdb_configure_tgt =================================================================== RCS file: devel/gdb/patches/patch-gdb_configure_tgt diff -N devel/gdb/patches/patch-gdb_configure_tgt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ devel/gdb/patches/patch-gdb_configure_tgt 10 Jul 2018 09:44:47 -0000 @@ -0,0 +1,18 @@ +$OpenBSD$ +Index: gdb/configure.tgt +--- gdb/configure.tgt.orig ++++ gdb/configure.tgt +@@ -51,6 +51,13 @@ aarch64*-*-linux*) + build_gdbserver=yes + ;; + ++aarch64*-*-openbsd*) ++ # Target: OpenBSD/arm64 ++ gdb_target_obs="aarch64-tdep.o aarch64obsd-tdep.o aarch64-insn.o \ ++ obsd-tdep.o solib-svr4.o \ ++ symfile-mem.o aarch64-insn.o" ++ ;; ++ + alpha*-*-linux*) + # Target: Little-endian Alpha running Linux + gdb_target_obs="alpha-tdep.o alpha-mdebug-tdep.o alpha-linux-tdep.o \
