]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdbserver/linux-m68k-low.cc
gdbserver/linux-low: turn 'regs_info' into a method
[thirdparty/binutils-gdb.git] / gdbserver / linux-m68k-low.cc
CommitLineData
0a30fbc4 1/* GNU/Linux/m68k specific low level interface, for the remote server for GDB.
b811d2c2 2 Copyright (C) 1995-2020 Free Software Foundation, Inc.
0a30fbc4
DJ
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
a9762ec7 8 the Free Software Foundation; either version 3 of the License, or
0a30fbc4
DJ
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
a9762ec7 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0a30fbc4
DJ
18
19#include "server.h"
58caa3dc 20#include "linux-low.h"
0a30fbc4 21
ef0478f6
TBA
22/* Linux target op definitions for the m68k architecture. */
23
24class m68k_target : public linux_process_target
25{
26public:
27
aa8d21c9
TBA
28 const regs_info *get_regs_info () override;
29
797bcff5
TBA
30protected:
31
32 void low_arch_setup () override;
ef0478f6
TBA
33};
34
35/* The singleton target ops object. */
36
37static m68k_target the_m68k_target;
38
d05b4ac3
UW
39/* Defined in auto-generated file reg-m68k.c. */
40void init_registers_m68k (void);
3aee8918 41extern const struct target_desc *tdesc_m68k;
d05b4ac3 42
0a30fbc4
DJ
43#ifdef HAVE_SYS_REG_H
44#include <sys/reg.h>
45#endif
46
4c0711e0 47#define m68k_num_regs 29
db1d3e1b 48#define m68k_num_gregs 18
0a30fbc4
DJ
49
50/* This table must line up with REGISTER_NAMES in tm-m68k.h */
2ec06d2e 51static int m68k_regmap[] =
0a30fbc4
DJ
52{
53#ifdef PT_D0
54 PT_D0 * 4, PT_D1 * 4, PT_D2 * 4, PT_D3 * 4,
55 PT_D4 * 4, PT_D5 * 4, PT_D6 * 4, PT_D7 * 4,
56 PT_A0 * 4, PT_A1 * 4, PT_A2 * 4, PT_A3 * 4,
57 PT_A4 * 4, PT_A5 * 4, PT_A6 * 4, PT_USP * 4,
58 PT_SR * 4, PT_PC * 4,
59#else
60 14 * 4, 0 * 4, 1 * 4, 2 * 4, 3 * 4, 4 * 4, 5 * 4, 6 * 4,
61 7 * 4, 8 * 4, 9 * 4, 10 * 4, 11 * 4, 12 * 4, 13 * 4, 15 * 4,
62 17 * 4, 18 * 4,
63#endif
64#ifdef PT_FP0
65 PT_FP0 * 4, PT_FP1 * 4, PT_FP2 * 4, PT_FP3 * 4,
66 PT_FP4 * 4, PT_FP5 * 4, PT_FP6 * 4, PT_FP7 * 4,
67 PT_FPCR * 4, PT_FPSR * 4, PT_FPIAR * 4
68#else
69 21 * 4, 24 * 4, 27 * 4, 30 * 4, 33 * 4, 36 * 4,
70 39 * 4, 42 * 4, 45 * 4, 46 * 4, 47 * 4
71#endif
72};
73
2ec06d2e
DJ
74static int
75m68k_cannot_store_register (int regno)
0a30fbc4 76{
2ec06d2e 77 return (regno >= m68k_num_regs);
0a30fbc4
DJ
78}
79
2ec06d2e
DJ
80static int
81m68k_cannot_fetch_register (int regno)
0a30fbc4 82{
2ec06d2e 83 return (regno >= m68k_num_regs);
0a30fbc4 84}
2ec06d2e 85
e9d25b98 86#ifdef HAVE_PTRACE_GETREGS
db1d3e1b 87#include <sys/procfs.h>
5826e159 88#include "nat/gdb_ptrace.h"
db1d3e1b
AS
89
90static void
442ea881 91m68k_fill_gregset (struct regcache *regcache, void *buf)
db1d3e1b
AS
92{
93 int i;
94
95 for (i = 0; i < m68k_num_gregs; i++)
442ea881 96 collect_register (regcache, i, (char *) buf + m68k_regmap[i]);
db1d3e1b
AS
97}
98
99static void
442ea881 100m68k_store_gregset (struct regcache *regcache, const void *buf)
db1d3e1b
AS
101{
102 int i;
103
104 for (i = 0; i < m68k_num_gregs; i++)
442ea881 105 supply_register (regcache, i, (const char *) buf + m68k_regmap[i]);
db1d3e1b
AS
106}
107
108static void
442ea881 109m68k_fill_fpregset (struct regcache *regcache, void *buf)
db1d3e1b
AS
110{
111 int i;
112
113 for (i = m68k_num_gregs; i < m68k_num_regs; i++)
442ea881
PA
114 collect_register (regcache, i, ((char *) buf
115 + (m68k_regmap[i] - m68k_regmap[m68k_num_gregs])));
db1d3e1b
AS
116}
117
118static void
442ea881 119m68k_store_fpregset (struct regcache *regcache, const void *buf)
db1d3e1b
AS
120{
121 int i;
122
123 for (i = m68k_num_gregs; i < m68k_num_regs; i++)
442ea881 124 supply_register (regcache, i, ((const char *) buf
db1d3e1b
AS
125 + (m68k_regmap[i] - m68k_regmap[m68k_num_gregs])));
126}
127
e9d25b98 128#endif /* HAVE_PTRACE_GETREGS */
db1d3e1b 129
3aee8918 130static struct regset_info m68k_regsets[] = {
e9d25b98 131#ifdef HAVE_PTRACE_GETREGS
1570b33e 132 { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t),
db1d3e1b
AS
133 GENERAL_REGS,
134 m68k_fill_gregset, m68k_store_gregset },
1570b33e 135 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, sizeof (elf_fpregset_t),
db1d3e1b
AS
136 FP_REGS,
137 m68k_fill_fpregset, m68k_store_fpregset },
e9d25b98 138#endif /* HAVE_PTRACE_GETREGS */
50bc912a 139 NULL_REGSET
db1d3e1b
AS
140};
141
dd373349 142static const gdb_byte m68k_breakpoint[] = { 0x4E, 0x4F };
db1d3e1b
AS
143#define m68k_breakpoint_len 2
144
dd373349
AT
145/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
146
147static const gdb_byte *
148m68k_sw_breakpoint_from_kind (int kind, int *size)
149{
150 *size = m68k_breakpoint_len;
151 return m68k_breakpoint;
152}
153
db1d3e1b
AS
154static int
155m68k_breakpoint_at (CORE_ADDR pc)
156{
157 unsigned char c[2];
158
159 read_inferior_memory (pc, c, 2);
160 if (c[0] == 0x4E && c[1] == 0x4F)
161 return 1;
162
163 return 0;
164}
165
fea36a59
MK
166#include <asm/ptrace.h>
167
28d3cf85 168#ifdef PTRACE_GET_THREAD_AREA
fea36a59
MK
169/* Fetch the thread-local storage pointer for libthread_db. */
170
171ps_err_e
754653a7 172ps_get_thread_area (struct ps_prochandle *ph,
fea36a59
MK
173 lwpid_t lwpid, int idx, void **base)
174{
175 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
176 return PS_ERR;
177
178 /* IDX is the bias from the thread pointer to the beginning of the
179 thread descriptor. It has to be subtracted due to implementation
180 quirks in libthread_db. */
181 *base = (void *) ((char *)*base - idx);
182
183 return PS_OK;
184}
28d3cf85 185#endif /* PTRACE_GET_THREAD_AREA */
fea36a59 186
3aee8918
PA
187static struct regsets_info m68k_regsets_info =
188 {
189 m68k_regsets, /* regsets */
190 0, /* num_regsets */
191 NULL, /* disabled_regsets */
192 };
193
194static struct usrregs_info m68k_usrregs_info =
195 {
196 m68k_num_regs,
197 m68k_regmap,
198 };
199
aa8d21c9 200static struct regs_info myregs_info =
3aee8918
PA
201 {
202 NULL, /* regset_bitmap */
203 &m68k_usrregs_info,
204 &m68k_regsets_info
205 };
206
aa8d21c9
TBA
207const regs_info *
208m68k_target::get_regs_info ()
3aee8918 209{
aa8d21c9 210 return &myregs_info;
3aee8918
PA
211}
212
797bcff5
TBA
213void
214m68k_target::low_arch_setup ()
3aee8918
PA
215{
216 current_process ()->tdesc = tdesc_m68k;
217}
218
5616b6c3
AS
219/* Support for hardware single step. */
220
221static int
222m68k_supports_hardware_single_step (void)
223{
224 return 1;
225}
226
2ec06d2e 227struct linux_target_ops the_low_target = {
2ec06d2e
DJ
228 m68k_cannot_fetch_register,
229 m68k_cannot_store_register,
c14dfd32 230 NULL, /* fetch_register */
276d4552
YQ
231 linux_get_pc_32bit,
232 linux_set_pc_32bit,
dd373349
AT
233 NULL, /* breakpoint_kind_from_pc */
234 m68k_sw_breakpoint_from_kind,
db1d3e1b
AS
235 NULL,
236 2,
237 m68k_breakpoint_at,
5616b6c3
AS
238 NULL, /* supports_z_point_type */
239 NULL, /* insert_point */
240 NULL, /* remove_point */
241 NULL, /* stopped_by_watchpoint */
242 NULL, /* stopped_data_address */
243 NULL, /* collect_ptrace_register */
244 NULL, /* supply_ptrace_register */
245 NULL, /* siginfo_fixup */
246 NULL, /* new_process */
247 NULL, /* delete_process */
248 NULL, /* new_thread */
249 NULL, /* delete_thread */
250 NULL, /* new_fork */
251 NULL, /* prepare_to_resume */
252 NULL, /* process_qsupported */
253 NULL, /* supports_tracepoints */
254 NULL, /* get_thread_area */
255 NULL, /* install_fast_tracepoint_jump_pad */
256 NULL, /* emit_ops */
257 NULL, /* get_min_fast_tracepoint_insn_len */
258 NULL, /* supports_range_stepping */
259 NULL, /* breakpoint_kind_from_current_state */
260 m68k_supports_hardware_single_step,
2ec06d2e 261};
3aee8918 262
ef0478f6
TBA
263/* The linux target ops object. */
264
265linux_process_target *the_linux_target = &the_m68k_target;
266
3aee8918
PA
267void
268initialize_low_arch (void)
269{
270 /* Initialize the Linux target descriptions. */
271 init_registers_m68k ();
272
273 initialize_regsets_info (&m68k_regsets_info);
274}