freebsd32_misc.c revision 107849
1100384Speter/*- 2100384Speter * Copyright (c) 2002 Doug Rabson 3100384Speter * All rights reserved. 4100384Speter * 5100384Speter * Redistribution and use in source and binary forms, with or without 6100384Speter * modification, are permitted provided that the following conditions 7100384Speter * are met: 8100384Speter * 1. Redistributions of source code must retain the above copyright 9100384Speter * notice, this list of conditions and the following disclaimer. 10100384Speter * 2. Redistributions in binary form must reproduce the above copyright 11100384Speter * notice, this list of conditions and the following disclaimer in the 12100384Speter * documentation and/or other materials provided with the distribution. 13100384Speter * 14100384Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15100384Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16100384Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17100384Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18100384Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19100384Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20100384Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21100384Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22100384Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23100384Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24100384Speter * SUCH DAMAGE. 25100384Speter * 26100384Speter * $FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 107849 2002-12-14 01:56:26Z alfred $ 27100384Speter */ 28100384Speter 29104738Speter#include "opt_compat.h" 30104738Speter 31100384Speter#include <sys/param.h> 32100384Speter#include <sys/systm.h> 33100384Speter#include <sys/bus.h> 34100384Speter#include <sys/dkstat.h> 35100384Speter#include <sys/exec.h> 36100384Speter#include <sys/fcntl.h> 37100384Speter#include <sys/filedesc.h> 38100384Speter#include <sys/imgact.h> 39100384Speter#include <sys/kernel.h> 40100384Speter#include <sys/lock.h> 41100384Speter#include <sys/malloc.h> 42100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 43100384Speter#include <sys/mman.h> 44100384Speter#include <sys/module.h> 45100384Speter#include <sys/mount.h> 46100384Speter#include <sys/mutex.h> 47100384Speter#include <sys/namei.h> 48100384Speter#include <sys/param.h> 49100384Speter#include <sys/proc.h> 50100384Speter#include <sys/reboot.h> 51100384Speter#include <sys/resource.h> 52100384Speter#include <sys/resourcevar.h> 53100384Speter#include <sys/selinfo.h> 54100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 55100384Speter#include <sys/signal.h> 56100384Speter#include <sys/signalvar.h> 57100384Speter#include <sys/socket.h> 58100384Speter#include <sys/socketvar.h> 59100384Speter#include <sys/stat.h> 60100384Speter#include <sys/sysctl.h> 61100384Speter#include <sys/sysent.h> 62100384Speter#include <sys/sysproto.h> 63100384Speter#include <sys/systm.h> 64100384Speter#include <sys/unistd.h> 65100384Speter#include <sys/user.h> 66100384Speter#include <sys/utsname.h> 67100384Speter#include <sys/vnode.h> 68100384Speter 69100384Speter#include <vm/vm.h> 70100384Speter#include <vm/vm_kern.h> 71100384Speter#include <vm/vm_param.h> 72100384Speter#include <vm/pmap.h> 73100384Speter#include <vm/vm_map.h> 74100384Speter#include <vm/vm_object.h> 75100384Speter#include <vm/vm_extern.h> 76100384Speter 77100384Speter#include <ia64/ia32/ia32_util.h> 78100384Speter#include <ia64/ia32/ia32.h> 79100384Speter#include <ia64/ia32/ia32_proto.h> 80100384Speter 81100384Speterstatic const char ia32_emul_path[] = "/compat/ia32"; 82100384Speter/* 83100384Speter * [ taken from the linux emulator ] 84100384Speter * Search an alternate path before passing pathname arguments on 85100384Speter * to system calls. Useful for keeping a separate 'emulation tree'. 86100384Speter * 87100384Speter * If cflag is set, we check if an attempt can be made to create 88100384Speter * the named file, i.e. we check if the directory it should 89100384Speter * be in exists. 90100384Speter */ 91100384Speterint 92100384Speteria32_emul_find(td, sgp, prefix, path, pbuf, cflag) 93100384Speter struct thread *td; 94100384Speter caddr_t *sgp; /* Pointer to stackgap memory */ 95100384Speter const char *prefix; 96100384Speter char *path; 97100384Speter char **pbuf; 98100384Speter int cflag; 99100384Speter{ 100100384Speter int error; 101100384Speter size_t len, sz; 102100384Speter char *buf, *cp, *ptr; 103100384Speter struct ucred *ucred; 104100384Speter struct nameidata nd; 105100384Speter struct nameidata ndroot; 106100384Speter struct vattr vat; 107100384Speter struct vattr vatroot; 108100384Speter 109100384Speter buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 110100384Speter *pbuf = path; 111100384Speter 112100384Speter for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) 113100384Speter continue; 114100384Speter 115100384Speter sz = MAXPATHLEN - (ptr - buf); 116100384Speter 117100384Speter /* 118100384Speter * If sgp is not given then the path is already in kernel space 119100384Speter */ 120100384Speter if (sgp == NULL) 121100384Speter error = copystr(path, ptr, sz, &len); 122100384Speter else 123100384Speter error = copyinstr(path, ptr, sz, &len); 124100384Speter 125100384Speter if (error) { 126100384Speter free(buf, M_TEMP); 127100384Speter return error; 128100384Speter } 129100384Speter 130100384Speter if (*ptr != '/') { 131100384Speter free(buf, M_TEMP); 132100384Speter return EINVAL; 133100384Speter } 134100384Speter 135100384Speter /* 136100384Speter * We know that there is a / somewhere in this pathname. 137100384Speter * Search backwards for it, to find the file's parent dir 138100384Speter * to see if it exists in the alternate tree. If it does, 139100384Speter * and we want to create a file (cflag is set). We don't 140100384Speter * need to worry about the root comparison in this case. 141100384Speter */ 142100384Speter 143100384Speter if (cflag) { 144100384Speter for (cp = &ptr[len] - 1; *cp != '/'; cp--) 145100384Speter ; 146100384Speter *cp = '\0'; 147100384Speter 148100384Speter NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 149100384Speter 150100384Speter if ((error = namei(&nd)) != 0) { 151100384Speter free(buf, M_TEMP); 152100384Speter return error; 153100384Speter } 154100384Speter 155100384Speter *cp = '/'; 156100384Speter } else { 157100384Speter NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 158100384Speter 159100384Speter if ((error = namei(&nd)) != 0) { 160100384Speter free(buf, M_TEMP); 161100384Speter return error; 162100384Speter } 163100384Speter 164100384Speter /* 165100384Speter * We now compare the vnode of the ia32_root to the one 166100384Speter * vnode asked. If they resolve to be the same, then we 167100384Speter * ignore the match so that the real root gets used. 168100384Speter * This avoids the problem of traversing "../.." to find the 169100384Speter * root directory and never finding it, because "/" resolves 170100384Speter * to the emulation root directory. This is expensive :-( 171100384Speter */ 172100384Speter NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, ia32_emul_path, 173100384Speter td); 174100384Speter 175100384Speter if ((error = namei(&ndroot)) != 0) { 176100384Speter /* Cannot happen! */ 177100384Speter free(buf, M_TEMP); 178100384Speter vrele(nd.ni_vp); 179100384Speter return error; 180100384Speter } 181100384Speter 182100384Speter ucred = td->td_ucred; 183100384Speter if ((error = VOP_GETATTR(nd.ni_vp, &vat, ucred, td)) != 0) { 184100384Speter goto bad; 185100384Speter } 186100384Speter 187100384Speter if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, ucred, 188100384Speter td)) != 0) { 189100384Speter goto bad; 190100384Speter } 191100384Speter 192100384Speter if (vat.va_fsid == vatroot.va_fsid && 193100384Speter vat.va_fileid == vatroot.va_fileid) { 194100384Speter error = ENOENT; 195100384Speter goto bad; 196100384Speter } 197100384Speter 198100384Speter } 199100384Speter if (sgp == NULL) 200100384Speter *pbuf = buf; 201100384Speter else { 202100384Speter sz = &ptr[len] - buf; 203100384Speter *pbuf = stackgap_alloc(sgp, sz + 1); 204100384Speter error = copyout(buf, *pbuf, sz); 205100384Speter free(buf, M_TEMP); 206100384Speter } 207100384Speter 208100384Speter vrele(nd.ni_vp); 209100384Speter if (!cflag) 210100384Speter vrele(ndroot.ni_vp); 211100384Speter 212100384Speter return error; 213100384Speter 214100384Speterbad: 215100384Speter vrele(ndroot.ni_vp); 216100384Speter vrele(nd.ni_vp); 217100384Speter free(buf, M_TEMP); 218100384Speter return error; 219100384Speter} 220100384Speter 221100384Speterint 222100384Speteria32_open(struct thread *td, struct ia32_open_args *uap) 223100384Speter{ 224100384Speter caddr_t sg; 225100384Speter 226100384Speter sg = stackgap_init(); 227100384Speter CHECKALTEXIST(td, &sg, uap->path); 228100384Speter 229100384Speter return open(td, (struct open_args *) uap); 230100384Speter} 231100384Speter 232100384Speterint 233100384Speteria32_wait4(struct thread *td, struct ia32_wait4_args *uap) 234100384Speter{ 235100384Speter int error; 236100384Speter caddr_t sg; 237100384Speter struct rusage32 *rusage32, ru32; 238100384Speter struct rusage *rusage = NULL, ru; 239100384Speter 240107849Salfred rusage32 = uap->rusage; 241100384Speter if (rusage32) { 242100384Speter sg = stackgap_init(); 243100384Speter rusage = stackgap_alloc(&sg, sizeof(struct rusage)); 244107849Salfred uap->rusage = (struct rusage32 *)rusage; 245100384Speter } 246100384Speter error = wait4(td, (struct wait_args *)uap); 247100384Speter if (error) 248100384Speter return (error); 249100384Speter if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) { 250100384Speter TV_CP(ru, ru32, ru_utime); 251100384Speter TV_CP(ru, ru32, ru_stime); 252100384Speter CP(ru, ru32, ru_maxrss); 253100384Speter CP(ru, ru32, ru_ixrss); 254100384Speter CP(ru, ru32, ru_idrss); 255100384Speter CP(ru, ru32, ru_isrss); 256100384Speter CP(ru, ru32, ru_minflt); 257100384Speter CP(ru, ru32, ru_majflt); 258100384Speter CP(ru, ru32, ru_nswap); 259100384Speter CP(ru, ru32, ru_inblock); 260100384Speter CP(ru, ru32, ru_oublock); 261100384Speter CP(ru, ru32, ru_msgsnd); 262100384Speter CP(ru, ru32, ru_msgrcv); 263100384Speter CP(ru, ru32, ru_nsignals); 264100384Speter CP(ru, ru32, ru_nvcsw); 265100384Speter CP(ru, ru32, ru_nivcsw); 266100384Speter error = copyout(&ru32, rusage32, sizeof(ru32)); 267100384Speter } 268100384Speter return (error); 269100384Speter} 270100384Speter 271100384Speterstatic void 272100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 273100384Speter{ 274100384Speter CP(*in, *out, f_bsize); 275100384Speter CP(*in, *out, f_iosize); 276100384Speter CP(*in, *out, f_blocks); 277100384Speter CP(*in, *out, f_bfree); 278100384Speter CP(*in, *out, f_bavail); 279100384Speter CP(*in, *out, f_files); 280100384Speter CP(*in, *out, f_ffree); 281100384Speter CP(*in, *out, f_fsid); 282100384Speter CP(*in, *out, f_owner); 283100384Speter CP(*in, *out, f_type); 284100384Speter CP(*in, *out, f_flags); 285100384Speter CP(*in, *out, f_flags); 286100384Speter CP(*in, *out, f_syncwrites); 287100384Speter CP(*in, *out, f_asyncwrites); 288100384Speter bcopy(in->f_fstypename, 289100384Speter out->f_fstypename, MFSNAMELEN); 290100384Speter bcopy(in->f_mntonname, 291100384Speter out->f_mntonname, MNAMELEN); 292100384Speter CP(*in, *out, f_syncreads); 293100384Speter CP(*in, *out, f_asyncreads); 294100384Speter bcopy(in->f_mntfromname, 295100384Speter out->f_mntfromname, MNAMELEN); 296100384Speter} 297100384Speter 298100384Speterint 299100384Speteria32_getfsstat(struct thread *td, struct ia32_getfsstat_args *uap) 300100384Speter{ 301100384Speter int error; 302100384Speter caddr_t sg; 303100384Speter struct statfs32 *sp32, stat32; 304100384Speter struct statfs *sp = NULL, stat; 305100384Speter int maxcount, count, i; 306100384Speter 307107849Salfred sp32 = uap->buf; 308107849Salfred maxcount = uap->bufsize / sizeof(struct statfs32); 309100384Speter 310100384Speter if (sp32) { 311100384Speter sg = stackgap_init(); 312100384Speter sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 313107849Salfred uap->buf = (struct statfs32 *)sp; 314100384Speter } 315100384Speter error = getfsstat(td, (struct getfsstat_args *) uap); 316100384Speter if (sp32 && !error) { 317100384Speter count = td->td_retval[0]; 318100384Speter for (i = 0; i < count; i++) { 319100384Speter error = copyin(&sp[i], &stat, sizeof(stat)); 320100384Speter if (error) 321100384Speter return (error); 322100384Speter copy_statfs(&stat, &stat32); 323100384Speter error = copyout(&stat32, &sp32[i], sizeof(stat32)); 324100384Speter if (error) 325100384Speter return (error); 326100384Speter } 327100384Speter } 328100384Speter return (error); 329100384Speter} 330100384Speter 331100384Speterint 332100384Speteria32_access(struct thread *td, struct ia32_access_args *uap) 333100384Speter{ 334100384Speter caddr_t sg; 335100384Speter 336100384Speter sg = stackgap_init(); 337100384Speter CHECKALTEXIST(td, &sg, uap->path); 338100384Speter 339100384Speter return access(td, (struct access_args *)uap); 340100384Speter} 341100384Speter 342100384Speterint 343100384Speteria32_chflags(struct thread *td, struct ia32_chflags_args *uap) 344100384Speter{ 345100384Speter caddr_t sg; 346100384Speter 347100384Speter sg = stackgap_init(); 348100384Speter CHECKALTEXIST(td, &sg, uap->path); 349100384Speter 350100384Speter return chflags(td, (struct chflags_args *)uap); 351100384Speter} 352100384Speter 353100384Speterstruct sigaltstack32 { 354100384Speter u_int32_t ss_sp; 355100384Speter u_int32_t ss_size; 356100384Speter int ss_flags; 357100384Speter}; 358100384Speter 359100384Speterint 360100384Speteria32_sigaltstack(struct thread *td, struct ia32_sigaltstack_args *uap) 361100384Speter{ 362100384Speter int error; 363100384Speter caddr_t sg; 364100384Speter struct sigaltstack32 *p32, *op32, s32; 365100384Speter struct sigaltstack *p = NULL, *op = NULL, s; 366100384Speter 367107849Salfred p32 = uap->ss; 368100384Speter if (p32) { 369100384Speter sg = stackgap_init(); 370100384Speter p = stackgap_alloc(&sg, sizeof(struct sigaltstack)); 371107849Salfred uap->ss = (struct sigaltstack32 *)p; 372100384Speter error = copyin(p32, &s32, sizeof(s32)); 373100384Speter if (error) 374100384Speter return (error); 375100384Speter PTRIN_CP(s32, s, ss_sp); 376100384Speter CP(s32, s, ss_size); 377100384Speter CP(s32, s, ss_flags); 378100384Speter error = copyout(&s, p, sizeof(s)); 379100384Speter if (error) 380100384Speter return (error); 381100384Speter } 382107849Salfred op32 = uap->oss; 383100384Speter if (op32) { 384100384Speter sg = stackgap_init(); 385100384Speter op = stackgap_alloc(&sg, sizeof(struct sigaltstack)); 386107849Salfred uap->oss = (struct sigaltstack32 *)op; 387100384Speter } 388100384Speter error = sigaltstack(td, (struct sigaltstack_args *) uap); 389100384Speter if (error) 390100384Speter return (error); 391100384Speter if (op32) { 392100384Speter error = copyin(op, &s, sizeof(s)); 393100384Speter if (error) 394100384Speter return (error); 395100384Speter PTROUT_CP(s, s32, ss_sp); 396100384Speter CP(s, s32, ss_size); 397100384Speter CP(s, s32, ss_flags); 398100384Speter error = copyout(&s32, op32, sizeof(s32)); 399100384Speter } 400100384Speter return (error); 401100384Speter} 402100384Speter 403100384Speterint 404100384Speteria32_execve(struct thread *td, struct ia32_execve_args *uap) 405100384Speter{ 406100384Speter int error; 407100384Speter caddr_t sg; 408100384Speter struct execve_args ap; 409100384Speter u_int32_t *p32, arg; 410100384Speter char **p; 411100384Speter int count; 412100384Speter 413100384Speter sg = stackgap_init(); 414107849Salfred CHECKALTEXIST(td, &sg, uap->fname); 415107849Salfred ap.fname = uap->fname; 416100384Speter 417107849Salfred if (uap->argv) { 418100384Speter count = 0; 419107849Salfred p32 = uap->argv; 420100384Speter do { 421100384Speter error = copyin(p32++, &arg, sizeof(arg)); 422100384Speter if (error) 423100384Speter return error; 424100384Speter count++; 425100384Speter } while (arg != 0); 426100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 427107849Salfred ap.argv = p; 428107849Salfred p32 = uap->argv; 429100384Speter do { 430100384Speter error = copyin(p32++, &arg, sizeof(arg)); 431100384Speter if (error) 432100384Speter return error; 433100384Speter *p++ = PTRIN(arg); 434100384Speter } while (arg != 0); 435100384Speter } 436107849Salfred if (uap->envv) { 437100384Speter count = 0; 438107849Salfred p32 = uap->envv; 439100384Speter do { 440100384Speter error = copyin(p32++, &arg, sizeof(arg)); 441100384Speter if (error) 442100384Speter return error; 443100384Speter count++; 444100384Speter } while (arg != 0); 445100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 446107849Salfred ap.envv = p; 447107849Salfred p32 = uap->envv; 448100384Speter do { 449100384Speter error = copyin(p32++, &arg, sizeof(arg)); 450100384Speter if (error) 451100384Speter return error; 452100384Speter *p++ = PTRIN(arg); 453100384Speter } while (arg != 0); 454100384Speter } 455100384Speter 456100384Speter return execve(td, &ap); 457100384Speter} 458100384Speter 459100384Speterstatic int 460100384Speteria32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 461100384Speter int prot, int fd, off_t pos) 462100384Speter{ 463100384Speter vm_map_t map; 464100384Speter vm_map_entry_t entry; 465100384Speter int rv; 466100384Speter 467100384Speter map = &td->td_proc->p_vmspace->vm_map; 468100384Speter if (fd != -1) 469100384Speter prot |= VM_PROT_WRITE; 470100384Speter 471100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 472100384Speter if ((entry->protection & prot) != prot) { 473100384Speter rv = vm_map_protect(map, 474100384Speter trunc_page(start), 475100384Speter round_page(end), 476100384Speter entry->protection | prot, 477100384Speter FALSE); 478100384Speter if (rv != KERN_SUCCESS) 479100384Speter return (EINVAL); 480100384Speter } 481100384Speter } else { 482100384Speter vm_offset_t addr = trunc_page(start); 483100384Speter rv = vm_map_find(map, 0, 0, 484100384Speter &addr, PAGE_SIZE, FALSE, prot, 485100384Speter VM_PROT_ALL, 0); 486100384Speter if (rv != KERN_SUCCESS) 487100384Speter return (EINVAL); 488100384Speter } 489100384Speter 490100384Speter if (fd != -1) { 491100384Speter struct pread_args r; 492107849Salfred r.fd = fd; 493107849Salfred r.buf = (void *) start; 494107849Salfred r.nbyte = end - start; 495107849Salfred r.offset = pos; 496100384Speter return (pread(td, &r)); 497100384Speter } else { 498100384Speter while (start < end) { 499100384Speter subyte((void *) start, 0); 500100384Speter start++; 501100384Speter } 502100384Speter return (0); 503100384Speter } 504100384Speter} 505100384Speter 506100384Speterint 507100384Speteria32_mmap(struct thread *td, struct ia32_mmap_args *uap) 508100384Speter{ 509100384Speter struct mmap_args ap; 510107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 511107849Salfred vm_size_t len = uap->len; 512107849Salfred int prot = uap->prot; 513107849Salfred int flags = uap->flags; 514107849Salfred int fd = uap->fd; 515107849Salfred off_t pos = (uap->poslo 516107849Salfred | ((off_t)uap->poshi << 32)); 517100384Speter vm_size_t pageoff; 518100384Speter int error; 519100384Speter 520100384Speter /* 521100384Speter * Attempt to handle page size hassles. 522100384Speter */ 523100384Speter pageoff = (pos & PAGE_MASK); 524100384Speter if (flags & MAP_FIXED) { 525100384Speter vm_offset_t start, end; 526100384Speter start = addr; 527100384Speter end = addr + len; 528100384Speter 529100384Speter if (start != trunc_page(start)) { 530100384Speter error = ia32_mmap_partial(td, start, round_page(start), 531100384Speter prot, fd, pos); 532100384Speter if (fd != -1) 533100384Speter pos += round_page(start) - start; 534100384Speter start = round_page(start); 535100384Speter } 536100384Speter if (end != round_page(end)) { 537100384Speter vm_offset_t t = trunc_page(end); 538100384Speter error = ia32_mmap_partial(td, t, end, 539100384Speter prot, fd, 540100384Speter pos + t - start); 541100384Speter end = trunc_page(end); 542100384Speter } 543100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 544100384Speter /* 545100384Speter * We can't map this region at all. The specified 546100384Speter * address doesn't have the same alignment as the file 547100384Speter * position. Fake the mapping by simply reading the 548100384Speter * entire region into memory. First we need to make 549100384Speter * sure the region exists. 550100384Speter */ 551100384Speter vm_map_t map; 552100384Speter struct pread_args r; 553100384Speter int rv; 554100384Speter 555100384Speter prot |= VM_PROT_WRITE; 556100384Speter map = &td->td_proc->p_vmspace->vm_map; 557100384Speter rv = vm_map_remove(map, start, end); 558100384Speter if (rv != KERN_SUCCESS) 559100384Speter return (EINVAL); 560100384Speter rv = vm_map_find(map, 0, 0, 561100384Speter &start, end - start, FALSE, 562100384Speter prot, VM_PROT_ALL, 0); 563100384Speter if (rv != KERN_SUCCESS) 564100384Speter return (EINVAL); 565107849Salfred r.fd = fd; 566107849Salfred r.buf = (void *) start; 567107849Salfred r.nbyte = end - start; 568107849Salfred r.offset = pos; 569100384Speter error = pread(td, &r); 570100384Speter if (error) 571100384Speter return (error); 572100384Speter 573100384Speter td->td_retval[0] = addr; 574100384Speter return (0); 575100384Speter } 576100384Speter if (end == start) { 577100384Speter /* 578100384Speter * After dealing with the ragged ends, there 579100384Speter * might be none left. 580100384Speter */ 581100384Speter td->td_retval[0] = addr; 582100384Speter return (0); 583100384Speter } 584100384Speter addr = start; 585100384Speter len = end - start; 586100384Speter } 587100384Speter 588107849Salfred ap.addr = (void *) addr; 589107849Salfred ap.len = len; 590107849Salfred ap.prot = prot; 591107849Salfred ap.flags = flags; 592107849Salfred ap.fd = fd; 593107849Salfred ap.pos = pos; 594100384Speter 595100384Speter return (mmap(td, &ap)); 596100384Speter} 597100384Speter 598100384Speterstruct itimerval32 { 599100384Speter struct timeval32 it_interval; 600100384Speter struct timeval32 it_value; 601100384Speter}; 602100384Speter 603100384Speterint 604100384Speteria32_setitimer(struct thread *td, struct ia32_setitimer_args *uap) 605100384Speter{ 606100384Speter int error; 607100384Speter caddr_t sg; 608100384Speter struct itimerval32 *p32, *op32, s32; 609100384Speter struct itimerval *p = NULL, *op = NULL, s; 610100384Speter 611107849Salfred p32 = uap->itv; 612100384Speter if (p32) { 613100384Speter sg = stackgap_init(); 614100384Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 615107849Salfred uap->itv = (struct itimerval32 *)p; 616100384Speter error = copyin(p32, &s32, sizeof(s32)); 617100384Speter if (error) 618100384Speter return (error); 619100384Speter TV_CP(s32, s, it_interval); 620100384Speter TV_CP(s32, s, it_value); 621100384Speter error = copyout(&s, p, sizeof(s)); 622100384Speter if (error) 623100384Speter return (error); 624100384Speter } 625107849Salfred op32 = uap->oitv; 626100384Speter if (op32) { 627100384Speter sg = stackgap_init(); 628100384Speter op = stackgap_alloc(&sg, sizeof(struct itimerval)); 629107849Salfred uap->oitv = (struct itimerval32 *)op; 630100384Speter } 631100384Speter error = setitimer(td, (struct setitimer_args *) uap); 632100384Speter if (error) 633100384Speter return (error); 634100384Speter if (op32) { 635100384Speter error = copyin(op, &s, sizeof(s)); 636100384Speter if (error) 637100384Speter return (error); 638100384Speter TV_CP(s, s32, it_interval); 639100384Speter TV_CP(s, s32, it_value); 640100384Speter error = copyout(&s32, op32, sizeof(s32)); 641100384Speter } 642100384Speter return (error); 643100384Speter} 644100384Speter 645100384Speterint 646100384Speteria32_select(struct thread *td, struct ia32_select_args *uap) 647100384Speter{ 648100384Speter int error; 649100384Speter caddr_t sg; 650100384Speter struct timeval32 *p32, s32; 651100384Speter struct timeval *p = NULL, s; 652100384Speter 653107849Salfred p32 = uap->tv; 654100384Speter if (p32) { 655100384Speter sg = stackgap_init(); 656100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 657107849Salfred uap->tv = (struct timeval32 *)p; 658100384Speter error = copyin(p32, &s32, sizeof(s32)); 659100384Speter if (error) 660100384Speter return (error); 661100384Speter CP(s32, s, tv_sec); 662100384Speter CP(s32, s, tv_usec); 663100384Speter error = copyout(&s, p, sizeof(s)); 664100384Speter if (error) 665100384Speter return (error); 666100384Speter } 667100384Speter /* 668100384Speter * XXX big-endian needs to convert the fd_sets too. 669100384Speter */ 670100384Speter return (select(td, (struct select_args *) uap)); 671100384Speter} 672100384Speter 673100384Speterint 674100384Speteria32_gettimeofday(struct thread *td, struct ia32_gettimeofday_args *uap) 675100384Speter{ 676100384Speter int error; 677100384Speter caddr_t sg; 678100384Speter struct timeval32 *p32, s32; 679100384Speter struct timeval *p = NULL, s; 680100384Speter 681107849Salfred p32 = uap->tp; 682100384Speter if (p32) { 683100384Speter sg = stackgap_init(); 684100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 685107849Salfred uap->tp = (struct timeval32 *)p; 686100384Speter } 687100384Speter error = gettimeofday(td, (struct gettimeofday_args *) uap); 688100384Speter if (error) 689100384Speter return (error); 690100384Speter if (p32) { 691100384Speter error = copyin(p, &s, sizeof(s)); 692100384Speter if (error) 693100384Speter return (error); 694100384Speter CP(s, s32, tv_sec); 695100384Speter CP(s, s32, tv_usec); 696100384Speter error = copyout(&s32, p32, sizeof(s32)); 697100384Speter if (error) 698100384Speter return (error); 699100384Speter } 700100384Speter return (error); 701100384Speter} 702100384Speter 703100384Speterint 704100384Speteria32_getrusage(struct thread *td, struct ia32_getrusage_args *uap) 705100384Speter{ 706100384Speter int error; 707100384Speter caddr_t sg; 708100384Speter struct rusage32 *p32, s32; 709100384Speter struct rusage *p = NULL, s; 710100384Speter 711107849Salfred p32 = uap->rusage; 712100384Speter if (p32) { 713100384Speter sg = stackgap_init(); 714100384Speter p = stackgap_alloc(&sg, sizeof(struct rusage)); 715107849Salfred uap->rusage = (struct rusage32 *)p; 716100384Speter } 717100384Speter error = getrusage(td, (struct getrusage_args *) uap); 718100384Speter if (error) 719100384Speter return (error); 720100384Speter if (p32) { 721100384Speter error = copyin(p, &s, sizeof(s)); 722100384Speter if (error) 723100384Speter return (error); 724100384Speter TV_CP(s, s32, ru_utime); 725100384Speter TV_CP(s, s32, ru_stime); 726100384Speter CP(s, s32, ru_maxrss); 727100384Speter CP(s, s32, ru_ixrss); 728100384Speter CP(s, s32, ru_idrss); 729100384Speter CP(s, s32, ru_isrss); 730100384Speter CP(s, s32, ru_minflt); 731100384Speter CP(s, s32, ru_majflt); 732100384Speter CP(s, s32, ru_nswap); 733100384Speter CP(s, s32, ru_inblock); 734100384Speter CP(s, s32, ru_oublock); 735100384Speter CP(s, s32, ru_msgsnd); 736100384Speter CP(s, s32, ru_msgrcv); 737100384Speter CP(s, s32, ru_nsignals); 738100384Speter CP(s, s32, ru_nvcsw); 739100384Speter CP(s, s32, ru_nivcsw); 740100384Speter error = copyout(&s32, p32, sizeof(s32)); 741100384Speter } 742100384Speter return (error); 743100384Speter} 744100384Speter 745100384Speterstruct iovec32 { 746100384Speter u_int32_t iov_base; 747100384Speter int iov_len; 748100384Speter}; 749100384Speter#define STACKGAPLEN 400 750100384Speter 751100384Speterint 752100384Speteria32_readv(struct thread *td, struct ia32_readv_args *uap) 753100384Speter{ 754100384Speter int error, osize, nsize, i; 755100384Speter caddr_t sg; 756100384Speter struct readv_args /* { 757100384Speter syscallarg(int) fd; 758100384Speter syscallarg(struct iovec *) iovp; 759100384Speter syscallarg(u_int) iovcnt; 760100384Speter } */ a; 761100384Speter struct iovec32 *oio; 762100384Speter struct iovec *nio; 763100384Speter 764100384Speter sg = stackgap_init(); 765100384Speter 766107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 767100384Speter return (EINVAL); 768100384Speter 769107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 770107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 771100384Speter 772100384Speter oio = malloc(osize, M_TEMP, M_WAITOK); 773100384Speter nio = malloc(nsize, M_TEMP, M_WAITOK); 774100384Speter 775100384Speter error = 0; 776107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 777100384Speter goto punt; 778107849Salfred for (i = 0; i < uap->iovcnt; i++) { 779100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 780100384Speter nio[i].iov_len = oio[i].iov_len; 781100384Speter } 782100384Speter 783107849Salfred a.fd = uap->fd; 784107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 785107849Salfred a.iovcnt = uap->iovcnt; 786100384Speter 787107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 788100384Speter goto punt; 789100384Speter error = readv(td, &a); 790100384Speter 791100384Speterpunt: 792100384Speter free(oio, M_TEMP); 793100384Speter free(nio, M_TEMP); 794100384Speter return (error); 795100384Speter} 796100384Speter 797100384Speterint 798100384Speteria32_writev(struct thread *td, struct ia32_writev_args *uap) 799100384Speter{ 800100384Speter int error, i, nsize, osize; 801100384Speter caddr_t sg; 802100384Speter struct writev_args /* { 803100384Speter syscallarg(int) fd; 804100384Speter syscallarg(struct iovec *) iovp; 805100384Speter syscallarg(u_int) iovcnt; 806100384Speter } */ a; 807100384Speter struct iovec32 *oio; 808100384Speter struct iovec *nio; 809100384Speter 810100384Speter sg = stackgap_init(); 811100384Speter 812107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 813100384Speter return (EINVAL); 814100384Speter 815107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 816107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 817100384Speter 818100384Speter oio = malloc(osize, M_TEMP, M_WAITOK); 819100384Speter nio = malloc(nsize, M_TEMP, M_WAITOK); 820100384Speter 821100384Speter error = 0; 822107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 823100384Speter goto punt; 824107849Salfred for (i = 0; i < uap->iovcnt; i++) { 825100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 826100384Speter nio[i].iov_len = oio[i].iov_len; 827100384Speter } 828100384Speter 829107849Salfred a.fd = uap->fd; 830107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 831107849Salfred a.iovcnt = uap->iovcnt; 832100384Speter 833107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 834100384Speter goto punt; 835100384Speter error = writev(td, &a); 836100384Speter 837100384Speterpunt: 838100384Speter free(oio, M_TEMP); 839100384Speter free(nio, M_TEMP); 840100384Speter return (error); 841100384Speter} 842100384Speter 843100384Speterint 844100384Speteria32_settimeofday(struct thread *td, struct ia32_settimeofday_args *uap) 845100384Speter{ 846100384Speter int error; 847100384Speter caddr_t sg; 848100384Speter struct timeval32 *p32, s32; 849100384Speter struct timeval *p = NULL, s; 850100384Speter 851107849Salfred p32 = uap->tv; 852100384Speter if (p32) { 853100384Speter sg = stackgap_init(); 854100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 855107849Salfred uap->tv = (struct timeval32 *)p; 856100384Speter error = copyin(p32, &s32, sizeof(s32)); 857100384Speter if (error) 858100384Speter return (error); 859100384Speter CP(s32, s, tv_sec); 860100384Speter CP(s32, s, tv_usec); 861100384Speter error = copyout(&s, p, sizeof(s)); 862100384Speter if (error) 863100384Speter return (error); 864100384Speter } 865100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 866100384Speter} 867100384Speter 868100384Speterint 869100384Speteria32_utimes(struct thread *td, struct ia32_utimes_args *uap) 870100384Speter{ 871100384Speter int error; 872100384Speter caddr_t sg; 873100384Speter struct timeval32 *p32, s32[2]; 874100384Speter struct timeval *p = NULL, s[2]; 875100384Speter 876107849Salfred p32 = uap->tptr; 877100384Speter if (p32) { 878100384Speter sg = stackgap_init(); 879100384Speter p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 880107849Salfred uap->tptr = (struct timeval32 *)p; 881100384Speter error = copyin(p32, s32, sizeof(s32)); 882100384Speter if (error) 883100384Speter return (error); 884100384Speter CP(s32[0], s[0], tv_sec); 885100384Speter CP(s32[0], s[0], tv_usec); 886100384Speter CP(s32[1], s[1], tv_sec); 887100384Speter CP(s32[1], s[1], tv_usec); 888100384Speter error = copyout(s, p, sizeof(s)); 889100384Speter if (error) 890100384Speter return (error); 891100384Speter } 892100384Speter return (utimes(td, (struct utimes_args *) uap)); 893100384Speter} 894100384Speter 895100384Speterint 896100384Speteria32_adjtime(struct thread *td, struct ia32_adjtime_args *uap) 897100384Speter{ 898100384Speter int error; 899100384Speter caddr_t sg; 900100384Speter struct timeval32 *p32, *op32, s32; 901100384Speter struct timeval *p = NULL, *op = NULL, s; 902100384Speter 903107849Salfred p32 = uap->delta; 904100384Speter if (p32) { 905100384Speter sg = stackgap_init(); 906100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 907107849Salfred uap->delta = (struct timeval32 *)p; 908100384Speter error = copyin(p32, &s32, sizeof(s32)); 909100384Speter if (error) 910100384Speter return (error); 911100384Speter CP(s32, s, tv_sec); 912100384Speter CP(s32, s, tv_usec); 913100384Speter error = copyout(&s, p, sizeof(s)); 914100384Speter if (error) 915100384Speter return (error); 916100384Speter } 917107849Salfred op32 = uap->olddelta; 918100384Speter if (op32) { 919100384Speter sg = stackgap_init(); 920100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 921107849Salfred uap->olddelta = (struct timeval32 *)op; 922100384Speter } 923100384Speter error = utimes(td, (struct utimes_args *) uap); 924100384Speter if (error) 925100384Speter return error; 926100384Speter if (op32) { 927100384Speter error = copyin(op, &s, sizeof(s)); 928100384Speter if (error) 929100384Speter return (error); 930100384Speter CP(s, s32, tv_sec); 931100384Speter CP(s, s32, tv_usec); 932100384Speter error = copyout(&s32, op32, sizeof(s32)); 933100384Speter } 934100384Speter return (error); 935100384Speter} 936100384Speter 937100384Speterint 938100384Speteria32_statfs(struct thread *td, struct ia32_statfs_args *uap) 939100384Speter{ 940100384Speter int error; 941100384Speter caddr_t sg; 942100384Speter struct statfs32 *p32, s32; 943100384Speter struct statfs *p = NULL, s; 944100384Speter 945107849Salfred p32 = uap->buf; 946100384Speter if (p32) { 947100384Speter sg = stackgap_init(); 948100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 949107849Salfred uap->buf = (struct statfs32 *)p; 950100384Speter } 951100384Speter error = statfs(td, (struct statfs_args *) uap); 952100384Speter if (error) 953100384Speter return (error); 954100384Speter if (p32) { 955100384Speter error = copyin(p, &s, sizeof(s)); 956100384Speter if (error) 957100384Speter return (error); 958100384Speter copy_statfs(&s, &s32); 959100384Speter error = copyout(&s32, p32, sizeof(s32)); 960100384Speter } 961100384Speter return (error); 962100384Speter} 963100384Speter 964100384Speterint 965100384Speteria32_fstatfs(struct thread *td, struct ia32_fstatfs_args *uap) 966100384Speter{ 967100384Speter int error; 968100384Speter caddr_t sg; 969100384Speter struct statfs32 *p32, s32; 970100384Speter struct statfs *p = NULL, s; 971100384Speter 972107849Salfred p32 = uap->buf; 973100384Speter if (p32) { 974100384Speter sg = stackgap_init(); 975100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 976107849Salfred uap->buf = (struct statfs32 *)p; 977100384Speter } 978100384Speter error = fstatfs(td, (struct fstatfs_args *) uap); 979100384Speter if (error) 980100384Speter return (error); 981100384Speter if (p32) { 982100384Speter error = copyin(p, &s, sizeof(s)); 983100384Speter if (error) 984100384Speter return (error); 985100384Speter copy_statfs(&s, &s32); 986100384Speter error = copyout(&s32, p32, sizeof(s32)); 987100384Speter } 988100384Speter return (error); 989100384Speter} 990100384Speter 991100384Speterint 992100384Speteria32_semsys(struct thread *td, struct ia32_semsys_args *uap) 993100384Speter{ 994100384Speter /* 995100384Speter * Vector through to semsys if it is loaded. 996100384Speter */ 997100384Speter return sysent[169].sy_call(td, uap); 998100384Speter} 999100384Speter 1000100384Speterint 1001100384Speteria32_msgsys(struct thread *td, struct ia32_msgsys_args *uap) 1002100384Speter{ 1003100384Speter /* 1004100384Speter * Vector through to msgsys if it is loaded. 1005100384Speter */ 1006100384Speter return sysent[170].sy_call(td, uap); 1007100384Speter} 1008100384Speter 1009100384Speterint 1010100384Speteria32_shmsys(struct thread *td, struct ia32_shmsys_args *uap) 1011100384Speter{ 1012100384Speter /* 1013100384Speter * Vector through to shmsys if it is loaded. 1014100384Speter */ 1015100384Speter return sysent[171].sy_call(td, uap); 1016100384Speter} 1017100384Speter 1018100384Speterint 1019100384Speteria32_pread(struct thread *td, struct ia32_pread_args *uap) 1020100384Speter{ 1021100384Speter struct pread_args ap; 1022100384Speter 1023107849Salfred ap.fd = uap->fd; 1024107849Salfred ap.buf = uap->buf; 1025107849Salfred ap.nbyte = uap->nbyte; 1026107849Salfred ap.offset = (uap->offsetlo 1027107849Salfred | ((off_t)uap->offsethi << 32)); 1028100384Speter return (pread(td, &ap)); 1029100384Speter} 1030100384Speter 1031100384Speterint 1032100384Speteria32_pwrite(struct thread *td, struct ia32_pwrite_args *uap) 1033100384Speter{ 1034100384Speter struct pwrite_args ap; 1035100384Speter 1036107849Salfred ap.fd = uap->fd; 1037107849Salfred ap.buf = uap->buf; 1038107849Salfred ap.nbyte = uap->nbyte; 1039107849Salfred ap.offset = (uap->offsetlo 1040107849Salfred | ((off_t)uap->offsethi << 32)); 1041100384Speter return (pwrite(td, &ap)); 1042100384Speter} 1043100384Speter 1044100384Speterint 1045100384Speteria32_lseek(struct thread *td, struct ia32_lseek_args *uap) 1046100384Speter{ 1047100384Speter int error; 1048100384Speter struct lseek_args ap; 1049100384Speter off_t pos; 1050100384Speter 1051107849Salfred ap.fd = uap->fd; 1052107849Salfred ap.offset = (uap->offsetlo 1053107849Salfred | ((off_t)uap->offsethi << 32)); 1054107849Salfred ap.whence = uap->whence; 1055100384Speter error = lseek(td, &ap); 1056100384Speter /* Expand the quad return into two parts for eax and edx */ 1057100384Speter pos = *(off_t *)(td->td_retval); 1058100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1059100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1060100384Speter return error; 1061100384Speter} 1062100384Speter 1063100384Speterint 1064100384Speteria32_truncate(struct thread *td, struct ia32_truncate_args *uap) 1065100384Speter{ 1066100384Speter struct truncate_args ap; 1067100384Speter 1068107849Salfred ap.path = uap->path; 1069107849Salfred ap.length = (uap->lengthlo 1070107849Salfred | ((off_t)uap->lengthhi << 32)); 1071100384Speter return (truncate(td, &ap)); 1072100384Speter} 1073100384Speter 1074100384Speterint 1075100384Speteria32_ftruncate(struct thread *td, struct ia32_ftruncate_args *uap) 1076100384Speter{ 1077100384Speter struct ftruncate_args ap; 1078100384Speter 1079107849Salfred ap.fd = uap->fd; 1080107849Salfred ap.length = (uap->lengthlo 1081107849Salfred | ((off_t)uap->lengthhi << 32)); 1082100384Speter return (ftruncate(td, &ap)); 1083100384Speter} 1084100384Speter 1085104738Speter#ifdef COMPAT_FREEBSD4 1086100384Speterint 1087104738Speterfreebsd4_ia32_sendfile(struct thread *td, 1088104738Speter struct freebsd4_ia32_sendfile_args *uap) 1089104738Speter{ 1090104738Speter struct freebsd4_sendfile_args ap; 1091104738Speter 1092107849Salfred ap.fd = uap->fd; 1093107849Salfred ap.s = uap->s; 1094107849Salfred ap.offset = (uap->offsetlo 1095107849Salfred | ((off_t)uap->offsethi << 32)); 1096107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1097107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1098107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1099107849Salfred ap.flags = uap->flags; 1100104738Speter return (freebsd4_sendfile(td, &ap)); 1101104738Speter} 1102104738Speter#endif 1103104738Speter 1104104738Speterint 1105100384Speteria32_sendfile(struct thread *td, struct ia32_sendfile_args *uap) 1106100384Speter{ 1107100384Speter struct sendfile_args ap; 1108100384Speter 1109107849Salfred ap.fd = uap->fd; 1110107849Salfred ap.s = uap->s; 1111107849Salfred ap.offset = (uap->offsetlo 1112107849Salfred | ((off_t)uap->offsethi << 32)); 1113107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1114107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1115107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1116107849Salfred ap.flags = uap->flags; 1117100384Speter return (sendfile(td, &ap)); 1118100384Speter} 1119100384Speter 1120100384Speterstruct stat32 { 1121100384Speter udev_t st_dev; 1122100384Speter ino_t st_ino; 1123100384Speter mode_t st_mode; 1124100384Speter nlink_t st_nlink; 1125100384Speter uid_t st_uid; 1126100384Speter gid_t st_gid; 1127100384Speter udev_t st_rdev; 1128100384Speter struct timespec32 st_atimespec; 1129100384Speter struct timespec32 st_mtimespec; 1130100384Speter struct timespec32 st_ctimespec; 1131100384Speter off_t st_size; 1132100384Speter int64_t st_blocks; 1133100384Speter u_int32_t st_blksize; 1134100384Speter u_int32_t st_flags; 1135100384Speter u_int32_t st_gen; 1136100384Speter}; 1137100384Speter 1138100384Speterstatic void 1139100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1140100384Speter{ 1141100384Speter CP(*in, *out, st_dev); 1142100384Speter CP(*in, *out, st_ino); 1143100384Speter CP(*in, *out, st_mode); 1144100384Speter CP(*in, *out, st_nlink); 1145100384Speter CP(*in, *out, st_uid); 1146100384Speter CP(*in, *out, st_gid); 1147100384Speter CP(*in, *out, st_rdev); 1148100384Speter TS_CP(*in, *out, st_atimespec); 1149100384Speter TS_CP(*in, *out, st_mtimespec); 1150100384Speter TS_CP(*in, *out, st_ctimespec); 1151100384Speter CP(*in, *out, st_size); 1152100384Speter CP(*in, *out, st_blocks); 1153100384Speter CP(*in, *out, st_blksize); 1154100384Speter CP(*in, *out, st_flags); 1155100384Speter CP(*in, *out, st_gen); 1156100384Speter} 1157100384Speter 1158100384Speterint 1159100384Speteria32_stat(struct thread *td, struct ia32_stat_args *uap) 1160100384Speter{ 1161100384Speter int error; 1162100384Speter caddr_t sg; 1163100384Speter struct stat32 *p32, s32; 1164100384Speter struct stat *p = NULL, s; 1165100384Speter 1166107849Salfred p32 = uap->ub; 1167100384Speter if (p32) { 1168100384Speter sg = stackgap_init(); 1169100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1170107849Salfred uap->ub = (struct stat32 *)p; 1171100384Speter } 1172100384Speter error = stat(td, (struct stat_args *) uap); 1173100384Speter if (error) 1174100384Speter return (error); 1175100384Speter if (p32) { 1176100384Speter error = copyin(p, &s, sizeof(s)); 1177100384Speter if (error) 1178100384Speter return (error); 1179100384Speter copy_stat(&s, &s32); 1180100384Speter error = copyout(&s32, p32, sizeof(s32)); 1181100384Speter } 1182100384Speter return (error); 1183100384Speter} 1184100384Speter 1185100384Speterint 1186100384Speteria32_fstat(struct thread *td, struct ia32_fstat_args *uap) 1187100384Speter{ 1188100384Speter int error; 1189100384Speter caddr_t sg; 1190100384Speter struct stat32 *p32, s32; 1191100384Speter struct stat *p = NULL, s; 1192100384Speter 1193107849Salfred p32 = uap->ub; 1194100384Speter if (p32) { 1195100384Speter sg = stackgap_init(); 1196100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1197107849Salfred uap->ub = (struct stat32 *)p; 1198100384Speter } 1199100384Speter error = fstat(td, (struct fstat_args *) uap); 1200100384Speter if (error) 1201100384Speter return (error); 1202100384Speter if (p32) { 1203100384Speter error = copyin(p, &s, sizeof(s)); 1204100384Speter if (error) 1205100384Speter return (error); 1206100384Speter copy_stat(&s, &s32); 1207100384Speter error = copyout(&s32, p32, sizeof(s32)); 1208100384Speter } 1209100384Speter return (error); 1210100384Speter} 1211100384Speter 1212100384Speterint 1213100384Speteria32_lstat(struct thread *td, struct ia32_lstat_args *uap) 1214100384Speter{ 1215100384Speter int error; 1216100384Speter caddr_t sg; 1217100384Speter struct stat32 *p32, s32; 1218100384Speter struct stat *p = NULL, s; 1219100384Speter 1220107849Salfred p32 = uap->ub; 1221100384Speter if (p32) { 1222100384Speter sg = stackgap_init(); 1223100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1224107849Salfred uap->ub = (struct stat32 *)p; 1225100384Speter } 1226100384Speter error = lstat(td, (struct lstat_args *) uap); 1227100384Speter if (error) 1228100384Speter return (error); 1229100384Speter if (p32) { 1230100384Speter error = copyin(p, &s, sizeof(s)); 1231100384Speter if (error) 1232100384Speter return (error); 1233100384Speter copy_stat(&s, &s32); 1234100384Speter error = copyout(&s32, p32, sizeof(s32)); 1235100384Speter } 1236100384Speter return (error); 1237100384Speter} 1238100384Speter 1239100384Speter/* 1240100384Speter * MPSAFE 1241100384Speter */ 1242100384Speterint 1243100384Speteria32_sysctl(struct thread *td, struct ia32_sysctl_args *uap) 1244100384Speter{ 1245100384Speter int error, name[CTL_MAXNAME]; 1246100384Speter size_t j, oldlen; 1247100384Speter 1248100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1249100384Speter return (EINVAL); 1250100384Speter 1251100384Speter error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1252100384Speter if (error) 1253100384Speter return (error); 1254100384Speter 1255100384Speter mtx_lock(&Giant); 1256100384Speter 1257100384Speter if (uap->oldlenp) 1258100384Speter oldlen = fuword32(uap->oldlenp); 1259100384Speter else 1260100384Speter oldlen = 0; 1261100384Speter error = userland_sysctl(td, name, uap->namelen, 1262100384Speter uap->old, &oldlen, 1, 1263100384Speter uap->new, uap->newlen, &j); 1264100384Speter if (error && error != ENOMEM) 1265100384Speter goto done2; 1266100384Speter if (uap->oldlenp) { 1267100384Speter suword32(uap->oldlenp, j); 1268100384Speter } 1269100384Speterdone2: 1270100384Speter mtx_unlock(&Giant); 1271100384Speter return (error); 1272100384Speter} 1273100384Speter 1274100384Speterstruct sigaction32 { 1275100384Speter u_int32_t sa_u; 1276100384Speter int sa_flags; 1277100384Speter sigset_t sa_mask; 1278100384Speter}; 1279100384Speter 1280100384Speterint 1281100384Speteria32_sigaction(struct thread *td, struct ia32_sigaction_args *uap) 1282100384Speter{ 1283100384Speter int error; 1284100384Speter caddr_t sg; 1285100384Speter struct sigaction32 *p32, *op32, s32; 1286100384Speter struct sigaction *p = NULL, *op = NULL, s; 1287100384Speter 1288107849Salfred p32 = uap->act; 1289100384Speter if (p32) { 1290100384Speter sg = stackgap_init(); 1291100384Speter p = stackgap_alloc(&sg, sizeof(struct sigaction)); 1292107849Salfred uap->act = (struct sigaction32 *)p; 1293100384Speter error = copyin(p32, &s32, sizeof(s32)); 1294100384Speter if (error) 1295100384Speter return (error); 1296100384Speter s.sa_handler = PTRIN(s32.sa_u); 1297100384Speter CP(s32, s, sa_flags); 1298100384Speter CP(s32, s, sa_mask); 1299100384Speter error = copyout(&s, p, sizeof(s)); 1300100384Speter if (error) 1301100384Speter return (error); 1302100384Speter } 1303107849Salfred op32 = uap->oact; 1304100384Speter if (op32) { 1305100384Speter sg = stackgap_init(); 1306100384Speter op = stackgap_alloc(&sg, sizeof(struct sigaction)); 1307107849Salfred uap->oact = (struct sigaction32 *)op; 1308100384Speter } 1309100384Speter error = sigaction(td, (struct sigaction_args *) uap); 1310100384Speter if (error) 1311100384Speter return (error); 1312100384Speter if (op32) { 1313100384Speter error = copyin(op, &s, sizeof(s)); 1314100384Speter if (error) 1315100384Speter return (error); 1316100384Speter s32.sa_u = PTROUT(s.sa_handler); 1317100384Speter CP(s, s32, sa_flags); 1318100384Speter CP(s, s32, sa_mask); 1319100384Speter error = copyout(&s32, op32, sizeof(s32)); 1320100384Speter } 1321100384Speter return (error); 1322100384Speter} 1323100384Speter 1324100384Speter#if 0 1325100384Speter 1326100384Speterint 1327100384Speteria32_xxx(struct thread *td, struct ia32_xxx_args *uap) 1328100384Speter{ 1329100384Speter int error; 1330100384Speter caddr_t sg; 1331100384Speter struct yyy32 *p32, s32; 1332100384Speter struct yyy *p = NULL, s; 1333100384Speter 1334107849Salfred p32 = uap->zzz; 1335100384Speter if (p32) { 1336100384Speter sg = stackgap_init(); 1337100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1338107849Salfred uap->zzz = (struct yyy32 *)p; 1339100384Speter error = copyin(p32, &s32, sizeof(s32)); 1340100384Speter if (error) 1341100384Speter return (error); 1342100384Speter /* translate in */ 1343100384Speter error = copyout(&s, p, sizeof(s)); 1344100384Speter if (error) 1345100384Speter return (error); 1346100384Speter } 1347100384Speter error = xxx(td, (struct xxx_args *) uap); 1348100384Speter if (error) 1349100384Speter return (error); 1350100384Speter if (p32) { 1351100384Speter error = copyin(p, &s, sizeof(s)); 1352100384Speter if (error) 1353100384Speter return (error); 1354100384Speter /* translate out */ 1355100384Speter error = copyout(&s32, p32, sizeof(s32)); 1356100384Speter } 1357100384Speter return (error); 1358100384Speter} 1359100384Speter 1360100384Speter#endif 1361