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