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