c4319a0fd53da5df72255dbeb1b0d061253d4453
[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 2 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, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor,
20    Boston, MA 02110-1301, USA.  */
21
22 #include "defs.h"
23 #include "gdbcore.h"
24 #include "regcache.h"
25 #include "gdb_string.h"
26 #include "inferior.h"
27 #include "target.h"
28 #include "linux-nat.h"
29
30 #include <sys/procfs.h>
31 #include <sys/ptrace.h>
32 #include <linux/version.h>
33
34 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,43)
35 #include <asm/offset.h>
36 #else
37 #include <asm/offsets.h>
38 #endif
39
40 #include "hppa-tdep.h"
41
42 /* Prototypes for supply_gregset etc. */
43 #include "gregset.h"
44
45 /* These must match the order of the register names.
46
47    Some sort of lookup table is needed because the offsets associated
48    with the registers are all over the board.  */
49
50 static const int u_offsets[] =
51   {
52     /* general registers */
53     -1,
54     PT_GR1,
55     PT_GR2,
56     PT_GR3,
57     PT_GR4,
58     PT_GR5,
59     PT_GR6,
60     PT_GR7,
61     PT_GR8,
62     PT_GR9,
63     PT_GR10,
64     PT_GR11,
65     PT_GR12,
66     PT_GR13,
67     PT_GR14,
68     PT_GR15,
69     PT_GR16,
70     PT_GR17,
71     PT_GR18,
72     PT_GR19,
73     PT_GR20,
74     PT_GR21,
75     PT_GR22,
76     PT_GR23,
77     PT_GR24,
78     PT_GR25,
79     PT_GR26,
80     PT_GR27,
81     PT_GR28,
82     PT_GR29,
83     PT_GR30,
84     PT_GR31,
85
86     PT_SAR,
87     PT_IAOQ0,
88     PT_IASQ0,
89     PT_IAOQ1,
90     PT_IASQ1,
91     -1, /* eiem */
92     PT_IIR,
93     PT_ISR,
94     PT_IOR,
95     PT_PSW,
96     -1, /* goto */
97
98     PT_SR4,
99     PT_SR0,
100     PT_SR1,
101     PT_SR2,
102     PT_SR3,
103     PT_SR5,
104     PT_SR6,
105     PT_SR7,
106
107     -1, /* cr0 */
108     -1, /* pid0 */
109     -1, /* pid1 */
110     -1, /* ccr */
111     -1, /* pid2 */
112     -1, /* pid3 */
113     -1, /* cr24 */
114     -1, /* cr25 */
115     -1, /* cr26 */
116     PT_CR27,
117     -1, /* cr28 */
118     -1, /* cr29 */
119     -1, /* cr30 */
120
121     /* Floating point regs.  */
122     PT_FR0,  PT_FR0 + 4,
123     PT_FR1,  PT_FR1 + 4,
124     PT_FR2,  PT_FR2 + 4,
125     PT_FR3,  PT_FR3 + 4,
126     PT_FR4,  PT_FR4 + 4,
127     PT_FR5,  PT_FR5 + 4,
128     PT_FR6,  PT_FR6 + 4,
129     PT_FR7,  PT_FR7 + 4,
130     PT_FR8,  PT_FR8 + 4,
131     PT_FR9,  PT_FR9 + 4,
132     PT_FR10, PT_FR10 + 4,
133     PT_FR11, PT_FR11 + 4,
134     PT_FR12, PT_FR12 + 4,
135     PT_FR13, PT_FR13 + 4,
136     PT_FR14, PT_FR14 + 4,
137     PT_FR15, PT_FR15 + 4,
138     PT_FR16, PT_FR16 + 4,
139     PT_FR17, PT_FR17 + 4,
140     PT_FR18, PT_FR18 + 4,
141     PT_FR19, PT_FR19 + 4,
142     PT_FR20, PT_FR20 + 4,
143     PT_FR21, PT_FR21 + 4,
144     PT_FR22, PT_FR22 + 4,
145     PT_FR23, PT_FR23 + 4,
146     PT_FR24, PT_FR24 + 4,
147     PT_FR25, PT_FR25 + 4,
148     PT_FR26, PT_FR26 + 4,
149     PT_FR27, PT_FR27 + 4,
150     PT_FR28, PT_FR28 + 4,
151     PT_FR29, PT_FR29 + 4,
152     PT_FR30, PT_FR30 + 4,
153     PT_FR31, PT_FR31 + 4,
154   };
155
156 static CORE_ADDR
157 hppa_linux_register_addr (int regno, CORE_ADDR blockend)
158 {
159   CORE_ADDR addr;
160
161   if ((unsigned) regno >= gdbarch_num_regs (current_gdbarch))
162     error (_("Invalid register number %d."), regno);
163
164   if (u_offsets[regno] == -1)
165     addr = 0;
166   else
167     {
168       addr = (CORE_ADDR) u_offsets[regno];
169     }
170
171   return addr;
172 }
173
174 /*
175  * Registers saved in a coredump:
176  * gr0..gr31
177  * sr0..sr7
178  * iaoq0..iaoq1
179  * iasq0..iasq1
180  * sar, iir, isr, ior, ipsw
181  * cr0, cr24..cr31
182  * cr8,9,12,13
183  * cr10, cr15
184  */
185 #define GR_REGNUM(_n)   (HPPA_R0_REGNUM+_n)
186 #define TR_REGNUM(_n)   (HPPA_TR0_REGNUM+_n)
187 static const int greg_map[] =
188   {
189     GR_REGNUM(0), GR_REGNUM(1), GR_REGNUM(2), GR_REGNUM(3),
190     GR_REGNUM(4), GR_REGNUM(5), GR_REGNUM(6), GR_REGNUM(7),
191     GR_REGNUM(8), GR_REGNUM(9), GR_REGNUM(10), GR_REGNUM(11),
192     GR_REGNUM(12), GR_REGNUM(13), GR_REGNUM(14), GR_REGNUM(15),
193     GR_REGNUM(16), GR_REGNUM(17), GR_REGNUM(18), GR_REGNUM(19),
194     GR_REGNUM(20), GR_REGNUM(21), GR_REGNUM(22), GR_REGNUM(23),
195     GR_REGNUM(24), GR_REGNUM(25), GR_REGNUM(26), GR_REGNUM(27),
196     GR_REGNUM(28), GR_REGNUM(29), GR_REGNUM(30), GR_REGNUM(31),
197
198     HPPA_SR4_REGNUM+1, HPPA_SR4_REGNUM+2, HPPA_SR4_REGNUM+3, HPPA_SR4_REGNUM+4,
199     HPPA_SR4_REGNUM, HPPA_SR4_REGNUM+5, HPPA_SR4_REGNUM+6, HPPA_SR4_REGNUM+7,
200
201     HPPA_PCOQ_HEAD_REGNUM, HPPA_PCOQ_TAIL_REGNUM,
202     HPPA_PCSQ_HEAD_REGNUM, HPPA_PCSQ_TAIL_REGNUM,
203
204     HPPA_SAR_REGNUM, HPPA_IIR_REGNUM, HPPA_ISR_REGNUM, HPPA_IOR_REGNUM,
205     HPPA_IPSW_REGNUM, HPPA_RCR_REGNUM,
206
207     TR_REGNUM(0), TR_REGNUM(1), TR_REGNUM(2), TR_REGNUM(3),
208     TR_REGNUM(4), TR_REGNUM(5), TR_REGNUM(6), TR_REGNUM(7),
209
210     HPPA_PID0_REGNUM, HPPA_PID1_REGNUM, HPPA_PID2_REGNUM, HPPA_PID3_REGNUM,
211     HPPA_CCR_REGNUM, HPPA_EIEM_REGNUM,
212   };
213
214
215
216 /* Fetch one register.  */
217
218 static void
219 fetch_register (struct regcache *regcache, int regno)
220 {
221   int tid;
222   int val;
223
224   if (gdbarch_cannot_fetch_register (current_gdbarch, regno))
225     {
226       regcache_raw_supply (regcache, regno, NULL);
227       return;
228     }
229
230   /* GNU/Linux LWP ID's are process ID's.  */
231   tid = TIDGET (inferior_ptid);
232   if (tid == 0)
233     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
234
235   errno = 0;
236   val = ptrace (PTRACE_PEEKUSER, tid, hppa_linux_register_addr (regno, 0), 0);
237   if (errno != 0)
238     error (_("Couldn't read register %s (#%d): %s."), REGISTER_NAME (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   int tid;
250   int val;
251
252   if (gdbarch_cannot_store_register (current_gdbarch, regno))
253     return;
254
255   /* GNU/Linux LWP ID's are process ID's.  */
256   tid = TIDGET (inferior_ptid);
257   if (tid == 0)
258     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
259
260   errno = 0;
261   regcache_raw_collect (regcache, regno, &val);
262   ptrace (PTRACE_POKEUSER, tid, hppa_linux_register_addr (regno, 0), val);
263   if (errno != 0)
264     error (_("Couldn't write register %s (#%d): %s."), REGISTER_NAME (regno),
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
272 static void
273 hppa_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
274 {
275   if (-1 == regno)
276     {
277       for (regno = 0; regno < gdbarch_num_regs (current_gdbarch); regno++)
278         fetch_register (regcache, regno);
279     }
280   else 
281     {
282       fetch_register (regcache, regno);
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
290 static void
291 hppa_linux_store_inferior_registers (struct regcache *regcache, int regno)
292 {
293   if (-1 == regno)
294     {
295       for (regno = 0; regno < gdbarch_num_regs (current_gdbarch); regno++)
296         store_register (regcache, regno);
297     }
298   else
299     {
300       store_register (regcache, regno);
301     }
302 }
303
304 /* Fill GDB's register array with the general-purpose register values
305    in *gregsetp.  */
306
307 void
308 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
309 {
310   int i;
311   const greg_t *regp = (const elf_greg_t *) gregsetp;
312
313   for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++)
314     {
315       int regno = greg_map[i];
316       regcache_raw_supply (regcache, regno, regp);
317     }
318 }
319
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
324 void
325 fill_gregset (const struct regcache *regcache,
326               gdb_gregset_t *gregsetp, int regno)
327 {
328   int i;
329
330   for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++)
331     {
332       int mregno = greg_map[i];
333
334       if (regno == -1 || regno == mregno)
335         {
336           regcache_raw_collect(regcache, mregno, &(*gregsetp)[i]);
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
345 void
346 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
347 {
348   int regi;
349   const char *from;
350
351   for (regi = 0; regi <= 31; regi++)
352     {
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);
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
364 void
365 fill_fpregset (const struct regcache *regcache,
366                gdb_fpregset_t *fpregsetp, int regno)
367 {
368   int i;
369
370   for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 32 * 2; i++)
371    {
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;
377       regcache_raw_collect (regcache, i, to);
378    }
379 }
380
381 void _initialize_hppa_linux_nat (void);
382
383 void
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.  */
392   t->to_fetch_registers = hppa_linux_fetch_inferior_registers;
393   t->to_store_registers = hppa_linux_store_inferior_registers;
394
395   /* Register the target.  */
396   linux_nat_add_target (t);
397 }