1 /* Functions specific to running GDB native on HPPA running GNU/Linux.
2 
3    Copyright 2004 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., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21 
22 #include "defs.h"
23 #include "gdbcore.h"
24 #include "regcache.h"
25 #include "gdb_string.h"
26 #include "inferior.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 CORE_ADDR
register_addr(int regno,CORE_ADDR blockend)155 register_addr (int regno, CORE_ADDR blockend)
156 {
157   CORE_ADDR addr;
158 
159   if ((unsigned) regno >= NUM_REGS)
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
fetch_register(int regno)217 fetch_register (int regno)
218 {
219   int tid;
220   int val;
221 
222   if (CANNOT_FETCH_REGISTER (regno))
223     {
224       regcache_raw_supply (current_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, register_addr (regno, 0), 0);
235   if (errno != 0)
236     error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regno),
237 	   regno, safe_strerror (errno));
238 
239   regcache_raw_supply (current_regcache, regno, &val);
240 }
241 
242 /* Store one register. */
243 
244 static void
store_register(int regno)245 store_register (int regno)
246 {
247   int tid;
248   int val;
249 
250   if (CANNOT_STORE_REGISTER (regno))
251     return;
252 
253   /* GNU/Linux LWP ID's are process ID's.  */
254   tid = TIDGET (inferior_ptid);
255   if (tid == 0)
256     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
257 
258   errno = 0;
259   regcache_raw_collect (current_regcache, regno, &val);
260   ptrace (PTRACE_POKEUSER, tid, register_addr (regno, 0), val);
261   if (errno != 0)
262     error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regno),
263 	   regno, safe_strerror (errno));
264 }
265 
266 /* Fetch registers from the child process.  Fetch all registers if
267    regno == -1, otherwise fetch all general registers or all floating
268    point registers depending upon the value of regno.  */
269 
270 void
fetch_inferior_registers(int regno)271 fetch_inferior_registers (int regno)
272 {
273   if (-1 == regno)
274     {
275       for (regno = 0; regno < NUM_REGS; regno++)
276         fetch_register (regno);
277     }
278   else
279     {
280       fetch_register (regno);
281     }
282 }
283 
284 /* Store registers back into the inferior.  Store all registers if
285    regno == -1, otherwise store all general registers or all floating
286    point registers depending upon the value of regno.  */
287 
288 void
store_inferior_registers(int regno)289 store_inferior_registers (int regno)
290 {
291   if (-1 == regno)
292     {
293       for (regno = 0; regno < NUM_REGS; regno++)
294 	store_register (regno);
295     }
296   else
297     {
298       store_register (regno);
299     }
300 }
301 
302 /* Fill GDB's register array with the general-purpose register values
303    in *gregsetp.  */
304 
305 void
supply_gregset(gdb_gregset_t * gregsetp)306 supply_gregset (gdb_gregset_t *gregsetp)
307 {
308   int i;
309   greg_t *regp = (elf_greg_t *) gregsetp;
310 
311   for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++)
312     {
313       int regno = greg_map[i];
314       regcache_raw_supply (current_regcache, regno, regp);
315     }
316 }
317 
318 /* Fill register regno (if it is a general-purpose register) in
319    *gregsetp with the appropriate value from GDB's register array.
320    If regno is -1, do this for all registers.  */
321 
322 void
fill_gregset(gdb_gregset_t * gregsetp,int regno)323 fill_gregset (gdb_gregset_t *gregsetp, int regno)
324 {
325   int i;
326 
327   for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++)
328     {
329       int mregno = greg_map[i];
330 
331       if (regno == -1 || regno == mregno)
332 	{
333           regcache_raw_collect(current_regcache, mregno, &(*gregsetp)[i]);
334 	}
335     }
336 }
337 
338 /*  Given a pointer to a floating point register set in /proc format
339    (fpregset_t *), unpack the register contents and supply them as gdb's
340    idea of the current floating point register values. */
341 
342 void
supply_fpregset(gdb_fpregset_t * fpregsetp)343 supply_fpregset (gdb_fpregset_t *fpregsetp)
344 {
345   int regi;
346   char *from;
347 
348   for (regi = 0; regi <= 31; regi++)
349     {
350       from = (char *) &((*fpregsetp)[regi]);
351       regcache_raw_supply (current_regcache, 2*regi + HPPA_FP0_REGNUM, from);
352       regcache_raw_supply (current_regcache, 2*regi + HPPA_FP0_REGNUM + 1,
353 			   from + 4);
354     }
355 }
356 
357 /*  Given a pointer to a floating point register set in /proc format
358    (fpregset_t *), update the register specified by REGNO from gdb's idea
359    of the current floating point register set.  If REGNO is -1, update
360    them all. */
361 
362 void
fill_fpregset(gdb_fpregset_t * fpregsetp,int regno)363 fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
364 {
365   int i;
366 
367   for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 32 * 2; i++)
368    {
369       /* Gross.  fpregset_t is double, registers[x] has single
370 	 precision reg.  */
371       char *to = (char *) &((*fpregsetp)[(i - HPPA_FP0_REGNUM) / 2]);
372       if ((i - HPPA_FP0_REGNUM) & 1)
373 	to += 4;
374       regcache_raw_collect (current_regcache, i, to);
375    }
376 }
377