1699b0f92Schristos /* Target-dependent code for ARM BSD's. 2699b0f92Schristos 3*6881a400Schristos Copyright (C) 2006-2023 Free Software Foundation, Inc. 4699b0f92Schristos 5699b0f92Schristos This file is part of GDB. 6699b0f92Schristos 7699b0f92Schristos This program is free software; you can redistribute it and/or modify 8699b0f92Schristos it under the terms of the GNU General Public License as published by 9699b0f92Schristos the Free Software Foundation; either version 3 of the License, or 10699b0f92Schristos (at your option) any later version. 11699b0f92Schristos 12699b0f92Schristos This program is distributed in the hope that it will be useful, 13699b0f92Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14699b0f92Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15699b0f92Schristos GNU General Public License for more details. 16699b0f92Schristos 17699b0f92Schristos You should have received a copy of the GNU General Public License 18699b0f92Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19699b0f92Schristos 20699b0f92Schristos #include "defs.h" 21699b0f92Schristos #include "osabi.h" 22699b0f92Schristos #include "regcache.h" 23699b0f92Schristos #include "regset.h" 24699b0f92Schristos 25699b0f92Schristos #include "arm-tdep.h" 26699b0f92Schristos 27699b0f92Schristos /* Core file support. */ 28699b0f92Schristos 29699b0f92Schristos /* Sizeof `struct reg' in <machine/reg.h>. */ 30699b0f92Schristos #define ARMBSD_SIZEOF_GREGS (17 * 4) 31699b0f92Schristos 32699b0f92Schristos /* Sizeof `struct fpreg' in <machine/reg.h. */ 33699b0f92Schristos #define ARMBSD_SIZEOF_FPREGS ((1 + (8 * 3)) * 4) 34699b0f92Schristos 35699b0f92Schristos static int 36699b0f92Schristos armbsd_fpreg_offset (int regnum) 37699b0f92Schristos { 38699b0f92Schristos if (regnum == ARM_FPS_REGNUM) 39699b0f92Schristos return 0; 40699b0f92Schristos 41699b0f92Schristos return 4 + (regnum - ARM_F0_REGNUM) * 12; 42699b0f92Schristos } 43699b0f92Schristos 44699b0f92Schristos /* Supply register REGNUM from the buffer specified by FPREGS and LEN 45699b0f92Schristos in the floating-point register set REGSET to register cache 46699b0f92Schristos REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ 47699b0f92Schristos 48699b0f92Schristos static void 49699b0f92Schristos armbsd_supply_fpregset (const struct regset *regset, 50699b0f92Schristos struct regcache *regcache, 51699b0f92Schristos int regnum, const void *fpregs, size_t len) 52699b0f92Schristos { 53699b0f92Schristos const gdb_byte *regs = (const gdb_byte *) fpregs; 54699b0f92Schristos int i; 55699b0f92Schristos 56699b0f92Schristos gdb_assert (len >= ARMBSD_SIZEOF_FPREGS); 57699b0f92Schristos 58699b0f92Schristos for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++) 59699b0f92Schristos { 60699b0f92Schristos if (regnum == i || regnum == -1) 617f2ac410Schristos regcache->raw_supply (i, regs + armbsd_fpreg_offset (i)); 62699b0f92Schristos } 63699b0f92Schristos } 64699b0f92Schristos 65699b0f92Schristos /* Supply register REGNUM from the buffer specified by GREGS and LEN 66699b0f92Schristos in the general-purpose register set REGSET to register cache 67699b0f92Schristos REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ 68699b0f92Schristos 69699b0f92Schristos static void 70699b0f92Schristos armbsd_supply_gregset (const struct regset *regset, 71699b0f92Schristos struct regcache *regcache, 72699b0f92Schristos int regnum, const void *gregs, size_t len) 73699b0f92Schristos { 74699b0f92Schristos const gdb_byte *regs = (const gdb_byte *) gregs; 75699b0f92Schristos int i; 76699b0f92Schristos 77699b0f92Schristos gdb_assert (len >= ARMBSD_SIZEOF_GREGS); 78699b0f92Schristos 79699b0f92Schristos for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++) 80699b0f92Schristos { 81699b0f92Schristos if (regnum == i || regnum == -1) 827f2ac410Schristos regcache->raw_supply (i, regs + i * 4); 83699b0f92Schristos } 84699b0f92Schristos 85699b0f92Schristos if (regnum == ARM_PS_REGNUM || regnum == -1) 867f2ac410Schristos regcache->raw_supply (i, regs + 16 * 4); 87699b0f92Schristos 88699b0f92Schristos if (len >= ARMBSD_SIZEOF_GREGS + ARMBSD_SIZEOF_FPREGS) 89699b0f92Schristos { 90699b0f92Schristos regs += ARMBSD_SIZEOF_GREGS; 91699b0f92Schristos len -= ARMBSD_SIZEOF_GREGS; 92699b0f92Schristos armbsd_supply_fpregset (regset, regcache, regnum, regs, len); 93699b0f92Schristos } 94699b0f92Schristos } 95699b0f92Schristos 96699b0f92Schristos /* ARM register sets. */ 97699b0f92Schristos 98699b0f92Schristos static const struct regset armbsd_gregset = 99699b0f92Schristos { 100699b0f92Schristos NULL, 101699b0f92Schristos armbsd_supply_gregset, 102699b0f92Schristos NULL, 103699b0f92Schristos REGSET_VARIABLE_SIZE 104699b0f92Schristos }; 105699b0f92Schristos 106699b0f92Schristos static const struct regset armbsd_fpregset = 107699b0f92Schristos { 108699b0f92Schristos NULL, 109699b0f92Schristos armbsd_supply_fpregset 110699b0f92Schristos }; 111699b0f92Schristos 112699b0f92Schristos /* Iterate over supported core file register note sections. */ 113699b0f92Schristos 114699b0f92Schristos void 115699b0f92Schristos armbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, 116699b0f92Schristos iterate_over_regset_sections_cb *cb, 117699b0f92Schristos void *cb_data, 118699b0f92Schristos const struct regcache *regcache) 119699b0f92Schristos { 1207f2ac410Schristos cb (".reg", ARMBSD_SIZEOF_GREGS, ARMBSD_SIZEOF_GREGS, &armbsd_gregset, NULL, 1217f2ac410Schristos cb_data); 1227f2ac410Schristos cb (".reg2", ARMBSD_SIZEOF_FPREGS, ARMBSD_SIZEOF_FPREGS, &armbsd_fpregset, 1237f2ac410Schristos NULL, cb_data); 124699b0f92Schristos } 125