]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Copyright (C) 2004 PathScale, Inc | |
3 | * Licensed under the GPL | |
4 | */ | |
5 | ||
6 | #include <errno.h> | |
7 | #include <string.h> | |
8 | #include "sysdep/ptrace_user.h" | |
9 | #include "sysdep/ptrace.h" | |
10 | #include "uml-config.h" | |
11 | #include "skas_ptregs.h" | |
12 | #include "registers.h" | |
13 | #include "user.h" | |
14 | ||
15 | /* These are set once at boot time and not changed thereafter */ | |
16 | ||
17 | static unsigned long exec_regs[HOST_FRAME_SIZE]; | |
18 | static unsigned long exec_fp_regs[HOST_FP_SIZE]; | |
19 | static unsigned long exec_fpx_regs[HOST_XFP_SIZE]; | |
20 | static int have_fpx_regs = 1; | |
21 | ||
22 | void init_thread_registers(union uml_pt_regs *to) | |
23 | { | |
24 | memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs)); | |
25 | memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp)); | |
26 | if(have_fpx_regs) | |
27 | memcpy(to->skas.xfp, exec_fpx_regs, sizeof(to->skas.xfp)); | |
28 | } | |
29 | ||
30 | /* XXX These need to use [GS]ETFPXREGS and copy_sc_{to,from}_user_skas needs | |
31 | * to pass in a sufficiently large buffer | |
32 | */ | |
33 | int save_fp_registers(int pid, unsigned long *fp_regs) | |
34 | { | |
35 | if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) | |
36 | return(-errno); | |
37 | return(0); | |
38 | } | |
39 | ||
40 | int restore_fp_registers(int pid, unsigned long *fp_regs) | |
41 | { | |
42 | if(ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) | |
43 | return(-errno); | |
44 | return(0); | |
45 | } | |
46 | ||
47 | static int move_registers(int pid, int int_op, union uml_pt_regs *regs, | |
48 | int fp_op, unsigned long *fp_regs) | |
49 | { | |
50 | if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) | |
51 | return(-errno); | |
52 | ||
53 | if(ptrace(fp_op, pid, 0, fp_regs) < 0) | |
54 | return(-errno); | |
55 | ||
56 | return(0); | |
57 | } | |
58 | ||
59 | void save_registers(int pid, union uml_pt_regs *regs) | |
60 | { | |
61 | unsigned long *fp_regs; | |
62 | int err, fp_op; | |
63 | ||
64 | if(have_fpx_regs){ | |
65 | fp_op = PTRACE_GETFPXREGS; | |
66 | fp_regs = regs->skas.xfp; | |
67 | } | |
68 | else { | |
69 | fp_op = PTRACE_GETFPREGS; | |
70 | fp_regs = regs->skas.fp; | |
71 | } | |
72 | ||
73 | err = move_registers(pid, PTRACE_GETREGS, regs, fp_op, fp_regs); | |
74 | if(err) | |
75 | panic("save_registers - saving registers failed, errno = %d\n", | |
76 | -err); | |
77 | } | |
78 | ||
79 | void restore_registers(int pid, union uml_pt_regs *regs) | |
80 | { | |
81 | unsigned long *fp_regs; | |
82 | int err, fp_op; | |
83 | ||
84 | if(have_fpx_regs){ | |
85 | fp_op = PTRACE_SETFPXREGS; | |
86 | fp_regs = regs->skas.xfp; | |
87 | } | |
88 | else { | |
89 | fp_op = PTRACE_SETFPREGS; | |
90 | fp_regs = regs->skas.fp; | |
91 | } | |
92 | ||
93 | err = move_registers(pid, PTRACE_SETREGS, regs, fp_op, fp_regs); | |
94 | if(err) | |
95 | panic("restore_registers - saving registers failed, " | |
96 | "errno = %d\n", -err); | |
97 | } | |
98 | ||
99 | void init_registers(int pid) | |
100 | { | |
101 | int err; | |
102 | ||
103 | err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); | |
104 | if(err) | |
105 | panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", | |
106 | err); | |
107 | ||
108 | err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); | |
109 | if(!err) | |
110 | return; | |
111 | ||
112 | have_fpx_regs = 0; | |
113 | if(err != EIO) | |
114 | panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", | |
115 | err); | |
116 | ||
117 | err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); | |
118 | if(err) | |
119 | panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", | |
120 | err); | |
121 | } | |
122 | ||
123 | /* | |
124 | * Overrides for Emacs so that we follow Linus's tabbing style. | |
125 | * Emacs will notice this stuff at the end of the file and automatically | |
126 | * adjust the settings for this buffer only. This must remain at the end | |
127 | * of the file. | |
128 | * --------------------------------------------------------------------------- | |
129 | * Local variables: | |
130 | * c-file-style: "linux" | |
131 | * End: | |
132 | */ |