]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/m68k-bsd-nat.c
PR24435, buffer overflow reading dynamic entries
[thirdparty/binutils-gdb.git] / gdb / m68k-bsd-nat.c
CommitLineData
8f2d3ea0
MK
1/* Native-dependent code for Motorola 68000 BSD's.
2
42a4f53d 3 Copyright (C) 2004-2019 Free Software Foundation, Inc.
8f2d3ea0
MK
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
8f2d3ea0
MK
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
8f2d3ea0
MK
19
20#include "defs.h"
cb162ff6 21#include "gdbcore.h"
8f2d3ea0
MK
22#include "inferior.h"
23#include "regcache.h"
24
8f2d3ea0
MK
25#include <sys/types.h>
26#include <sys/ptrace.h>
27#include <machine/reg.h>
28
29#include "m68k-tdep.h"
bcfca652 30#include "inf-ptrace.h"
8f2d3ea0 31
f6ac5f3d
PA
32struct m68k_bsd_nat_target final : public inf_ptrace_target
33{
34 void fetch_registers (struct regcache *, int) override;
35 void store_registers (struct regcache *, int) override;
36};
37
38static m68k_bsd_nat_target the_m68k_bsd_nat_target;
39
8f2d3ea0
MK
40static int
41m68kbsd_gregset_supplies_p (int regnum)
42{
43 return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM);
44}
45
46static int
47m68kbsd_fpregset_supplies_p (int regnum)
48{
49 return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM);
50}
51
52/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
53
54static void
55m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
56{
57 const char *regs = gregs;
58 int regnum;
59
60 for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++)
73e1c03f 61 regcache->raw_supply (regnum, regs + regnum * 4);
8f2d3ea0
MK
62}
63
64/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
65
66static void
67m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
68{
ac7936df 69 struct gdbarch *gdbarch = regcache->arch ();
8f2d3ea0
MK
70 const char *regs = fpregs;
71 int regnum;
72
73 for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++)
73e1c03f
SM
74 regcache->raw_supply (regnum,
75 regs + m68kbsd_fpreg_offset (gdbarch, regnum));
8f2d3ea0
MK
76}
77
78/* Collect the general-purpose registers from REGCACHE and store them
79 in GREGS. */
80
81static void
82m68kbsd_collect_gregset (const struct regcache *regcache,
83 void *gregs, int regnum)
84{
85 char *regs = gregs;
86 int i;
87
88 for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
89 {
90 if (regnum == -1 || regnum == i)
34a79281 91 regcache->raw_collect (i, regs + i * 4);
8f2d3ea0
MK
92 }
93}
94
95/* Collect the floating-point registers from REGCACHE and store them
96 in FPREGS. */
97
98static void
99m68kbsd_collect_fpregset (struct regcache *regcache,
100 void *fpregs, int regnum)
101{
ac7936df 102 struct gdbarch *gdbarch = regcache->arch ();
8f2d3ea0
MK
103 char *regs = fpregs;
104 int i;
105
106 for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
107 {
108 if (regnum == -1 || regnum == i)
34a79281 109 regcache->raw_collect (i, regs + m68kbsd_fpreg_offset (gdbarch, i));
8f2d3ea0
MK
110 }
111}
112\f
113
114/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
115 for all registers (including the floating-point registers). */
116
f6ac5f3d
PA
117void
118m68k_bsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
8f2d3ea0 119{
e99b03dc 120 pid_t pid = regcache->ptid ().pid ();
bcc0c096 121
8f2d3ea0
MK
122 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
123 {
124 struct reg regs;
125
bcc0c096 126 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 127 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 128
56be3814 129 m68kbsd_supply_gregset (regcache, &regs);
8f2d3ea0
MK
130 }
131
132 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
133 {
134 struct fpreg fpregs;
135
bcc0c096 136 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 137 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 138
56be3814 139 m68kbsd_supply_fpregset (regcache, &fpregs);
8f2d3ea0
MK
140 }
141}
142
143/* Store register REGNUM back into the inferior. If REGNUM is -1, do
144 this for all registers (including the floating-point registers). */
145
f6ac5f3d
PA
146void
147m68k_bsd_nat_target::store_registers (struct regcache *regcache, int regnum)
8f2d3ea0 148{
e99b03dc 149 pid_t pid = regcache->ptid ().pid ();
bcc0c096 150
8f2d3ea0
MK
151 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
152 {
153 struct reg regs;
154
bcc0c096 155 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 156 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 157
56be3814 158 m68kbsd_collect_gregset (regcache, &regs, regnum);
8f2d3ea0 159
bcc0c096 160 if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 161 perror_with_name (_("Couldn't write registers"));
8f2d3ea0
MK
162 }
163
164 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
165 {
166 struct fpreg fpregs;
167
bcc0c096 168 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 169 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 170
56be3814 171 m68kbsd_collect_fpregset (regcache, &fpregs, regnum);
8f2d3ea0 172
bcc0c096 173 if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 174 perror_with_name (_("Couldn't write floating point status"));
8f2d3ea0
MK
175 }
176}
cb162ff6
MK
177\f
178
179/* Support for debugging kernel virtual memory images. */
180
cb162ff6
MK
181#include <machine/pcb.h>
182
183#include "bsd-kvm.h"
184
185/* OpenBSD doesn't have these. */
186#ifndef PCB_REGS_FP
187#define PCB_REGS_FP 10
188#endif
189#ifndef PCB_REGS_SP
190#define PCB_REGS_SP 11
191#endif
192
193static int
194m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
195{
196 int regnum, tmp;
197 int i = 0;
198
199 /* The following is true for NetBSD 1.6.2:
200
201 The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for
202 all callee-saved registers. From this information we reconstruct
203 the register state as it would look when we just returned from
204 cpu_switch(). */
205
206 /* The stack pointer shouldn't be zero. */
207 if (pcb->pcb_regs[PCB_REGS_SP] == 0)
208 return 0;
209
210 for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
73e1c03f 211 regcache->raw_supply (regnum, &pcb->pcb_regs[i++]);
cb162ff6 212 for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
73e1c03f 213 regcache->raw_supply (regnum, &pcb->pcb_regs[i++]);
cb162ff6
MK
214
215 tmp = pcb->pcb_ps & 0xffff;
73e1c03f 216 regcache->raw_supply (M68K_PS_REGNUM, &tmp);
cb162ff6
MK
217
218 read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp);
73e1c03f 219 regcache->raw_supply (M68K_PC_REGNUM, &tmp);
cb162ff6
MK
220
221 return 1;
222}
cb162ff6
MK
223
224void
225_initialize_m68kbsd_nat (void)
226{
d9f719f1 227 add_inf_child_target (&the_m68k_bsd_nat_target);
abbc6945 228
cb162ff6
MK
229 /* Support debugging kernel virtual memory images. */
230 bsd_kvm_add_target (m68kbsd_supply_pcb);
231}