1 /*-
2 * Copyright (c) 2002 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
13 *
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
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include "opt_compat.h"
31
32 #define __ELF_WORD_SIZE 32
33
34 #include <sys/param.h>
35 #include <sys/exec.h>
36 #include <sys/fcntl.h>
37 #include <sys/imgact.h>
38 #include <sys/kernel.h>
39 #include <sys/lock.h>
40 #include <sys/malloc.h>
41 #include <sys/mutex.h>
42 #include <sys/mman.h>
43 #include <sys/namei.h>
44 #include <sys/pioctl.h>
45 #include <sys/proc.h>
46 #include <sys/procfs.h>
47 #include <sys/resourcevar.h>
48 #include <sys/systm.h>
49 #include <sys/signalvar.h>
50 #include <sys/stat.h>
51 #include <sys/sx.h>
52 #include <sys/syscall.h>
53 #include <sys/sysctl.h>
54 #include <sys/sysent.h>
55 #include <sys/vnode.h>
56 #include <sys/imgact_elf.h>
57 #include <sys/sysproto.h>
58
59 #include <machine/frame.h>
60 #include <machine/md_var.h>
61 #include <machine/pcb.h>
62
63 #include <vm/vm.h>
64 #include <vm/vm_kern.h>
65 #include <vm/vm_param.h>
66 #include <vm/pmap.h>
67 #include <vm/vm_map.h>
68 #include <vm/vm_object.h>
69 #include <vm/vm_extern.h>
70
71 #include <compat/freebsd32/freebsd32_util.h>
72 #include <compat/freebsd32/freebsd32_proto.h>
73 #include <compat/ia32/ia32_signal.h>
74 #include <i386/include/psl.h>
75 #include <i386/include/segments.h>
76 #include <i386/include/specialreg.h>
77
78 /*
79 * Signal sending has not been implemented on ia64. This causes
80 * the sigtramp code to not understand the arguments and the application
81 * will generally crash if it tries to handle a signal. Calling
82 * sendsig() means that at least untrapped signals will work.
83 */
84 void
85 ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
86 {
87 sendsig(catcher, sig, mask, code);
88 }
89
90 #ifdef COMPAT_FREEBSD4
91 int
92 freebsd4_freebsd32_sigreturn(struct thread *td, struct freebsd4_freebsd32_sigreturn_args *uap)
93 {
94 return (sigreturn(td, (struct sigreturn_args *)uap));
95 }
96 #endif
97
98 int
99 freebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap)
100 {
101 return (sigreturn(td, (struct sigreturn_args *)uap));
102 }
103
104
105 void
106 ia32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
107 {
108 struct trapframe *tf = td->td_frame;
109 vm_offset_t gdt, ldt;
110 u_int64_t codesel, datasel, ldtsel;
111 u_int64_t codeseg, dataseg, gdtseg, ldtseg;
112 struct segment_descriptor desc;
113 struct vmspace *vmspace = td->td_proc->p_vmspace;
114
115 exec_setregs(td, entry, stack, ps_strings);
116
117 /* Non-syscall frames are cleared by exec_setregs() */
118 if (tf->tf_flags & FRAME_SYSCALL) {
119 bzero(&tf->tf_scratch, sizeof(tf->tf_scratch));
120 bzero(&tf->tf_scratch_fp, sizeof(tf->tf_scratch_fp));
121 } else
122 tf->tf_special.ndirty = 0;
123
124 tf->tf_special.psr |= IA64_PSR_IS;
125 tf->tf_special.sp = stack;
126
127 /* Point the RSE backstore to something harmless. */
128 tf->tf_special.bspstore = (FREEBSD32_PS_STRINGS - sz_ia32_sigcode -
129 SPARE_USRSPACE + 15) & ~15;
130
131 codesel = LSEL(LUCODE_SEL, SEL_UPL);
132 datasel = LSEL(LUDATA_SEL, SEL_UPL);
133 ldtsel = GSEL(GLDT_SEL, SEL_UPL);
134
135 /* Setup ia32 segment registers. */
136 tf->tf_scratch.gr16 = (datasel << 48) | (datasel << 32) |
137 (datasel << 16) | datasel;
138 tf->tf_scratch.gr17 = (ldtsel << 32) | (datasel << 16) | codesel;
139
140 /*
141 * Build the GDT and LDT.
142 */
143 gdt = FREEBSD32_USRSTACK;
144 vm_map_find(&vmspace->vm_map, 0, 0, &gdt, IA32_PAGE_SIZE << 1, 0,
145 VM_PROT_ALL, VM_PROT_ALL, 0);
146 ldt = gdt + IA32_PAGE_SIZE;
147
148 desc.sd_lolimit = 8*NLDT-1;
149 desc.sd_lobase = ldt & 0xffffff;
150 desc.sd_type = SDT_SYSLDT;
151 desc.sd_dpl = SEL_UPL;
152 desc.sd_p = 1;
153 desc.sd_hilimit = 0;
154 desc.sd_def32 = 0;
155 desc.sd_gran = 0;
156 desc.sd_hibase = ldt >> 24;
157 copyout(&desc, (caddr_t) gdt + 8*GLDT_SEL, sizeof(desc));
158
159 desc.sd_lolimit = ((FREEBSD32_USRSTACK >> 12) - 1) & 0xffff;
160 desc.sd_lobase = 0;
161 desc.sd_type = SDT_MEMERA;
162 desc.sd_dpl = SEL_UPL;
163 desc.sd_p = 1;
164 desc.sd_hilimit = ((FREEBSD32_USRSTACK >> 12) - 1) >> 16;
165 desc.sd_def32 = 1;
166 desc.sd_gran = 1;
167 desc.sd_hibase = 0;
168 copyout(&desc, (caddr_t) ldt + 8*LUCODE_SEL, sizeof(desc));
169 desc.sd_type = SDT_MEMRWA;
170 copyout(&desc, (caddr_t) ldt + 8*LUDATA_SEL, sizeof(desc));
171
172 codeseg = 0 /* base */
173 + (((FREEBSD32_USRSTACK >> 12) - 1) << 32) /* limit */
174 + ((long)SDT_MEMERA << 52)
175 + ((long)SEL_UPL << 57)
176 + (1L << 59) /* present */
177 + (1L << 62) /* 32 bits */
178 + (1L << 63); /* page granularity */
179 dataseg = 0 /* base */
180 + (((FREEBSD32_USRSTACK >> 12) - 1) << 32) /* limit */
181 + ((long)SDT_MEMRWA << 52)
182 + ((long)SEL_UPL << 57)
183 + (1L << 59) /* present */
184 + (1L << 62) /* 32 bits */
185 + (1L << 63); /* page granularity */
186
187 tf->tf_scratch.csd = codeseg;
188 tf->tf_scratch.ssd = dataseg;
189 tf->tf_scratch.gr24 = dataseg; /* ESD */
190 tf->tf_scratch.gr27 = dataseg; /* DSD */
191 tf->tf_scratch.gr28 = dataseg; /* FSD */
192 tf->tf_scratch.gr29 = dataseg; /* GSD */
193
194 gdtseg = gdt /* base */
195 + ((8L*NGDT - 1) << 32) /* limit */
196 + ((long)SDT_SYSNULL << 52)
197 + ((long)SEL_UPL << 57)
198 + (1L << 59) /* present */
199 + (0L << 62) /* 16 bits */
200 + (0L << 63); /* byte granularity */
201 ldtseg = ldt /* base */
202 + ((8L*NLDT - 1) << 32) /* limit */
203 + ((long)SDT_SYSLDT << 52)
204 + ((long)SEL_UPL << 57)
205 + (1L << 59) /* present */
206 + (0L << 62) /* 16 bits */
207 + (0L << 63); /* byte granularity */
208
209 tf->tf_scratch.gr30 = ldtseg; /* LDTD */
210 tf->tf_scratch.gr31 = gdtseg; /* GDTD */
211
212 /* Set ia32 control registers on this processor. */
213 ia64_set_cflg(CR0_PE | CR0_PG | ((long)(CR4_XMM | CR4_FXSR) << 32));
214 ia64_set_eflag(PSL_USER);
215
216 /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */
217 tf->tf_scratch.gr11 = FREEBSD32_PS_STRINGS;
218
219 /*
220 * XXX - Linux emulator
221 * Make sure sure edx is 0x0 on entry. Linux binaries depend
222 * on it.
223 */
224 td->td_retval[1] = 0;
225 }
226
227 void
228 ia32_restorectx(struct pcb *pcb)
229 {
230
231 ia64_set_cflg(pcb->pcb_ia32_cflg);
232 ia64_set_eflag(pcb->pcb_ia32_eflag);
233 ia64_set_fcr(pcb->pcb_ia32_fcr);
234 ia64_set_fdr(pcb->pcb_ia32_fdr);
235 ia64_set_fir(pcb->pcb_ia32_fir);
236 ia64_set_fsr(pcb->pcb_ia32_fsr);
237 }
238
239 void
240 ia32_savectx(struct pcb *pcb)
241 {
242
243 pcb->pcb_ia32_cflg = ia64_get_cflg();
244 pcb->pcb_ia32_eflag = ia64_get_eflag();
245 pcb->pcb_ia32_fcr = ia64_get_fcr();
246 pcb->pcb_ia32_fdr = ia64_get_fdr();
247 pcb->pcb_ia32_fir = ia64_get_fir();
248 pcb->pcb_ia32_fsr = ia64_get_fsr();
249 }
250
251 int
252 freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap)
253 {
254
255 return (nosys(td, NULL));
256 }
257
258 int
259 freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap)
260 {
261
262 return (nosys(td, NULL));
263 }
264
265 int
266 freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
267 {
268
269 return (nosys(td, NULL));
270 }
Cache object: 30355b169626c6121d1680e42e4c5670
|