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