From patchwork Sat Aug 12 02:05:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Baldwin X-Patchwork-Id: 22107 Received: (qmail 43533 invoked by alias); 12 Aug 2017 02:05:52 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 40017 invoked by uid 89); 12 Aug 2017 02:05:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS, SPF_SOFTFAIL autolearn=ham version=3.3.2 spammy= X-HELO: mail.baldwin.cx Received: from bigwig.baldwin.cx (HELO mail.baldwin.cx) (96.47.65.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 12 Aug 2017 02:05:42 +0000 Received: from ralph.baldwin.cx.com (c-73-231-226-104.hsd1.ca.comcast.net [73.231.226.104]) by mail.baldwin.cx (Postfix) with ESMTPSA id A8E3E10AF07 for ; Fri, 11 Aug 2017 22:05:39 -0400 (EDT) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH 1/2] Add FreeBSD/aarch64 architecture. Date: Fri, 11 Aug 2017 19:05:34 -0700 Message-Id: <20170812020535.89850-2-jhb@FreeBSD.org> In-Reply-To: <20170812020535.89850-1-jhb@FreeBSD.org> References: <20170812020535.89850-1-jhb@FreeBSD.org> X-IsSubscribed: yes Support for collecting and supplying general purpose and floating point register sets is provided along with signal frame unwinding. gdb/ChangeLog: * Makefile.in (ALL_64_TARGET_OBS): Add aarch64-fbsd-tdep.o. (ALLDEPFILES): Add aarch64-fbsd-tdep.c. * NEWS: Mention new FreeBSD/aarch64 target. * configure.tgt: Add aarch64*-*-freebsd*. * aarch64-fbsd-tdep.c: New file. * aarch64-fbsd-tdep.h: New file. --- gdb/ChangeLog | 9 +++ gdb/Makefile.in | 2 + gdb/NEWS | 4 + gdb/aarch64-fbsd-tdep.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/aarch64-fbsd-tdep.h | 33 ++++++++ gdb/configure.tgt | 5 ++ 6 files changed, 261 insertions(+) create mode 100644 gdb/aarch64-fbsd-tdep.c create mode 100644 gdb/aarch64-fbsd-tdep.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 55a0b12d50..94cbd33158 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2017-08-08 John Baldwin + + * Makefile.in (ALL_64_TARGET_OBS): Add aarch64-fbsd-tdep.o. + (ALLDEPFILES): Add aarch64-fbsd-tdep.c. + * NEWS: Mention new FreeBSD/aarch64 target. + * configure.tgt: Add aarch64*-*-freebsd*. + * aarch64-fbsd-tdep.c: New file. + * aarch64-fbsd-tdep.h: New file. + 2017-08-09 Tom Tromey * skip.c (skiplist_entry): New constructor. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index c6e618a541..7369f93e27 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -751,6 +751,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 \ @@ -2490,6 +2491,7 @@ force_update: MAKEOVERRIDES = ALLDEPFILES = \ + aarch64-fbsd-tdep.c \ aarch64-linux-nat.c \ aarch64-linux-tdep.c \ aarch64-newlib-tdep.c \ diff --git a/gdb/NEWS b/gdb/NEWS index 9cd1df1cfe..2083fc2bfa 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -26,6 +26,10 @@ set debug separate-debug-file show debug separate-debug-file Control the display of debug output about separate debug file search. +* New targets + +FreeBSD/aarch64 aarch64*-*-freebsd* + *** Changes in GDB 8.0 * GDB now supports access to the PKU register on GNU/Linux. The register is diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c new file mode 100644 index 0000000000..f8ce627282 --- /dev/null +++ b/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 . */ + +#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 a/gdb/aarch64-fbsd-tdep.h b/gdb/aarch64-fbsd-tdep.h new file mode 100644 index 0000000000..0f66dd3925 --- /dev/null +++ b/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 . */ + +#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 a/gdb/configure.tgt b/gdb/configure.tgt index fdcb7b1d69..f72a0dbbc1 100644 --- a/gdb/configure.tgt +++ b/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 \