ansify function definitionsdiff -r1.20 -r1.21 src/sys/compat/linux32/arch/amd64/linux32_machdep.c
(cegger)
--- src/sys/compat/linux32/arch/amd64/linux32_machdep.c 2008/10/19 09:44:31 1.20
+++ src/sys/compat/linux32/arch/amd64/linux32_machdep.c 2009/03/15 15:56:50 1.21
@@ -1,505 +1,500 @@ | @@ -1,505 +1,500 @@ | |||
1 | /* $NetBSD: linux32_machdep.c,v 1.20 2008/10/19 09:44:31 njoly Exp $ */ | 1 | /* $NetBSD: linux32_machdep.c,v 1.21 2009/03/15 15:56:50 cegger Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. | 4 | * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. All advertising materials mentioning features or use of this software | |
15 | * must display the following acknowledgement: | 15 | * must display the following acknowledgement: | |
16 | * This product includes software developed by Emmanuel Dreyfus | 16 | * This product includes software developed by Emmanuel Dreyfus | |
17 | * 4. The name of the author may not be used to endorse or promote | 17 | * 4. The name of the author may not be used to endorse or promote | |
18 | * products derived from this software without specific prior written | 18 | * products derived from this software without specific prior written | |
19 | * permission. | 19 | * permission. | |
20 | * | 20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | 21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | |
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | 24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | |
25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
31 | * POSSIBILITY OF SUCH DAMAGE. | 31 | * POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
34 | __KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.20 2008/10/19 09:44:31 njoly Exp $"); | 34 | __KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.21 2009/03/15 15:56:50 cegger Exp $"); | |
35 | 35 | |||
36 | #include <sys/param.h> | 36 | #include <sys/param.h> | |
37 | #include <sys/systm.h> | 37 | #include <sys/systm.h> | |
38 | #include <sys/signalvar.h> | 38 | #include <sys/signalvar.h> | |
39 | #include <sys/kernel.h> | 39 | #include <sys/kernel.h> | |
40 | #include <sys/proc.h> | 40 | #include <sys/proc.h> | |
41 | #include <sys/user.h> | 41 | #include <sys/user.h> | |
42 | #include <sys/buf.h> | 42 | #include <sys/buf.h> | |
43 | #include <sys/reboot.h> | 43 | #include <sys/reboot.h> | |
44 | #include <sys/conf.h> | 44 | #include <sys/conf.h> | |
45 | #include <sys/exec.h> | 45 | #include <sys/exec.h> | |
46 | #include <sys/file.h> | 46 | #include <sys/file.h> | |
47 | #include <sys/callout.h> | 47 | #include <sys/callout.h> | |
48 | #include <sys/malloc.h> | 48 | #include <sys/malloc.h> | |
49 | #include <sys/mbuf.h> | 49 | #include <sys/mbuf.h> | |
50 | #include <sys/msgbuf.h> | 50 | #include <sys/msgbuf.h> | |
51 | #include <sys/mount.h> | 51 | #include <sys/mount.h> | |
52 | #include <sys/vnode.h> | 52 | #include <sys/vnode.h> | |
53 | #include <sys/device.h> | 53 | #include <sys/device.h> | |
54 | #include <sys/syscallargs.h> | 54 | #include <sys/syscallargs.h> | |
55 | #include <sys/filedesc.h> | 55 | #include <sys/filedesc.h> | |
56 | #include <sys/exec_elf.h> | 56 | #include <sys/exec_elf.h> | |
57 | #include <sys/disklabel.h> | 57 | #include <sys/disklabel.h> | |
58 | #include <sys/ioctl.h> | 58 | #include <sys/ioctl.h> | |
59 | #include <sys/wait.h> | 59 | #include <sys/wait.h> | |
60 | #include <miscfs/specfs/specdev.h> | 60 | #include <miscfs/specfs/specdev.h> | |
61 | 61 | |||
62 | #include <machine/netbsd32_machdep.h> | 62 | #include <machine/netbsd32_machdep.h> | |
63 | 63 | |||
64 | #include <compat/netbsd32/netbsd32.h> | 64 | #include <compat/netbsd32/netbsd32.h> | |
65 | #include <compat/netbsd32/netbsd32_syscallargs.h> | 65 | #include <compat/netbsd32/netbsd32_syscallargs.h> | |
66 | 66 | |||
67 | #include <compat/linux/common/linux_signal.h> | 67 | #include <compat/linux/common/linux_signal.h> | |
68 | #include <compat/linux/common/linux_errno.h> | 68 | #include <compat/linux/common/linux_errno.h> | |
69 | 69 | |||
70 | #include <compat/linux32/common/linux32_types.h> | 70 | #include <compat/linux32/common/linux32_types.h> | |
71 | #include <compat/linux32/common/linux32_errno.h> | 71 | #include <compat/linux32/common/linux32_errno.h> | |
72 | #include <compat/linux32/common/linux32_machdep.h> | 72 | #include <compat/linux32/common/linux32_machdep.h> | |
73 | #include <compat/linux32/common/linux32_signal.h> | 73 | #include <compat/linux32/common/linux32_signal.h> | |
74 | #include <compat/linux32/common/linux32_exec.h> | 74 | #include <compat/linux32/common/linux32_exec.h> | |
75 | #include <compat/linux32/linux32_syscallargs.h> | 75 | #include <compat/linux32/linux32_syscallargs.h> | |
76 | 76 | |||
77 | #include <sys/cpu.h> | 77 | #include <sys/cpu.h> | |
78 | #include <machine/cpufunc.h> | 78 | #include <machine/cpufunc.h> | |
79 | #include <machine/psl.h> | 79 | #include <machine/psl.h> | |
80 | #include <machine/reg.h> | 80 | #include <machine/reg.h> | |
81 | #include <machine/segments.h> | 81 | #include <machine/segments.h> | |
82 | #include <machine/specialreg.h> | 82 | #include <machine/specialreg.h> | |
83 | #include <machine/sysarch.h> | 83 | #include <machine/sysarch.h> | |
84 | #include <machine/vmparam.h> | 84 | #include <machine/vmparam.h> | |
85 | 85 | |||
86 | extern char linux32_sigcode[1]; | 86 | extern char linux32_sigcode[1]; | |
87 | extern char linux32_rt_sigcode[1]; | 87 | extern char linux32_rt_sigcode[1]; | |
88 | extern char linux32_esigcode[1]; | 88 | extern char linux32_esigcode[1]; | |
89 | 89 | |||
90 | extern void (osyscall_return)(void); | 90 | extern void (osyscall_return)(void); | |
91 | 91 | |||
92 | static void linux32_save_ucontext(struct lwp *, struct trapframe *, | 92 | static void linux32_save_ucontext(struct lwp *, struct trapframe *, | |
93 | const sigset_t *, struct sigaltstack *, struct linux32_ucontext *); | 93 | const sigset_t *, struct sigaltstack *, struct linux32_ucontext *); | |
94 | static void linux32_save_sigcontext(struct lwp *, struct trapframe *, | 94 | static void linux32_save_sigcontext(struct lwp *, struct trapframe *, | |
95 | const sigset_t *, struct linux32_sigcontext *); | 95 | const sigset_t *, struct linux32_sigcontext *); | |
96 | static void linux32_rt_sendsig(const ksiginfo_t *, const sigset_t *); | 96 | static void linux32_rt_sendsig(const ksiginfo_t *, const sigset_t *); | |
97 | static void linux32_old_sendsig(const ksiginfo_t *, const sigset_t *); | 97 | static void linux32_old_sendsig(const ksiginfo_t *, const sigset_t *); | |
98 | static int linux32_restore_sigcontext(struct lwp *, | 98 | static int linux32_restore_sigcontext(struct lwp *, | |
99 | struct linux32_sigcontext *, register_t *); | 99 | struct linux32_sigcontext *, register_t *); | |
100 | 100 | |||
101 | void | 101 | void | |
102 | linux32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) | 102 | linux32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) | |
103 | { | 103 | { | |
104 | if (SIGACTION(curproc, ksi->ksi_signo).sa_flags & SA_SIGINFO) | 104 | if (SIGACTION(curproc, ksi->ksi_signo).sa_flags & SA_SIGINFO) | |
105 | linux32_rt_sendsig(ksi, mask); | 105 | linux32_rt_sendsig(ksi, mask); | |
106 | else | 106 | else | |
107 | linux32_old_sendsig(ksi, mask); | 107 | linux32_old_sendsig(ksi, mask); | |
108 | return; | 108 | return; | |
109 | } | 109 | } | |
110 | 110 | |||
111 | void | 111 | void | |
112 | linux32_old_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) | 112 | linux32_old_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) | |
113 | { | 113 | { | |
114 | struct lwp *l = curlwp; | 114 | struct lwp *l = curlwp; | |
115 | struct proc *p = l->l_proc; | 115 | struct proc *p = l->l_proc; | |
116 | struct trapframe *tf; | 116 | struct trapframe *tf; | |
117 | struct linux32_sigframe *fp, frame; | 117 | struct linux32_sigframe *fp, frame; | |
118 | int onstack, error; | 118 | int onstack, error; | |
119 | int sig = ksi->ksi_signo; | 119 | int sig = ksi->ksi_signo; | |
120 | sig_t catcher = SIGACTION(p, sig).sa_handler; | 120 | sig_t catcher = SIGACTION(p, sig).sa_handler; | |
121 | struct sigaltstack *sas = &l->l_sigstk; | 121 | struct sigaltstack *sas = &l->l_sigstk; | |
122 | 122 | |||
123 | tf = l->l_md.md_regs; | 123 | tf = l->l_md.md_regs; | |
124 | /* Do we need to jump onto the signal stack? */ | 124 | /* Do we need to jump onto the signal stack? */ | |
125 | onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && | 125 | onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && | |
126 | (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; | 126 | (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; | |
127 | 127 | |||
128 | 128 | |||
129 | /* Allocate space for the signal handler context. */ | 129 | /* Allocate space for the signal handler context. */ | |
130 | if (onstack) | 130 | if (onstack) | |
131 | fp = (struct linux32_sigframe *)((char *)sas->ss_sp + | 131 | fp = (struct linux32_sigframe *)((char *)sas->ss_sp + | |
132 | sas->ss_size); | 132 | sas->ss_size); | |
133 | else | 133 | else | |
134 | fp = (struct linux32_sigframe *)tf->tf_rsp; | 134 | fp = (struct linux32_sigframe *)tf->tf_rsp; | |
135 | fp--; | 135 | fp--; | |
136 | 136 | |||
137 | /* Build stack frame for signal trampoline. */ | 137 | /* Build stack frame for signal trampoline. */ | |
138 | NETBSD32PTR32(frame.sf_handler, catcher); | 138 | NETBSD32PTR32(frame.sf_handler, catcher); | |
139 | frame.sf_sig = native_to_linux32_signo[sig]; | 139 | frame.sf_sig = native_to_linux32_signo[sig]; | |
140 | 140 | |||
141 | linux32_save_sigcontext(l, tf, mask, &frame.sf_sc); | 141 | linux32_save_sigcontext(l, tf, mask, &frame.sf_sc); | |
142 | 142 | |||
143 | sendsig_reset(l, sig); | 143 | sendsig_reset(l, sig); | |
144 | mutex_exit(p->p_lock); | 144 | mutex_exit(p->p_lock); | |
145 | error = copyout(&frame, fp, sizeof(frame)); | 145 | error = copyout(&frame, fp, sizeof(frame)); | |
146 | mutex_enter(p->p_lock); | 146 | mutex_enter(p->p_lock); | |
147 | 147 | |||
148 | if (error != 0) { | 148 | if (error != 0) { | |
149 | /* | 149 | /* | |
150 | * Process has trashed its stack; give it an illegal | 150 | * Process has trashed its stack; give it an illegal | |
151 | * instruction to halt it in its tracks. | 151 | * instruction to halt it in its tracks. | |
152 | */ | 152 | */ | |
153 | sigexit(l, SIGILL); | 153 | sigexit(l, SIGILL); | |
154 | /* NOTREACHED */ | 154 | /* NOTREACHED */ | |
155 | } | 155 | } | |
156 | 156 | |||
157 | /* | 157 | /* | |
158 | * Build context to run handler in. | 158 | * Build context to run handler in. | |
159 | */ | 159 | */ | |
160 | tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 160 | tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
161 | tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 161 | tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
162 | tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 162 | tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
163 | tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 163 | tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
164 | tf->tf_rip = ((long)p->p_sigctx.ps_sigcode) & 0xffffffff; | 164 | tf->tf_rip = ((long)p->p_sigctx.ps_sigcode) & 0xffffffff; | |
165 | tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff; | 165 | tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff; | |
166 | tf->tf_rflags &= ~PSL_CLEARSIG & 0xffffffff; | 166 | tf->tf_rflags &= ~PSL_CLEARSIG & 0xffffffff; | |
167 | tf->tf_rsp = (long)fp & 0xffffffff; | 167 | tf->tf_rsp = (long)fp & 0xffffffff; | |
168 | tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 168 | tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
169 | 169 | |||
170 | /* Remember that we're now on the signal stack. */ | 170 | /* Remember that we're now on the signal stack. */ | |
171 | if (onstack) | 171 | if (onstack) | |
172 | sas->ss_flags |= SS_ONSTACK; | 172 | sas->ss_flags |= SS_ONSTACK; | |
173 | 173 | |||
174 | return; | 174 | return; | |
175 | } | 175 | } | |
176 | 176 | |||
177 | void | 177 | void | |
178 | linux32_rt_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) | 178 | linux32_rt_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) | |
179 | { | 179 | { | |
180 | struct lwp *l = curlwp; | 180 | struct lwp *l = curlwp; | |
181 | struct proc *p = l->l_proc; | 181 | struct proc *p = l->l_proc; | |
182 | struct trapframe *tf; | 182 | struct trapframe *tf; | |
183 | struct linux32_rt_sigframe *fp, frame; | 183 | struct linux32_rt_sigframe *fp, frame; | |
184 | int onstack, error; | 184 | int onstack, error; | |
185 | linux32_siginfo_t *lsi; | 185 | linux32_siginfo_t *lsi; | |
186 | int sig = ksi->ksi_signo; | 186 | int sig = ksi->ksi_signo; | |
187 | sig_t catcher = SIGACTION(p, sig).sa_handler; | 187 | sig_t catcher = SIGACTION(p, sig).sa_handler; | |
188 | struct sigaltstack *sas = &l->l_sigstk; | 188 | struct sigaltstack *sas = &l->l_sigstk; | |
189 | 189 | |||
190 | tf = l->l_md.md_regs; | 190 | tf = l->l_md.md_regs; | |
191 | /* Do we need to jump onto the signal stack? */ | 191 | /* Do we need to jump onto the signal stack? */ | |
192 | onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && | 192 | onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && | |
193 | (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; | 193 | (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; | |
194 | 194 | |||
195 | 195 | |||
196 | /* Allocate space for the signal handler context. */ | 196 | /* Allocate space for the signal handler context. */ | |
197 | if (onstack) | 197 | if (onstack) | |
198 | fp = (struct linux32_rt_sigframe *)((char *)sas->ss_sp + | 198 | fp = (struct linux32_rt_sigframe *)((char *)sas->ss_sp + | |
199 | sas->ss_size); | 199 | sas->ss_size); | |
200 | else | 200 | else | |
201 | fp = (struct linux32_rt_sigframe *)tf->tf_rsp; | 201 | fp = (struct linux32_rt_sigframe *)tf->tf_rsp; | |
202 | fp--; | 202 | fp--; | |
203 | 203 | |||
204 | /* Build stack frame for signal trampoline. */ | 204 | /* Build stack frame for signal trampoline. */ | |
205 | NETBSD32PTR32(frame.sf_handler, catcher); | 205 | NETBSD32PTR32(frame.sf_handler, catcher); | |
206 | frame.sf_sig = native_to_linux32_signo[sig]; | 206 | frame.sf_sig = native_to_linux32_signo[sig]; | |
207 | NETBSD32PTR32(frame.sf_sip, &fp->sf_si); | 207 | NETBSD32PTR32(frame.sf_sip, &fp->sf_si); | |
208 | NETBSD32PTR32(frame.sf_ucp, &fp->sf_uc); | 208 | NETBSD32PTR32(frame.sf_ucp, &fp->sf_uc); | |
209 | 209 | |||
210 | lsi = &frame.sf_si; | 210 | lsi = &frame.sf_si; | |
211 | (void)memset(lsi, 0, sizeof(frame.sf_si)); | 211 | (void)memset(lsi, 0, sizeof(frame.sf_si)); | |
212 | lsi->lsi_errno = native_to_linux32_errno[ksi->ksi_errno]; | 212 | lsi->lsi_errno = native_to_linux32_errno[ksi->ksi_errno]; | |
213 | lsi->lsi_code = native_to_linux_si_code(ksi->ksi_code); | 213 | lsi->lsi_code = native_to_linux_si_code(ksi->ksi_code); | |
214 | lsi->lsi_signo = frame.sf_sig; | 214 | lsi->lsi_signo = frame.sf_sig; | |
215 | switch (lsi->lsi_signo) { | 215 | switch (lsi->lsi_signo) { | |
216 | case LINUX32_SIGILL: | 216 | case LINUX32_SIGILL: | |
217 | case LINUX32_SIGFPE: | 217 | case LINUX32_SIGFPE: | |
218 | case LINUX32_SIGSEGV: | 218 | case LINUX32_SIGSEGV: | |
219 | case LINUX32_SIGBUS: | 219 | case LINUX32_SIGBUS: | |
220 | case LINUX32_SIGTRAP: | 220 | case LINUX32_SIGTRAP: | |
221 | NETBSD32PTR32(lsi->lsi_addr, ksi->ksi_addr); | 221 | NETBSD32PTR32(lsi->lsi_addr, ksi->ksi_addr); | |
222 | break; | 222 | break; | |
223 | case LINUX32_SIGCHLD: | 223 | case LINUX32_SIGCHLD: | |
224 | lsi->lsi_uid = ksi->ksi_uid; | 224 | lsi->lsi_uid = ksi->ksi_uid; | |
225 | lsi->lsi_pid = ksi->ksi_pid; | 225 | lsi->lsi_pid = ksi->ksi_pid; | |
226 | lsi->lsi_utime = ksi->ksi_utime; | 226 | lsi->lsi_utime = ksi->ksi_utime; | |
227 | lsi->lsi_stime = ksi->ksi_stime; | 227 | lsi->lsi_stime = ksi->ksi_stime; | |
228 | 228 | |||
229 | /* We use the same codes */ | 229 | /* We use the same codes */ | |
230 | lsi->lsi_code = ksi->ksi_code; | 230 | lsi->lsi_code = ksi->ksi_code; | |
231 | /* XXX is that right? */ | 231 | /* XXX is that right? */ | |
232 | lsi->lsi_status = WEXITSTATUS(ksi->ksi_status); | 232 | lsi->lsi_status = WEXITSTATUS(ksi->ksi_status); | |
233 | break; | 233 | break; | |
234 | case LINUX32_SIGIO: | 234 | case LINUX32_SIGIO: | |
235 | lsi->lsi_band = ksi->ksi_band; | 235 | lsi->lsi_band = ksi->ksi_band; | |
236 | lsi->lsi_fd = ksi->ksi_fd; | 236 | lsi->lsi_fd = ksi->ksi_fd; | |
237 | break; | 237 | break; | |
238 | default: | 238 | default: | |
239 | lsi->lsi_uid = ksi->ksi_uid; | 239 | lsi->lsi_uid = ksi->ksi_uid; | |
240 | lsi->lsi_pid = ksi->ksi_pid; | 240 | lsi->lsi_pid = ksi->ksi_pid; | |
241 | if (lsi->lsi_signo == LINUX32_SIGALRM || | 241 | if (lsi->lsi_signo == LINUX32_SIGALRM || | |
242 | lsi->lsi_signo >= LINUX32_SIGRTMIN) | 242 | lsi->lsi_signo >= LINUX32_SIGRTMIN) | |
243 | NETBSD32PTR32(lsi->lsi_value.sival_ptr, | 243 | NETBSD32PTR32(lsi->lsi_value.sival_ptr, | |
244 | ksi->ksi_value.sival_ptr); | 244 | ksi->ksi_value.sival_ptr); | |
245 | break; | 245 | break; | |
246 | } | 246 | } | |
247 | 247 | |||
248 | /* Save register context. */ | 248 | /* Save register context. */ | |
249 | linux32_save_ucontext(l, tf, mask, sas, &frame.sf_uc); | 249 | linux32_save_ucontext(l, tf, mask, sas, &frame.sf_uc); | |
250 | sendsig_reset(l, sig); | 250 | sendsig_reset(l, sig); | |
251 | mutex_exit(p->p_lock); | 251 | mutex_exit(p->p_lock); | |
252 | error = copyout(&frame, fp, sizeof(frame)); | 252 | error = copyout(&frame, fp, sizeof(frame)); | |
253 | mutex_enter(p->p_lock); | 253 | mutex_enter(p->p_lock); | |
254 | 254 | |||
255 | if (error != 0) { | 255 | if (error != 0) { | |
256 | /* | 256 | /* | |
257 | * Process has trashed its stack; give it an illegal | 257 | * Process has trashed its stack; give it an illegal | |
258 | * instruction to halt it in its tracks. | 258 | * instruction to halt it in its tracks. | |
259 | */ | 259 | */ | |
260 | sigexit(l, SIGILL); | 260 | sigexit(l, SIGILL); | |
261 | /* NOTREACHED */ | 261 | /* NOTREACHED */ | |
262 | } | 262 | } | |
263 | 263 | |||
264 | /* | 264 | /* | |
265 | * Build context to run handler in. | 265 | * Build context to run handler in. | |
266 | */ | 266 | */ | |
267 | tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 267 | tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
268 | tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 268 | tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
269 | tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 269 | tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
270 | tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 270 | tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
271 | tf->tf_rip = (((long)p->p_sigctx.ps_sigcode) + | 271 | tf->tf_rip = (((long)p->p_sigctx.ps_sigcode) + | |
272 | (linux32_rt_sigcode - linux32_sigcode)) & 0xffffffff; | 272 | (linux32_rt_sigcode - linux32_sigcode)) & 0xffffffff; | |
273 | tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff; | 273 | tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff; | |
274 | tf->tf_rflags &= ~PSL_CLEARSIG & 0xffffffff; | 274 | tf->tf_rflags &= ~PSL_CLEARSIG & 0xffffffff; | |
275 | tf->tf_rsp = (long)fp & 0xffffffff; | 275 | tf->tf_rsp = (long)fp & 0xffffffff; | |
276 | tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 276 | tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
277 | 277 | |||
278 | /* Remember that we're now on the signal stack. */ | 278 | /* Remember that we're now on the signal stack. */ | |
279 | if (onstack) | 279 | if (onstack) | |
280 | sas->ss_flags |= SS_ONSTACK; | 280 | sas->ss_flags |= SS_ONSTACK; | |
281 | 281 | |||
282 | return; | 282 | return; | |
283 | } | 283 | } | |
284 | 284 | |||
285 | void | 285 | void | |
286 | linux32_setregs(struct lwp *l, struct exec_package *pack, u_long stack) | 286 | linux32_setregs(struct lwp *l, struct exec_package *pack, u_long stack) | |
287 | { | 287 | { | |
288 | struct pcb *pcb = &l->l_addr->u_pcb; | 288 | struct pcb *pcb = &l->l_addr->u_pcb; | |
289 | struct trapframe *tf; | 289 | struct trapframe *tf; | |
290 | struct proc *p = l->l_proc; | 290 | struct proc *p = l->l_proc; | |
291 | void **retaddr; | 291 | void **retaddr; | |
292 | 292 | |||
293 | /* If we were using the FPU, forget about it. */ | 293 | /* If we were using the FPU, forget about it. */ | |
294 | if (l->l_addr->u_pcb.pcb_fpcpu != NULL) | 294 | if (l->l_addr->u_pcb.pcb_fpcpu != NULL) | |
295 | fpusave_lwp(l, 0); | 295 | fpusave_lwp(l, 0); | |
296 | 296 | |||
297 | #if defined(USER_LDT) && 0 | 297 | #if defined(USER_LDT) && 0 | |
298 | pmap_ldt_cleanup(p); | 298 | pmap_ldt_cleanup(p); | |
299 | #endif | 299 | #endif | |
300 | 300 | |||
301 | netbsd32_adjust_limits(p); | 301 | netbsd32_adjust_limits(p); | |
302 | 302 | |||
303 | l->l_md.md_flags &= ~MDP_USEDFPU; | 303 | l->l_md.md_flags &= ~MDP_USEDFPU; | |
304 | pcb->pcb_flags = 0; | 304 | pcb->pcb_flags = 0; | |
305 | pcb->pcb_savefpu.fp_fxsave.fx_fcw = __Linux_NPXCW__; | 305 | pcb->pcb_savefpu.fp_fxsave.fx_fcw = __Linux_NPXCW__; | |
306 | pcb->pcb_savefpu.fp_fxsave.fx_mxcsr = __INITIAL_MXCSR__; | 306 | pcb->pcb_savefpu.fp_fxsave.fx_mxcsr = __INITIAL_MXCSR__; | |
307 | pcb->pcb_savefpu.fp_fxsave.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__; | 307 | pcb->pcb_savefpu.fp_fxsave.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__; | |
308 | pcb->pcb_fs = 0; | 308 | pcb->pcb_fs = 0; | |
309 | pcb->pcb_gs = 0; | 309 | pcb->pcb_gs = 0; | |
310 | 310 | |||
311 | 311 | |||
312 | p->p_flag |= PK_32; | 312 | p->p_flag |= PK_32; | |
313 | 313 | |||
314 | tf = l->l_md.md_regs; | 314 | tf = l->l_md.md_regs; | |
315 | tf->tf_rax = 0; | 315 | tf->tf_rax = 0; | |
316 | tf->tf_rbx = (u_int64_t)p->p_psstr & 0xffffffff; | 316 | tf->tf_rbx = (u_int64_t)p->p_psstr & 0xffffffff; | |
317 | tf->tf_rcx = pack->ep_entry & 0xffffffff; | 317 | tf->tf_rcx = pack->ep_entry & 0xffffffff; | |
318 | tf->tf_rdx = 0; | 318 | tf->tf_rdx = 0; | |
319 | tf->tf_rsi = 0; | 319 | tf->tf_rsi = 0; | |
320 | tf->tf_rdi = 0; | 320 | tf->tf_rdi = 0; | |
321 | tf->tf_rbp = 0; | 321 | tf->tf_rbp = 0; | |
322 | tf->tf_rsp = stack & 0xffffffff; | 322 | tf->tf_rsp = stack & 0xffffffff; | |
323 | tf->tf_r8 = 0; | 323 | tf->tf_r8 = 0; | |
324 | tf->tf_r9 = 0; | 324 | tf->tf_r9 = 0; | |
325 | tf->tf_r10 = 0; | 325 | tf->tf_r10 = 0; | |
326 | tf->tf_r11 = 0; | 326 | tf->tf_r11 = 0; | |
327 | tf->tf_r12 = 0; | 327 | tf->tf_r12 = 0; | |
328 | tf->tf_r13 = 0; | 328 | tf->tf_r13 = 0; | |
329 | tf->tf_r14 = 0; | 329 | tf->tf_r14 = 0; | |
330 | tf->tf_r15 = 0; | 330 | tf->tf_r15 = 0; | |
331 | tf->tf_rip = pack->ep_entry & 0xffffffff; | 331 | tf->tf_rip = pack->ep_entry & 0xffffffff; | |
332 | tf->tf_rflags = PSL_USERSET; | 332 | tf->tf_rflags = PSL_USERSET; | |
333 | tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff; | 333 | tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff; | |
334 | tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 334 | tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
335 | tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 335 | tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
336 | tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 336 | tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
337 | tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 337 | tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
338 | tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | 338 | tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff; | |
339 | 339 | |||
340 | /* XXX frob return address to return via old iret method, not sysret */ | 340 | /* XXX frob return address to return via old iret method, not sysret */ | |
341 | retaddr = (void **)tf - 1; | 341 | retaddr = (void **)tf - 1; | |
342 | *retaddr = (void *)osyscall_return; | 342 | *retaddr = (void *)osyscall_return; | |
343 | return; | 343 | return; | |
344 | } | 344 | } | |
345 | 345 | |||
346 | static void | 346 | static void | |
347 | linux32_save_ucontext(struct lwp *l, struct trapframe *tf, const sigset_t *mask, struct sigaltstack *sas, struct linux32_ucontext *uc) | 347 | linux32_save_ucontext(struct lwp *l, struct trapframe *tf, const sigset_t *mask, struct sigaltstack *sas, struct linux32_ucontext *uc) | |
348 | { | 348 | { | |
349 | uc->uc_flags = 0; | 349 | uc->uc_flags = 0; | |
350 | NETBSD32PTR32(uc->uc_link, NULL); | 350 | NETBSD32PTR32(uc->uc_link, NULL); | |
351 | native_to_linux32_sigaltstack(&uc->uc_stack, sas); | 351 | native_to_linux32_sigaltstack(&uc->uc_stack, sas); | |
352 | linux32_save_sigcontext(l, tf, mask, &uc->uc_mcontext); | 352 | linux32_save_sigcontext(l, tf, mask, &uc->uc_mcontext); | |
353 | native_to_linux32_sigset(&uc->uc_sigmask, mask); | 353 | native_to_linux32_sigset(&uc->uc_sigmask, mask); | |
354 | (void)memset(&uc->uc_fpregs_mem, 0, sizeof(uc->uc_fpregs_mem)); | 354 | (void)memset(&uc->uc_fpregs_mem, 0, sizeof(uc->uc_fpregs_mem)); | |
355 | } | 355 | } | |
356 | 356 | |||
357 | static void | 357 | static void | |
358 | linux32_save_sigcontext(l, tf, mask, sc) | 358 | linux32_save_sigcontext(struct lwp *l, struct trapframe *tf, | |
359 | struct lwp *l; | 359 | const sigset_t *mask, struct linux32_sigcontext *sc) | |
360 | struct trapframe *tf; | |||
361 | const sigset_t *mask; | |||
362 | struct linux32_sigcontext *sc; | |||
363 | { | 360 | { | |
364 | /* Save register context. */ | 361 | /* Save register context. */ | |
365 | sc->sc_gs = tf->tf_gs; | 362 | sc->sc_gs = tf->tf_gs; | |
366 | sc->sc_fs = tf->tf_fs; | 363 | sc->sc_fs = tf->tf_fs; | |
367 | sc->sc_es = tf->tf_es; | 364 | sc->sc_es = tf->tf_es; | |
368 | sc->sc_ds = tf->tf_ds; | 365 | sc->sc_ds = tf->tf_ds; | |
369 | sc->sc_eflags = tf->tf_rflags; | 366 | sc->sc_eflags = tf->tf_rflags; | |
370 | sc->sc_edi = tf->tf_rdi; | 367 | sc->sc_edi = tf->tf_rdi; | |
371 | sc->sc_esi = tf->tf_rsi; | 368 | sc->sc_esi = tf->tf_rsi; | |
372 | sc->sc_esp = tf->tf_rsp; | 369 | sc->sc_esp = tf->tf_rsp; | |
373 | sc->sc_ebp = tf->tf_rbp; | 370 | sc->sc_ebp = tf->tf_rbp; | |
374 | sc->sc_ebx = tf->tf_rbx; | 371 | sc->sc_ebx = tf->tf_rbx; | |
375 | sc->sc_edx = tf->tf_rdx; | 372 | sc->sc_edx = tf->tf_rdx; | |
376 | sc->sc_ecx = tf->tf_rcx; | 373 | sc->sc_ecx = tf->tf_rcx; | |
377 | sc->sc_eax = tf->tf_rax; | 374 | sc->sc_eax = tf->tf_rax; | |
378 | sc->sc_eip = tf->tf_rip; | 375 | sc->sc_eip = tf->tf_rip; | |
379 | sc->sc_cs = tf->tf_cs; | 376 | sc->sc_cs = tf->tf_cs; | |
380 | sc->sc_esp_at_signal = tf->tf_rsp; | 377 | sc->sc_esp_at_signal = tf->tf_rsp; | |
381 | sc->sc_ss = tf->tf_ss; | 378 | sc->sc_ss = tf->tf_ss; | |
382 | sc->sc_err = tf->tf_err; | 379 | sc->sc_err = tf->tf_err; | |
383 | sc->sc_trapno = tf->tf_trapno; | 380 | sc->sc_trapno = tf->tf_trapno; | |
384 | sc->sc_cr2 = l->l_addr->u_pcb.pcb_cr2; | 381 | sc->sc_cr2 = l->l_addr->u_pcb.pcb_cr2; | |
385 | NETBSD32PTR32(sc->sc_387, NULL); | 382 | NETBSD32PTR32(sc->sc_387, NULL); | |
386 | 383 | |||
387 | /* Save signal stack. */ | 384 | /* Save signal stack. */ | |
388 | /* Linux doesn't save the onstack flag in sigframe */ | 385 | /* Linux doesn't save the onstack flag in sigframe */ | |
389 | 386 | |||
390 | /* Save signal mask. */ | 387 | /* Save signal mask. */ | |
391 | native_to_linux32_old_sigset(&sc->sc_mask, mask); | 388 | native_to_linux32_old_sigset(&sc->sc_mask, mask); | |
392 | } | 389 | } | |
393 | 390 | |||
394 | int | 391 | int | |
395 | linux32_sys_sigreturn(struct lwp *l, const struct linux32_sys_sigreturn_args *uap, register_t *retval) | 392 | linux32_sys_sigreturn(struct lwp *l, const struct linux32_sys_sigreturn_args *uap, register_t *retval) | |
396 | { | 393 | { | |
397 | /* { | 394 | /* { | |
398 | syscallarg(linux32_sigcontextp_t) scp; | 395 | syscallarg(linux32_sigcontextp_t) scp; | |
399 | } */ | 396 | } */ | |
400 | struct linux32_sigcontext ctx; | 397 | struct linux32_sigcontext ctx; | |
401 | int error; | 398 | int error; | |
402 | 399 | |||
403 | if ((error = copyin(SCARG_P32(uap, scp), &ctx, sizeof(ctx))) != 0) | 400 | if ((error = copyin(SCARG_P32(uap, scp), &ctx, sizeof(ctx))) != 0) | |
404 | return error; | 401 | return error; | |
405 | 402 | |||
406 | return linux32_restore_sigcontext(l, &ctx, retval); | 403 | return linux32_restore_sigcontext(l, &ctx, retval); | |
407 | } | 404 | } | |
408 | 405 | |||
409 | int | 406 | int | |
410 | linux32_sys_rt_sigreturn(struct lwp *l, const struct linux32_sys_rt_sigreturn_args *uap, register_t *retval) | 407 | linux32_sys_rt_sigreturn(struct lwp *l, const struct linux32_sys_rt_sigreturn_args *uap, register_t *retval) | |
411 | { | 408 | { | |
412 | /* { | 409 | /* { | |
413 | syscallarg(linux32_ucontextp_t) ucp; | 410 | syscallarg(linux32_ucontextp_t) ucp; | |
414 | } */ | 411 | } */ | |
415 | struct linux32_ucontext ctx; | 412 | struct linux32_ucontext ctx; | |
416 | int error; | 413 | int error; | |
417 | 414 | |||
418 | if ((error = copyin(SCARG_P32(uap, ucp), &ctx, sizeof(ctx))) != 0) | 415 | if ((error = copyin(SCARG_P32(uap, ucp), &ctx, sizeof(ctx))) != 0) | |
419 | return error; | 416 | return error; | |
420 | 417 | |||
421 | return linux32_restore_sigcontext(l, &ctx.uc_mcontext, retval); | 418 | return linux32_restore_sigcontext(l, &ctx.uc_mcontext, retval); | |
422 | } | 419 | } | |
423 | 420 | |||
424 | static int | 421 | static int | |
425 | linux32_restore_sigcontext(l, scp, retval) | 422 | linux32_restore_sigcontext(struct lwp *l, struct linux32_sigcontext *scp, | |
426 | struct lwp *l; | 423 | register_t *retval) | |
427 | struct linux32_sigcontext *scp; | |||
428 | register_t *retval; | |||
429 | { | 424 | { | |
430 | struct trapframe *tf; | 425 | struct trapframe *tf; | |
431 | struct proc *p = l->l_proc; | 426 | struct proc *p = l->l_proc; | |
432 | struct sigaltstack *sas = &l->l_sigstk; | 427 | struct sigaltstack *sas = &l->l_sigstk; | |
433 | sigset_t mask; | 428 | sigset_t mask; | |
434 | ssize_t ss_gap; | 429 | ssize_t ss_gap; | |
435 | 430 | |||
436 | /* Restore register context. */ | 431 | /* Restore register context. */ | |
437 | tf = l->l_md.md_regs; | 432 | tf = l->l_md.md_regs; | |
438 | 433 | |||
439 | /* | 434 | /* | |
440 | * Check for security violations. If we're returning to | 435 | * Check for security violations. If we're returning to | |
441 | * protected mode, the CPU will validate the segment registers | 436 | * protected mode, the CPU will validate the segment registers | |
442 | * automatically and generate a trap on violations. We handle | 437 | * automatically and generate a trap on violations. We handle | |
443 | * the trap, rather than doing all of the checking here. | 438 | * the trap, rather than doing all of the checking here. | |
444 | */ | 439 | */ | |
445 | if (((scp->sc_eflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 || | 440 | if (((scp->sc_eflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 || | |
446 | !USERMODE(scp->sc_cs, scp->sc_eflags)) | 441 | !USERMODE(scp->sc_cs, scp->sc_eflags)) | |
447 | return EINVAL; | 442 | return EINVAL; | |
448 | 443 | |||
449 | if (scp->sc_fs != 0 && !VALID_USER_DSEL32(scp->sc_fs)) | 444 | if (scp->sc_fs != 0 && !VALID_USER_DSEL32(scp->sc_fs)) | |
450 | return EINVAL; | 445 | return EINVAL; | |
451 | 446 | |||
452 | if (scp->sc_gs != 0 && !VALID_USER_DSEL32(scp->sc_gs)) | 447 | if (scp->sc_gs != 0 && !VALID_USER_DSEL32(scp->sc_gs)) | |
453 | return EINVAL; | 448 | return EINVAL; | |
454 | 449 | |||
455 | if (scp->sc_es != 0 && !VALID_USER_DSEL32(scp->sc_es)) | 450 | if (scp->sc_es != 0 && !VALID_USER_DSEL32(scp->sc_es)) | |
456 | return EINVAL; | 451 | return EINVAL; | |
457 | 452 | |||
458 | if (!VALID_USER_DSEL32(scp->sc_ds) || | 453 | if (!VALID_USER_DSEL32(scp->sc_ds) || | |
459 | !VALID_USER_DSEL32(scp->sc_ss)) | 454 | !VALID_USER_DSEL32(scp->sc_ss)) | |
460 | return EINVAL; | 455 | return EINVAL; | |
461 | 456 | |||
462 | if (scp->sc_eip >= VM_MAXUSER_ADDRESS32) | 457 | if (scp->sc_eip >= VM_MAXUSER_ADDRESS32) | |
463 | return EINVAL; | 458 | return EINVAL; | |
464 | 459 | |||
465 | tf->tf_gs = (register_t)scp->sc_gs & 0xffffffff; | 460 | tf->tf_gs = (register_t)scp->sc_gs & 0xffffffff; | |
466 | tf->tf_fs = (register_t)scp->sc_fs & 0xffffffff; | 461 | tf->tf_fs = (register_t)scp->sc_fs & 0xffffffff; | |
467 | tf->tf_es = (register_t)scp->sc_es & 0xffffffff; | 462 | tf->tf_es = (register_t)scp->sc_es & 0xffffffff; | |
468 | tf->tf_ds = (register_t)scp->sc_ds & 0xffffffff; | 463 | tf->tf_ds = (register_t)scp->sc_ds & 0xffffffff; | |
469 | tf->tf_rflags &= ~PSL_USER; | 464 | tf->tf_rflags &= ~PSL_USER; | |
470 | tf->tf_rflags |= ((register_t)scp->sc_eflags & PSL_USER); | 465 | tf->tf_rflags |= ((register_t)scp->sc_eflags & PSL_USER); | |
471 | tf->tf_rdi = (register_t)scp->sc_edi & 0xffffffff; | 466 | tf->tf_rdi = (register_t)scp->sc_edi & 0xffffffff; | |
472 | tf->tf_rsi = (register_t)scp->sc_esi & 0xffffffff; | 467 | tf->tf_rsi = (register_t)scp->sc_esi & 0xffffffff; | |
473 | tf->tf_rbp = (register_t)scp->sc_ebp & 0xffffffff; | 468 | tf->tf_rbp = (register_t)scp->sc_ebp & 0xffffffff; | |
474 | tf->tf_rbx = (register_t)scp->sc_ebx & 0xffffffff; | 469 | tf->tf_rbx = (register_t)scp->sc_ebx & 0xffffffff; | |
475 | tf->tf_rdx = (register_t)scp->sc_edx & 0xffffffff; | 470 | tf->tf_rdx = (register_t)scp->sc_edx & 0xffffffff; | |
476 | tf->tf_rcx = (register_t)scp->sc_ecx & 0xffffffff; | 471 | tf->tf_rcx = (register_t)scp->sc_ecx & 0xffffffff; | |
477 | tf->tf_rax = (register_t)scp->sc_eax & 0xffffffff; | 472 | tf->tf_rax = (register_t)scp->sc_eax & 0xffffffff; | |
478 | tf->tf_rip = (register_t)scp->sc_eip & 0xffffffff; | 473 | tf->tf_rip = (register_t)scp->sc_eip & 0xffffffff; | |
479 | tf->tf_cs = (register_t)scp->sc_cs & 0xffffffff; | 474 | tf->tf_cs = (register_t)scp->sc_cs & 0xffffffff; | |
480 | tf->tf_rsp = (register_t)scp->sc_esp_at_signal & 0xffffffff; | 475 | tf->tf_rsp = (register_t)scp->sc_esp_at_signal & 0xffffffff; | |
481 | tf->tf_ss = (register_t)scp->sc_ss & 0xffffffff; | 476 | tf->tf_ss = (register_t)scp->sc_ss & 0xffffffff; | |
482 | 477 | |||
483 | mutex_enter(p->p_lock); | 478 | mutex_enter(p->p_lock); | |
484 | 479 | |||
485 | /* Restore signal stack. */ | 480 | /* Restore signal stack. */ | |
486 | ss_gap = (ssize_t) | 481 | ss_gap = (ssize_t) | |
487 | ((char *)NETBSD32IPTR64(scp->sc_esp_at_signal) | 482 | ((char *)NETBSD32IPTR64(scp->sc_esp_at_signal) | |
488 | - (char *)sas->ss_sp); | 483 | - (char *)sas->ss_sp); | |
489 | if (ss_gap >= 0 && ss_gap < sas->ss_size) | 484 | if (ss_gap >= 0 && ss_gap < sas->ss_size) | |
490 | sas->ss_flags |= SS_ONSTACK; | 485 | sas->ss_flags |= SS_ONSTACK; | |
491 | else | 486 | else | |
492 | sas->ss_flags &= ~SS_ONSTACK; | 487 | sas->ss_flags &= ~SS_ONSTACK; | |
493 | 488 | |||
494 | /* Restore signal mask. */ | 489 | /* Restore signal mask. */ | |
495 | linux32_old_to_native_sigset(&mask, &scp->sc_mask); | 490 | linux32_old_to_native_sigset(&mask, &scp->sc_mask); | |
496 | (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); | 491 | (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); | |
497 | 492 | |||
498 | mutex_exit(p->p_lock); | 493 | mutex_exit(p->p_lock); | |
499 | 494 | |||
500 | #ifdef DEBUG_LINUX | 495 | #ifdef DEBUG_LINUX | |
501 | printf("linux32_sigreturn: rip = 0x%lx, rsp = 0x%lx, flags = 0x%lx\n", | 496 | printf("linux32_sigreturn: rip = 0x%lx, rsp = 0x%lx, flags = 0x%lx\n", | |
502 | tf->tf_rip, tf->tf_rsp, tf->tf_rflags); | 497 | tf->tf_rip, tf->tf_rsp, tf->tf_rflags); | |
503 | #endif | 498 | #endif | |
504 | return EJUSTRETURN; | 499 | return EJUSTRETURN; | |
505 | } | 500 | } |
--- src/sys/compat/linux32/common/linux32_exec_elf32.c 2008/04/28 20:23:44 1.8
+++ src/sys/compat/linux32/common/linux32_exec_elf32.c 2009/03/15 15:56:50 1.9
@@ -1,251 +1,247 @@ | @@ -1,251 +1,247 @@ | |||
1 | /* $NetBSD: linux32_exec_elf32.c,v 1.8 2008/04/28 20:23:44 martin Exp $ */ | 1 | /* $NetBSD: linux32_exec_elf32.c,v 1.9 2009/03/15 15:56:50 cegger Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1995, 1998, 2000, 2001,2006 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1995, 1998, 2000, 2001,2006 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and | 8 | * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and | |
9 | * Emmanuel Dreyfus. | 9 | * Emmanuel Dreyfus. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * | 19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
30 | * POSSIBILITY OF SUCH DAMAGE. | 30 | * POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
34 | __KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.8 2008/04/28 20:23:44 martin Exp $"); | 34 | __KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.9 2009/03/15 15:56:50 cegger Exp $"); | |
35 | 35 | |||
36 | #define ELFSIZE 32 | 36 | #define ELFSIZE 32 | |
37 | 37 | |||
38 | #include <sys/param.h> | 38 | #include <sys/param.h> | |
39 | #include <sys/systm.h> | 39 | #include <sys/systm.h> | |
40 | #include <sys/proc.h> | 40 | #include <sys/proc.h> | |
41 | #include <sys/malloc.h> | 41 | #include <sys/malloc.h> | |
42 | #include <sys/vnode.h> | 42 | #include <sys/vnode.h> | |
43 | #include <sys/exec.h> | 43 | #include <sys/exec.h> | |
44 | #include <sys/exec_elf.h> | 44 | #include <sys/exec_elf.h> | |
45 | #include <sys/kauth.h> | 45 | #include <sys/kauth.h> | |
46 | #include <sys/kernel.h> | 46 | #include <sys/kernel.h> | |
47 | #include <sys/resourcevar.h> | 47 | #include <sys/resourcevar.h> | |
48 | #include <sys/signal.h> | 48 | #include <sys/signal.h> | |
49 | #include <sys/signalvar.h> | 49 | #include <sys/signalvar.h> | |
50 | 50 | |||
51 | #include <compat/linux/common/linux_exec.h> | 51 | #include <compat/linux/common/linux_exec.h> | |
52 | #include <compat/netbsd32/netbsd32.h> | 52 | #include <compat/netbsd32/netbsd32.h> | |
53 | #include <compat/netbsd32/netbsd32_exec.h> | 53 | #include <compat/netbsd32/netbsd32_exec.h> | |
54 | #include <compat/linux32/common/linux32_exec.h> | 54 | #include <compat/linux32/common/linux32_exec.h> | |
55 | 55 | |||
56 | #include <machine/frame.h> | 56 | #include <machine/frame.h> | |
57 | 57 | |||
58 | #ifdef DEBUG_LINUX | 58 | #ifdef DEBUG_LINUX | |
59 | #define DPRINTF(a) uprintf a | 59 | #define DPRINTF(a) uprintf a | |
60 | #else | 60 | #else | |
61 | #define DPRINTF(a) | 61 | #define DPRINTF(a) | |
62 | #endif | 62 | #endif | |
63 | 63 | |||
64 | int linux32_copyinargs(struct exec_package *, struct ps_strings *, | 64 | int linux32_copyinargs(struct exec_package *, struct ps_strings *, | |
65 | void *, size_t, const void *, const void *); | 65 | void *, size_t, const void *, const void *); | |
66 | 66 | |||
67 | int | 67 | int | |
68 | ELFNAME2(linux32,probe)(l, epp, eh, itp, pos) | 68 | ELFNAME2(linux32,probe)(struct lwp *l, struct exec_package *epp, | |
69 | struct lwp *l; | 69 | void *eh, char *itp, vaddr_t *pos) | |
70 | struct exec_package *epp; | |||
71 | void *eh; | |||
72 | char *itp; | |||
73 | vaddr_t *pos; | |||
74 | { | 70 | { | |
75 | int error; | 71 | int error; | |
76 | 72 | |||
77 | if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) && | 73 | if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) && | |
78 | #ifdef LINUX32_GCC_SIGNATURE | 74 | #ifdef LINUX32_GCC_SIGNATURE | |
79 | ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) && | 75 | ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) && | |
80 | #endif | 76 | #endif | |
81 | #ifdef LINUX32_ATEXIT_SIGNATURE | 77 | #ifdef LINUX32_ATEXIT_SIGNATURE | |
82 | ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) && | 78 | ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) && | |
83 | #endif | 79 | #endif | |
84 | #ifdef LINUX32_DEBUGLINK_SIGNATURE | 80 | #ifdef LINUX32_DEBUGLINK_SIGNATURE | |
85 | ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) && | 81 | ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) && | |
86 | #endif | 82 | #endif | |
87 | 1) | 83 | 1) | |
88 | return error; | 84 | return error; | |
89 | 85 | |||
90 | if (itp) { | 86 | if (itp) { | |
91 | if ((error = emul_find_interp(l, epp, itp))) | 87 | if ((error = emul_find_interp(l, epp, itp))) | |
92 | return (error); | 88 | return (error); | |
93 | } | 89 | } | |
94 | #if 0 | 90 | #if 0 | |
95 | DPRINTF(("linux32_probe: returning 0\n")); | 91 | DPRINTF(("linux32_probe: returning 0\n")); | |
96 | #endif | 92 | #endif | |
97 | 93 | |||
98 | epp->ep_flags |= EXEC_32; | 94 | epp->ep_flags |= EXEC_32; | |
99 | epp->ep_vm_minaddr = VM_MIN_ADDRESS; | 95 | epp->ep_vm_minaddr = VM_MIN_ADDRESS; | |
100 | epp->ep_vm_maxaddr = USRSTACK32; | 96 | epp->ep_vm_maxaddr = USRSTACK32; | |
101 | 97 | |||
102 | return 0; | 98 | return 0; | |
103 | } | 99 | } | |
104 | 100 | |||
105 | /* round up and down to page boundaries. */ | 101 | /* round up and down to page boundaries. */ | |
106 | #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) | 102 | #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) | |
107 | #define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) | 103 | #define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) | |
108 | 104 | |||
109 | /* | 105 | /* | |
110 | * Copy arguments onto the stack in the normal way, but add some | 106 | * Copy arguments onto the stack in the normal way, but add some | |
111 | * extra information in case of dynamic binding. | 107 | * extra information in case of dynamic binding. | |
112 | */ | 108 | */ | |
113 | int | 109 | int | |
114 | linux32_elf32_copyargs(struct lwp *l, struct exec_package *pack, | 110 | linux32_elf32_copyargs(struct lwp *l, struct exec_package *pack, | |
115 | struct ps_strings *arginfo, char **stackp, void *argp) | 111 | struct ps_strings *arginfo, char **stackp, void *argp) | |
116 | { | 112 | { | |
117 | struct linux32_extra_stack_data *esdp, esd; | 113 | struct linux32_extra_stack_data *esdp, esd; | |
118 | struct elf_args *ap; | 114 | struct elf_args *ap; | |
119 | struct vattr *vap; | 115 | struct vattr *vap; | |
120 | Elf_Ehdr *eh; | 116 | Elf_Ehdr *eh; | |
121 | Elf_Phdr *ph; | 117 | Elf_Phdr *ph; | |
122 | Elf_Addr phdr = 0; | 118 | Elf_Addr phdr = 0; | |
123 | u_long phsize; | 119 | u_long phsize; | |
124 | int error; | 120 | int error; | |
125 | int i; | 121 | int i; | |
126 | 122 | |||
127 | if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0) | 123 | if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0) | |
128 | return error; | 124 | return error; | |
129 | 125 | |||
130 | /* | 126 | /* | |
131 | * Push extra arguments on the stack needed by dynamically | 127 | * Push extra arguments on the stack needed by dynamically | |
132 | * linked binaries and static binaries as well. | 128 | * linked binaries and static binaries as well. | |
133 | */ | 129 | */ | |
134 | memset(&esd, 0, sizeof(esd)); | 130 | memset(&esd, 0, sizeof(esd)); | |
135 | esdp = (struct linux32_extra_stack_data *)(*stackp); | 131 | esdp = (struct linux32_extra_stack_data *)(*stackp); | |
136 | ap = (struct elf_args *)pack->ep_emul_arg; | 132 | ap = (struct elf_args *)pack->ep_emul_arg; | |
137 | vap = pack->ep_vap; | 133 | vap = pack->ep_vap; | |
138 | eh = (Elf_Ehdr *)pack->ep_hdr; | 134 | eh = (Elf_Ehdr *)pack->ep_hdr; | |
139 | 135 | |||
140 | /* | 136 | /* | |
141 | * We forgot this, so we ned to reload it now. XXX keep track of it? | 137 | * We forgot this, so we ned to reload it now. XXX keep track of it? | |
142 | */ | 138 | */ | |
143 | if (ap == NULL) { | 139 | if (ap == NULL) { | |
144 | phsize = eh->e_phnum * sizeof(Elf_Phdr); | 140 | phsize = eh->e_phnum * sizeof(Elf_Phdr); | |
145 | ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); | 141 | ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); | |
146 | error = exec_read_from(l, pack->ep_vp, eh->e_phoff, ph, phsize); | 142 | error = exec_read_from(l, pack->ep_vp, eh->e_phoff, ph, phsize); | |
147 | if (error != 0) { | 143 | if (error != 0) { | |
148 | for (i = 0; i < eh->e_phnum; i++) { | 144 | for (i = 0; i < eh->e_phnum; i++) { | |
149 | if (ph[i].p_type == PT_PHDR) { | 145 | if (ph[i].p_type == PT_PHDR) { | |
150 | phdr = ph[i].p_vaddr; | 146 | phdr = ph[i].p_vaddr; | |
151 | break; | 147 | break; | |
152 | } | 148 | } | |
153 | } | 149 | } | |
154 | } | 150 | } | |
155 | free(ph, M_TEMP); | 151 | free(ph, M_TEMP); | |
156 | } | 152 | } | |
157 | 153 | |||
158 | 154 | |||
159 | /* | 155 | /* | |
160 | * The exec_package doesn't have a proc pointer and it's not | 156 | * The exec_package doesn't have a proc pointer and it's not | |
161 | * exactly trivial to add one since the credentials are | 157 | * exactly trivial to add one since the credentials are | |
162 | * changing. XXX Linux uses curlwp's credentials. | 158 | * changing. XXX Linux uses curlwp's credentials. | |
163 | * Why can't we use them too? XXXad we do now; what's different | 159 | * Why can't we use them too? XXXad we do now; what's different | |
164 | * about Linux's LWP creds? | 160 | * about Linux's LWP creds? | |
165 | */ | 161 | */ | |
166 | 162 | |||
167 | i = 0; | 163 | i = 0; | |
168 | esd.ai[i].a_type = LINUX_AT_SYSINFO; | 164 | esd.ai[i].a_type = LINUX_AT_SYSINFO; | |
169 | esd.ai[i++].a_v = NETBSD32PTR32I(&esdp->kernel_vsyscall[0]); | 165 | esd.ai[i++].a_v = NETBSD32PTR32I(&esdp->kernel_vsyscall[0]); | |
170 | 166 | |||
171 | esd.ai[i].a_type = LINUX_AT_SYSINFO_EHDR; | 167 | esd.ai[i].a_type = LINUX_AT_SYSINFO_EHDR; | |
172 | esd.ai[i++].a_v = NETBSD32PTR32I(&esdp->elfhdr); | 168 | esd.ai[i++].a_v = NETBSD32PTR32I(&esdp->elfhdr); | |
173 | 169 | |||
174 | esd.ai[i].a_type = LINUX_AT_HWCAP; | 170 | esd.ai[i].a_type = LINUX_AT_HWCAP; | |
175 | esd.ai[i++].a_v = LINUX32_CPUCAP; | 171 | esd.ai[i++].a_v = LINUX32_CPUCAP; | |
176 | 172 | |||
177 | esd.ai[i].a_type = AT_PAGESZ; | 173 | esd.ai[i].a_type = AT_PAGESZ; | |
178 | esd.ai[i++].a_v = PAGE_SIZE; | 174 | esd.ai[i++].a_v = PAGE_SIZE; | |
179 | 175 | |||
180 | esd.ai[i].a_type = LINUX_AT_CLKTCK; | 176 | esd.ai[i].a_type = LINUX_AT_CLKTCK; | |
181 | esd.ai[i++].a_v = hz; | 177 | esd.ai[i++].a_v = hz; | |
182 | 178 | |||
183 | esd.ai[i].a_type = AT_PHDR; | 179 | esd.ai[i].a_type = AT_PHDR; | |
184 | esd.ai[i++].a_v = (ap ? ap->arg_phaddr: phdr); | 180 | esd.ai[i++].a_v = (ap ? ap->arg_phaddr: phdr); | |
185 | 181 | |||
186 | esd.ai[i].a_type = AT_PHENT; | 182 | esd.ai[i].a_type = AT_PHENT; | |
187 | esd.ai[i++].a_v = (ap ? ap->arg_phentsize : eh->e_phentsize); | 183 | esd.ai[i++].a_v = (ap ? ap->arg_phentsize : eh->e_phentsize); | |
188 | 184 | |||
189 | esd.ai[i].a_type = AT_PHNUM; | 185 | esd.ai[i].a_type = AT_PHNUM; | |
190 | esd.ai[i++].a_v = (ap ? ap->arg_phnum : eh->e_phnum); | 186 | esd.ai[i++].a_v = (ap ? ap->arg_phnum : eh->e_phnum); | |
191 | 187 | |||
192 | esd.ai[i].a_type = AT_BASE; | 188 | esd.ai[i].a_type = AT_BASE; | |
193 | esd.ai[i++].a_v = (ap ? ap->arg_interp : 0); | 189 | esd.ai[i++].a_v = (ap ? ap->arg_interp : 0); | |
194 | 190 | |||
195 | esd.ai[i].a_type = AT_FLAGS; | 191 | esd.ai[i].a_type = AT_FLAGS; | |
196 | esd.ai[i++].a_v = 0; | 192 | esd.ai[i++].a_v = 0; | |
197 | 193 | |||
198 | esd.ai[i].a_type = AT_ENTRY; | 194 | esd.ai[i].a_type = AT_ENTRY; | |
199 | esd.ai[i++].a_v = (ap ? ap->arg_entry : eh->e_entry); | 195 | esd.ai[i++].a_v = (ap ? ap->arg_entry : eh->e_entry); | |
200 | 196 | |||
201 | esd.ai[i].a_type = LINUX_AT_EGID; | 197 | esd.ai[i].a_type = LINUX_AT_EGID; | |
202 | esd.ai[i++].a_v = ((vap->va_mode & S_ISGID) ? | 198 | esd.ai[i++].a_v = ((vap->va_mode & S_ISGID) ? | |
203 | vap->va_gid : kauth_cred_getegid(l->l_cred)); | 199 | vap->va_gid : kauth_cred_getegid(l->l_cred)); | |
204 | 200 | |||
205 | esd.ai[i].a_type = LINUX_AT_GID; | 201 | esd.ai[i].a_type = LINUX_AT_GID; | |
206 | esd.ai[i++].a_v = kauth_cred_getgid(l->l_cred); | 202 | esd.ai[i++].a_v = kauth_cred_getgid(l->l_cred); | |
207 | 203 | |||
208 | esd.ai[i].a_type = LINUX_AT_EUID; | 204 | esd.ai[i].a_type = LINUX_AT_EUID; | |
209 | esd.ai[i++].a_v = ((vap->va_mode & S_ISUID) ? | 205 | esd.ai[i++].a_v = ((vap->va_mode & S_ISUID) ? | |
210 | vap->va_uid : kauth_cred_geteuid(l->l_cred)); | 206 | vap->va_uid : kauth_cred_geteuid(l->l_cred)); | |
211 | 207 | |||
212 | esd.ai[i].a_type = LINUX_AT_UID; | 208 | esd.ai[i].a_type = LINUX_AT_UID; | |
213 | esd.ai[i++].a_v = kauth_cred_getuid(l->l_cred); | 209 | esd.ai[i++].a_v = kauth_cred_getuid(l->l_cred); | |
214 | 210 | |||
215 | esd.ai[i].a_type = LINUX_AT_SECURE; | 211 | esd.ai[i].a_type = LINUX_AT_SECURE; | |
216 | esd.ai[i++].a_v = 0; | 212 | esd.ai[i++].a_v = 0; | |
217 | 213 | |||
218 | esd.ai[i].a_type = LINUX_AT_PLATFORM; | 214 | esd.ai[i].a_type = LINUX_AT_PLATFORM; | |
219 | esd.ai[i++].a_v = NETBSD32PTR32I(&esdp->hw_platform[0]); | 215 | esd.ai[i++].a_v = NETBSD32PTR32I(&esdp->hw_platform[0]); | |
220 | 216 | |||
221 | esd.ai[i].a_type = AT_NULL; | 217 | esd.ai[i].a_type = AT_NULL; | |
222 | esd.ai[i++].a_v = 0; | 218 | esd.ai[i++].a_v = 0; | |
223 | 219 | |||
224 | #ifdef DEBUG_LINUX | 220 | #ifdef DEBUG_LINUX | |
225 | if (i != LINUX32_ELF_AUX_ENTRIES) { | 221 | if (i != LINUX32_ELF_AUX_ENTRIES) { | |
226 | printf("linux32_elf32_copyargs: %d Aux entries\n", i); | 222 | printf("linux32_elf32_copyargs: %d Aux entries\n", i); | |
227 | return EINVAL; | 223 | return EINVAL; | |
228 | } | 224 | } | |
229 | #endif | 225 | #endif | |
230 | 226 | |||
231 | memcpy(esd.kernel_vsyscall, linux32_kernel_vsyscall, | 227 | memcpy(esd.kernel_vsyscall, linux32_kernel_vsyscall, | |
232 | sizeof(linux32_kernel_vsyscall)); | 228 | sizeof(linux32_kernel_vsyscall)); | |
233 | 229 | |||
234 | memcpy(&esd.elfhdr, eh, sizeof(*eh)); | 230 | memcpy(&esd.elfhdr, eh, sizeof(*eh)); | |
235 | 231 | |||
236 | strcpy(esd.hw_platform, LINUX32_PLATFORM); | 232 | strcpy(esd.hw_platform, LINUX32_PLATFORM); | |
237 | 233 | |||
238 | if (ap) { | 234 | if (ap) { | |
239 | free((char *)ap, M_TEMP); | 235 | free((char *)ap, M_TEMP); | |
240 | pack->ep_emul_arg = NULL; | 236 | pack->ep_emul_arg = NULL; | |
241 | } | 237 | } | |
242 | 238 | |||
243 | /* | 239 | /* | |
244 | * Copy out the ELF auxiliary table and hw platform name | 240 | * Copy out the ELF auxiliary table and hw platform name | |
245 | */ | 241 | */ | |
246 | if ((error = copyout(&esd, esdp, sizeof(esd))) != 0) | 242 | if ((error = copyout(&esd, esdp, sizeof(esd))) != 0) | |
247 | return error; | 243 | return error; | |
248 | *stackp += sizeof(esd); | 244 | *stackp += sizeof(esd); | |
249 | return 0; | 245 | return 0; | |
250 | } | 246 | } | |
251 | 247 |
--- src/sys/compat/linux32/common/linux32_unistd.c 2009/01/16 13:10:47 1.30
+++ src/sys/compat/linux32/common/linux32_unistd.c 2009/03/15 15:56:50 1.31
@@ -1,552 +1,549 @@ | @@ -1,552 +1,549 @@ | |||
1 | /* $NetBSD: linux32_unistd.c,v 1.30 2009/01/16 13:10:47 njoly Exp $ */ | 1 | /* $NetBSD: linux32_unistd.c,v 1.31 2009/03/15 15:56:50 cegger Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. | 4 | * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. All advertising materials mentioning features or use of this software | |
15 | * must display the following acknowledgement: | 15 | * must display the following acknowledgement: | |
16 | * This product includes software developed by Emmanuel Dreyfus | 16 | * This product includes software developed by Emmanuel Dreyfus | |
17 | * 4. The name of the author may not be used to endorse or promote | 17 | * 4. The name of the author may not be used to endorse or promote | |
18 | * products derived from this software without specific prior written | 18 | * products derived from this software without specific prior written | |
19 | * permission. | 19 | * permission. | |
20 | * | 20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | 21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | |
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | 24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | |
25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
31 | * POSSIBILITY OF SUCH DAMAGE. | 31 | * POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #include <sys/cdefs.h> | 34 | #include <sys/cdefs.h> | |
35 | 35 | |||
36 | __KERNEL_RCSID(0, "$NetBSD: linux32_unistd.c,v 1.30 2009/01/16 13:10:47 njoly Exp $"); | 36 | __KERNEL_RCSID(0, "$NetBSD: linux32_unistd.c,v 1.31 2009/03/15 15:56:50 cegger Exp $"); | |
37 | 37 | |||
38 | #include <sys/types.h> | 38 | #include <sys/types.h> | |
39 | #include <sys/param.h> | 39 | #include <sys/param.h> | |
40 | #include <sys/fstypes.h> | 40 | #include <sys/fstypes.h> | |
41 | #include <sys/signal.h> | 41 | #include <sys/signal.h> | |
42 | #include <sys/dirent.h> | 42 | #include <sys/dirent.h> | |
43 | #include <sys/kernel.h> | 43 | #include <sys/kernel.h> | |
44 | #include <sys/fcntl.h> | 44 | #include <sys/fcntl.h> | |
45 | #include <sys/select.h> | 45 | #include <sys/select.h> | |
46 | #include <sys/proc.h> | 46 | #include <sys/proc.h> | |
47 | #include <sys/ucred.h> | 47 | #include <sys/ucred.h> | |
48 | #include <sys/swap.h> | 48 | #include <sys/swap.h> | |
49 | #include <sys/kauth.h> | 49 | #include <sys/kauth.h> | |
50 | 50 | |||
51 | #include <machine/types.h> | 51 | #include <machine/types.h> | |
52 | 52 | |||
53 | #include <sys/syscallargs.h> | 53 | #include <sys/syscallargs.h> | |
54 | 54 | |||
55 | #include <compat/netbsd32/netbsd32.h> | 55 | #include <compat/netbsd32/netbsd32.h> | |
56 | #include <compat/netbsd32/netbsd32_conv.h> | 56 | #include <compat/netbsd32/netbsd32_conv.h> | |
57 | 57 | |||
58 | #include <compat/linux/common/linux_types.h> | 58 | #include <compat/linux/common/linux_types.h> | |
59 | #include <compat/linux/common/linux_signal.h> | 59 | #include <compat/linux/common/linux_signal.h> | |
60 | #include <compat/linux/common/linux_machdep.h> | 60 | #include <compat/linux/common/linux_machdep.h> | |
61 | #include <compat/linux/common/linux_misc.h> | 61 | #include <compat/linux/common/linux_misc.h> | |
62 | #include <compat/linux/common/linux_oldolduname.h> | 62 | #include <compat/linux/common/linux_oldolduname.h> | |
63 | #include <compat/linux/common/linux_ipc.h> | 63 | #include <compat/linux/common/linux_ipc.h> | |
64 | #include <compat/linux/common/linux_sem.h> | 64 | #include <compat/linux/common/linux_sem.h> | |
65 | #include <compat/linux/linux_syscallargs.h> | 65 | #include <compat/linux/linux_syscallargs.h> | |
66 | 66 | |||
67 | #include <compat/linux32/common/linux32_types.h> | 67 | #include <compat/linux32/common/linux32_types.h> | |
68 | #include <compat/linux32/common/linux32_signal.h> | 68 | #include <compat/linux32/common/linux32_signal.h> | |
69 | #include <compat/linux32/common/linux32_machdep.h> | 69 | #include <compat/linux32/common/linux32_machdep.h> | |
70 | #include <compat/linux32/common/linux32_sysctl.h> | 70 | #include <compat/linux32/common/linux32_sysctl.h> | |
71 | #include <compat/linux32/common/linux32_socketcall.h> | 71 | #include <compat/linux32/common/linux32_socketcall.h> | |
72 | #include <compat/linux32/linux32_syscallargs.h> | 72 | #include <compat/linux32/linux32_syscallargs.h> | |
73 | 73 | |||
74 | static int linux32_select1(struct lwp *, register_t *, | 74 | static int linux32_select1(struct lwp *, register_t *, | |
75 | int, fd_set *, fd_set *, fd_set *, struct timeval *); | 75 | int, fd_set *, fd_set *, fd_set *, struct timeval *); | |
76 | 76 | |||
77 | int | 77 | int | |
78 | linux32_sys_brk(struct lwp *l, const struct linux32_sys_brk_args *uap, register_t *retval) | 78 | linux32_sys_brk(struct lwp *l, const struct linux32_sys_brk_args *uap, register_t *retval) | |
79 | { | 79 | { | |
80 | /* { | 80 | /* { | |
81 | syscallarg(netbsd32_charp) nsize; | 81 | syscallarg(netbsd32_charp) nsize; | |
82 | } */ | 82 | } */ | |
83 | struct linux_sys_brk_args ua; | 83 | struct linux_sys_brk_args ua; | |
84 | 84 | |||
85 | NETBSD32TOP_UAP(nsize, char); | 85 | NETBSD32TOP_UAP(nsize, char); | |
86 | return linux_sys_brk(l, &ua, retval); | 86 | return linux_sys_brk(l, &ua, retval); | |
87 | } | 87 | } | |
88 | 88 | |||
89 | int | 89 | int | |
90 | linux32_sys_llseek(struct lwp *l, const struct linux32_sys_llseek_args *uap, register_t *retval) | 90 | linux32_sys_llseek(struct lwp *l, const struct linux32_sys_llseek_args *uap, register_t *retval) | |
91 | { | 91 | { | |
92 | /* { | 92 | /* { | |
93 | syscallarg(int) fd; | 93 | syscallarg(int) fd; | |
94 | syscallarg(u_int32_t) ohigh; | 94 | syscallarg(u_int32_t) ohigh; | |
95 | syscallarg(u_int32_t) olow; | 95 | syscallarg(u_int32_t) olow; | |
96 | syscallarg(netbsd32_voidp) res; | 96 | syscallarg(netbsd32_voidp) res; | |
97 | syscallarg(int) whence; | 97 | syscallarg(int) whence; | |
98 | } */ | 98 | } */ | |
99 | struct linux_sys_llseek_args ua; | 99 | struct linux_sys_llseek_args ua; | |
100 | 100 | |||
101 | NETBSD32TO64_UAP(fd); | 101 | NETBSD32TO64_UAP(fd); | |
102 | NETBSD32TO64_UAP(ohigh); | 102 | NETBSD32TO64_UAP(ohigh); | |
103 | NETBSD32TO64_UAP(olow); | 103 | NETBSD32TO64_UAP(olow); | |
104 | NETBSD32TOP_UAP(res, void); | 104 | NETBSD32TOP_UAP(res, void); | |
105 | NETBSD32TO64_UAP(whence); | 105 | NETBSD32TO64_UAP(whence); | |
106 | 106 | |||
107 | return linux_sys_llseek(l, &ua, retval); | 107 | return linux_sys_llseek(l, &ua, retval); | |
108 | } | 108 | } | |
109 | 109 | |||
110 | int | 110 | int | |
111 | linux32_sys_select(struct lwp *l, const struct linux32_sys_select_args *uap, register_t *retval) | 111 | linux32_sys_select(struct lwp *l, const struct linux32_sys_select_args *uap, register_t *retval) | |
112 | { | 112 | { | |
113 | /* { | 113 | /* { | |
114 | syscallarg(int) nfds; | 114 | syscallarg(int) nfds; | |
115 | syscallarg(netbsd32_fd_setp_t) readfds; | 115 | syscallarg(netbsd32_fd_setp_t) readfds; | |
116 | syscallarg(netbsd32_fd_setp_t) writefds; | 116 | syscallarg(netbsd32_fd_setp_t) writefds; | |
117 | syscallarg(netbsd32_fd_setp_t) exceptfds; | 117 | syscallarg(netbsd32_fd_setp_t) exceptfds; | |
118 | syscallarg(netbsd32_timeval50p_t) timeout; | 118 | syscallarg(netbsd32_timeval50p_t) timeout; | |
119 | } */ | 119 | } */ | |
120 | 120 | |||
121 | return linux32_select1(l, retval, SCARG(uap, nfds), | 121 | return linux32_select1(l, retval, SCARG(uap, nfds), | |
122 | SCARG_P32(uap, readfds), | 122 | SCARG_P32(uap, readfds), | |
123 | SCARG_P32(uap, writefds), | 123 | SCARG_P32(uap, writefds), | |
124 | SCARG_P32(uap, exceptfds), | 124 | SCARG_P32(uap, exceptfds), | |
125 | SCARG_P32(uap, timeout)); | 125 | SCARG_P32(uap, timeout)); | |
126 | } | 126 | } | |
127 | 127 | |||
128 | int | 128 | int | |
129 | linux32_sys_oldselect(struct lwp *l, const struct linux32_sys_oldselect_args *uap, register_t *retval) | 129 | linux32_sys_oldselect(struct lwp *l, const struct linux32_sys_oldselect_args *uap, register_t *retval) | |
130 | { | 130 | { | |
131 | /* { | 131 | /* { | |
132 | syscallarg(linux32_oldselectp_t) lsp; | 132 | syscallarg(linux32_oldselectp_t) lsp; | |
133 | } */ | 133 | } */ | |
134 | struct linux32_oldselect lsp32; | 134 | struct linux32_oldselect lsp32; | |
135 | int error; | 135 | int error; | |
136 | 136 | |||
137 | if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0) | 137 | if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0) | |
138 | return error; | 138 | return error; | |
139 | 139 | |||
140 | return linux32_select1(l, retval, lsp32.nfds, | 140 | return linux32_select1(l, retval, lsp32.nfds, | |
141 | NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds), | 141 | NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds), | |
142 | NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout)); | 142 | NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout)); | |
143 | } | 143 | } | |
144 | 144 | |||
145 | static int | 145 | static int | |
146 | linux32_select1(l, retval, nfds, readfds, writefds, exceptfds, timeout) | 146 | linux32_select1(struct lwp *l, register_t *retval, int nfds, | |
147 | struct lwp *l; | 147 | fd_set *readfds, fd_set *writefds, fd_set *exceptfds, | |
148 | register_t *retval; | 148 | struct timeval *timeout) | |
149 | int nfds; | |||
150 | fd_set *readfds, *writefds, *exceptfds; | |||
151 | struct timeval *timeout; | |||
152 | { | 149 | { | |
153 | struct timeval tv0, tv1, utv, *tv = NULL; | 150 | struct timeval tv0, tv1, utv, *tv = NULL; | |
154 | struct netbsd32_timeval50 utv32; | 151 | struct netbsd32_timeval50 utv32; | |
155 | int error; | 152 | int error; | |
156 | 153 | |||
157 | timerclear(&utv); /* XXX GCC4 */ | 154 | timerclear(&utv); /* XXX GCC4 */ | |
158 | 155 | |||
159 | /* | 156 | /* | |
160 | * Store current time for computation of the amount of | 157 | * Store current time for computation of the amount of | |
161 | * time left. | 158 | * time left. | |
162 | */ | 159 | */ | |
163 | if (timeout) { | 160 | if (timeout) { | |
164 | if ((error = copyin(timeout, &utv32, sizeof(utv32)))) | 161 | if ((error = copyin(timeout, &utv32, sizeof(utv32)))) | |
165 | return error; | 162 | return error; | |
166 | 163 | |||
167 | netbsd32_to_timeval50(&utv32, &utv); | 164 | netbsd32_to_timeval50(&utv32, &utv); | |
168 | 165 | |||
169 | if (itimerfix(&utv)) { | 166 | if (itimerfix(&utv)) { | |
170 | /* | 167 | /* | |
171 | * The timeval was invalid. Convert it to something | 168 | * The timeval was invalid. Convert it to something | |
172 | * valid that will act as it does under Linux. | 169 | * valid that will act as it does under Linux. | |
173 | */ | 170 | */ | |
174 | utv.tv_sec += utv.tv_usec / 1000000; | 171 | utv.tv_sec += utv.tv_usec / 1000000; | |
175 | utv.tv_usec %= 1000000; | 172 | utv.tv_usec %= 1000000; | |
176 | if (utv.tv_usec < 0) { | 173 | if (utv.tv_usec < 0) { | |
177 | utv.tv_sec -= 1; | 174 | utv.tv_sec -= 1; | |
178 | utv.tv_usec += 1000000; | 175 | utv.tv_usec += 1000000; | |
179 | } | 176 | } | |
180 | if (utv.tv_sec < 0) | 177 | if (utv.tv_sec < 0) | |
181 | timerclear(&utv); | 178 | timerclear(&utv); | |
182 | } | 179 | } | |
183 | microtime(&tv0); | 180 | microtime(&tv0); | |
184 | tv = &utv; | 181 | tv = &utv; | |
185 | } | 182 | } | |
186 | 183 | |||
187 | error = selcommon(l, retval, nfds, | 184 | error = selcommon(l, retval, nfds, | |
188 | readfds, writefds, exceptfds, tv, NULL); | 185 | readfds, writefds, exceptfds, tv, NULL); | |
189 | 186 | |||
190 | if (error) { | 187 | if (error) { | |
191 | /* | 188 | /* | |
192 | * See fs/select.c in the Linux kernel. Without this, | 189 | * See fs/select.c in the Linux kernel. Without this, | |
193 | * Maelstrom doesn't work. | 190 | * Maelstrom doesn't work. | |
194 | */ | 191 | */ | |
195 | if (error == ERESTART) | 192 | if (error == ERESTART) | |
196 | error = EINTR; | 193 | error = EINTR; | |
197 | return error; | 194 | return error; | |
198 | } | 195 | } | |
199 | 196 | |||
200 | if (timeout) { | 197 | if (timeout) { | |
201 | if (*retval) { | 198 | if (*retval) { | |
202 | /* | 199 | /* | |
203 | * Compute how much time was left of the timeout, | 200 | * Compute how much time was left of the timeout, | |
204 | * by subtracting the current time and the time | 201 | * by subtracting the current time and the time | |
205 | * before we started the call, and subtracting | 202 | * before we started the call, and subtracting | |
206 | * that result from the user-supplied value. | 203 | * that result from the user-supplied value. | |
207 | */ | 204 | */ | |
208 | microtime(&tv1); | 205 | microtime(&tv1); | |
209 | timersub(&tv1, &tv0, &tv1); | 206 | timersub(&tv1, &tv0, &tv1); | |
210 | timersub(&utv, &tv1, &utv); | 207 | timersub(&utv, &tv1, &utv); | |
211 | if (utv.tv_sec < 0) | 208 | if (utv.tv_sec < 0) | |
212 | timerclear(&utv); | 209 | timerclear(&utv); | |
213 | } else { | 210 | } else { | |
214 | timerclear(&utv); | 211 | timerclear(&utv); | |
215 | } | 212 | } | |
216 | 213 | |||
217 | netbsd32_from_timeval50(&utv, &utv32); | 214 | netbsd32_from_timeval50(&utv, &utv32); | |
218 | 215 | |||
219 | if ((error = copyout(&utv32, timeout, sizeof(utv32)))) | 216 | if ((error = copyout(&utv32, timeout, sizeof(utv32)))) | |
220 | return error; | 217 | return error; | |
221 | } | 218 | } | |
222 | 219 | |||
223 | return 0; | 220 | return 0; | |
224 | } | 221 | } | |
225 | 222 | |||
226 | int | 223 | int | |
227 | linux32_sys_pipe(struct lwp *l, const struct linux32_sys_pipe_args *uap, register_t *retval) | 224 | linux32_sys_pipe(struct lwp *l, const struct linux32_sys_pipe_args *uap, register_t *retval) | |
228 | { | 225 | { | |
229 | /* { | 226 | /* { | |
230 | syscallarg(netbsd32_intp) fd; | 227 | syscallarg(netbsd32_intp) fd; | |
231 | } */ | 228 | } */ | |
232 | int error; | 229 | int error; | |
233 | int pfds[2]; | 230 | int pfds[2]; | |
234 | 231 | |||
235 | if ((error = sys_pipe(l, 0, retval))) | 232 | if ((error = sys_pipe(l, 0, retval))) | |
236 | return error; | 233 | return error; | |
237 | 234 | |||
238 | pfds[0] = (int)retval[0]; | 235 | pfds[0] = (int)retval[0]; | |
239 | pfds[1] = (int)retval[1]; | 236 | pfds[1] = (int)retval[1]; | |
240 | 237 | |||
241 | if ((error = copyout(pfds, SCARG_P32(uap, fd), 2 * sizeof (int))) != 0) | 238 | if ((error = copyout(pfds, SCARG_P32(uap, fd), 2 * sizeof (int))) != 0) | |
242 | return error; | 239 | return error; | |
243 | 240 | |||
244 | retval[0] = 0; | 241 | retval[0] = 0; | |
245 | retval[1] = 0; | 242 | retval[1] = 0; | |
246 | 243 | |||
247 | return 0; | 244 | return 0; | |
248 | } | 245 | } | |
249 | 246 | |||
250 | 247 | |||
251 | int | 248 | int | |
252 | linux32_sys_unlink(struct lwp *l, const struct linux32_sys_unlink_args *uap, register_t *retval) | 249 | linux32_sys_unlink(struct lwp *l, const struct linux32_sys_unlink_args *uap, register_t *retval) | |
253 | { | 250 | { | |
254 | /* { | 251 | /* { | |
255 | syscallarg(const netbsd32_charp) path; | 252 | syscallarg(const netbsd32_charp) path; | |
256 | } */ | 253 | } */ | |
257 | struct linux_sys_unlink_args ua; | 254 | struct linux_sys_unlink_args ua; | |
258 | 255 | |||
259 | NETBSD32TOP_UAP(path, const char); | 256 | NETBSD32TOP_UAP(path, const char); | |
260 | 257 | |||
261 | return linux_sys_unlink(l, &ua, retval); | 258 | return linux_sys_unlink(l, &ua, retval); | |
262 | } | 259 | } | |
263 | 260 | |||
264 | int | 261 | int | |
265 | linux32_sys_creat(struct lwp *l, const struct linux32_sys_creat_args *uap, register_t *retval) | 262 | linux32_sys_creat(struct lwp *l, const struct linux32_sys_creat_args *uap, register_t *retval) | |
266 | { | 263 | { | |
267 | /* { | 264 | /* { | |
268 | syscallarg(const netbsd32_charp) path; | 265 | syscallarg(const netbsd32_charp) path; | |
269 | syscallarg(int) mode; | 266 | syscallarg(int) mode; | |
270 | } */ | 267 | } */ | |
271 | struct sys_open_args ua; | 268 | struct sys_open_args ua; | |
272 | 269 | |||
273 | NETBSD32TOP_UAP(path, const char); | 270 | NETBSD32TOP_UAP(path, const char); | |
274 | SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY; | 271 | SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY; | |
275 | NETBSD32TO64_UAP(mode); | 272 | NETBSD32TO64_UAP(mode); | |
276 | 273 | |||
277 | return sys_open(l, &ua, retval); | 274 | return sys_open(l, &ua, retval); | |
278 | } | 275 | } | |
279 | 276 | |||
280 | int | 277 | int | |
281 | linux32_sys_mknod(struct lwp *l, const struct linux32_sys_mknod_args *uap, register_t *retval) | 278 | linux32_sys_mknod(struct lwp *l, const struct linux32_sys_mknod_args *uap, register_t *retval) | |
282 | { | 279 | { | |
283 | /* { | 280 | /* { | |
284 | syscallarg(const netbsd32_charp) path; | 281 | syscallarg(const netbsd32_charp) path; | |
285 | syscallarg(int) mode; | 282 | syscallarg(int) mode; | |
286 | syscallarg(int) dev; | 283 | syscallarg(int) dev; | |
287 | } */ | 284 | } */ | |
288 | struct linux_sys_mknod_args ua; | 285 | struct linux_sys_mknod_args ua; | |
289 | 286 | |||
290 | NETBSD32TOP_UAP(path, const char); | 287 | NETBSD32TOP_UAP(path, const char); | |
291 | NETBSD32TO64_UAP(mode); | 288 | NETBSD32TO64_UAP(mode); | |
292 | NETBSD32TO64_UAP(dev); | 289 | NETBSD32TO64_UAP(dev); | |
293 | 290 | |||
294 | return linux_sys_mknod(l, &ua, retval); | 291 | return linux_sys_mknod(l, &ua, retval); | |
295 | } | 292 | } | |
296 | 293 | |||
297 | int | 294 | int | |
298 | linux32_sys_break(struct lwp *l, const struct linux32_sys_break_args *uap, register_t *retval) | 295 | linux32_sys_break(struct lwp *l, const struct linux32_sys_break_args *uap, register_t *retval) | |
299 | { | 296 | { | |
300 | #if 0 | 297 | #if 0 | |
301 | /* { | 298 | /* { | |
302 | syscallarg(const netbsd32_charp) nsize; | 299 | syscallarg(const netbsd32_charp) nsize; | |
303 | } */ | 300 | } */ | |
304 | #endif | 301 | #endif | |
305 | 302 | |||
306 | return ENOSYS; | 303 | return ENOSYS; | |
307 | } | 304 | } | |
308 | 305 | |||
309 | int | 306 | int | |
310 | linux32_sys_swapon(struct lwp *l, const struct linux32_sys_swapon_args *uap, register_t *retval) | 307 | linux32_sys_swapon(struct lwp *l, const struct linux32_sys_swapon_args *uap, register_t *retval) | |
311 | { | 308 | { | |
312 | /* { | 309 | /* { | |
313 | syscallarg(const netbsd32_charp) name; | 310 | syscallarg(const netbsd32_charp) name; | |
314 | } */ | 311 | } */ | |
315 | struct sys_swapctl_args ua; | 312 | struct sys_swapctl_args ua; | |
316 | 313 | |||
317 | SCARG(&ua, cmd) = SWAP_ON; | 314 | SCARG(&ua, cmd) = SWAP_ON; | |
318 | SCARG(&ua, arg) = SCARG_P32(uap, name); | 315 | SCARG(&ua, arg) = SCARG_P32(uap, name); | |
319 | SCARG(&ua, misc) = 0; /* priority */ | 316 | SCARG(&ua, misc) = 0; /* priority */ | |
320 | return (sys_swapctl(l, &ua, retval)); | 317 | return (sys_swapctl(l, &ua, retval)); | |
321 | } | 318 | } | |
322 | 319 | |||
323 | int | 320 | int | |
324 | linux32_sys_swapoff(struct lwp *l, const struct linux32_sys_swapoff_args *uap, register_t *retval) | 321 | linux32_sys_swapoff(struct lwp *l, const struct linux32_sys_swapoff_args *uap, register_t *retval) | |
325 | { | 322 | { | |
326 | /* { | 323 | /* { | |
327 | syscallarg(const netbsd32_charp) path; | 324 | syscallarg(const netbsd32_charp) path; | |
328 | } */ | 325 | } */ | |
329 | struct sys_swapctl_args ua; | 326 | struct sys_swapctl_args ua; | |
330 | 327 | |||
331 | SCARG(&ua, cmd) = SWAP_OFF; | 328 | SCARG(&ua, cmd) = SWAP_OFF; | |
332 | SCARG(&ua, arg) = SCARG_P32(uap, path); | 329 | SCARG(&ua, arg) = SCARG_P32(uap, path); | |
333 | SCARG(&ua, misc) = 0; /* priority */ | 330 | SCARG(&ua, misc) = 0; /* priority */ | |
334 | return (sys_swapctl(l, &ua, retval)); | 331 | return (sys_swapctl(l, &ua, retval)); | |
335 | } | 332 | } | |
336 | 333 | |||
337 | 334 | |||
338 | int | 335 | int | |
339 | linux32_sys_reboot(struct lwp *l, const struct linux32_sys_reboot_args *uap, register_t *retval) | 336 | linux32_sys_reboot(struct lwp *l, const struct linux32_sys_reboot_args *uap, register_t *retval) | |
340 | { | 337 | { | |
341 | /* { | 338 | /* { | |
342 | syscallarg(int) magic1; | 339 | syscallarg(int) magic1; | |
343 | syscallarg(int) magic2; | 340 | syscallarg(int) magic2; | |
344 | syscallarg(int) cmd; | 341 | syscallarg(int) cmd; | |
345 | syscallarg(netbsd32_voidp) arg; | 342 | syscallarg(netbsd32_voidp) arg; | |
346 | } */ | 343 | } */ | |
347 | struct linux_sys_reboot_args ua; | 344 | struct linux_sys_reboot_args ua; | |
348 | 345 | |||
349 | NETBSD32TO64_UAP(magic1); | 346 | NETBSD32TO64_UAP(magic1); | |
350 | NETBSD32TO64_UAP(magic2); | 347 | NETBSD32TO64_UAP(magic2); | |
351 | NETBSD32TO64_UAP(cmd); | 348 | NETBSD32TO64_UAP(cmd); | |
352 | NETBSD32TOP_UAP(arg, void); | 349 | NETBSD32TOP_UAP(arg, void); | |
353 | 350 | |||
354 | return linux_sys_reboot(l, &ua, retval); | 351 | return linux_sys_reboot(l, &ua, retval); | |
355 | } | 352 | } | |
356 | 353 | |||
357 | int | 354 | int | |
358 | linux32_sys_setresuid(struct lwp *l, const struct linux32_sys_setresuid_args *uap, register_t *retval) | 355 | linux32_sys_setresuid(struct lwp *l, const struct linux32_sys_setresuid_args *uap, register_t *retval) | |
359 | { | 356 | { | |
360 | /* { | 357 | /* { | |
361 | syscallarg(uid_t) ruid; | 358 | syscallarg(uid_t) ruid; | |
362 | syscallarg(uid_t) euid; | 359 | syscallarg(uid_t) euid; | |
363 | syscallarg(uid_t) suid; | 360 | syscallarg(uid_t) suid; | |
364 | } */ | 361 | } */ | |
365 | struct linux_sys_setresuid_args ua; | 362 | struct linux_sys_setresuid_args ua; | |
366 | 363 | |||
367 | NETBSD32TO64_UAP(ruid); | 364 | NETBSD32TO64_UAP(ruid); | |
368 | NETBSD32TO64_UAP(euid); | 365 | NETBSD32TO64_UAP(euid); | |
369 | NETBSD32TO64_UAP(suid); | 366 | NETBSD32TO64_UAP(suid); | |
370 | 367 | |||
371 | return linux_sys_setresuid(l, &ua, retval); | 368 | return linux_sys_setresuid(l, &ua, retval); | |
372 | } | 369 | } | |
373 | 370 | |||
374 | int | 371 | int | |
375 | linux32_sys_getresuid(struct lwp *l, const struct linux32_sys_getresuid_args *uap, register_t *retval) | 372 | linux32_sys_getresuid(struct lwp *l, const struct linux32_sys_getresuid_args *uap, register_t *retval) | |
376 | { | 373 | { | |
377 | /* { | 374 | /* { | |
378 | syscallarg(linux32_uidp_t) ruid; | 375 | syscallarg(linux32_uidp_t) ruid; | |
379 | syscallarg(linux32_uidp_t) euid; | 376 | syscallarg(linux32_uidp_t) euid; | |
380 | syscallarg(linux32_uidp_t) suid; | 377 | syscallarg(linux32_uidp_t) suid; | |
381 | } */ | 378 | } */ | |
382 | kauth_cred_t pc = l->l_cred; | 379 | kauth_cred_t pc = l->l_cred; | |
383 | int error; | 380 | int error; | |
384 | uid_t uid; | 381 | uid_t uid; | |
385 | 382 | |||
386 | uid = kauth_cred_getuid(pc); | 383 | uid = kauth_cred_getuid(pc); | |
387 | if ((error = copyout(&uid, SCARG_P32(uap, ruid), sizeof(uid_t))) != 0) | 384 | if ((error = copyout(&uid, SCARG_P32(uap, ruid), sizeof(uid_t))) != 0) | |
388 | return error; | 385 | return error; | |
389 | 386 | |||
390 | uid = kauth_cred_geteuid(pc); | 387 | uid = kauth_cred_geteuid(pc); | |
391 | if ((error = copyout(&uid, SCARG_P32(uap, euid), sizeof(uid_t))) != 0) | 388 | if ((error = copyout(&uid, SCARG_P32(uap, euid), sizeof(uid_t))) != 0) | |
392 | return error; | 389 | return error; | |
393 | 390 | |||
394 | uid = kauth_cred_getsvuid(pc); | 391 | uid = kauth_cred_getsvuid(pc); | |
395 | return copyout(&uid, SCARG_P32(uap, suid), sizeof(uid_t)); | 392 | return copyout(&uid, SCARG_P32(uap, suid), sizeof(uid_t)); | |
396 | } | 393 | } | |
397 | 394 | |||
398 | int | 395 | int | |
399 | linux32_sys_setresgid(struct lwp *l, const struct linux32_sys_setresgid_args *uap, register_t *retval) | 396 | linux32_sys_setresgid(struct lwp *l, const struct linux32_sys_setresgid_args *uap, register_t *retval) | |
400 | { | 397 | { | |
401 | /* { | 398 | /* { | |
402 | syscallarg(gid_t) rgid; | 399 | syscallarg(gid_t) rgid; | |
403 | syscallarg(gid_t) egid; | 400 | syscallarg(gid_t) egid; | |
404 | syscallarg(gid_t) sgid; | 401 | syscallarg(gid_t) sgid; | |
405 | } */ | 402 | } */ | |
406 | struct linux_sys_setresgid_args ua; | 403 | struct linux_sys_setresgid_args ua; | |
407 | 404 | |||
408 | NETBSD32TO64_UAP(rgid); | 405 | NETBSD32TO64_UAP(rgid); | |
409 | NETBSD32TO64_UAP(egid); | 406 | NETBSD32TO64_UAP(egid); | |
410 | NETBSD32TO64_UAP(sgid); | 407 | NETBSD32TO64_UAP(sgid); | |
411 | 408 | |||
412 | return linux_sys_setresgid(l, &ua, retval); | 409 | return linux_sys_setresgid(l, &ua, retval); | |
413 | } | 410 | } | |
414 | 411 | |||
415 | int | 412 | int | |
416 | linux32_sys_getresgid(struct lwp *l, const struct linux32_sys_getresgid_args *uap, register_t *retval) | 413 | linux32_sys_getresgid(struct lwp *l, const struct linux32_sys_getresgid_args *uap, register_t *retval) | |
417 | { | 414 | { | |
418 | /* { | 415 | /* { | |
419 | syscallarg(linux32_gidp_t) rgid; | 416 | syscallarg(linux32_gidp_t) rgid; | |
420 | syscallarg(linux32_gidp_t) egid; | 417 | syscallarg(linux32_gidp_t) egid; | |
421 | syscallarg(linux32_gidp_t) sgid; | 418 | syscallarg(linux32_gidp_t) sgid; | |
422 | } */ | 419 | } */ | |
423 | kauth_cred_t pc = l->l_cred; | 420 | kauth_cred_t pc = l->l_cred; | |
424 | int error; | 421 | int error; | |
425 | gid_t gid; | 422 | gid_t gid; | |
426 | 423 | |||
427 | gid = kauth_cred_getgid(pc); | 424 | gid = kauth_cred_getgid(pc); | |
428 | if ((error = copyout(&gid, SCARG_P32(uap, rgid), sizeof(gid_t))) != 0) | 425 | if ((error = copyout(&gid, SCARG_P32(uap, rgid), sizeof(gid_t))) != 0) | |
429 | return error; | 426 | return error; | |
430 | 427 | |||
431 | gid = kauth_cred_getegid(pc); | 428 | gid = kauth_cred_getegid(pc); | |
432 | if ((error = copyout(&gid, SCARG_P32(uap, egid), sizeof(gid_t))) != 0) | 429 | if ((error = copyout(&gid, SCARG_P32(uap, egid), sizeof(gid_t))) != 0) | |
433 | return error; | 430 | return error; | |
434 | 431 | |||
435 | gid = kauth_cred_getsvgid(pc); | 432 | gid = kauth_cred_getsvgid(pc); | |
436 | return copyout(&gid, SCARG_P32(uap, sgid), sizeof(gid_t)); | 433 | return copyout(&gid, SCARG_P32(uap, sgid), sizeof(gid_t)); | |
437 | } | 434 | } | |
438 | 435 | |||
439 | int | 436 | int | |
440 | linux32_sys_nice(struct lwp *l, const struct linux32_sys_nice_args *uap, register_t *retval) | 437 | linux32_sys_nice(struct lwp *l, const struct linux32_sys_nice_args *uap, register_t *retval) | |
441 | { | 438 | { | |
442 | /* { | 439 | /* { | |
443 | syscallarg(int) incr; | 440 | syscallarg(int) incr; | |
444 | } */ | 441 | } */ | |
445 | struct proc *p = l->l_proc; | 442 | struct proc *p = l->l_proc; | |
446 | struct sys_setpriority_args bsa; | 443 | struct sys_setpriority_args bsa; | |
447 | 444 | |||
448 | SCARG(&bsa, which) = PRIO_PROCESS; | 445 | SCARG(&bsa, which) = PRIO_PROCESS; | |
449 | SCARG(&bsa, who) = 0; | 446 | SCARG(&bsa, who) = 0; | |
450 | SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr); | 447 | SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr); | |
451 | 448 | |||
452 | return sys_setpriority(l, &bsa, retval); | 449 | return sys_setpriority(l, &bsa, retval); | |
453 | } | 450 | } | |
454 | 451 | |||
455 | int | 452 | int | |
456 | linux32_sys_alarm(struct lwp *l, const struct linux32_sys_alarm_args *uap, register_t *retval) | 453 | linux32_sys_alarm(struct lwp *l, const struct linux32_sys_alarm_args *uap, register_t *retval) | |
457 | { | 454 | { | |
458 | /* { | 455 | /* { | |
459 | syscallarg(unsigned int) secs; | 456 | syscallarg(unsigned int) secs; | |
460 | } */ | 457 | } */ | |
461 | struct linux_sys_alarm_args ua; | 458 | struct linux_sys_alarm_args ua; | |
462 | 459 | |||
463 | NETBSD32TO64_UAP(secs); | 460 | NETBSD32TO64_UAP(secs); | |
464 | 461 | |||
465 | return linux_sys_alarm(l, &ua, retval); | 462 | return linux_sys_alarm(l, &ua, retval); | |
466 | } | 463 | } | |
467 | 464 | |||
468 | int | 465 | int | |
469 | linux32_sys_fdatasync(struct lwp *l, const struct linux32_sys_fdatasync_args *uap, register_t *retval) | 466 | linux32_sys_fdatasync(struct lwp *l, const struct linux32_sys_fdatasync_args *uap, register_t *retval) | |
470 | { | 467 | { | |
471 | /* { | 468 | /* { | |
472 | syscallarg(int) fd; | 469 | syscallarg(int) fd; | |
473 | } */ | 470 | } */ | |
474 | struct linux_sys_fdatasync_args ua; | 471 | struct linux_sys_fdatasync_args ua; | |
475 | 472 | |||
476 | NETBSD32TO64_UAP(fd); | 473 | NETBSD32TO64_UAP(fd); | |
477 | 474 | |||
478 | return linux_sys_fdatasync(l, &ua, retval); | 475 | return linux_sys_fdatasync(l, &ua, retval); | |
479 | } | 476 | } | |
480 | 477 | |||
481 | int | 478 | int | |
482 | linux32_sys_setfsuid(struct lwp *l, const struct linux32_sys_setfsuid_args *uap, register_t *retval) | 479 | linux32_sys_setfsuid(struct lwp *l, const struct linux32_sys_setfsuid_args *uap, register_t *retval) | |
483 | { | 480 | { | |
484 | /* { | 481 | /* { | |
485 | syscallarg(uid_t) uid; | 482 | syscallarg(uid_t) uid; | |
486 | } */ | 483 | } */ | |
487 | struct linux_sys_setfsuid_args ua; | 484 | struct linux_sys_setfsuid_args ua; | |
488 | 485 | |||
489 | NETBSD32TO64_UAP(uid); | 486 | NETBSD32TO64_UAP(uid); | |
490 | 487 | |||
491 | return linux_sys_setfsuid(l, &ua, retval); | 488 | return linux_sys_setfsuid(l, &ua, retval); | |
492 | } | 489 | } | |
493 | 490 | |||
494 | int | 491 | int | |
495 | linux32_sys_setfsgid(struct lwp *l, const struct linux32_sys_setfsgid_args *uap, register_t *retval) | 492 | linux32_sys_setfsgid(struct lwp *l, const struct linux32_sys_setfsgid_args *uap, register_t *retval) | |
496 | { | 493 | { | |
497 | /* { | 494 | /* { | |
498 | syscallarg(gid_t) gid; | 495 | syscallarg(gid_t) gid; | |
499 | } */ | 496 | } */ | |
500 | struct linux_sys_setfsgid_args ua; | 497 | struct linux_sys_setfsgid_args ua; | |
501 | 498 | |||
502 | NETBSD32TO64_UAP(gid); | 499 | NETBSD32TO64_UAP(gid); | |
503 | 500 | |||
504 | return linux_sys_setfsgid(l, &ua, retval); | 501 | return linux_sys_setfsgid(l, &ua, retval); | |
505 | } | 502 | } | |
506 | 503 | |||
507 | /* | 504 | /* | |
508 | * pread(2). | 505 | * pread(2). | |
509 | */ | 506 | */ | |
510 | int | 507 | int | |
511 | linux32_sys_pread(struct lwp *l, | 508 | linux32_sys_pread(struct lwp *l, | |
512 | const struct linux32_sys_pread_args *uap, register_t *retval) | 509 | const struct linux32_sys_pread_args *uap, register_t *retval) | |
513 | { | 510 | { | |
514 | /* { | 511 | /* { | |
515 | syscallarg(int) fd; | 512 | syscallarg(int) fd; | |
516 | syscallarg(netbsd32_voidp) buf; | 513 | syscallarg(netbsd32_voidp) buf; | |
517 | syscallarg(netbsd32_size_t) nbyte; | 514 | syscallarg(netbsd32_size_t) nbyte; | |
518 | syscallarg(linux32_off_t) offset; | 515 | syscallarg(linux32_off_t) offset; | |
519 | } */ | 516 | } */ | |
520 | struct sys_pread_args pra; | 517 | struct sys_pread_args pra; | |
521 | 518 | |||
522 | SCARG(&pra, fd) = SCARG(uap, fd); | 519 | SCARG(&pra, fd) = SCARG(uap, fd); | |
523 | SCARG(&pra, buf) = SCARG_P32(uap, buf); | 520 | SCARG(&pra, buf) = SCARG_P32(uap, buf); | |
524 | SCARG(&pra, nbyte) = SCARG(uap, nbyte); | 521 | SCARG(&pra, nbyte) = SCARG(uap, nbyte); | |
525 | SCARG(&pra, offset) = SCARG(uap, offset); | 522 | SCARG(&pra, offset) = SCARG(uap, offset); | |
526 | 523 | |||
527 | return sys_pread(l, &pra, retval); | 524 | return sys_pread(l, &pra, retval); | |
528 | } | 525 | } | |
529 | 526 | |||
530 | /* | 527 | /* | |
531 | * pwrite(2). | 528 | * pwrite(2). | |
532 | */ | 529 | */ | |
533 | int | 530 | int | |
534 | linux32_sys_pwrite(struct lwp *l, | 531 | linux32_sys_pwrite(struct lwp *l, | |
535 | const struct linux32_sys_pwrite_args *uap, register_t *retval) | 532 | const struct linux32_sys_pwrite_args *uap, register_t *retval) | |
536 | { | 533 | { | |
537 | /* { | 534 | /* { | |
538 | syscallarg(int) fd; | 535 | syscallarg(int) fd; | |
539 | syscallarg(const netbsd32_voidp) buf; | 536 | syscallarg(const netbsd32_voidp) buf; | |
540 | syscallarg(netbsd32_size_t) nbyte; | 537 | syscallarg(netbsd32_size_t) nbyte; | |
541 | syscallarg(linux32_off_t) offset; | 538 | syscallarg(linux32_off_t) offset; | |
542 | } */ | 539 | } */ | |
543 | struct sys_pwrite_args pra; | 540 | struct sys_pwrite_args pra; | |
544 | 541 | |||
545 | SCARG(&pra, fd) = SCARG(uap, fd); | 542 | SCARG(&pra, fd) = SCARG(uap, fd); | |
546 | SCARG(&pra, buf) = SCARG_P32(uap, buf); | 543 | SCARG(&pra, buf) = SCARG_P32(uap, buf); | |
547 | SCARG(&pra, nbyte) = SCARG(uap, nbyte); | 544 | SCARG(&pra, nbyte) = SCARG(uap, nbyte); | |
548 | SCARG(&pra, offset) = SCARG(uap, offset); | 545 | SCARG(&pra, offset) = SCARG(uap, offset); | |
549 | 546 | |||
550 | return sys_pwrite(l, &pra, retval); | 547 | return sys_pwrite(l, &pra, retval); | |
551 | } | 548 | } | |
552 | 549 |