Switch the license of all .c files to GPLv3.
[platform/upstream/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   int tid;
220   int val;
221
222   if (gdbarch_cannot_fetch_register (current_gdbarch, regno))
223     {
224       regcache_raw_supply (regcache, regno, NULL);
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;
234   val = ptrace (PTRACE_PEEKUSER, tid, hppa_linux_register_addr (regno, 0), 0);
235   if (errno != 0)
236     error (_("Couldn't read register %s (#%d): %s."), 
237            gdbarch_register_name (current_gdbarch, regno),
238            regno, safe_strerror (errno));
239
240   regcache_raw_supply (regcache, regno, &val);
241 }
242
243 /* Store one register. */
244
245 static void
246 store_register (const struct regcache *regcache, int regno)
247 {
248   int tid;
249   int val;
250
251   if (gdbarch_cannot_store_register (current_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 (current_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; 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 }