1/* Native-dependent code for FreeBSD/arm. 2 3 Copyright (C) 2017-2023 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20#include "defs.h" 21#include "inferior.h" 22#include "target.h" 23 24#include "elf/common.h" 25 26#include <sys/types.h> 27#include <sys/ptrace.h> 28#include <machine/reg.h> 29 30#include "fbsd-nat.h" 31#include "arm-tdep.h" 32#include "arm-fbsd-tdep.h" 33#include "inf-ptrace.h" 34 35struct arm_fbsd_nat_target : public fbsd_nat_target 36{ 37 void fetch_registers (struct regcache *, int) override; 38 void store_registers (struct regcache *, int) override; 39 const struct target_desc *read_description () override; 40}; 41 42static arm_fbsd_nat_target the_arm_fbsd_nat_target; 43 44/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this 45 for all registers. */ 46 47void 48arm_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) 49{ 50 fetch_register_set<struct reg> (regcache, regnum, PT_GETREGS, 51 &arm_fbsd_gregset); 52#ifdef PT_GETVFPREGS 53 fetch_register_set<struct vfpreg> (regcache, regnum, PT_GETVFPREGS, 54 &arm_fbsd_vfpregset); 55#endif 56#ifdef PT_GETREGSET 57 gdbarch *gdbarch = regcache->arch (); 58 arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch); 59 60 if (tdep->tls_regnum > 0) 61 fetch_regset<uint32_t> (regcache, regnum, NT_ARM_TLS, &arm_fbsd_tls_regset, 62 tdep->tls_regnum); 63#endif 64} 65 66/* Store register REGNUM back into the inferior. If REGNUM is -1, do 67 this for all registers. */ 68 69void 70arm_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum) 71{ 72 store_register_set<struct reg> (regcache, regnum, PT_GETREGS, PT_SETREGS, 73 &arm_fbsd_gregset); 74#ifdef PT_GETVFPREGS 75 store_register_set<struct vfpreg> (regcache, regnum, PT_GETVFPREGS, 76 PT_SETVFPREGS, &arm_fbsd_vfpregset); 77#endif 78#ifdef PT_GETREGSET 79 gdbarch *gdbarch = regcache->arch (); 80 arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch); 81 82 if (tdep->tls_regnum > 0) 83 store_regset<uint32_t> (regcache, regnum, NT_ARM_TLS, &arm_fbsd_tls_regset, 84 tdep->tls_regnum); 85#endif 86} 87 88/* Implement the to_read_description method. */ 89 90const struct target_desc * 91arm_fbsd_nat_target::read_description () 92{ 93 const struct target_desc *desc; 94 bool tls = false; 95 96#ifdef PT_GETREGSET 97 tls = have_regset (inferior_ptid, NT_ARM_TLS) != 0; 98#endif 99 desc = arm_fbsd_read_description_auxv (tls); 100 if (desc == NULL) 101 desc = this->beneath ()->read_description (); 102 return desc; 103} 104 105void _initialize_arm_fbsd_nat (); 106void 107_initialize_arm_fbsd_nat () 108{ 109 add_inf_child_target (&the_arm_fbsd_nat_target); 110} 111