OSDN Git Service

PR 11123
[pf3gnuchains/pf3gnuchains3x.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, 2010
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 target_ops *ops,
274                                      struct regcache *regcache, int regno)
275 {
276   if (-1 == regno)
277     {
278       for (regno = 0;
279            regno < gdbarch_num_regs (get_regcache_arch (regcache));
280            regno++)
281         fetch_register (regcache, regno);
282     }
283   else 
284     {
285       fetch_register (regcache, regno);
286     }
287 }
288
289 /* Store registers back into the inferior.  Store all registers if
290    regno == -1, otherwise store all general registers or all floating
291    point registers depending upon the value of regno.  */
292
293 static void
294 hppa_linux_store_inferior_registers (struct target_ops *ops,
295                                      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 }