Add support for NetBSD threads in hppa-nbsd-nat.c
[deliverable/binutils-gdb.git] / gdb / ppc-nbsd-nat.c
CommitLineData
def18405
MK
1/* Native-dependent code for NetBSD/powerpc.
2
b811d2c2 3 Copyright (C) 2002-2020 Free Software Foundation, Inc.
def18405 4
485721b1 5 Contributed by Wasabi Systems, Inc.
e42180d7
C
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
e42180d7
C
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
e42180d7 21
52feded7
KR
22/* We define this to get types like register_t. */
23#define _KERNTYPES
0baeab03
PA
24#include "defs.h"
25
e42180d7
C
26#include <sys/types.h>
27#include <sys/ptrace.h>
28#include <machine/reg.h>
69e9e646
NW
29#include <machine/frame.h>
30#include <machine/pcb.h>
e42180d7 31
69e9e646 32#include "gdbcore.h"
def18405 33#include "inferior.h"
69e9e646 34#include "regcache.h"
def18405 35
485721b1 36#include "ppc-tdep.h"
03b62bbb 37#include "ppc-nbsd-tdep.h"
def18405 38#include "bsd-kvm.h"
5bf970f9
AC
39#include "inf-ptrace.h"
40
f6ac5f3d
PA
41struct ppc_nbsd_nat_target final : public inf_ptrace_target
42{
43 void fetch_registers (struct regcache *, int) override;
44 void store_registers (struct regcache *, int) override;
45};
46
47static ppc_nbsd_nat_target the_ppc_nbsd_nat_target;
48
485721b1 49/* Returns true if PT_GETREGS fetches this register. */
def18405 50
485721b1 51static int
206988c4 52getregs_supplies (struct gdbarch *gdbarch, int regnum)
e42180d7 53{
206988c4 54 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
485721b1 55
def18405
MK
56 return ((regnum >= tdep->ppc_gp0_regnum
57 && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
58 || regnum == tdep->ppc_lr_regnum
59 || regnum == tdep->ppc_cr_regnum
60 || regnum == tdep->ppc_xer_regnum
61 || regnum == tdep->ppc_ctr_regnum
206988c4 62 || regnum == gdbarch_pc_regnum (gdbarch));
e42180d7
C
63}
64
485721b1 65/* Like above, but for PT_GETFPREGS. */
def18405 66
485721b1 67static int
206988c4 68getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
e42180d7 69{
206988c4 70 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
e42180d7 71
383f0f5b
JB
72 /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
73 point registers. Traditionally, GDB's register set has still
74 listed the floating point registers for such machines, so this
75 code is harmless. However, the new E500 port actually omits the
76 floating point registers entirely from the register set --- they
77 don't even have register numbers assigned to them.
78
79 It's not clear to me how best to update this code, so this assert
80 will alert the first person to encounter the NetBSD/E500
81 combination to the problem. */
206988c4 82 gdb_assert (ppc_floating_point_unit_p (gdbarch));
383f0f5b 83
def18405
MK
84 return ((regnum >= tdep->ppc_fp0_regnum
85 && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
86 || regnum == tdep->ppc_fpscr_regnum);
485721b1 87}
e42180d7 88
f6ac5f3d
PA
89void
90ppc_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
e42180d7 91{
ac7936df 92 struct gdbarch *gdbarch = regcache->arch ();
e99b03dc 93 pid_t pid = regcache->ptid ().pid ();
c7da12c7 94 int lwp = regcache->ptid ().lwp ();
206988c4
MD
95
96 if (regnum == -1 || getregs_supplies (gdbarch, regnum))
485721b1
JT
97 {
98 struct reg regs;
99
c7da12c7 100 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
e2e0b3e5 101 perror_with_name (_("Couldn't get registers"));
485721b1 102
56be3814 103 ppc_supply_gregset (&ppcnbsd_gregset, regcache,
def18405 104 regnum, &regs, sizeof regs);
485721b1
JT
105 }
106
206988c4 107 if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
485721b1
JT
108 {
109 struct fpreg fpregs;
110
c7da12c7 111 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
e2e0b3e5 112 perror_with_name (_("Couldn't get FP registers"));
485721b1 113
56be3814 114 ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
def18405 115 regnum, &fpregs, sizeof fpregs);
485721b1 116 }
e42180d7
C
117}
118
f6ac5f3d
PA
119void
120ppc_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
e42180d7 121{
ac7936df 122 struct gdbarch *gdbarch = regcache->arch ();
e99b03dc 123 pid_t pid = regcache->ptid ().pid ();
c7da12c7 124 int lwp = regcache->ptid ().lwp ();
206988c4
MD
125
126 if (regnum == -1 || getregs_supplies (gdbarch, regnum))
485721b1
JT
127 {
128 struct reg regs;
129
c7da12c7 130 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
e2e0b3e5 131 perror_with_name (_("Couldn't get registers"));
485721b1 132
56be3814 133 ppc_collect_gregset (&ppcnbsd_gregset, regcache,
def18405 134 regnum, &regs, sizeof regs);
485721b1 135
c7da12c7 136 if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
e2e0b3e5 137 perror_with_name (_("Couldn't write registers"));
485721b1
JT
138 }
139
206988c4 140 if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
485721b1
JT
141 {
142 struct fpreg fpregs;
143
c7da12c7 144 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
e2e0b3e5 145 perror_with_name (_("Couldn't get FP registers"));
485721b1 146
56be3814 147 ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
def18405
MK
148 regnum, &fpregs, sizeof fpregs);
149
c7da12c7 150 if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
e2e0b3e5 151 perror_with_name (_("Couldn't set FP registers"));
485721b1 152 }
e42180d7 153}
69e9e646
NW
154
155static int
156ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
157{
158 struct switchframe sf;
159 struct callframe cf;
ac7936df 160 struct gdbarch *gdbarch = regcache->arch ();
40a6adc1 161 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
69e9e646
NW
162 int i;
163
164 /* The stack pointer shouldn't be zero. */
165 if (pcb->pcb_sp == 0)
166 return 0;
167
def18405 168 read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
73e1c03f
SM
169 regcache->raw_supply (tdep->ppc_cr_regnum, &sf.cr);
170 regcache->raw_supply (tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
69e9e646 171 for (i = 0 ; i < 19 ; i++)
73e1c03f 172 regcache->raw_supply (tdep->ppc_gp0_regnum + 13 + i, &sf.fixreg[i]);
69e9e646 173
def18405 174 read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
73e1c03f
SM
175 regcache->raw_supply (tdep->ppc_gp0_regnum + 30, &cf.r30);
176 regcache->raw_supply (tdep->ppc_gp0_regnum + 31, &cf.r31);
177 regcache->raw_supply (tdep->ppc_gp0_regnum + 1, &cf.sp);
69e9e646 178
def18405 179 read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
73e1c03f
SM
180 regcache->raw_supply (tdep->ppc_lr_regnum, &cf.lr);
181 regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &cf.lr);
69e9e646
NW
182
183 return 1;
184}
185
6c265988 186void _initialize_ppcnbsd_nat ();
69e9e646 187void
6c265988 188_initialize_ppcnbsd_nat ()
69e9e646
NW
189{
190 /* Support debugging kernel virtual memory images. */
191 bsd_kvm_add_target (ppcnbsd_supply_pcb);
def18405 192
d9f719f1 193 add_inf_child_target (&the_ppc_nbsd_nat_target);
69e9e646 194}
This page took 3.262924 seconds and 4 git commands to generate.