2 * Alpha register context support
4 * Copyright (C) 2004 Vincent BĂ©ron
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library 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 GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #ifdef HAVE_SYS_PTRACE_H
33 # include <sys/ptrace.h>
40 #if 0 /* no longer used */
42 #ifdef HAVE_SYS_USER_H
43 # include <sys/user.h>
46 /* user definitions from asm/user.h */
47 struct kernel_user_struct
49 unsigned long regs
[EF_SIZE
/8+32];
53 unsigned long start_code
;
54 unsigned long start_data
;
55 unsigned long start_stack
;
62 /* get thread context */
63 static void get_thread_context( struct thread
*thread
, unsigned int flags
, CONTEXT
*context
)
65 int pid
= get_ptrace_pid(thread
);
66 if (flags
& CONTEXT_FULL
)
68 struct kernel_user_struct regs
;
69 if (ptrace( PTRACE_GETREGS
, pid
, 0, ®s
) == -1) goto error
;
70 if (flags
& CONTEXT_INTEGER
)
72 context
->IntV0
= regs
.regs
[EF_V0
];
73 context
->IntT0
= regs
.regs
[EF_T0
];
74 context
->IntT1
= regs
.regs
[EF_T1
];
75 context
->IntT2
= regs
.regs
[EF_T2
];
76 context
->IntT3
= regs
.regs
[EF_T3
];
77 context
->IntT4
= regs
.regs
[EF_T4
];
78 context
->IntT5
= regs
.regs
[EF_T5
];
79 context
->IntT6
= regs
.regs
[EF_T6
];
80 context
->IntT7
= regs
.regs
[EF_T7
];
81 context
->IntS0
= regs
.regs
[EF_S0
];
82 context
->IntS1
= regs
.regs
[EF_S1
];
83 context
->IntS2
= regs
.regs
[EF_S2
];
84 context
->IntS3
= regs
.regs
[EF_S3
];
85 context
->IntS4
= regs
.regs
[EF_S4
];
86 context
->IntS5
= regs
.regs
[EF_S5
];
87 context
->IntFp
= regs
.regs
[EF_S6
];
88 context
->IntA0
= regs
.regs
[EF_A0
];
89 context
->IntA1
= regs
.regs
[EF_A1
];
90 context
->IntA2
= regs
.regs
[EF_A2
];
91 context
->IntA3
= regs
.regs
[EF_A3
];
92 context
->IntA4
= regs
.regs
[EF_A4
];
93 context
->IntA5
= regs
.regs
[EF_A5
];
94 context
->IntT8
= regs
.regs
[EF_T8
];
95 context
->IntT9
= regs
.regs
[EF_T9
];
96 context
->IntT10
= regs
.regs
[EF_T10
];
97 context
->IntT11
= regs
.regs
[EF_T11
];
98 context
->IntT12
= regs
.regs
[EF_T12
];
99 context
->IntAt
= regs
.regs
[EF_AT
];
100 context
->IntZero
= 0;
102 if (flags
& CONTEXT_CONTROL
)
104 context
->IntRa
= regs
.regs
[EF_RA
];
105 context
->IntGp
= regs
.regs
[EF_GP
];
106 context
->IntSp
= regs
.regs
[EF_SP
];
107 context
->Fir
= regs
.regs
[EF_PC
];
108 context
->Psr
= regs
.regs
[EF_PS
];
110 if (flags
& CONTEXT_FLOATING_POINT
)
112 context
->FltF0
= regs
.regs
[EF_SIZE
/8+0];
113 context
->FltF1
= regs
.regs
[EF_SIZE
/8+1];
114 context
->FltF2
= regs
.regs
[EF_SIZE
/8+2];
115 context
->FltF3
= regs
.regs
[EF_SIZE
/8+3];
116 context
->FltF4
= regs
.regs
[EF_SIZE
/8+4];
117 context
->FltF5
= regs
.regs
[EF_SIZE
/8+5];
118 context
->FltF6
= regs
.regs
[EF_SIZE
/8+6];
119 context
->FltF7
= regs
.regs
[EF_SIZE
/8+7];
120 context
->FltF8
= regs
.regs
[EF_SIZE
/8+8];
121 context
->FltF9
= regs
.regs
[EF_SIZE
/8+9];
122 context
->FltF10
= regs
.regs
[EF_SIZE
/8+10];
123 context
->FltF11
= regs
.regs
[EF_SIZE
/8+11];
124 context
->FltF12
= regs
.regs
[EF_SIZE
/8+12];
125 context
->FltF13
= regs
.regs
[EF_SIZE
/8+13];
126 context
->FltF14
= regs
.regs
[EF_SIZE
/8+14];
127 context
->FltF15
= regs
.regs
[EF_SIZE
/8+15];
128 context
->FltF16
= regs
.regs
[EF_SIZE
/8+16];
129 context
->FltF17
= regs
.regs
[EF_SIZE
/8+17];
130 context
->FltF18
= regs
.regs
[EF_SIZE
/8+18];
131 context
->FltF19
= regs
.regs
[EF_SIZE
/8+19];
132 context
->FltF20
= regs
.regs
[EF_SIZE
/8+20];
133 context
->FltF21
= regs
.regs
[EF_SIZE
/8+21];
134 context
->FltF22
= regs
.regs
[EF_SIZE
/8+22];
135 context
->FltF23
= regs
.regs
[EF_SIZE
/8+23];
136 context
->FltF24
= regs
.regs
[EF_SIZE
/8+24];
137 context
->FltF25
= regs
.regs
[EF_SIZE
/8+25];
138 context
->FltF26
= regs
.regs
[EF_SIZE
/8+26];
139 context
->FltF27
= regs
.regs
[EF_SIZE
/8+27];
140 context
->FltF28
= regs
.regs
[EF_SIZE
/8+28];
141 context
->FltF29
= regs
.regs
[EF_SIZE
/8+29];
142 context
->FltF30
= regs
.regs
[EF_SIZE
/8+30];
144 context
->Fpcr
= regs
.regs
[EF_SIZE
/8+31];
145 context
->SoftFpcr
= 0; /* FIXME */
147 context
->ContextFlags
|= flags
& CONTEXT_FULL
;
154 /* set a thread context */
155 static void set_thread_context( struct thread
*thread
, unsigned int flags
, const CONTEXT
*context
)
157 int pid
= get_ptrace_pid(thread
);
158 if (flags
& CONTEXT_FULL
)
160 struct kernel_user_struct regs
;
161 if (ptrace( PTRACE_GETREGS
, pid
, 0, ®s
) == -1) goto error
;
162 if (flags
& CONTEXT_INTEGER
)
164 regs
.regs
[EF_V0
] = context
->IntV0
;
165 regs
.regs
[EF_T0
] = context
->IntT0
;
166 regs
.regs
[EF_T1
] = context
->IntT1
;
167 regs
.regs
[EF_T2
] = context
->IntT2
;
168 regs
.regs
[EF_T3
] = context
->IntT3
;
169 regs
.regs
[EF_T4
] = context
->IntT4
;
170 regs
.regs
[EF_T5
] = context
->IntT5
;
171 regs
.regs
[EF_T6
] = context
->IntT6
;
172 regs
.regs
[EF_T7
] = context
->IntT7
;
173 regs
.regs
[EF_S0
] = context
->IntS0
;
174 regs
.regs
[EF_S1
] = context
->IntS1
;
175 regs
.regs
[EF_S2
] = context
->IntS2
;
176 regs
.regs
[EF_S3
] = context
->IntS3
;
177 regs
.regs
[EF_S4
] = context
->IntS4
;
178 regs
.regs
[EF_S5
] = context
->IntS5
;
179 regs
.regs
[EF_S6
] = context
->IntFp
;
180 regs
.regs
[EF_A0
] = context
->IntA0
;
181 regs
.regs
[EF_A1
] = context
->IntA1
;
182 regs
.regs
[EF_A2
] = context
->IntA2
;
183 regs
.regs
[EF_A3
] = context
->IntA3
;
184 regs
.regs
[EF_A4
] = context
->IntA4
;
185 regs
.regs
[EF_A5
] = context
->IntA5
;
186 regs
.regs
[EF_T8
] = context
->IntT8
;
187 regs
.regs
[EF_T9
] = context
->IntT9
;
188 regs
.regs
[EF_T10
] = context
->IntT10
;
189 regs
.regs
[EF_T11
] = context
->IntT11
;
190 regs
.regs
[EF_T12
] = context
->IntT12
;
191 regs
.regs
[EF_AT
] = context
->IntAt
;
193 if (flags
& CONTEXT_CONTROL
)
195 regs
.regs
[EF_RA
] = context
->IntRa
;
196 regs
.regs
[EF_GP
] = context
->IntGp
;
197 regs
.regs
[EF_SP
] = context
->IntSp
;
198 regs
.regs
[EF_PC
] = context
->Fir
;
199 regs
.regs
[EF_PS
] = context
->Psr
;
201 if (flags
& CONTEXT_FLOATING_POINT
)
203 regs
.regs
[EF_SIZE
/8+0] = context
->FltF0
;
204 regs
.regs
[EF_SIZE
/8+1] = context
->FltF1
;
205 regs
.regs
[EF_SIZE
/8+2] = context
->FltF2
;
206 regs
.regs
[EF_SIZE
/8+3] = context
->FltF3
;
207 regs
.regs
[EF_SIZE
/8+4] = context
->FltF4
;
208 regs
.regs
[EF_SIZE
/8+5] = context
->FltF5
;
209 regs
.regs
[EF_SIZE
/8+6] = context
->FltF6
;
210 regs
.regs
[EF_SIZE
/8+7] = context
->FltF7
;
211 regs
.regs
[EF_SIZE
/8+8] = context
->FltF8
;
212 regs
.regs
[EF_SIZE
/8+9] = context
->FltF9
;
213 regs
.regs
[EF_SIZE
/8+10] = context
->FltF10
;
214 regs
.regs
[EF_SIZE
/8+11] = context
->FltF11
;
215 regs
.regs
[EF_SIZE
/8+12] = context
->FltF12
;
216 regs
.regs
[EF_SIZE
/8+13] = context
->FltF13
;
217 regs
.regs
[EF_SIZE
/8+14] = context
->FltF14
;
218 regs
.regs
[EF_SIZE
/8+15] = context
->FltF15
;
219 regs
.regs
[EF_SIZE
/8+16] = context
->FltF16
;
220 regs
.regs
[EF_SIZE
/8+17] = context
->FltF17
;
221 regs
.regs
[EF_SIZE
/8+18] = context
->FltF18
;
222 regs
.regs
[EF_SIZE
/8+19] = context
->FltF19
;
223 regs
.regs
[EF_SIZE
/8+20] = context
->FltF20
;
224 regs
.regs
[EF_SIZE
/8+21] = context
->FltF21
;
225 regs
.regs
[EF_SIZE
/8+22] = context
->FltF22
;
226 regs
.regs
[EF_SIZE
/8+23] = context
->FltF23
;
227 regs
.regs
[EF_SIZE
/8+24] = context
->FltF24
;
228 regs
.regs
[EF_SIZE
/8+25] = context
->FltF25
;
229 regs
.regs
[EF_SIZE
/8+26] = context
->FltF26
;
230 regs
.regs
[EF_SIZE
/8+27] = context
->FltF27
;
231 regs
.regs
[EF_SIZE
/8+28] = context
->FltF28
;
232 regs
.regs
[EF_SIZE
/8+29] = context
->FltF29
;
233 regs
.regs
[EF_SIZE
/8+30] = context
->FltF30
;
234 regs
.regs
[EF_SIZE
/8+31] = context
->Fpcr
;
236 if (ptrace( PTRACE_SETREGS
, pid
, 0, ®s
) == -1) goto error
;
245 /* copy a context structure according to the flags */
246 void copy_context( CONTEXT
*to
, const CONTEXT
*from
, unsigned int flags
)
248 flags
&= ~CONTEXT_ALPHA
; /* get rid of CPU id */
249 if (flags
& CONTEXT_CONTROL
)
251 to
->IntRa
= from
->IntRa
;
252 to
->IntGp
= from
->IntGp
;
253 to
->IntSp
= from
->IntSp
;
257 if (flags
& CONTEXT_INTEGER
)
259 to
->IntV0
= from
->IntV0
;
260 to
->IntT0
= from
->IntT0
;
261 to
->IntT1
= from
->IntT1
;
262 to
->IntT2
= from
->IntT2
;
263 to
->IntT3
= from
->IntT3
;
264 to
->IntT4
= from
->IntT4
;
265 to
->IntT5
= from
->IntT5
;
266 to
->IntT6
= from
->IntT6
;
267 to
->IntT7
= from
->IntT7
;
268 to
->IntS0
= from
->IntS0
;
269 to
->IntS1
= from
->IntS1
;
270 to
->IntS2
= from
->IntS2
;
271 to
->IntS3
= from
->IntS3
;
272 to
->IntS4
= from
->IntS4
;
273 to
->IntS5
= from
->IntS5
;
274 to
->IntFp
= from
->IntFp
;
275 to
->IntA0
= from
->IntA0
;
276 to
->IntA1
= from
->IntA1
;
277 to
->IntA2
= from
->IntA2
;
278 to
->IntA3
= from
->IntA3
;
279 to
->IntA4
= from
->IntA4
;
280 to
->IntA5
= from
->IntA5
;
281 to
->IntT8
= from
->IntT8
;
282 to
->IntT9
= from
->IntT9
;
283 to
->IntT10
= from
->IntT10
;
284 to
->IntT11
= from
->IntT11
;
285 to
->IntT12
= from
->IntT12
;
286 to
->IntAt
= from
->IntAt
;
287 to
->IntZero
= from
->IntZero
;
289 if (flags
& CONTEXT_FLOATING_POINT
)
291 to
->FltF0
= from
->FltF0
;
292 to
->FltF1
= from
->FltF1
;
293 to
->FltF2
= from
->FltF2
;
294 to
->FltF3
= from
->FltF3
;
295 to
->FltF4
= from
->FltF4
;
296 to
->FltF5
= from
->FltF5
;
297 to
->FltF6
= from
->FltF6
;
298 to
->FltF7
= from
->FltF7
;
299 to
->FltF8
= from
->FltF8
;
300 to
->FltF9
= from
->FltF9
;
301 to
->FltF10
= from
->FltF10
;
302 to
->FltF11
= from
->FltF11
;
303 to
->FltF12
= from
->FltF12
;
304 to
->FltF13
= from
->FltF13
;
305 to
->FltF14
= from
->FltF14
;
306 to
->FltF15
= from
->FltF15
;
307 to
->FltF16
= from
->FltF16
;
308 to
->FltF17
= from
->FltF17
;
309 to
->FltF18
= from
->FltF18
;
310 to
->FltF19
= from
->FltF19
;
311 to
->FltF20
= from
->FltF20
;
312 to
->FltF21
= from
->FltF21
;
313 to
->FltF22
= from
->FltF22
;
314 to
->FltF23
= from
->FltF23
;
315 to
->FltF24
= from
->FltF24
;
316 to
->FltF25
= from
->FltF25
;
317 to
->FltF26
= from
->FltF26
;
318 to
->FltF27
= from
->FltF27
;
319 to
->FltF28
= from
->FltF28
;
320 to
->FltF29
= from
->FltF29
;
321 to
->FltF30
= from
->FltF30
;
322 to
->FltF31
= from
->FltF31
;
323 to
->Fpcr
= from
->Fpcr
;
324 to
->SoftFpcr
= from
->SoftFpcr
;
326 to
->ContextFlags
|= flags
;
329 /* retrieve the current instruction pointer of a context */
330 void *get_context_ip( const CONTEXT
*context
)
332 return (void *)context
->Fir
;
335 /* return the context flag that contains the CPU id */
336 unsigned int get_context_cpu_flag(void)
338 return CONTEXT_ALPHA
;
341 /* return only the context flags that correspond to system regs */
342 /* (system regs are the ones we can't access on the client side) */
343 unsigned int get_context_system_regs( unsigned int flags
)
345 return 0; /* FIXME: implement client-side handling */
348 #endif /* __ALPHA__ */