]> Git Repo - binutils.git/blob - gdbserver/linux-sparc-low.cc
Automatic date update in version.in
[binutils.git] / gdbserver / linux-sparc-low.cc
1 /* Low level interface to ptrace, for the remote server for GDB.
2    Copyright (C) 1995-2022 Free Software Foundation, Inc.
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
8    the Free Software Foundation; either version 3 of the License, or
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
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 #include "server.h"
20 #include "linux-low.h"
21
22 #include "nat/gdb_ptrace.h"
23
24 #include "gdb_proc_service.h"
25
26 /* The stack pointer is offset from the stack frame by a BIAS of 2047
27    (0x7ff) for 64-bit code.  BIAS is likely to be defined on SPARC
28    hosts, so undefine it first.  */
29 #undef BIAS
30 #define BIAS 2047
31
32 #ifdef HAVE_SYS_REG_H
33 #include <sys/reg.h>
34 #endif
35
36 #define INSN_SIZE 4
37
38 #define SPARC_R_REGS_NUM 32
39 #define SPARC_F_REGS_NUM 48
40 #define SPARC_CONTROL_REGS_NUM 6
41
42 #define sparc_num_regs \
43   (SPARC_R_REGS_NUM + SPARC_F_REGS_NUM + SPARC_CONTROL_REGS_NUM)
44
45 /* Linux target op definitions for the SPARC architecture.  */
46
47 class sparc_target : public linux_process_target
48 {
49 public:
50
51   const regs_info *get_regs_info () override;
52
53   const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
54
55 protected:
56
57   void low_arch_setup () override;
58
59   bool low_cannot_fetch_register (int regno) override;
60
61   bool low_cannot_store_register (int regno) override;
62
63   bool low_supports_breakpoints () override;
64
65   CORE_ADDR low_get_pc (regcache *regcache) override;
66
67   /* No low_set_pc is needed.  */
68
69   bool low_breakpoint_at (CORE_ADDR pc) override;
70 };
71
72 /* The singleton target ops object.  */
73
74 static sparc_target the_sparc_target;
75
76 bool
77 sparc_target::low_supports_breakpoints ()
78 {
79   return true;
80 }
81
82 CORE_ADDR
83 sparc_target::low_get_pc (regcache *regcache)
84 {
85   return linux_get_pc_64bit (regcache);
86 }
87
88 /* Each offset is multiplied by 8, because of the register size.
89    These offsets apply to the buffer sent/filled by ptrace.
90    Additionally, the array elements order corresponds to the .dat file, and the
91    gdb's registers enumeration order.  */
92
93 static int sparc_regmap[] = {
94   /* These offsets correspond to GET/SETREGSET.  */
95         -1,  0*8,  1*8,  2*8,  3*8,  4*8,  5*8,  6*8,    /* g0 .. g7 */
96         7*8,  8*8,  9*8, 10*8, 11*8, 12*8, 13*8, 14*8,   /* o0 .. o5, sp, o7 */
97         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,    /* l0 .. l7 */
98         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,    /* i0 .. i5, fp, i7 */
99
100   /* Floating point registers offsets correspond to GET/SETFPREGSET.  */
101     0*4,  1*4,  2*4,  3*4,  4*4,  5*4,  6*4,  7*4,         /*  f0 ..  f7 */
102     8*4,  9*4, 10*4, 11*4, 12*4, 13*4, 14*4, 15*4,         /*  f8 .. f15 */
103    16*4, 17*4, 18*4, 19*4, 20*4, 21*4, 22*4, 23*4,         /* f16 .. f23 */
104    24*4, 25*4, 26*4, 27*4, 28*4, 29*4, 30*4, 31*4,         /* f24 .. f31 */
105
106   /* F32 offset starts next to f31: 31*4+4 = 16 * 8.  */
107    16*8, 17*8, 18*8, 19*8, 20*8, 21*8, 22*8, 23*8,         /* f32 .. f46 */
108    24*8, 25*8, 26*8, 27*8, 28*8, 29*8, 30*8, 31*8,         /* f48 .. f62 */
109
110    17 *8, /*    pc */
111    18 *8, /*   npc */
112    16 *8, /* state */
113   /* FSR offset also corresponds to GET/SETFPREGSET, ans is placed
114      next to f62.  */
115    32 *8, /*   fsr */
116       -1, /*  fprs */
117   /* Y register is 32-bits length, but gdb takes care of that.  */
118    19 *8, /*     y */
119
120 };
121
122
123 struct regs_range_t
124 {
125   int regno_start;
126   int regno_end;
127 };
128
129 static const struct regs_range_t gregs_ranges[] = {
130  {  0, 31 }, /*   g0 .. i7  */
131  { 80, 82 }, /*   pc .. state */
132  { 84, 85 }  /* fprs .. y */
133 };
134
135 #define N_GREGS_RANGES (sizeof (gregs_ranges) / sizeof (struct regs_range_t))
136
137 static const struct regs_range_t fpregs_ranges[] = {
138  { 32, 79 }, /* f0 .. f62  */
139  { 83, 83 }  /* fsr */
140 };
141
142 #define N_FPREGS_RANGES (sizeof (fpregs_ranges) / sizeof (struct regs_range_t))
143
144 /* Defined in auto-generated file reg-sparc64.c.  */
145 void init_registers_sparc64 (void);
146 extern const struct target_desc *tdesc_sparc64;
147
148 bool
149 sparc_target::low_cannot_store_register (int regno)
150 {
151   return (regno >= sparc_num_regs || sparc_regmap[regno] == -1);
152 }
153
154 bool
155 sparc_target::low_cannot_fetch_register (int regno)
156 {
157   return (regno >= sparc_num_regs || sparc_regmap[regno] == -1);
158 }
159
160 static void
161 sparc_fill_gregset_to_stack (struct regcache *regcache, const void *buf)
162 {
163   int i;
164   CORE_ADDR addr = 0;
165   unsigned char tmp_reg_buf[8];
166   const int l0_regno = find_regno (regcache->tdesc, "l0");
167   const int i7_regno = l0_regno + 15;
168
169   /* These registers have to be stored in the stack.  */
170   memcpy (&addr,
171           ((char *) buf) + sparc_regmap[find_regno (regcache->tdesc, "sp")],
172           sizeof (addr));
173
174   addr += BIAS;
175
176   for (i = l0_regno; i <= i7_regno; i++)
177     {
178       collect_register (regcache, i, tmp_reg_buf);
179       the_target->write_memory (addr, tmp_reg_buf, sizeof (tmp_reg_buf));
180       addr += sizeof (tmp_reg_buf);
181     }
182 }
183
184 static void
185 sparc_fill_gregset (struct regcache *regcache, void *buf)
186 {
187   int i;
188   int range;
189
190   for (range = 0; range < N_GREGS_RANGES; range++)
191     for (i = gregs_ranges[range].regno_start;
192          i <= gregs_ranges[range].regno_end; i++)
193       if (sparc_regmap[i] != -1)
194         collect_register (regcache, i, ((char *) buf) + sparc_regmap[i]);
195
196   sparc_fill_gregset_to_stack (regcache, buf);
197 }
198
199 static void
200 sparc_fill_fpregset (struct regcache *regcache, void *buf)
201 {
202   int i;
203   int range;
204
205   for (range = 0; range < N_FPREGS_RANGES; range++)
206     for (i = fpregs_ranges[range].regno_start;
207          i <= fpregs_ranges[range].regno_end; i++)
208       collect_register (regcache, i, ((char *) buf) + sparc_regmap[i]);
209
210 }
211
212 static void
213 sparc_store_gregset_from_stack (struct regcache *regcache, const void *buf)
214 {
215   int i;
216   CORE_ADDR addr = 0;
217   unsigned char tmp_reg_buf[8];
218   const int l0_regno = find_regno (regcache->tdesc, "l0");
219   const int i7_regno = l0_regno + 15;
220
221   /* These registers have to be obtained from the stack.  */
222   memcpy (&addr,
223           ((char *) buf) + sparc_regmap[find_regno (regcache->tdesc, "sp")],
224           sizeof (addr));
225
226   addr += BIAS;
227
228   for (i = l0_regno; i <= i7_regno; i++)
229     {
230       the_target->read_memory (addr, tmp_reg_buf, sizeof (tmp_reg_buf));
231       supply_register (regcache, i, tmp_reg_buf);
232       addr += sizeof (tmp_reg_buf);
233     }
234 }
235
236 static void
237 sparc_store_gregset (struct regcache *regcache, const void *buf)
238 {
239   int i;
240   char zerobuf[8];
241   int range;
242
243   memset (zerobuf, 0, sizeof (zerobuf));
244
245   for (range = 0; range < N_GREGS_RANGES; range++)
246     for (i = gregs_ranges[range].regno_start;
247          i <= gregs_ranges[range].regno_end; i++)
248       if (sparc_regmap[i] != -1)
249         supply_register (regcache, i, ((char *) buf) + sparc_regmap[i]);
250       else
251         supply_register (regcache, i, zerobuf);
252
253   sparc_store_gregset_from_stack (regcache, buf);
254 }
255
256 static void
257 sparc_store_fpregset (struct regcache *regcache, const void *buf)
258 {
259   int i;
260   int range;
261
262   for (range = 0; range < N_FPREGS_RANGES; range++)
263     for (i = fpregs_ranges[range].regno_start;
264          i <= fpregs_ranges[range].regno_end;
265          i++)
266       supply_register (regcache, i, ((char *) buf) + sparc_regmap[i]);
267 }
268
269 static const gdb_byte sparc_breakpoint[INSN_SIZE] = {
270   0x91, 0xd0, 0x20, 0x01
271 };
272 #define sparc_breakpoint_len INSN_SIZE
273
274 /* Implementation of target ops method "sw_breakpoint_from_kind".  */
275
276 const gdb_byte *
277 sparc_target::sw_breakpoint_from_kind (int kind, int *size)
278 {
279   *size = sparc_breakpoint_len;
280   return sparc_breakpoint;
281 }
282
283 bool
284 sparc_target::low_breakpoint_at (CORE_ADDR where)
285 {
286   unsigned char insn[INSN_SIZE];
287
288   read_memory (where, (unsigned char *) insn, sizeof (insn));
289
290   if (memcmp (sparc_breakpoint, insn, sizeof (insn)) == 0)
291     return true;
292
293   /* If necessary, recognize more trap instructions here.  GDB only
294      uses TRAP Always.  */
295
296   return false;
297 }
298
299 void
300 sparc_target::low_arch_setup ()
301 {
302   current_process ()->tdesc = tdesc_sparc64;
303 }
304
305 static struct regset_info sparc_regsets[] = {
306   { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t),
307     GENERAL_REGS,
308     sparc_fill_gregset, sparc_store_gregset },
309   { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, sizeof (fpregset_t),
310     FP_REGS,
311     sparc_fill_fpregset, sparc_store_fpregset },
312   NULL_REGSET
313 };
314
315 static struct regsets_info sparc_regsets_info =
316   {
317     sparc_regsets, /* regsets */
318     0, /* num_regsets */
319     NULL, /* disabled_regsets */
320   };
321
322 static struct usrregs_info sparc_usrregs_info =
323   {
324     sparc_num_regs,
325     /* No regmap needs to be provided since this impl. doesn't use
326        USRREGS.  */
327     NULL
328   };
329
330 static struct regs_info myregs_info =
331   {
332     NULL, /* regset_bitmap */
333     &sparc_usrregs_info,
334     &sparc_regsets_info
335   };
336
337 const regs_info *
338 sparc_target::get_regs_info ()
339 {
340   return &myregs_info;
341 }
342
343 /* The linux target ops object.  */
344
345 linux_process_target *the_linux_target = &the_sparc_target;
346
347 void
348 initialize_low_arch (void)
349 {
350   /* Initialize the Linux target descriptions.  */
351   init_registers_sparc64 ();
352
353   initialize_regsets_info (&sparc_regsets_info);
354 }
This page took 0.045165 seconds and 4 git commands to generate.