1 /*- 2 * Copyright (c) 2004 Tim J. Robbins 3 * Copyright (c) 2002 Doug Rabson 4 * Copyright (c) 2000 Marcel Moolenaar 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer 12 * in this position and unchanged. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/kernel.h> 36 #include <sys/systm.h> 37 #include <sys/imgact.h> 38 #include <sys/limits.h> 39 #include <sys/lock.h> 40 #include <sys/malloc.h> 41 #include <sys/mman.h> 42 #include <sys/mutex.h> 43 #include <sys/proc.h> 44 #include <sys/resource.h> 45 #include <sys/resourcevar.h> 46 #include <sys/syscallsubr.h> 47 #include <sys/sysproto.h> 48 #include <sys/unistd.h> 49 50 #include <machine/frame.h> 51 52 #include <vm/vm.h> 53 #include <vm/pmap.h> 54 #include <vm/vm_extern.h> 55 #include <vm/vm_kern.h> 56 #include <vm/vm_map.h> 57 58 #include <amd64/linux32/linux.h> 59 #include <amd64/linux32/linux32_proto.h> 60 #include <compat/linux/linux_ipc.h> 61 #include <compat/linux/linux_signal.h> 62 #include <compat/linux/linux_util.h> 63 64 struct l_old_select_argv { 65 l_int nfds; 66 l_uintptr_t readfds; 67 l_uintptr_t writefds; 68 l_uintptr_t exceptfds; 69 l_uintptr_t timeout; 70 } __packed; 71 72 int 73 linux_to_bsd_sigaltstack(int lsa) 74 { 75 int bsa = 0; 76 77 if (lsa & LINUX_SS_DISABLE) 78 bsa |= SS_DISABLE; 79 if (lsa & LINUX_SS_ONSTACK) 80 bsa |= SS_ONSTACK; 81 return (bsa); 82 } 83 84 int 85 bsd_to_linux_sigaltstack(int bsa) 86 { 87 int lsa = 0; 88 89 if (bsa & SS_DISABLE) 90 lsa |= LINUX_SS_DISABLE; 91 if (bsa & SS_ONSTACK) 92 lsa |= LINUX_SS_ONSTACK; 93 return (lsa); 94 } 95 96 /* 97 * Custom version of exec_copyin_args() so that we can translate 98 * the pointers. 99 */ 100 static int 101 linux_exec_copyin_args(struct image_args *args, char *fname, 102 enum uio_seg segflg, char **argv, char **envv) 103 { 104 char *argp, *envp; 105 u_int32_t *p32, arg; 106 size_t length; 107 int error; 108 109 bzero(args, sizeof(*args)); 110 if (argv == NULL) 111 return (EFAULT); 112 113 /* 114 * Allocate temporary demand zeroed space for argument and 115 * environment strings 116 */ 117 args->buf = (char *) kmem_alloc_wait(exec_map, 118 PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 119 if (args->buf == NULL) 120 return (ENOMEM); 121 args->begin_argv = args->buf; 122 args->endp = args->begin_argv; 123 args->stringspace = ARG_MAX; 124 125 args->fname = args->buf + ARG_MAX; 126 127 /* 128 * Copy the file name. 129 */ 130 error = (segflg == UIO_SYSSPACE) ? 131 copystr(fname, args->fname, PATH_MAX, &length) : 132 copyinstr(fname, args->fname, PATH_MAX, &length); 133 if (error != 0) 134 goto err_exit; 135 136 /* 137 * extract arguments first 138 */ 139 p32 = (u_int32_t *)argv; 140 for (;;) { 141 error = copyin(p32++, &arg, sizeof(arg)); 142 if (error) 143 goto err_exit; 144 if (arg == 0) 145 break; 146 argp = PTRIN(arg); 147 error = copyinstr(argp, args->endp, args->stringspace, &length); 148 if (error) { 149 if (error == ENAMETOOLONG) 150 error = E2BIG; 151 152 goto err_exit; 153 } 154 args->stringspace -= length; 155 args->endp += length; 156 args->argc++; 157 } 158 159 args->begin_envv = args->endp; 160 161 /* 162 * extract environment strings 163 */ 164 if (envv) { 165 p32 = (u_int32_t *)envv; 166 for (;;) { 167 error = copyin(p32++, &arg, sizeof(arg)); 168 if (error) 169 goto err_exit; 170 if (arg == 0) 171 break; 172 envp = PTRIN(arg); 173 error = copyinstr(envp, args->endp, args->stringspace, 174 &length); 175 if (error) { 176 if (error == ENAMETOOLONG) 177 error = E2BIG; 178 goto err_exit; 179 } 180 args->stringspace -= length; 181 args->endp += length; 182 args->envc++; 183 } 184 } 185 186 return (0); 187 188 err_exit: 189 kmem_free_wakeup(exec_map, (vm_offset_t)args->buf, 190 PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 191 args->buf = NULL; 192 return (error); 193 } 194 195 int 196 linux_execve(struct thread *td, struct linux_execve_args *args) 197 { 198 struct image_args eargs; 199 char *path; 200 int error; 201 202 LCONVPATHEXIST(td, args->path, &path); 203 204 #ifdef DEBUG 205 if (ldebug(execve)) 206 printf(ARGS(execve, "%s"), path); 207 #endif 208 209 error = linux_exec_copyin_args(&eargs, path, UIO_SYSSPACE, args->argp, 210 args->envp); 211 free(path, M_TEMP); 212 if (error == 0) 213 error = kern_execve(td, &eargs, NULL); 214 return (error); 215 } 216 217 struct iovec32 { 218 u_int32_t iov_base; 219 int iov_len; 220 }; 221 222 CTASSERT(sizeof(struct iovec32) == 8); 223 224 static int 225 linux32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 226 { 227 struct iovec32 iov32; 228 struct iovec *iov; 229 struct uio *uio; 230 u_int iovlen; 231 int error, i; 232 233 *uiop = NULL; 234 if (iovcnt > UIO_MAXIOV) 235 return (EINVAL); 236 iovlen = iovcnt * sizeof(struct iovec); 237 uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 238 iov = (struct iovec *)(uio + 1); 239 for (i = 0; i < iovcnt; i++) { 240 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 241 if (error) { 242 free(uio, M_IOV); 243 return (error); 244 } 245 iov[i].iov_base = PTRIN(iov32.iov_base); 246 iov[i].iov_len = iov32.iov_len; 247 } 248 uio->uio_iov = iov; 249 uio->uio_iovcnt = iovcnt; 250 uio->uio_segflg = UIO_USERSPACE; 251 uio->uio_offset = -1; 252 uio->uio_resid = 0; 253 for (i = 0; i < iovcnt; i++) { 254 if (iov->iov_len > INT_MAX - uio->uio_resid) { 255 free(uio, M_IOV); 256 return (EINVAL); 257 } 258 uio->uio_resid += iov->iov_len; 259 iov++; 260 } 261 *uiop = uio; 262 return (0); 263 } 264 265 int 266 linux_readv(struct thread *td, struct linux_readv_args *uap) 267 { 268 struct uio *auio; 269 int error; 270 271 error = linux32_copyinuio(uap->iovp, uap->iovcnt, &auio); 272 if (error) 273 return (error); 274 error = kern_readv(td, uap->fd, auio); 275 free(auio, M_IOV); 276 return (error); 277 } 278 279 int 280 linux_writev(struct thread *td, struct linux_writev_args *uap) 281 { 282 struct uio *auio; 283 int error; 284 285 error = linux32_copyinuio(uap->iovp, uap->iovcnt, &auio); 286 if (error) 287 return (error); 288 error = kern_writev(td, uap->fd, auio); 289 free(auio, M_IOV); 290 return (error); 291 } 292 293 struct l_ipc_kludge { 294 l_uintptr_t msgp; 295 l_long msgtyp; 296 } __packed; 297 298 int 299 linux_ipc(struct thread *td, struct linux_ipc_args *args) 300 { 301 302 switch (args->what & 0xFFFF) { 303 case LINUX_SEMOP: { 304 struct linux_semop_args a; 305 306 a.semid = args->arg1; 307 a.tsops = args->ptr; 308 a.nsops = args->arg2; 309 return (linux_semop(td, &a)); 310 } 311 case LINUX_SEMGET: { 312 struct linux_semget_args a; 313 314 a.key = args->arg1; 315 a.nsems = args->arg2; 316 a.semflg = args->arg3; 317 return (linux_semget(td, &a)); 318 } 319 case LINUX_SEMCTL: { 320 struct linux_semctl_args a; 321 int error; 322 323 a.semid = args->arg1; 324 a.semnum = args->arg2; 325 a.cmd = args->arg3; 326 error = copyin(args->ptr, &a.arg, sizeof(a.arg)); 327 if (error) 328 return (error); 329 return (linux_semctl(td, &a)); 330 } 331 case LINUX_MSGSND: { 332 struct linux_msgsnd_args a; 333 334 a.msqid = args->arg1; 335 a.msgp = args->ptr; 336 a.msgsz = args->arg2; 337 a.msgflg = args->arg3; 338 return (linux_msgsnd(td, &a)); 339 } 340 case LINUX_MSGRCV: { 341 struct linux_msgrcv_args a; 342 343 a.msqid = args->arg1; 344 a.msgsz = args->arg2; 345 a.msgflg = args->arg3; 346 if ((args->what >> 16) == 0) { 347 struct l_ipc_kludge tmp; 348 int error; 349 350 if (args->ptr == 0) 351 return (EINVAL); 352 error = copyin(args->ptr, &tmp, sizeof(tmp)); 353 if (error) 354 return (error); 355 a.msgp = PTRIN(tmp.msgp); 356 a.msgtyp = tmp.msgtyp; 357 } else { 358 a.msgp = args->ptr; 359 a.msgtyp = args->arg5; 360 } 361 return (linux_msgrcv(td, &a)); 362 } 363 case LINUX_MSGGET: { 364 struct linux_msgget_args a; 365 366 a.key = args->arg1; 367 a.msgflg = args->arg2; 368 return (linux_msgget(td, &a)); 369 } 370 case LINUX_MSGCTL: { 371 struct linux_msgctl_args a; 372 373 a.msqid = args->arg1; 374 a.cmd = args->arg2; 375 a.buf = args->ptr; 376 return (linux_msgctl(td, &a)); 377 } 378 case LINUX_SHMAT: { 379 struct linux_shmat_args a; 380 381 a.shmid = args->arg1; 382 a.shmaddr = args->ptr; 383 a.shmflg = args->arg2; 384 a.raddr = PTRIN((l_uint)args->arg3); 385 return (linux_shmat(td, &a)); 386 } 387 case LINUX_SHMDT: { 388 struct linux_shmdt_args a; 389 390 a.shmaddr = args->ptr; 391 return (linux_shmdt(td, &a)); 392 } 393 case LINUX_SHMGET: { 394 struct linux_shmget_args a; 395 396 a.key = args->arg1; 397 a.size = args->arg2; 398 a.shmflg = args->arg3; 399 return (linux_shmget(td, &a)); 400 } 401 case LINUX_SHMCTL: { 402 struct linux_shmctl_args a; 403 404 a.shmid = args->arg1; 405 a.cmd = args->arg2; 406 a.buf = args->ptr; 407 return (linux_shmctl(td, &a)); 408 } 409 default: 410 break; 411 } 412 413 return (EINVAL); 414 } 415 416 int 417 linux_old_select(struct thread *td, struct linux_old_select_args *args) 418 { 419 struct l_old_select_argv linux_args; 420 struct linux_select_args newsel; 421 int error; 422 423 #ifdef DEBUG 424 if (ldebug(old_select)) 425 printf(ARGS(old_select, "%p"), args->ptr); 426 #endif 427 428 error = copyin(args->ptr, &linux_args, sizeof(linux_args)); 429 if (error) 430 return (error); 431 432 newsel.nfds = linux_args.nfds; 433 newsel.readfds = PTRIN(linux_args.readfds); 434 newsel.writefds = PTRIN(linux_args.writefds); 435 newsel.exceptfds = PTRIN(linux_args.exceptfds); 436 newsel.timeout = PTRIN(linux_args.timeout); 437 return (linux_select(td, &newsel)); 438 } 439 440 int 441 linux_fork(struct thread *td, struct linux_fork_args *args) 442 { 443 int error; 444 445 #ifdef DEBUG 446 if (ldebug(fork)) 447 printf(ARGS(fork, "")); 448 #endif 449 450 if ((error = fork(td, (struct fork_args *)args)) != 0) 451 return (error); 452 453 if (td->td_retval[1] == 1) 454 td->td_retval[0] = 0; 455 return (0); 456 } 457 458 int 459 linux_vfork(struct thread *td, struct linux_vfork_args *args) 460 { 461 int error; 462 463 #ifdef DEBUG 464 if (ldebug(vfork)) 465 printf(ARGS(vfork, "")); 466 #endif 467 468 if ((error = vfork(td, (struct vfork_args *)args)) != 0) 469 return (error); 470 /* Are we the child? */ 471 if (td->td_retval[1] == 1) 472 td->td_retval[0] = 0; 473 return (0); 474 } 475 476 int 477 linux_clone(struct thread *td, struct linux_clone_args *args) 478 { 479 int error, ff = RFPROC | RFSTOPPED; 480 struct proc *p2; 481 struct thread *td2; 482 int exit_signal; 483 484 #ifdef DEBUG 485 if (ldebug(clone)) { 486 printf(ARGS(clone, "flags %x, stack %x"), 487 (unsigned int)(uintptr_t)args->flags, 488 (unsigned int)(uintptr_t)args->stack); 489 } 490 #endif 491 492 exit_signal = args->flags & 0x000000ff; 493 if (exit_signal >= LINUX_NSIG) 494 return (EINVAL); 495 496 if (exit_signal <= LINUX_SIGTBLSZ) 497 exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)]; 498 499 if (args->flags & CLONE_VM) 500 ff |= RFMEM; 501 if (args->flags & CLONE_SIGHAND) 502 ff |= RFSIGSHARE; 503 if (!(args->flags & CLONE_FILES)) 504 ff |= RFFDG; 505 506 error = fork1(td, ff, 0, &p2); 507 if (error) 508 return (error); 509 510 511 PROC_LOCK(p2); 512 p2->p_sigparent = exit_signal; 513 PROC_UNLOCK(p2); 514 td2 = FIRST_THREAD_IN_PROC(p2); 515 /* in a case of stack = NULL we are supposed to COW calling process stack 516 * this is what normal fork() does so we just keep the tf_rsp arg intact 517 */ 518 if (args->stack) 519 td2->td_frame->tf_rsp = PTROUT(args->stack); 520 521 #ifdef DEBUG 522 if (ldebug(clone)) 523 printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"), 524 (long)p2->p_pid, args->stack, exit_signal); 525 #endif 526 527 /* 528 * Make this runnable after we are finished with it. 529 */ 530 mtx_lock_spin(&sched_lock); 531 TD_SET_CAN_RUN(td2); 532 setrunqueue(td2, SRQ_BORING); 533 mtx_unlock_spin(&sched_lock); 534 535 td->td_retval[0] = p2->p_pid; 536 td->td_retval[1] = 0; 537 return (0); 538 } 539 540 /* XXX move */ 541 struct l_mmap_argv { 542 l_ulong addr; 543 l_ulong len; 544 l_ulong prot; 545 l_ulong flags; 546 l_ulong fd; 547 l_ulong pgoff; 548 }; 549 550 #define STACK_SIZE (2 * 1024 * 1024) 551 #define GUARD_SIZE (4 * PAGE_SIZE) 552 553 static int linux_mmap_common(struct thread *, struct l_mmap_argv *); 554 555 int 556 linux_mmap2(struct thread *td, struct linux_mmap2_args *args) 557 { 558 struct l_mmap_argv linux_args; 559 560 #ifdef DEBUG 561 if (ldebug(mmap2)) 562 printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"), 563 (void *)(intptr_t)args->addr, args->len, args->prot, 564 args->flags, args->fd, args->pgoff); 565 #endif 566 567 linux_args.addr = PTROUT(args->addr); 568 linux_args.len = args->len; 569 linux_args.prot = args->prot; 570 linux_args.flags = args->flags; 571 linux_args.fd = args->fd; 572 linux_args.pgoff = args->pgoff; 573 574 return (linux_mmap_common(td, &linux_args)); 575 } 576 577 int 578 linux_mmap(struct thread *td, struct linux_mmap_args *args) 579 { 580 int error; 581 struct l_mmap_argv linux_args; 582 583 error = copyin(args->ptr, &linux_args, sizeof(linux_args)); 584 if (error) 585 return (error); 586 587 #ifdef DEBUG 588 if (ldebug(mmap)) 589 printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"), 590 (void *)(intptr_t)linux_args.addr, linux_args.len, 591 linux_args.prot, linux_args.flags, linux_args.fd, 592 linux_args.pgoff); 593 #endif 594 if ((linux_args.pgoff % PAGE_SIZE) != 0) 595 return (EINVAL); 596 linux_args.pgoff /= PAGE_SIZE; 597 598 return (linux_mmap_common(td, &linux_args)); 599 } 600 601 static int 602 linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args) 603 { 604 struct proc *p = td->td_proc; 605 struct mmap_args /* { 606 caddr_t addr; 607 size_t len; 608 int prot; 609 int flags; 610 int fd; 611 long pad; 612 off_t pos; 613 } */ bsd_args; 614 int error; 615 616 error = 0; 617 bsd_args.flags = 0; 618 if (linux_args->flags & LINUX_MAP_SHARED) 619 bsd_args.flags |= MAP_SHARED; 620 if (linux_args->flags & LINUX_MAP_PRIVATE) 621 bsd_args.flags |= MAP_PRIVATE; 622 if (linux_args->flags & LINUX_MAP_FIXED) 623 bsd_args.flags |= MAP_FIXED; 624 if (linux_args->flags & LINUX_MAP_ANON) 625 bsd_args.flags |= MAP_ANON; 626 else 627 bsd_args.flags |= MAP_NOSYNC; 628 if (linux_args->flags & LINUX_MAP_GROWSDOWN) { 629 bsd_args.flags |= MAP_STACK; 630 631 /* The linux MAP_GROWSDOWN option does not limit auto 632 * growth of the region. Linux mmap with this option 633 * takes as addr the inital BOS, and as len, the initial 634 * region size. It can then grow down from addr without 635 * limit. However, linux threads has an implicit internal 636 * limit to stack size of STACK_SIZE. Its just not 637 * enforced explicitly in linux. But, here we impose 638 * a limit of (STACK_SIZE - GUARD_SIZE) on the stack 639 * region, since we can do this with our mmap. 640 * 641 * Our mmap with MAP_STACK takes addr as the maximum 642 * downsize limit on BOS, and as len the max size of 643 * the region. It them maps the top SGROWSIZ bytes, 644 * and autgrows the region down, up to the limit 645 * in addr. 646 * 647 * If we don't use the MAP_STACK option, the effect 648 * of this code is to allocate a stack region of a 649 * fixed size of (STACK_SIZE - GUARD_SIZE). 650 */ 651 652 /* This gives us TOS */ 653 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) + 654 linux_args->len; 655 656 if ((caddr_t)PTRIN(bsd_args.addr) > 657 p->p_vmspace->vm_maxsaddr) { 658 /* Some linux apps will attempt to mmap 659 * thread stacks near the top of their 660 * address space. If their TOS is greater 661 * than vm_maxsaddr, vm_map_growstack() 662 * will confuse the thread stack with the 663 * process stack and deliver a SEGV if they 664 * attempt to grow the thread stack past their 665 * current stacksize rlimit. To avoid this, 666 * adjust vm_maxsaddr upwards to reflect 667 * the current stacksize rlimit rather 668 * than the maximum possible stacksize. 669 * It would be better to adjust the 670 * mmap'ed region, but some apps do not check 671 * mmap's return value. 672 */ 673 PROC_LOCK(p); 674 p->p_vmspace->vm_maxsaddr = 675 (char *)LINUX32_USRSTACK - 676 lim_cur(p, RLIMIT_STACK); 677 PROC_UNLOCK(p); 678 } 679 680 /* This gives us our maximum stack size */ 681 if (linux_args->len > STACK_SIZE - GUARD_SIZE) 682 bsd_args.len = linux_args->len; 683 else 684 bsd_args.len = STACK_SIZE - GUARD_SIZE; 685 686 /* This gives us a new BOS. If we're using VM_STACK, then 687 * mmap will just map the top SGROWSIZ bytes, and let 688 * the stack grow down to the limit at BOS. If we're 689 * not using VM_STACK we map the full stack, since we 690 * don't have a way to autogrow it. 691 */ 692 bsd_args.addr -= bsd_args.len; 693 } else { 694 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr); 695 bsd_args.len = linux_args->len; 696 } 697 /* 698 * XXX i386 Linux always emulator forces PROT_READ on (why?) 699 * so we do the same. We add PROT_EXEC to work around buggy 700 * applications (e.g. Java) that take advantage of the fact 701 * that execute permissions are not enforced by x86 CPUs. 702 */ 703 bsd_args.prot = linux_args->prot | PROT_EXEC | PROT_READ; 704 if (linux_args->flags & LINUX_MAP_ANON) 705 bsd_args.fd = -1; 706 else 707 bsd_args.fd = linux_args->fd; 708 bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE; 709 bsd_args.pad = 0; 710 711 #ifdef DEBUG 712 if (ldebug(mmap)) 713 printf("-> %s(%p, %d, %d, 0x%08x, %d, 0x%x)\n", 714 __func__, 715 (void *)bsd_args.addr, (int)bsd_args.len, bsd_args.prot, 716 bsd_args.flags, bsd_args.fd, (int)bsd_args.pos); 717 #endif 718 error = mmap(td, &bsd_args); 719 #ifdef DEBUG 720 if (ldebug(mmap)) 721 printf("-> %s() return: 0x%x (0x%08x)\n", 722 __func__, error, (u_int)td->td_retval[0]); 723 #endif 724 return (error); 725 } 726 727 int 728 linux_pipe(struct thread *td, struct linux_pipe_args *args) 729 { 730 int pip[2]; 731 int error; 732 register_t reg_rdx; 733 734 #ifdef DEBUG 735 if (ldebug(pipe)) 736 printf(ARGS(pipe, "*")); 737 #endif 738 739 reg_rdx = td->td_retval[1]; 740 error = pipe(td, 0); 741 if (error) { 742 td->td_retval[1] = reg_rdx; 743 return (error); 744 } 745 746 pip[0] = td->td_retval[0]; 747 pip[1] = td->td_retval[1]; 748 error = copyout(pip, args->pipefds, 2 * sizeof(int)); 749 if (error) { 750 td->td_retval[1] = reg_rdx; 751 return (error); 752 } 753 754 td->td_retval[1] = reg_rdx; 755 td->td_retval[0] = 0; 756 return (0); 757 } 758 759 int 760 linux_sigaction(struct thread *td, struct linux_sigaction_args *args) 761 { 762 l_osigaction_t osa; 763 l_sigaction_t act, oact; 764 int error; 765 766 #ifdef DEBUG 767 if (ldebug(sigaction)) 768 printf(ARGS(sigaction, "%d, %p, %p"), 769 args->sig, (void *)args->nsa, (void *)args->osa); 770 #endif 771 772 if (args->nsa != NULL) { 773 error = copyin(args->nsa, &osa, sizeof(l_osigaction_t)); 774 if (error) 775 return (error); 776 act.lsa_handler = osa.lsa_handler; 777 act.lsa_flags = osa.lsa_flags; 778 act.lsa_restorer = osa.lsa_restorer; 779 LINUX_SIGEMPTYSET(act.lsa_mask); 780 act.lsa_mask.__bits[0] = osa.lsa_mask; 781 } 782 783 error = linux_do_sigaction(td, args->sig, args->nsa ? &act : NULL, 784 args->osa ? &oact : NULL); 785 786 if (args->osa != NULL && !error) { 787 osa.lsa_handler = oact.lsa_handler; 788 osa.lsa_flags = oact.lsa_flags; 789 osa.lsa_restorer = oact.lsa_restorer; 790 osa.lsa_mask = oact.lsa_mask.__bits[0]; 791 error = copyout(&osa, args->osa, sizeof(l_osigaction_t)); 792 } 793 794 return (error); 795 } 796 797 /* 798 * Linux has two extra args, restart and oldmask. We dont use these, 799 * but it seems that "restart" is actually a context pointer that 800 * enables the signal to happen with a different register set. 801 */ 802 int 803 linux_sigsuspend(struct thread *td, struct linux_sigsuspend_args *args) 804 { 805 sigset_t sigmask; 806 l_sigset_t mask; 807 808 #ifdef DEBUG 809 if (ldebug(sigsuspend)) 810 printf(ARGS(sigsuspend, "%08lx"), (unsigned long)args->mask); 811 #endif 812 813 LINUX_SIGEMPTYSET(mask); 814 mask.__bits[0] = args->mask; 815 linux_to_bsd_sigset(&mask, &sigmask); 816 return (kern_sigsuspend(td, sigmask)); 817 } 818 819 int 820 linux_rt_sigsuspend(struct thread *td, struct linux_rt_sigsuspend_args *uap) 821 { 822 l_sigset_t lmask; 823 sigset_t sigmask; 824 int error; 825 826 #ifdef DEBUG 827 if (ldebug(rt_sigsuspend)) 828 printf(ARGS(rt_sigsuspend, "%p, %d"), 829 (void *)uap->newset, uap->sigsetsize); 830 #endif 831 832 if (uap->sigsetsize != sizeof(l_sigset_t)) 833 return (EINVAL); 834 835 error = copyin(uap->newset, &lmask, sizeof(l_sigset_t)); 836 if (error) 837 return (error); 838 839 linux_to_bsd_sigset(&lmask, &sigmask); 840 return (kern_sigsuspend(td, sigmask)); 841 } 842 843 int 844 linux_pause(struct thread *td, struct linux_pause_args *args) 845 { 846 struct proc *p = td->td_proc; 847 sigset_t sigmask; 848 849 #ifdef DEBUG 850 if (ldebug(pause)) 851 printf(ARGS(pause, "")); 852 #endif 853 854 PROC_LOCK(p); 855 sigmask = td->td_sigmask; 856 PROC_UNLOCK(p); 857 return (kern_sigsuspend(td, sigmask)); 858 } 859 860 int 861 linux_sigaltstack(struct thread *td, struct linux_sigaltstack_args *uap) 862 { 863 stack_t ss, oss; 864 l_stack_t lss; 865 int error; 866 867 #ifdef DEBUG 868 if (ldebug(sigaltstack)) 869 printf(ARGS(sigaltstack, "%p, %p"), uap->uss, uap->uoss); 870 #endif 871 872 if (uap->uss != NULL) { 873 error = copyin(uap->uss, &lss, sizeof(l_stack_t)); 874 if (error) 875 return (error); 876 877 ss.ss_sp = PTRIN(lss.ss_sp); 878 ss.ss_size = lss.ss_size; 879 ss.ss_flags = linux_to_bsd_sigaltstack(lss.ss_flags); 880 } 881 error = kern_sigaltstack(td, (uap->uss != NULL) ? &ss : NULL, 882 (uap->uoss != NULL) ? &oss : NULL); 883 if (!error && uap->uoss != NULL) { 884 lss.ss_sp = PTROUT(oss.ss_sp); 885 lss.ss_size = oss.ss_size; 886 lss.ss_flags = bsd_to_linux_sigaltstack(oss.ss_flags); 887 error = copyout(&lss, uap->uoss, sizeof(l_stack_t)); 888 } 889 890 return (error); 891 } 892 893 int 894 linux_ftruncate64(struct thread *td, struct linux_ftruncate64_args *args) 895 { 896 struct ftruncate_args sa; 897 898 #ifdef DEBUG 899 if (ldebug(ftruncate64)) 900 printf(ARGS(ftruncate64, "%u, %jd"), args->fd, 901 (intmax_t)args->length); 902 #endif 903 904 sa.fd = args->fd; 905 sa.pad = 0; 906 sa.length = args->length; 907 return ftruncate(td, &sa); 908 } 909 910 int 911 linux_gettimeofday(struct thread *td, struct linux_gettimeofday_args *uap) 912 { 913 struct timeval atv; 914 l_timeval atv32; 915 struct timezone rtz; 916 int error = 0; 917 918 if (uap->tp) { 919 microtime(&atv); 920 atv32.tv_sec = atv.tv_sec; 921 atv32.tv_usec = atv.tv_usec; 922 error = copyout(&atv32, uap->tp, sizeof (atv32)); 923 } 924 if (error == 0 && uap->tzp != NULL) { 925 rtz.tz_minuteswest = tz_minuteswest; 926 rtz.tz_dsttime = tz_dsttime; 927 error = copyout(&rtz, uap->tzp, sizeof (rtz)); 928 } 929 return (error); 930 } 931 932 int 933 linux_nanosleep(struct thread *td, struct linux_nanosleep_args *uap) 934 { 935 struct timespec rqt, rmt; 936 struct l_timespec ats32; 937 int error; 938 939 error = copyin(uap->rqtp, &ats32, sizeof(ats32)); 940 if (error != 0) 941 return (error); 942 rqt.tv_sec = ats32.tv_sec; 943 rqt.tv_nsec = ats32.tv_nsec; 944 error = kern_nanosleep(td, &rqt, &rmt); 945 if (uap->rmtp != NULL) { 946 ats32.tv_sec = rmt.tv_sec; 947 ats32.tv_nsec = rmt.tv_nsec; 948 error = copyout(&ats32, uap->rmtp, sizeof(ats32)); 949 } 950 return (error); 951 } 952 953 int 954 linux_getrusage(struct thread *td, struct linux_getrusage_args *uap) 955 { 956 struct l_rusage s32; 957 struct rusage s; 958 int error; 959 960 error = kern_getrusage(td, uap->who, &s); 961 if (error != 0) 962 return (error); 963 if (uap->rusage != NULL) { 964 s32.ru_utime.tv_sec = s.ru_utime.tv_sec; 965 s32.ru_utime.tv_usec = s.ru_utime.tv_usec; 966 s32.ru_stime.tv_sec = s.ru_stime.tv_sec; 967 s32.ru_stime.tv_usec = s.ru_stime.tv_usec; 968 s32.ru_maxrss = s.ru_maxrss; 969 s32.ru_ixrss = s.ru_ixrss; 970 s32.ru_idrss = s.ru_idrss; 971 s32.ru_isrss = s.ru_isrss; 972 s32.ru_minflt = s.ru_minflt; 973 s32.ru_majflt = s.ru_majflt; 974 s32.ru_nswap = s.ru_nswap; 975 s32.ru_inblock = s.ru_inblock; 976 s32.ru_oublock = s.ru_oublock; 977 s32.ru_msgsnd = s.ru_msgsnd; 978 s32.ru_msgrcv = s.ru_msgrcv; 979 s32.ru_nsignals = s.ru_nsignals; 980 s32.ru_nvcsw = s.ru_nvcsw; 981 s32.ru_nivcsw = s.ru_nivcsw; 982 error = copyout(&s32, uap->rusage, sizeof(s32)); 983 } 984 return (error); 985 } 986 987 int 988 linux_sched_rr_get_interval(struct thread *td, 989 struct linux_sched_rr_get_interval_args *uap) 990 { 991 struct timespec ts; 992 struct l_timespec ts32; 993 int error; 994 995 error = kern_sched_rr_get_interval(td, uap->pid, &ts); 996 if (error != 0) 997 return (error); 998 ts32.tv_sec = ts.tv_sec; 999 ts32.tv_nsec = ts.tv_nsec; 1000 return (copyout(&ts32, uap->interval, sizeof(ts32))); 1001 } 1002 1003 int 1004 linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) 1005 { 1006 struct mprotect_args bsd_args; 1007 1008 bsd_args.addr = uap->addr; 1009 bsd_args.len = uap->len; 1010 bsd_args.prot = uap->prot; 1011 /* XXX PROT_READ implies PROT_EXEC; see linux_mmap_common(). */ 1012 if ((bsd_args.prot & PROT_READ) != 0) 1013 bsd_args.prot |= PROT_EXEC; 1014 return (mprotect(td, &bsd_args)); 1015 } 1016