Remove regcache_get_ptid
[deliverable/binutils-gdb.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->ptid ());
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->ptid ());
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_inf_child_target (&the_hppa_linux_nat_target);
395 }
This page took 0.038435 seconds and 5 git commands to generate.