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