2004-05-07 Jason Molenda (jmolenda@apple.com)
[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
26 #include <sys/procfs.h>
27 #include <string.h>
28 #include <asm/offsets.h>
29
30 #include "hppa-tdep.h"
31
32 /* Prototypes for supply_gregset etc. */
33 #include "gregset.h"
34
35 /* These must match the order of the register names.
36
37 Some sort of lookup table is needed because the offsets associated
38 with the registers are all over the board. */
39
40 static const int u_offsets[] =
41 {
42 /* general registers */
43 -1,
44 PT_GR1,
45 PT_GR2,
46 PT_GR3,
47 PT_GR4,
48 PT_GR5,
49 PT_GR6,
50 PT_GR7,
51 PT_GR8,
52 PT_GR9,
53 PT_GR10,
54 PT_GR11,
55 PT_GR12,
56 PT_GR13,
57 PT_GR14,
58 PT_GR15,
59 PT_GR16,
60 PT_GR17,
61 PT_GR18,
62 PT_GR19,
63 PT_GR20,
64 PT_GR21,
65 PT_GR22,
66 PT_GR23,
67 PT_GR24,
68 PT_GR25,
69 PT_GR26,
70 PT_GR27,
71 PT_GR28,
72 PT_GR29,
73 PT_GR30,
74 PT_GR31,
75
76 PT_SAR,
77 PT_IAOQ0,
78 PT_IASQ0,
79 PT_IAOQ1,
80 PT_IASQ1,
81 -1, /* eiem */
82 PT_IIR,
83 PT_ISR,
84 PT_IOR,
85 PT_PSW,
86 -1, /* goto */
87
88 PT_SR4,
89 PT_SR0,
90 PT_SR1,
91 PT_SR2,
92 PT_SR3,
93 PT_SR5,
94 PT_SR6,
95 PT_SR7,
96
97 -1, /* cr0 */
98 -1, /* pid0 */
99 -1, /* pid1 */
100 -1, /* ccr */
101 -1, /* pid2 */
102 -1, /* pid3 */
103 -1, /* cr24 */
104 -1, /* cr25 */
105 -1, /* cr26 */
106 PT_CR27,
107 -1, /* cr28 */
108 -1, /* cr29 */
109 -1, /* cr30 */
110
111 /* Floating point regs. */
112 PT_FR0, PT_FR0 + 4,
113 PT_FR1, PT_FR1 + 4,
114 PT_FR2, PT_FR2 + 4,
115 PT_FR3, PT_FR3 + 4,
116 PT_FR4, PT_FR4 + 4,
117 PT_FR5, PT_FR5 + 4,
118 PT_FR6, PT_FR6 + 4,
119 PT_FR7, PT_FR7 + 4,
120 PT_FR8, PT_FR8 + 4,
121 PT_FR9, PT_FR9 + 4,
122 PT_FR10, PT_FR10 + 4,
123 PT_FR11, PT_FR11 + 4,
124 PT_FR12, PT_FR12 + 4,
125 PT_FR13, PT_FR13 + 4,
126 PT_FR14, PT_FR14 + 4,
127 PT_FR15, PT_FR15 + 4,
128 PT_FR16, PT_FR16 + 4,
129 PT_FR17, PT_FR17 + 4,
130 PT_FR18, PT_FR18 + 4,
131 PT_FR19, PT_FR19 + 4,
132 PT_FR20, PT_FR20 + 4,
133 PT_FR21, PT_FR21 + 4,
134 PT_FR22, PT_FR22 + 4,
135 PT_FR23, PT_FR23 + 4,
136 PT_FR24, PT_FR24 + 4,
137 PT_FR25, PT_FR25 + 4,
138 PT_FR26, PT_FR26 + 4,
139 PT_FR27, PT_FR27 + 4,
140 PT_FR28, PT_FR28 + 4,
141 PT_FR29, PT_FR29 + 4,
142 PT_FR30, PT_FR30 + 4,
143 PT_FR31, PT_FR31 + 4,
144 };
145
146 CORE_ADDR
147 register_addr (int regno, CORE_ADDR blockend)
148 {
149 CORE_ADDR addr;
150
151 if ((unsigned) regno >= NUM_REGS)
152 error ("Invalid register number %d.", regno);
153
154 if (u_offsets[regno] == -1)
155 addr = 0;
156 else
157 {
158 addr = (CORE_ADDR) u_offsets[regno];
159 }
160
161 return addr;
162 }
163
164 /*
165 * Registers saved in a coredump:
166 * gr0..gr31
167 * sr0..sr7
168 * iaoq0..iaoq1
169 * iasq0..iasq1
170 * sar, iir, isr, ior, ipsw
171 * cr0, cr24..cr31
172 * cr8,9,12,13
173 * cr10, cr15
174 */
175 #define GR_REGNUM(_n) (HPPA_R0_REGNUM+_n)
176 #define TR_REGNUM(_n) (HPPA_TR0_REGNUM+_n)
177 static const int greg_map[] =
178 {
179 GR_REGNUM(0), GR_REGNUM(1), GR_REGNUM(2), GR_REGNUM(3),
180 GR_REGNUM(4), GR_REGNUM(5), GR_REGNUM(6), GR_REGNUM(7),
181 GR_REGNUM(8), GR_REGNUM(9), GR_REGNUM(10), GR_REGNUM(11),
182 GR_REGNUM(12), GR_REGNUM(13), GR_REGNUM(14), GR_REGNUM(15),
183 GR_REGNUM(16), GR_REGNUM(17), GR_REGNUM(18), GR_REGNUM(19),
184 GR_REGNUM(20), GR_REGNUM(21), GR_REGNUM(22), GR_REGNUM(23),
185 GR_REGNUM(24), GR_REGNUM(25), GR_REGNUM(26), GR_REGNUM(27),
186 GR_REGNUM(28), GR_REGNUM(29), GR_REGNUM(30), GR_REGNUM(31),
187
188 HPPA_SR4_REGNUM+1, HPPA_SR4_REGNUM+2, HPPA_SR4_REGNUM+3, HPPA_SR4_REGNUM+4,
189 HPPA_SR4_REGNUM, HPPA_SR4_REGNUM+5, HPPA_SR4_REGNUM+6, HPPA_SR4_REGNUM+7,
190
191 HPPA_PCOQ_HEAD_REGNUM, HPPA_PCOQ_TAIL_REGNUM,
192 HPPA_PCSQ_HEAD_REGNUM, HPPA_PCSQ_TAIL_REGNUM,
193
194 HPPA_SAR_REGNUM, HPPA_IIR_REGNUM, HPPA_ISR_REGNUM, HPPA_IOR_REGNUM,
195 HPPA_IPSW_REGNUM, HPPA_RCR_REGNUM,
196
197 TR_REGNUM(0), TR_REGNUM(1), TR_REGNUM(2), TR_REGNUM(3),
198 TR_REGNUM(4), TR_REGNUM(5), TR_REGNUM(6), TR_REGNUM(7),
199
200 HPPA_PID0_REGNUM, HPPA_PID1_REGNUM, HPPA_PID2_REGNUM, HPPA_PID3_REGNUM,
201 HPPA_CCR_REGNUM, HPPA_EIEM_REGNUM,
202 };
203
204 void
205 supply_gregset (gdb_gregset_t *gregsetp)
206 {
207 int i;
208 greg_t *regp = (elf_greg_t *) gregsetp;
209
210 for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++)
211 {
212 int regno = greg_map[i];
213 int size = register_size (current_gdbarch, regno);
214 /* When running a 64 bit kernel, a greg_t may be larger than the
215 actual register, so just pick off the LS bits of big-endian word. */
216 supply_register (regno, ((char *) (regp + 1)) - size);
217 }
218 }
219
220 void
221 fill_gregset (gdb_gregset_t *gregsetp, int regno)
222 {
223 int i;
224 greg_t *regp = (greg_t *) gregsetp;
225
226 memset (gregsetp, 0, sizeof (*gregsetp));
227 for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++)
228 {
229 int regi = greg_map[i];
230
231 if (regno == -1 || regi == regno)
232 {
233 int rawsize = register_size (current_gdbarch, regi);
234 regcache_collect (regi, ((char *) (regp + 1)) - rawsize);
235 }
236 }
237 }
238
239 /* Given a pointer to a floating point register set in /proc format
240 (fpregset_t *), unpack the register contents and supply them as gdb's
241 idea of the current floating point register values. */
242
243 void
244 supply_fpregset (gdb_fpregset_t *fpregsetp)
245 {
246 register int regi;
247 char *from;
248
249 for (regi = 0; regi <= 31; regi++)
250 {
251 from = (char *) &((*fpregsetp)[regi]);
252 supply_register (2*regi + HPPA_FP0_REGNUM, from);
253 supply_register (2*regi + HPPA_FP0_REGNUM + 1, from + 4);
254 }
255 }
256
257 /* Given a pointer to a floating point register set in /proc format
258 (fpregset_t *), update the register specified by REGNO from gdb's idea
259 of the current floating point register set. If REGNO is -1, update
260 them all. */
261
262 void
263 fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
264 {
265 int i;
266
267 for (i = 0; i < NUM_REGS; i++)
268 {
269 if (regno == -1 || regno == i)
270 {
271 /* Gross. fpregset_t is double, registers[x] has single
272 precision reg. */
273 char *to = (char *) &((*fpregsetp)[(i - HPPA_FP0_REGNUM) / 2]);
274 if ((i - HPPA_FP0_REGNUM) & 1)
275 to += 4;
276 regcache_collect (i, to);
277 }
278 }
279 }
This page took 0.042396 seconds and 4 git commands to generate.