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