]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Copyright (C) 2004 PathScale, Inc | |
f0c4cad9 | 3 | * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
1da177e4 LT |
4 | * Licensed under the GPL |
5 | */ | |
6 | ||
7 | #include <errno.h> | |
3787fa6d | 8 | #include <sys/ptrace.h> |
14c8a77e | 9 | #include <sys/user.h> |
f0c4cad9 | 10 | #include "kern_constants.h" |
13c06be3 | 11 | #include "longjmp.h" |
1da177e4 | 12 | #include "user.h" |
f0c4cad9 | 13 | #include "sysdep/ptrace_user.h" |
1da177e4 | 14 | |
1da177e4 LT |
15 | int save_fp_registers(int pid, unsigned long *fp_regs) |
16 | { | |
f0c4cad9 | 17 | if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) |
6c59e2f5 JD |
18 | return -errno; |
19 | return 0; | |
1da177e4 LT |
20 | } |
21 | ||
22 | int restore_fp_registers(int pid, unsigned long *fp_regs) | |
23 | { | |
f0c4cad9 | 24 | if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) |
6c59e2f5 JD |
25 | return -errno; |
26 | return 0; | |
1da177e4 LT |
27 | } |
28 | ||
a5f6096c JD |
29 | int save_fpx_registers(int pid, unsigned long *fp_regs) |
30 | { | |
f0c4cad9 | 31 | if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) |
a5f6096c JD |
32 | return -errno; |
33 | return 0; | |
34 | } | |
35 | ||
36 | int restore_fpx_registers(int pid, unsigned long *fp_regs) | |
37 | { | |
f0c4cad9 | 38 | if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) |
a5f6096c JD |
39 | return -errno; |
40 | return 0; | |
41 | } | |
42 | ||
75e29b18 | 43 | unsigned long get_thread_reg(int reg, jmp_buf *buf) |
fad1c45c | 44 | { |
f0c4cad9 JD |
45 | switch (reg) { |
46 | case EIP: | |
47 | return buf[0]->__eip; | |
48 | case UESP: | |
49 | return buf[0]->__esp; | |
50 | case EBP: | |
51 | return buf[0]->__ebp; | |
75e29b18 | 52 | default: |
f0c4cad9 JD |
53 | printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", |
54 | reg); | |
75e29b18 JD |
55 | return 0; |
56 | } | |
fad1c45c | 57 | } |
a5f6096c JD |
58 | |
59 | int have_fpx_regs = 1; | |
60 | ||
2f56debd JD |
61 | int get_fp_registers(int pid, unsigned long *regs) |
62 | { | |
63 | if (have_fpx_regs) | |
64 | return save_fpx_registers(pid, regs); | |
65 | else | |
66 | return save_fp_registers(pid, regs); | |
67 | } | |
68 | ||
69 | int put_fp_registers(int pid, unsigned long *regs) | |
70 | { | |
71 | if (have_fpx_regs) | |
72 | return restore_fpx_registers(pid, regs); | |
73 | else | |
74 | return restore_fp_registers(pid, regs); | |
75 | } | |
76 | ||
a5f6096c JD |
77 | void arch_init_registers(int pid) |
78 | { | |
14c8a77e | 79 | struct user_fpxregs_struct fpx_regs; |
a5f6096c JD |
80 | int err; |
81 | ||
47906dd9 | 82 | err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs); |
5134d8fe | 83 | if (!err) |
a5f6096c JD |
84 | return; |
85 | ||
5134d8fe | 86 | if (errno != EIO) |
a5f6096c JD |
87 | panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", |
88 | errno); | |
89 | ||
90 | have_fpx_regs = 0; | |
91 | } |