2 * Copyright (c) 2005 Doug Rabson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/malloc.h>
37 #include <sys/ptrace.h>
38 #include <machine/frame.h>
39 #include <machine/md_var.h>
40 #include <machine/pcb.h>
42 #if !defined(CPU_DISABLE_SSE) && defined(I686_CPU)
43 #define CPU_ENABLE_SSE
48 cpu_ptrace_xstate(struct thread
*td
, int req
, void *addr
, int data
)
50 struct ptrace_xstate_info info
;
58 case PT_GETXSTATE_OLD
:
60 savefpu
= (char *)(get_pcb_user_save_td(td
) + 1);
61 error
= copyout(savefpu
, addr
,
62 cpu_max_ext_state_size
- sizeof(union savefpu
));
65 case PT_SETXSTATE_OLD
:
66 if (data
> cpu_max_ext_state_size
- sizeof(union savefpu
)) {
70 savefpu
= malloc(data
, M_TEMP
, M_WAITOK
);
71 error
= copyin(addr
, savefpu
, data
);
74 error
= npxsetxstate(td
, savefpu
, data
);
76 free(savefpu
, M_TEMP
);
79 case PT_GETXSTATE_INFO
:
80 if (data
!= sizeof(info
)) {
84 info
.xsave_len
= cpu_max_ext_state_size
;
85 info
.xsave_mask
= xsave_mask
;
86 error
= copyout(&info
, addr
, data
);
91 savefpu
= (char *)(get_pcb_user_save_td(td
));
92 error
= copyout(savefpu
, addr
, cpu_max_ext_state_size
);
96 if (data
< sizeof(union savefpu
) ||
97 data
> cpu_max_ext_state_size
) {
101 savefpu
= malloc(data
, M_TEMP
, M_WAITOK
);
102 error
= copyin(addr
, savefpu
, data
);
104 error
= npxsetregs(td
, (union savefpu
*)savefpu
,
105 savefpu
+ sizeof(union savefpu
), data
-
106 sizeof(union savefpu
));
107 free(savefpu
, M_TEMP
);
120 cpu_ptrace_xmm(struct thread
*td
, int req
, void *addr
, int data
)
122 #ifdef CPU_ENABLE_SSE
123 struct savexmm
*fpstate
;
129 fpstate
= &get_pcb_user_save_td(td
)->sv_xmm
;
133 error
= copyout(fpstate
, addr
, sizeof(*fpstate
));
138 error
= copyin(addr
, fpstate
, sizeof(*fpstate
));
139 fpstate
->sv_env
.en_mxcsr
&= cpu_mxcsr_mask
;
142 case PT_GETXSTATE_OLD
:
143 case PT_SETXSTATE_OLD
:
144 case PT_GETXSTATE_INFO
:
147 error
= cpu_ptrace_xstate(td
, req
, addr
, data
);
161 cpu_ptrace(struct thread
*td
, int req
, void *addr
, int data
)
163 struct segment_descriptor
*sdp
, sd
;
170 case PT_GETXSTATE_OLD
:
171 case PT_SETXSTATE_OLD
:
172 case PT_GETXSTATE_INFO
:
175 error
= cpu_ptrace_xmm(td
, req
, addr
, data
);
180 sdp
= req
== PT_GETFSBASE
? &td
->td_pcb
->pcb_fsd
:
181 &td
->td_pcb
->pcb_gsd
;
182 r
= sdp
->sd_hibase
<< 24 | sdp
->sd_lobase
;
183 error
= copyout(&r
, addr
, sizeof(r
));
188 error
= copyin(addr
, &r
, sizeof(r
));
191 fill_based_sd(&sd
, r
);
192 if (req
== PT_SETFSBASE
) {
193 td
->td_pcb
->pcb_fsd
= sd
;
194 td
->td_frame
->tf_fs
= GSEL(GUFS_SEL
, SEL_UPL
);
196 td
->td_pcb
->pcb_gsd
= sd
;
197 td
->td_pcb
->pcb_gs
= GSEL(GUGS_SEL
, SEL_UPL
);