linux_sysvec.c (83163) | linux_sysvec.c (83221) |
---|---|
1/*- 2 * Copyright (c) 1994-1996 S�ren Schmidt 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 --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * | 1/*- 2 * Copyright (c) 1994-1996 S�ren Schmidt 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 --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * |
28 * $FreeBSD: head/sys/i386/linux/linux_sysvec.c 83163 2001-09-06 22:20:41Z jhb $ | 28 * $FreeBSD: head/sys/i386/linux/linux_sysvec.c 83221 2001-09-08 19:07:04Z marcel $ |
29 */ 30 31/* XXX we use functions that might not exist. */ 32#include "opt_compat.h" 33 34#ifndef COMPAT_43 35#error "Unable to compile Linux-emulator due to missing COMPAT_43 option!" 36#endif --- 170 unchanged lines hidden (view full) --- 207extern int _ucodesel, _udatasel; 208extern unsigned long linux_sznonrtsigcode; 209 210static void 211linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 212{ 213 register struct proc *p = curproc; 214 register struct trapframe *regs; | 29 */ 30 31/* XXX we use functions that might not exist. */ 32#include "opt_compat.h" 33 34#ifndef COMPAT_43 35#error "Unable to compile Linux-emulator due to missing COMPAT_43 option!" 36#endif --- 170 unchanged lines hidden (view full) --- 207extern int _ucodesel, _udatasel; 208extern unsigned long linux_sznonrtsigcode; 209 210static void 211linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 212{ 213 register struct proc *p = curproc; 214 register struct trapframe *regs; |
215 struct linux_rt_sigframe *fp, frame; | 215 struct l_rt_sigframe *fp, frame; |
216 int oonstack; 217 218 PROC_LOCK_ASSERT(p, MA_OWNED); 219 regs = p->p_frame; 220 oonstack = sigonstack(regs->tf_esp); 221 222#ifdef DEBUG | 216 int oonstack; 217 218 PROC_LOCK_ASSERT(p, MA_OWNED); 219 regs = p->p_frame; 220 oonstack = sigonstack(regs->tf_esp); 221 222#ifdef DEBUG |
223 if (ldebug(sigreturn)) | 223 if (ldebug(rt_sendsig)) |
224 printf(ARGS(rt_sendsig, "%p, %d, %p, %lu"), 225 catcher, sig, (void*)mask, code); 226#endif 227 /* 228 * Allocate space for the signal handler context. 229 */ 230 if ((p->p_flag & P_ALTSTACK) && !oonstack && 231 SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { | 224 printf(ARGS(rt_sendsig, "%p, %d, %p, %lu"), 225 catcher, sig, (void*)mask, code); 226#endif 227 /* 228 * Allocate space for the signal handler context. 229 */ 230 if ((p->p_flag & P_ALTSTACK) && !oonstack && 231 SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { |
232 fp = (struct linux_rt_sigframe *)(p->p_sigstk.ss_sp + 233 p->p_sigstk.ss_size - sizeof(struct linux_rt_sigframe)); | 232 fp = (struct l_rt_sigframe *)(p->p_sigstk.ss_sp + 233 p->p_sigstk.ss_size - sizeof(struct l_rt_sigframe)); |
234 } else | 234 } else |
235 fp = (struct linux_rt_sigframe *)regs->tf_esp - 1; | 235 fp = (struct l_rt_sigframe *)regs->tf_esp - 1; |
236 PROC_UNLOCK(p); 237 238 /* 239 * grow() will return FALSE if the fp will not fit inside the stack 240 * and the stack can not be grown. useracc will return FALSE 241 * if access is denied. 242 */ 243 if ((grow_stack (p, (int)fp) == FALSE) || | 236 PROC_UNLOCK(p); 237 238 /* 239 * grow() will return FALSE if the fp will not fit inside the stack 240 * and the stack can not be grown. useracc will return FALSE 241 * if access is denied. 242 */ 243 if ((grow_stack (p, (int)fp) == FALSE) || |
244 !useracc((caddr_t)fp, sizeof (struct linux_rt_sigframe), | 244 !useracc((caddr_t)fp, sizeof (struct l_rt_sigframe), |
245 VM_PROT_WRITE)) { 246 /* 247 * Process has trashed its stack; give it an illegal 248 * instruction to halt it in its tracks. 249 */ 250 PROC_LOCK(p); 251 SIGACTION(p, SIGILL) = SIG_DFL; 252 SIGDELSET(p->p_sigignore, SIGILL); 253 SIGDELSET(p->p_sigcatch, SIGILL); 254 SIGDELSET(p->p_sigmask, SIGILL); 255#ifdef DEBUG | 245 VM_PROT_WRITE)) { 246 /* 247 * Process has trashed its stack; give it an illegal 248 * instruction to halt it in its tracks. 249 */ 250 PROC_LOCK(p); 251 SIGACTION(p, SIGILL) = SIG_DFL; 252 SIGDELSET(p->p_sigignore, SIGILL); 253 SIGDELSET(p->p_sigcatch, SIGILL); 254 SIGDELSET(p->p_sigmask, SIGILL); 255#ifdef DEBUG |
256 if (ldebug(sigreturn)) | 256 if (ldebug(rt_sendsig)) |
257 printf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"), 258 fp, oonstack); 259#endif 260 psignal(p, SIGILL); 261 return; 262 } 263 264 /* --- 44 unchanged lines hidden (view full) --- 309 frame.sf_sc.uc_mcontext.sc_cs = regs->tf_cs; 310 frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_eflags; 311 frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_esp; 312 frame.sf_sc.uc_mcontext.sc_ss = regs->tf_ss; 313 frame.sf_sc.uc_mcontext.sc_err = regs->tf_err; 314 frame.sf_sc.uc_mcontext.sc_trapno = code; /* XXX ???? */ 315 316#ifdef DEBUG | 257 printf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"), 258 fp, oonstack); 259#endif 260 psignal(p, SIGILL); 261 return; 262 } 263 264 /* --- 44 unchanged lines hidden (view full) --- 309 frame.sf_sc.uc_mcontext.sc_cs = regs->tf_cs; 310 frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_eflags; 311 frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_esp; 312 frame.sf_sc.uc_mcontext.sc_ss = regs->tf_ss; 313 frame.sf_sc.uc_mcontext.sc_err = regs->tf_err; 314 frame.sf_sc.uc_mcontext.sc_trapno = code; /* XXX ???? */ 315 316#ifdef DEBUG |
317 if (ldebug(sigreturn)) | 317 if (ldebug(rt_sendsig)) |
318 printf(LMSG("rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"), 319 frame.sf_sc.uc_stack.ss_flags, p->p_sigstk.ss_sp, 320 p->p_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask); 321#endif 322 323 if (copyout(&frame, fp, sizeof(frame)) != 0) { 324 /* 325 * Process has trashed its stack; give it an illegal --- 31 unchanged lines hidden (view full) --- 357 * specified pc, psl. 358 */ 359 360static void 361linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 362{ 363 register struct proc *p = curproc; 364 register struct trapframe *regs; | 318 printf(LMSG("rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"), 319 frame.sf_sc.uc_stack.ss_flags, p->p_sigstk.ss_sp, 320 p->p_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask); 321#endif 322 323 if (copyout(&frame, fp, sizeof(frame)) != 0) { 324 /* 325 * Process has trashed its stack; give it an illegal --- 31 unchanged lines hidden (view full) --- 357 * specified pc, psl. 358 */ 359 360static void 361linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 362{ 363 register struct proc *p = curproc; 364 register struct trapframe *regs; |
365 struct linux_sigframe *fp, frame; 366 linux_sigset_t lmask; | 365 struct l_sigframe *fp, frame; 366 l_sigset_t lmask; |
367 int oonstack, i; 368 369 if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { 370 /* Signal handler installed with SA_SIGINFO. */ 371 linux_rt_sendsig(catcher, sig, mask, code); 372 return; 373 } 374 375 regs = p->p_frame; 376 oonstack = sigonstack(regs->tf_esp); 377 378#ifdef DEBUG | 367 int oonstack, i; 368 369 if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { 370 /* Signal handler installed with SA_SIGINFO. */ 371 linux_rt_sendsig(catcher, sig, mask, code); 372 return; 373 } 374 375 regs = p->p_frame; 376 oonstack = sigonstack(regs->tf_esp); 377 378#ifdef DEBUG |
379 if (ldebug(sigreturn)) | 379 if (ldebug(sendsig)) |
380 printf(ARGS(sendsig, "%p, %d, %p, %lu"), 381 catcher, sig, (void*)mask, code); 382#endif 383 384 /* 385 * Allocate space for the signal handler context. 386 */ | 380 printf(ARGS(sendsig, "%p, %d, %p, %lu"), 381 catcher, sig, (void*)mask, code); 382#endif 383 384 /* 385 * Allocate space for the signal handler context. 386 */ |
387 PROC_LOCK(p); | |
388 if ((p->p_flag & P_ALTSTACK) && !oonstack && 389 SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { | 387 if ((p->p_flag & P_ALTSTACK) && !oonstack && 388 SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { |
390 fp = (struct linux_sigframe *)(p->p_sigstk.ss_sp + 391 p->p_sigstk.ss_size - sizeof(struct linux_sigframe)); | 389 fp = (struct l_sigframe *)(p->p_sigstk.ss_sp + 390 p->p_sigstk.ss_size - sizeof(struct l_sigframe)); |
392 } else | 391 } else |
393 fp = (struct linux_sigframe *)regs->tf_esp - 1; | 392 fp = (struct l_sigframe *)regs->tf_esp - 1; |
394 PROC_UNLOCK(p); 395 396 /* 397 * grow() will return FALSE if the fp will not fit inside the stack 398 * and the stack can not be grown. useracc will return FALSE 399 * if access is denied. 400 */ 401 if ((grow_stack (p, (int)fp) == FALSE) || | 393 PROC_UNLOCK(p); 394 395 /* 396 * grow() will return FALSE if the fp will not fit inside the stack 397 * and the stack can not be grown. useracc will return FALSE 398 * if access is denied. 399 */ 400 if ((grow_stack (p, (int)fp) == FALSE) || |
402 !useracc((caddr_t)fp, sizeof (struct linux_sigframe), | 401 !useracc((caddr_t)fp, sizeof (struct l_sigframe), |
403 VM_PROT_WRITE)) { 404 /* 405 * Process has trashed its stack; give it an illegal 406 * instruction to halt it in its tracks. 407 */ 408 PROC_LOCK(p); 409 SIGACTION(p, SIGILL) = SIG_DFL; 410 SIGDELSET(p->p_sigignore, SIGILL); 411 SIGDELSET(p->p_sigcatch, SIGILL); 412 SIGDELSET(p->p_sigmask, SIGILL); 413 psignal(p, SIGILL); | 402 VM_PROT_WRITE)) { 403 /* 404 * Process has trashed its stack; give it an illegal 405 * instruction to halt it in its tracks. 406 */ 407 PROC_LOCK(p); 408 SIGACTION(p, SIGILL) = SIG_DFL; 409 SIGDELSET(p->p_sigignore, SIGILL); 410 SIGDELSET(p->p_sigcatch, SIGILL); 411 SIGDELSET(p->p_sigmask, SIGILL); 412 psignal(p, SIGILL); |
414 PROC_UNLOCK(p); | |
415 return; 416 } 417 418 /* 419 * Build the argument list for the signal handler. 420 */ 421 if (p->p_sysent->sv_sigtbl) 422 if (sig <= p->p_sysent->sv_sigsize) --- 22 unchanged lines hidden (view full) --- 445 frame.sf_sc.sc_eip = regs->tf_eip; 446 frame.sf_sc.sc_cs = regs->tf_cs; 447 frame.sf_sc.sc_eflags = regs->tf_eflags; 448 frame.sf_sc.sc_esp_at_signal = regs->tf_esp; 449 frame.sf_sc.sc_ss = regs->tf_ss; 450 frame.sf_sc.sc_err = regs->tf_err; 451 frame.sf_sc.sc_trapno = code; /* XXX ???? */ 452 | 413 return; 414 } 415 416 /* 417 * Build the argument list for the signal handler. 418 */ 419 if (p->p_sysent->sv_sigtbl) 420 if (sig <= p->p_sysent->sv_sigsize) --- 22 unchanged lines hidden (view full) --- 443 frame.sf_sc.sc_eip = regs->tf_eip; 444 frame.sf_sc.sc_cs = regs->tf_cs; 445 frame.sf_sc.sc_eflags = regs->tf_eflags; 446 frame.sf_sc.sc_esp_at_signal = regs->tf_esp; 447 frame.sf_sc.sc_ss = regs->tf_ss; 448 frame.sf_sc.sc_err = regs->tf_err; 449 frame.sf_sc.sc_trapno = code; /* XXX ???? */ 450 |
453 bzero(&frame.sf_fpstate, sizeof(struct linux_fpstate)); | 451 bzero(&frame.sf_fpstate, sizeof(struct l_fpstate)); |
454 455 for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) 456 frame.sf_extramask[i] = lmask.__bits[i+1]; 457 458 if (copyout(&frame, fp, sizeof(frame)) != 0) { 459 /* 460 * Process has trashed its stack; give it an illegal 461 * instruction to halt it in its tracks. --- 9 unchanged lines hidden (view full) --- 471 regs->tf_esp = (int)fp; 472 regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); 473 regs->tf_eflags &= ~PSL_VM; 474 regs->tf_cs = _ucodesel; 475 regs->tf_ds = _udatasel; 476 regs->tf_es = _udatasel; 477 regs->tf_fs = _udatasel; 478 regs->tf_ss = _udatasel; | 452 453 for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) 454 frame.sf_extramask[i] = lmask.__bits[i+1]; 455 456 if (copyout(&frame, fp, sizeof(frame)) != 0) { 457 /* 458 * Process has trashed its stack; give it an illegal 459 * instruction to halt it in its tracks. --- 9 unchanged lines hidden (view full) --- 469 regs->tf_esp = (int)fp; 470 regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); 471 regs->tf_eflags &= ~PSL_VM; 472 regs->tf_cs = _ucodesel; 473 regs->tf_ds = _udatasel; 474 regs->tf_es = _udatasel; 475 regs->tf_fs = _udatasel; 476 regs->tf_ss = _udatasel; |
477 PROC_LOCK(p); |
|
479} 480 481/* 482 * System call to cleanup state after a signal 483 * has been taken. Reset signal mask and 484 * stack state from context left by sendsig (above). 485 * Return to previous pc and psl as specified by 486 * context left by sendsig. Check carefully to 487 * make sure that the user has not modified the 488 * psl to gain improper privileges or to cause 489 * a machine fault. 490 */ 491int 492linux_sigreturn(p, args) 493 struct proc *p; 494 struct linux_sigreturn_args *args; 495{ | 478} 479 480/* 481 * System call to cleanup state after a signal 482 * has been taken. Reset signal mask and 483 * stack state from context left by sendsig (above). 484 * Return to previous pc and psl as specified by 485 * context left by sendsig. Check carefully to 486 * make sure that the user has not modified the 487 * psl to gain improper privileges or to cause 488 * a machine fault. 489 */ 490int 491linux_sigreturn(p, args) 492 struct proc *p; 493 struct linux_sigreturn_args *args; 494{ |
496 struct linux_sigframe frame; | 495 struct l_sigframe frame; |
497 register struct trapframe *regs; | 496 register struct trapframe *regs; |
498 linux_sigset_t lmask; | 497 l_sigset_t lmask; |
499 int eflags, i; 500 501 regs = p->p_frame; 502 503#ifdef DEBUG 504 if (ldebug(sigreturn)) 505 printf(ARGS(sigreturn, "%p"), (void *)args->sfp); 506#endif --- 77 unchanged lines hidden (view full) --- 584 * a machine fault. 585 */ 586int 587linux_rt_sigreturn(p, args) 588 struct proc *p; 589 struct linux_rt_sigreturn_args *args; 590{ 591 struct sigaltstack_args sasargs; | 498 int eflags, i; 499 500 regs = p->p_frame; 501 502#ifdef DEBUG 503 if (ldebug(sigreturn)) 504 printf(ARGS(sigreturn, "%p"), (void *)args->sfp); 505#endif --- 77 unchanged lines hidden (view full) --- 583 * a machine fault. 584 */ 585int 586linux_rt_sigreturn(p, args) 587 struct proc *p; 588 struct linux_rt_sigreturn_args *args; 589{ 590 struct sigaltstack_args sasargs; |
592 struct linux_ucontext uc; 593 struct linux_sigcontext *context; 594 linux_stack_t *lss; | 591 struct l_ucontext uc; 592 struct l_sigcontext *context; 593 l_stack_t *lss; |
595 stack_t *ss; 596 register struct trapframe *regs; 597 int eflags; 598 caddr_t sg = stackgap_init(); 599 600 regs = p->p_frame; 601 602#ifdef DEBUG --- 264 unchanged lines hidden --- | 594 stack_t *ss; 595 register struct trapframe *regs; 596 int eflags; 597 caddr_t sg = stackgap_init(); 598 599 regs = p->p_frame; 600 601#ifdef DEBUG --- 264 unchanged lines hidden --- |