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