Convert struct target_ops to C++
[external/binutils.git] / gdb / hppa-linux-nat.c
1 /* Functions specific to running GDB native on HPPA running GNU/Linux.
2
3    Copyright (C) 2004-2018 Free Software Foundation, Inc.
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
9    the Free Software Foundation; either version 3 of the License, or
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
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "gdbcore.h"
22 #include "regcache.h"
23 #include "inferior.h"
24 #include "target.h"
25 #include "linux-nat.h"
26 #include "inf-ptrace.h"
27
28 #include <sys/procfs.h>
29 #include "nat/gdb_ptrace.h"
30 #include <linux/version.h>
31
32 #include <asm/ptrace.h>
33 #include "hppa-linux-offsets.h"
34
35 #include "hppa-tdep.h"
36
37 class hppa_linux_nat_target final : public linux_nat_target
38 {
39 public:
40   /* Add our register access methods.  */
41   void fetch_registers (struct regcache *, int) override;
42   void store_registers (struct regcache *, int) override;
43 };
44
45 static hppa_linux_nat_target the_hppa_linux_nat_target;
46
47 /* Prototypes for supply_gregset etc.  */
48 #include "gregset.h"
49
50 /* These must match the order of the register names.
51
52    Some sort of lookup table is needed because the offsets associated
53    with the registers are all over the board.  */
54
55 static const int u_offsets[] =
56   {
57     /* general registers */
58     -1,
59     PT_GR1,
60     PT_GR2,
61     PT_GR3,
62     PT_GR4,
63     PT_GR5,
64     PT_GR6,
65     PT_GR7,
66     PT_GR8,
67     PT_GR9,
68     PT_GR10,
69     PT_GR11,
70     PT_GR12,
71     PT_GR13,
72     PT_GR14,
73     PT_GR15,
74     PT_GR16,
75     PT_GR17,
76     PT_GR18,
77     PT_GR19,
78     PT_GR20,
79     PT_GR21,
80     PT_GR22,
81     PT_GR23,
82     PT_GR24,
83     PT_GR25,
84     PT_GR26,
85     PT_GR27,
86     PT_GR28,
87     PT_GR29,
88     PT_GR30,
89     PT_GR31,
90
91     PT_SAR,
92     PT_IAOQ0,
93     PT_IASQ0,
94     PT_IAOQ1,
95     PT_IASQ1,
96     -1, /* eiem */
97     PT_IIR,
98     PT_ISR,
99     PT_IOR,
100     PT_PSW,
101     -1, /* goto */
102
103     PT_SR4,
104     PT_SR0,
105     PT_SR1,
106     PT_SR2,
107     PT_SR3,
108     PT_SR5,
109     PT_SR6,
110     PT_SR7,
111
112     -1, /* cr0 */
113     -1, /* pid0 */
114     -1, /* pid1 */
115     -1, /* ccr */
116     -1, /* pid2 */
117     -1, /* pid3 */
118     -1, /* cr24 */
119     -1, /* cr25 */
120     -1, /* cr26 */
121     PT_CR27,
122     -1, /* cr28 */
123     -1, /* cr29 */
124     -1, /* cr30 */
125
126     /* Floating point regs.  */
127     PT_FR0,  PT_FR0 + 4,
128     PT_FR1,  PT_FR1 + 4,
129     PT_FR2,  PT_FR2 + 4,
130     PT_FR3,  PT_FR3 + 4,
131     PT_FR4,  PT_FR4 + 4,
132     PT_FR5,  PT_FR5 + 4,
133     PT_FR6,  PT_FR6 + 4,
134     PT_FR7,  PT_FR7 + 4,
135     PT_FR8,  PT_FR8 + 4,
136     PT_FR9,  PT_FR9 + 4,
137     PT_FR10, PT_FR10 + 4,
138     PT_FR11, PT_FR11 + 4,
139     PT_FR12, PT_FR12 + 4,
140     PT_FR13, PT_FR13 + 4,
141     PT_FR14, PT_FR14 + 4,
142     PT_FR15, PT_FR15 + 4,
143     PT_FR16, PT_FR16 + 4,
144     PT_FR17, PT_FR17 + 4,
145     PT_FR18, PT_FR18 + 4,
146     PT_FR19, PT_FR19 + 4,
147     PT_FR20, PT_FR20 + 4,
148     PT_FR21, PT_FR21 + 4,
149     PT_FR22, PT_FR22 + 4,
150     PT_FR23, PT_FR23 + 4,
151     PT_FR24, PT_FR24 + 4,
152     PT_FR25, PT_FR25 + 4,
153     PT_FR26, PT_FR26 + 4,
154     PT_FR27, PT_FR27 + 4,
155     PT_FR28, PT_FR28 + 4,
156     PT_FR29, PT_FR29 + 4,
157     PT_FR30, PT_FR30 + 4,
158     PT_FR31, PT_FR31 + 4,
159   };
160
161 static CORE_ADDR
162 hppa_linux_register_addr (int regno, CORE_ADDR blockend)
163 {
164   CORE_ADDR addr;
165
166   if ((unsigned) regno >= ARRAY_SIZE (u_offsets))
167     error (_("Invalid register number %d."), regno);
168
169   if (u_offsets[regno] == -1)
170     addr = 0;
171   else
172     {
173       addr = (CORE_ADDR) u_offsets[regno];
174     }
175
176   return addr;
177 }
178
179 /*
180  * Registers saved in a coredump:
181  * gr0..gr31
182  * sr0..sr7
183  * iaoq0..iaoq1
184  * iasq0..iasq1
185  * sar, iir, isr, ior, ipsw
186  * cr0, cr24..cr31
187  * cr8,9,12,13
188  * cr10, cr15
189  */
190 #define GR_REGNUM(_n)   (HPPA_R0_REGNUM+_n)
191 #define TR_REGNUM(_n)   (HPPA_TR0_REGNUM+_n)
192 static const int greg_map[] =
193   {
194     GR_REGNUM(0), GR_REGNUM(1), GR_REGNUM(2), GR_REGNUM(3),
195     GR_REGNUM(4), GR_REGNUM(5), GR_REGNUM(6), GR_REGNUM(7),
196     GR_REGNUM(8), GR_REGNUM(9), GR_REGNUM(10), GR_REGNUM(11),
197     GR_REGNUM(12), GR_REGNUM(13), GR_REGNUM(14), GR_REGNUM(15),
198     GR_REGNUM(16), GR_REGNUM(17), GR_REGNUM(18), GR_REGNUM(19),
199     GR_REGNUM(20), GR_REGNUM(21), GR_REGNUM(22), GR_REGNUM(23),
200     GR_REGNUM(24), GR_REGNUM(25), GR_REGNUM(26), GR_REGNUM(27),
201     GR_REGNUM(28), GR_REGNUM(29), GR_REGNUM(30), GR_REGNUM(31),
202
203     HPPA_SR4_REGNUM+1, HPPA_SR4_REGNUM+2, HPPA_SR4_REGNUM+3, HPPA_SR4_REGNUM+4,
204     HPPA_SR4_REGNUM, HPPA_SR4_REGNUM+5, HPPA_SR4_REGNUM+6, HPPA_SR4_REGNUM+7,
205
206     HPPA_PCOQ_HEAD_REGNUM, HPPA_PCOQ_TAIL_REGNUM,
207     HPPA_PCSQ_HEAD_REGNUM, HPPA_PCSQ_TAIL_REGNUM,
208
209     HPPA_SAR_REGNUM, HPPA_IIR_REGNUM, HPPA_ISR_REGNUM, HPPA_IOR_REGNUM,
210     HPPA_IPSW_REGNUM, HPPA_RCR_REGNUM,
211
212     TR_REGNUM(0), TR_REGNUM(1), TR_REGNUM(2), TR_REGNUM(3),
213     TR_REGNUM(4), TR_REGNUM(5), TR_REGNUM(6), TR_REGNUM(7),
214
215     HPPA_PID0_REGNUM, HPPA_PID1_REGNUM, HPPA_PID2_REGNUM, HPPA_PID3_REGNUM,
216     HPPA_CCR_REGNUM, HPPA_EIEM_REGNUM,
217   };
218
219
220
221 /* Fetch one register.  */
222
223 static void
224 fetch_register (struct regcache *regcache, int regno)
225 {
226   struct gdbarch *gdbarch = regcache->arch ();
227   pid_t tid;
228   int val;
229
230   if (gdbarch_cannot_fetch_register (gdbarch, regno))
231     {
232       regcache_raw_supply (regcache, regno, NULL);
233       return;
234     }
235
236   tid = get_ptrace_pid (regcache_get_ptid (regcache));
237
238   errno = 0;
239   val = ptrace (PTRACE_PEEKUSER, tid, hppa_linux_register_addr (regno, 0), 0);
240   if (errno != 0)
241     error (_("Couldn't read register %s (#%d): %s."), 
242            gdbarch_register_name (gdbarch, regno),
243            regno, safe_strerror (errno));
244
245   regcache_raw_supply (regcache, regno, &val);
246 }
247
248 /* Store one register.  */
249
250 static void
251 store_register (const struct regcache *regcache, int regno)
252 {
253   struct gdbarch *gdbarch = regcache->arch ();
254   pid_t tid;
255   int val;
256
257   if (gdbarch_cannot_store_register (gdbarch, regno))
258     return;
259
260   tid = get_ptrace_pid (regcache_get_ptid (regcache));
261
262   errno = 0;
263   regcache_raw_collect (regcache, regno, &val);
264   ptrace (PTRACE_POKEUSER, tid, hppa_linux_register_addr (regno, 0), val);
265   if (errno != 0)
266     error (_("Couldn't write register %s (#%d): %s."),
267            gdbarch_register_name (gdbarch, regno),
268            regno, safe_strerror (errno));
269 }
270
271 /* Fetch registers from the child process.  Fetch all registers if
272    regno == -1, otherwise fetch all general registers or all floating
273    point registers depending upon the value of regno.  */
274
275 void
276 hppa_linux_nat_target::fetch_inferior_registers (struct regcache *regcache,
277                                                  int regno)
278 {
279   if (-1 == regno)
280     {
281       for (regno = 0;
282            regno < gdbarch_num_regs (regcache->arch ());
283            regno++)
284         fetch_register (regcache, regno);
285     }
286   else 
287     {
288       fetch_register (regcache, regno);
289     }
290 }
291
292 /* Store registers back into the inferior.  Store all registers if
293    regno == -1, otherwise store all general registers or all floating
294    point registers depending upon the value of regno.  */
295
296 void
297 hppa_linux_nat_target::store_registers (struct regcache *regcache, int regno)
298 {
299   if (-1 == regno)
300     {
301       for (regno = 0;
302            regno < gdbarch_num_regs (regcache->arch ());
303            regno++)
304         store_register (regcache, regno);
305     }
306   else
307     {
308       store_register (regcache, regno);
309     }
310 }
311
312 /* Fill GDB's register array with the general-purpose register values
313    in *gregsetp.  */
314
315 void
316 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
317 {
318   int i;
319   const greg_t *regp = (const elf_greg_t *) gregsetp;
320
321   for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++)
322     {
323       int regno = greg_map[i];
324       regcache_raw_supply (regcache, regno, regp);
325     }
326 }
327
328 /* Fill register regno (if it is a general-purpose register) in
329    *gregsetp with the appropriate value from GDB's register array.
330    If regno is -1, do this for all registers.  */
331
332 void
333 fill_gregset (const struct regcache *regcache,
334               gdb_gregset_t *gregsetp, int regno)
335 {
336   int i;
337
338   for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++)
339     {
340       int mregno = greg_map[i];
341
342       if (regno == -1 || regno == mregno)
343         {
344           regcache_raw_collect(regcache, mregno, &(*gregsetp)[i]);
345         }
346     }
347 }
348
349 /*  Given a pointer to a floating point register set in /proc format
350    (fpregset_t *), unpack the register contents and supply them as gdb's
351    idea of the current floating point register values.  */
352
353 void
354 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
355 {
356   int regi;
357   const char *from;
358
359   for (regi = 0; regi <= 31; regi++)
360     {
361       from = (const char *) &((*fpregsetp)[regi]);
362       regcache_raw_supply (regcache, 2*regi + HPPA_FP0_REGNUM, from);
363       regcache_raw_supply (regcache, 2*regi + HPPA_FP0_REGNUM + 1, from + 4);
364     }
365 }
366
367 /*  Given a pointer to a floating point register set in /proc format
368    (fpregset_t *), update the register specified by REGNO from gdb's idea
369    of the current floating point register set.  If REGNO is -1, update
370    them all.  */
371
372 void
373 fill_fpregset (const struct regcache *regcache,
374                gdb_fpregset_t *fpregsetp, int regno)
375 {
376   int i;
377
378   for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 32 * 2; i++)
379    {
380       /* Gross.  fpregset_t is double, registers[x] has single
381          precision reg.  */
382       char *to = (char *) &((*fpregsetp)[(i - HPPA_FP0_REGNUM) / 2]);
383       if ((i - HPPA_FP0_REGNUM) & 1)
384         to += 4;
385       regcache_raw_collect (regcache, i, to);
386    }
387 }
388
389 void
390 _initialize_hppa_linux_nat (void)
391 {
392   /* Register the target.  */
393   linux_target = &the_hppa_linux_nat_target;
394   add_target (&the_hppa_linux_nat_target);
395 }