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