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