2007-10-08 Markus Deuling <deuling@de.ibm.com>
[external/binutils.git] / gdb / hppa-linux-nat.c
1 /* Functions specific to running GDB native on HPPA running GNU/Linux.
2
3    Copyright (C) 2004, 2005, 2006, 2007 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 "gdb_string.h"
24 #include "inferior.h"
25 #include "target.h"
26 #include "linux-nat.h"
27
28 #include <sys/procfs.h>
29 #include <sys/ptrace.h>
30 #include <linux/version.h>
31
32 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,43)
33 #include <asm/offset.h>
34 #else
35 #include <asm/offsets.h>
36 #endif
37
38 #include "hppa-tdep.h"
39
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
48 static 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
154 static CORE_ADDR
155 hppa_linux_register_addr (int regno, CORE_ADDR blockend)
156 {
157   CORE_ADDR addr;
158
159   if ((unsigned) regno >= gdbarch_num_regs (current_gdbarch))
160     error (_("Invalid register number %d."), regno);
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  */
183 #define GR_REGNUM(_n)   (HPPA_R0_REGNUM+_n)
184 #define TR_REGNUM(_n)   (HPPA_TR0_REGNUM+_n)
185 static 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
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,
198
199     HPPA_PCOQ_HEAD_REGNUM, HPPA_PCOQ_TAIL_REGNUM,
200     HPPA_PCSQ_HEAD_REGNUM, HPPA_PCSQ_TAIL_REGNUM,
201
202     HPPA_SAR_REGNUM, HPPA_IIR_REGNUM, HPPA_ISR_REGNUM, HPPA_IOR_REGNUM,
203     HPPA_IPSW_REGNUM, HPPA_RCR_REGNUM,
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
208     HPPA_PID0_REGNUM, HPPA_PID1_REGNUM, HPPA_PID2_REGNUM, HPPA_PID3_REGNUM,
209     HPPA_CCR_REGNUM, HPPA_EIEM_REGNUM,
210   };
211
212
213
214 /* Fetch one register.  */
215
216 static void
217 fetch_register (struct regcache *regcache, int regno)
218 {
219   struct gdbarch *gdbarch = get_regcache_arch (regcache);
220   int tid;
221   int val;
222
223   if (gdbarch_cannot_fetch_register (gdbarch, regno))
224     {
225       regcache_raw_supply (regcache, regno, NULL);
226       return;
227     }
228
229   /* GNU/Linux LWP ID's are process ID's.  */
230   tid = TIDGET (inferior_ptid);
231   if (tid == 0)
232     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
233
234   errno = 0;
235   val = ptrace (PTRACE_PEEKUSER, tid, hppa_linux_register_addr (regno, 0), 0);
236   if (errno != 0)
237     error (_("Couldn't read register %s (#%d): %s."), 
238            gdbarch_register_name (gdbarch, regno),
239            regno, safe_strerror (errno));
240
241   regcache_raw_supply (regcache, regno, &val);
242 }
243
244 /* Store one register. */
245
246 static void
247 store_register (const struct regcache *regcache, int regno)
248 {
249   struct gdbarch *gdbarch = get_regcache_arch (regcache);
250   int tid;
251   int val;
252
253   if (gdbarch_cannot_store_register (gdbarch, regno))
254     return;
255
256   /* GNU/Linux LWP ID's are process ID's.  */
257   tid = TIDGET (inferior_ptid);
258   if (tid == 0)
259     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
260
261   errno = 0;
262   regcache_raw_collect (regcache, regno, &val);
263   ptrace (PTRACE_POKEUSER, tid, hppa_linux_register_addr (regno, 0), val);
264   if (errno != 0)
265     error (_("Couldn't write register %s (#%d): %s."),
266            gdbarch_register_name (gdbarch, regno),
267            regno, safe_strerror (errno));
268 }
269
270 /* Fetch registers from the child process.  Fetch all registers if
271    regno == -1, otherwise fetch all general registers or all floating
272    point registers depending upon the value of regno.  */
273
274 static void
275 hppa_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
276 {
277   if (-1 == regno)
278     {
279       for (regno = 0;
280            regno < gdbarch_num_regs (get_regcache_arch (regcache));
281            regno++)
282         fetch_register (regcache, regno);
283     }
284   else 
285     {
286       fetch_register (regcache, regno);
287     }
288 }
289
290 /* Store registers back into the inferior.  Store all registers if
291    regno == -1, otherwise store all general registers or all floating
292    point registers depending upon the value of regno.  */
293
294 static void
295 hppa_linux_store_inferior_registers (struct regcache *regcache, int regno)
296 {
297   if (-1 == regno)
298     {
299       for (regno = 0;
300            regno < gdbarch_num_regs (get_regcache_arch (regcache));
301            regno++)
302         store_register (regcache, regno);
303     }
304   else
305     {
306       store_register (regcache, regno);
307     }
308 }
309
310 /* Fill GDB's register array with the general-purpose register values
311    in *gregsetp.  */
312
313 void
314 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
315 {
316   int i;
317   const greg_t *regp = (const elf_greg_t *) gregsetp;
318
319   for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++)
320     {
321       int regno = greg_map[i];
322       regcache_raw_supply (regcache, regno, regp);
323     }
324 }
325
326 /* Fill register regno (if it is a general-purpose register) in
327    *gregsetp with the appropriate value from GDB's register array.
328    If regno is -1, do this for all registers.  */
329
330 void
331 fill_gregset (const struct regcache *regcache,
332               gdb_gregset_t *gregsetp, int regno)
333 {
334   int i;
335
336   for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++)
337     {
338       int mregno = greg_map[i];
339
340       if (regno == -1 || regno == mregno)
341         {
342           regcache_raw_collect(regcache, mregno, &(*gregsetp)[i]);
343         }
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 (regcache, 2*regi + HPPA_FP0_REGNUM, from);
361       regcache_raw_supply (regcache, 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 (regcache, i, to);
384    }
385 }
386
387 void _initialize_hppa_linux_nat (void);
388
389 void
390 _initialize_hppa_linux_nat (void)
391 {
392   struct target_ops *t;
393
394   /* Fill in the generic GNU/Linux methods.  */
395   t = linux_target ();
396
397   /* Add our register access methods.  */
398   t->to_fetch_registers = hppa_linux_fetch_inferior_registers;
399   t->to_store_registers = hppa_linux_store_inferior_registers;
400
401   /* Register the target.  */
402   linux_nat_add_target (t);
403 }