freebsd32_misc.c revision 113859
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 113859 2003-04-22 18:23:49Z jhb $ 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/exec.h> 35100384Speter#include <sys/fcntl.h> 36100384Speter#include <sys/filedesc.h> 37100384Speter#include <sys/imgact.h> 38100384Speter#include <sys/kernel.h> 39100384Speter#include <sys/lock.h> 40100384Speter#include <sys/malloc.h> 41100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 42100384Speter#include <sys/mman.h> 43100384Speter#include <sys/module.h> 44100384Speter#include <sys/mount.h> 45100384Speter#include <sys/mutex.h> 46100384Speter#include <sys/namei.h> 47100384Speter#include <sys/param.h> 48100384Speter#include <sys/proc.h> 49100384Speter#include <sys/reboot.h> 50100384Speter#include <sys/resource.h> 51100384Speter#include <sys/resourcevar.h> 52100384Speter#include <sys/selinfo.h> 53100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 54100384Speter#include <sys/signal.h> 55100384Speter#include <sys/signalvar.h> 56100384Speter#include <sys/socket.h> 57100384Speter#include <sys/socketvar.h> 58100384Speter#include <sys/stat.h> 59113859Sjhb#include <sys/syscallsubr.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 109111119Simp 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{ 362113859Sjhb struct sigaltstack32 s32; 363113859Sjhb struct sigaltstack ss, oss, *ssp; 364100384Speter int error; 365100384Speter 366113859Sjhb if (uap->ss != NULL) { 367113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 368100384Speter if (error) 369100384Speter return (error); 370113859Sjhb PTRIN_CP(s32, ss, ss_sp); 371113859Sjhb CP(s32, ss, ss_size); 372113859Sjhb CP(s32, ss, ss_flags); 373113859Sjhb ssp = &ss; 374113859Sjhb } else 375113859Sjhb ssp = NULL; 376113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 377113859Sjhb if (error == 0 && uap->oss != NULL) { 378113859Sjhb PTROUT_CP(oss, s32, ss_sp); 379113859Sjhb CP(oss, s32, ss_size); 380113859Sjhb CP(oss, s32, ss_flags); 381113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 382100384Speter } 383100384Speter return (error); 384100384Speter} 385100384Speter 386100384Speterint 387100384Speteria32_execve(struct thread *td, struct ia32_execve_args *uap) 388100384Speter{ 389100384Speter int error; 390100384Speter caddr_t sg; 391100384Speter struct execve_args ap; 392100384Speter u_int32_t *p32, arg; 393100384Speter char **p; 394100384Speter int count; 395100384Speter 396100384Speter sg = stackgap_init(); 397107849Salfred CHECKALTEXIST(td, &sg, uap->fname); 398107849Salfred ap.fname = uap->fname; 399100384Speter 400107849Salfred if (uap->argv) { 401100384Speter count = 0; 402107849Salfred p32 = uap->argv; 403100384Speter do { 404100384Speter error = copyin(p32++, &arg, sizeof(arg)); 405100384Speter if (error) 406100384Speter return error; 407100384Speter count++; 408100384Speter } while (arg != 0); 409100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 410107849Salfred ap.argv = p; 411107849Salfred p32 = uap->argv; 412100384Speter do { 413100384Speter error = copyin(p32++, &arg, sizeof(arg)); 414100384Speter if (error) 415100384Speter return error; 416100384Speter *p++ = PTRIN(arg); 417100384Speter } while (arg != 0); 418100384Speter } 419107849Salfred if (uap->envv) { 420100384Speter count = 0; 421107849Salfred p32 = uap->envv; 422100384Speter do { 423100384Speter error = copyin(p32++, &arg, sizeof(arg)); 424100384Speter if (error) 425100384Speter return error; 426100384Speter count++; 427100384Speter } while (arg != 0); 428100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 429107849Salfred ap.envv = p; 430107849Salfred p32 = uap->envv; 431100384Speter do { 432100384Speter error = copyin(p32++, &arg, sizeof(arg)); 433100384Speter if (error) 434100384Speter return error; 435100384Speter *p++ = PTRIN(arg); 436100384Speter } while (arg != 0); 437100384Speter } 438100384Speter 439100384Speter return execve(td, &ap); 440100384Speter} 441100384Speter 442100384Speterstatic int 443100384Speteria32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 444100384Speter int prot, int fd, off_t pos) 445100384Speter{ 446100384Speter vm_map_t map; 447100384Speter vm_map_entry_t entry; 448100384Speter int rv; 449100384Speter 450100384Speter map = &td->td_proc->p_vmspace->vm_map; 451100384Speter if (fd != -1) 452100384Speter prot |= VM_PROT_WRITE; 453100384Speter 454100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 455100384Speter if ((entry->protection & prot) != prot) { 456100384Speter rv = vm_map_protect(map, 457100384Speter trunc_page(start), 458100384Speter round_page(end), 459100384Speter entry->protection | prot, 460100384Speter FALSE); 461100384Speter if (rv != KERN_SUCCESS) 462100384Speter return (EINVAL); 463100384Speter } 464100384Speter } else { 465100384Speter vm_offset_t addr = trunc_page(start); 466100384Speter rv = vm_map_find(map, 0, 0, 467100384Speter &addr, PAGE_SIZE, FALSE, prot, 468100384Speter VM_PROT_ALL, 0); 469100384Speter if (rv != KERN_SUCCESS) 470100384Speter return (EINVAL); 471100384Speter } 472100384Speter 473100384Speter if (fd != -1) { 474100384Speter struct pread_args r; 475107849Salfred r.fd = fd; 476107849Salfred r.buf = (void *) start; 477107849Salfred r.nbyte = end - start; 478107849Salfred r.offset = pos; 479100384Speter return (pread(td, &r)); 480100384Speter } else { 481100384Speter while (start < end) { 482100384Speter subyte((void *) start, 0); 483100384Speter start++; 484100384Speter } 485100384Speter return (0); 486100384Speter } 487100384Speter} 488100384Speter 489100384Speterint 490100384Speteria32_mmap(struct thread *td, struct ia32_mmap_args *uap) 491100384Speter{ 492100384Speter struct mmap_args ap; 493107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 494107849Salfred vm_size_t len = uap->len; 495107849Salfred int prot = uap->prot; 496107849Salfred int flags = uap->flags; 497107849Salfred int fd = uap->fd; 498107849Salfred off_t pos = (uap->poslo 499107849Salfred | ((off_t)uap->poshi << 32)); 500100384Speter vm_size_t pageoff; 501100384Speter int error; 502100384Speter 503100384Speter /* 504100384Speter * Attempt to handle page size hassles. 505100384Speter */ 506100384Speter pageoff = (pos & PAGE_MASK); 507100384Speter if (flags & MAP_FIXED) { 508100384Speter vm_offset_t start, end; 509100384Speter start = addr; 510100384Speter end = addr + len; 511100384Speter 512100384Speter if (start != trunc_page(start)) { 513100384Speter error = ia32_mmap_partial(td, start, round_page(start), 514100384Speter prot, fd, pos); 515100384Speter if (fd != -1) 516100384Speter pos += round_page(start) - start; 517100384Speter start = round_page(start); 518100384Speter } 519100384Speter if (end != round_page(end)) { 520100384Speter vm_offset_t t = trunc_page(end); 521100384Speter error = ia32_mmap_partial(td, t, end, 522100384Speter prot, fd, 523100384Speter pos + t - start); 524100384Speter end = trunc_page(end); 525100384Speter } 526100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 527100384Speter /* 528100384Speter * We can't map this region at all. The specified 529100384Speter * address doesn't have the same alignment as the file 530100384Speter * position. Fake the mapping by simply reading the 531100384Speter * entire region into memory. First we need to make 532100384Speter * sure the region exists. 533100384Speter */ 534100384Speter vm_map_t map; 535100384Speter struct pread_args r; 536100384Speter int rv; 537100384Speter 538100384Speter prot |= VM_PROT_WRITE; 539100384Speter map = &td->td_proc->p_vmspace->vm_map; 540100384Speter rv = vm_map_remove(map, start, end); 541100384Speter if (rv != KERN_SUCCESS) 542100384Speter return (EINVAL); 543100384Speter rv = vm_map_find(map, 0, 0, 544100384Speter &start, end - start, FALSE, 545100384Speter prot, VM_PROT_ALL, 0); 546100384Speter if (rv != KERN_SUCCESS) 547100384Speter return (EINVAL); 548107849Salfred r.fd = fd; 549107849Salfred r.buf = (void *) start; 550107849Salfred r.nbyte = end - start; 551107849Salfred r.offset = pos; 552100384Speter error = pread(td, &r); 553100384Speter if (error) 554100384Speter return (error); 555100384Speter 556100384Speter td->td_retval[0] = addr; 557100384Speter return (0); 558100384Speter } 559100384Speter if (end == start) { 560100384Speter /* 561100384Speter * After dealing with the ragged ends, there 562100384Speter * might be none left. 563100384Speter */ 564100384Speter td->td_retval[0] = addr; 565100384Speter return (0); 566100384Speter } 567100384Speter addr = start; 568100384Speter len = end - start; 569100384Speter } 570100384Speter 571107849Salfred ap.addr = (void *) addr; 572107849Salfred ap.len = len; 573107849Salfred ap.prot = prot; 574107849Salfred ap.flags = flags; 575107849Salfred ap.fd = fd; 576107849Salfred ap.pos = pos; 577100384Speter 578100384Speter return (mmap(td, &ap)); 579100384Speter} 580100384Speter 581100384Speterstruct itimerval32 { 582100384Speter struct timeval32 it_interval; 583100384Speter struct timeval32 it_value; 584100384Speter}; 585100384Speter 586100384Speterint 587100384Speteria32_setitimer(struct thread *td, struct ia32_setitimer_args *uap) 588100384Speter{ 589100384Speter int error; 590100384Speter caddr_t sg; 591100384Speter struct itimerval32 *p32, *op32, s32; 592100384Speter struct itimerval *p = NULL, *op = NULL, s; 593100384Speter 594107849Salfred p32 = uap->itv; 595100384Speter if (p32) { 596100384Speter sg = stackgap_init(); 597100384Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 598107849Salfred uap->itv = (struct itimerval32 *)p; 599100384Speter error = copyin(p32, &s32, sizeof(s32)); 600100384Speter if (error) 601100384Speter return (error); 602100384Speter TV_CP(s32, s, it_interval); 603100384Speter TV_CP(s32, s, it_value); 604100384Speter error = copyout(&s, p, sizeof(s)); 605100384Speter if (error) 606100384Speter return (error); 607100384Speter } 608107849Salfred op32 = uap->oitv; 609100384Speter if (op32) { 610100384Speter sg = stackgap_init(); 611100384Speter op = stackgap_alloc(&sg, sizeof(struct itimerval)); 612107849Salfred uap->oitv = (struct itimerval32 *)op; 613100384Speter } 614100384Speter error = setitimer(td, (struct setitimer_args *) uap); 615100384Speter if (error) 616100384Speter return (error); 617100384Speter if (op32) { 618100384Speter error = copyin(op, &s, sizeof(s)); 619100384Speter if (error) 620100384Speter return (error); 621100384Speter TV_CP(s, s32, it_interval); 622100384Speter TV_CP(s, s32, it_value); 623100384Speter error = copyout(&s32, op32, sizeof(s32)); 624100384Speter } 625100384Speter return (error); 626100384Speter} 627100384Speter 628100384Speterint 629100384Speteria32_select(struct thread *td, struct ia32_select_args *uap) 630100384Speter{ 631100384Speter int error; 632100384Speter caddr_t sg; 633100384Speter struct timeval32 *p32, s32; 634100384Speter struct timeval *p = NULL, s; 635100384Speter 636107849Salfred p32 = uap->tv; 637100384Speter if (p32) { 638100384Speter sg = stackgap_init(); 639100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 640107849Salfred uap->tv = (struct timeval32 *)p; 641100384Speter error = copyin(p32, &s32, sizeof(s32)); 642100384Speter if (error) 643100384Speter return (error); 644100384Speter CP(s32, s, tv_sec); 645100384Speter CP(s32, s, tv_usec); 646100384Speter error = copyout(&s, p, sizeof(s)); 647100384Speter if (error) 648100384Speter return (error); 649100384Speter } 650100384Speter /* 651100384Speter * XXX big-endian needs to convert the fd_sets too. 652100384Speter */ 653100384Speter return (select(td, (struct select_args *) uap)); 654100384Speter} 655100384Speter 656100384Speterint 657100384Speteria32_gettimeofday(struct thread *td, struct ia32_gettimeofday_args *uap) 658100384Speter{ 659100384Speter int error; 660100384Speter caddr_t sg; 661100384Speter struct timeval32 *p32, s32; 662100384Speter struct timeval *p = NULL, s; 663100384Speter 664107849Salfred p32 = uap->tp; 665100384Speter if (p32) { 666100384Speter sg = stackgap_init(); 667100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 668107849Salfred uap->tp = (struct timeval32 *)p; 669100384Speter } 670100384Speter error = gettimeofday(td, (struct gettimeofday_args *) uap); 671100384Speter if (error) 672100384Speter return (error); 673100384Speter if (p32) { 674100384Speter error = copyin(p, &s, sizeof(s)); 675100384Speter if (error) 676100384Speter return (error); 677100384Speter CP(s, s32, tv_sec); 678100384Speter CP(s, s32, tv_usec); 679100384Speter error = copyout(&s32, p32, sizeof(s32)); 680100384Speter if (error) 681100384Speter return (error); 682100384Speter } 683100384Speter return (error); 684100384Speter} 685100384Speter 686100384Speterint 687100384Speteria32_getrusage(struct thread *td, struct ia32_getrusage_args *uap) 688100384Speter{ 689100384Speter int error; 690100384Speter caddr_t sg; 691100384Speter struct rusage32 *p32, s32; 692100384Speter struct rusage *p = NULL, s; 693100384Speter 694107849Salfred p32 = uap->rusage; 695100384Speter if (p32) { 696100384Speter sg = stackgap_init(); 697100384Speter p = stackgap_alloc(&sg, sizeof(struct rusage)); 698107849Salfred uap->rusage = (struct rusage32 *)p; 699100384Speter } 700100384Speter error = getrusage(td, (struct getrusage_args *) uap); 701100384Speter if (error) 702100384Speter return (error); 703100384Speter if (p32) { 704100384Speter error = copyin(p, &s, sizeof(s)); 705100384Speter if (error) 706100384Speter return (error); 707100384Speter TV_CP(s, s32, ru_utime); 708100384Speter TV_CP(s, s32, ru_stime); 709100384Speter CP(s, s32, ru_maxrss); 710100384Speter CP(s, s32, ru_ixrss); 711100384Speter CP(s, s32, ru_idrss); 712100384Speter CP(s, s32, ru_isrss); 713100384Speter CP(s, s32, ru_minflt); 714100384Speter CP(s, s32, ru_majflt); 715100384Speter CP(s, s32, ru_nswap); 716100384Speter CP(s, s32, ru_inblock); 717100384Speter CP(s, s32, ru_oublock); 718100384Speter CP(s, s32, ru_msgsnd); 719100384Speter CP(s, s32, ru_msgrcv); 720100384Speter CP(s, s32, ru_nsignals); 721100384Speter CP(s, s32, ru_nvcsw); 722100384Speter CP(s, s32, ru_nivcsw); 723100384Speter error = copyout(&s32, p32, sizeof(s32)); 724100384Speter } 725100384Speter return (error); 726100384Speter} 727100384Speter 728100384Speterstruct iovec32 { 729100384Speter u_int32_t iov_base; 730100384Speter int iov_len; 731100384Speter}; 732100384Speter#define STACKGAPLEN 400 733100384Speter 734100384Speterint 735100384Speteria32_readv(struct thread *td, struct ia32_readv_args *uap) 736100384Speter{ 737100384Speter int error, osize, nsize, i; 738100384Speter caddr_t sg; 739100384Speter struct readv_args /* { 740100384Speter syscallarg(int) fd; 741100384Speter syscallarg(struct iovec *) iovp; 742100384Speter syscallarg(u_int) iovcnt; 743100384Speter } */ a; 744100384Speter struct iovec32 *oio; 745100384Speter struct iovec *nio; 746100384Speter 747100384Speter sg = stackgap_init(); 748100384Speter 749107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 750100384Speter return (EINVAL); 751100384Speter 752107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 753107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 754100384Speter 755111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 756111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 757100384Speter 758100384Speter error = 0; 759107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 760100384Speter goto punt; 761107849Salfred for (i = 0; i < uap->iovcnt; i++) { 762100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 763100384Speter nio[i].iov_len = oio[i].iov_len; 764100384Speter } 765100384Speter 766107849Salfred a.fd = uap->fd; 767107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 768107849Salfred a.iovcnt = uap->iovcnt; 769100384Speter 770107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 771100384Speter goto punt; 772100384Speter error = readv(td, &a); 773100384Speter 774100384Speterpunt: 775100384Speter free(oio, M_TEMP); 776100384Speter free(nio, M_TEMP); 777100384Speter return (error); 778100384Speter} 779100384Speter 780100384Speterint 781100384Speteria32_writev(struct thread *td, struct ia32_writev_args *uap) 782100384Speter{ 783100384Speter int error, i, nsize, osize; 784100384Speter caddr_t sg; 785100384Speter struct writev_args /* { 786100384Speter syscallarg(int) fd; 787100384Speter syscallarg(struct iovec *) iovp; 788100384Speter syscallarg(u_int) iovcnt; 789100384Speter } */ a; 790100384Speter struct iovec32 *oio; 791100384Speter struct iovec *nio; 792100384Speter 793100384Speter sg = stackgap_init(); 794100384Speter 795107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 796100384Speter return (EINVAL); 797100384Speter 798107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 799107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 800100384Speter 801111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 802111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 803100384Speter 804100384Speter error = 0; 805107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 806100384Speter goto punt; 807107849Salfred for (i = 0; i < uap->iovcnt; i++) { 808100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 809100384Speter nio[i].iov_len = oio[i].iov_len; 810100384Speter } 811100384Speter 812107849Salfred a.fd = uap->fd; 813107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 814107849Salfred a.iovcnt = uap->iovcnt; 815100384Speter 816107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 817100384Speter goto punt; 818100384Speter error = writev(td, &a); 819100384Speter 820100384Speterpunt: 821100384Speter free(oio, M_TEMP); 822100384Speter free(nio, M_TEMP); 823100384Speter return (error); 824100384Speter} 825100384Speter 826100384Speterint 827100384Speteria32_settimeofday(struct thread *td, struct ia32_settimeofday_args *uap) 828100384Speter{ 829100384Speter int error; 830100384Speter caddr_t sg; 831100384Speter struct timeval32 *p32, s32; 832100384Speter struct timeval *p = NULL, s; 833100384Speter 834107849Salfred p32 = uap->tv; 835100384Speter if (p32) { 836100384Speter sg = stackgap_init(); 837100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 838107849Salfred uap->tv = (struct timeval32 *)p; 839100384Speter error = copyin(p32, &s32, sizeof(s32)); 840100384Speter if (error) 841100384Speter return (error); 842100384Speter CP(s32, s, tv_sec); 843100384Speter CP(s32, s, tv_usec); 844100384Speter error = copyout(&s, p, sizeof(s)); 845100384Speter if (error) 846100384Speter return (error); 847100384Speter } 848100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 849100384Speter} 850100384Speter 851100384Speterint 852100384Speteria32_utimes(struct thread *td, struct ia32_utimes_args *uap) 853100384Speter{ 854100384Speter int error; 855100384Speter caddr_t sg; 856100384Speter struct timeval32 *p32, s32[2]; 857100384Speter struct timeval *p = NULL, s[2]; 858100384Speter 859107849Salfred p32 = uap->tptr; 860100384Speter if (p32) { 861100384Speter sg = stackgap_init(); 862100384Speter p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 863107849Salfred uap->tptr = (struct timeval32 *)p; 864100384Speter error = copyin(p32, s32, sizeof(s32)); 865100384Speter if (error) 866100384Speter return (error); 867100384Speter CP(s32[0], s[0], tv_sec); 868100384Speter CP(s32[0], s[0], tv_usec); 869100384Speter CP(s32[1], s[1], tv_sec); 870100384Speter CP(s32[1], s[1], tv_usec); 871100384Speter error = copyout(s, p, sizeof(s)); 872100384Speter if (error) 873100384Speter return (error); 874100384Speter } 875100384Speter return (utimes(td, (struct utimes_args *) uap)); 876100384Speter} 877100384Speter 878100384Speterint 879100384Speteria32_adjtime(struct thread *td, struct ia32_adjtime_args *uap) 880100384Speter{ 881100384Speter int error; 882100384Speter caddr_t sg; 883100384Speter struct timeval32 *p32, *op32, s32; 884100384Speter struct timeval *p = NULL, *op = NULL, s; 885100384Speter 886107849Salfred p32 = uap->delta; 887100384Speter if (p32) { 888100384Speter sg = stackgap_init(); 889100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 890107849Salfred uap->delta = (struct timeval32 *)p; 891100384Speter error = copyin(p32, &s32, sizeof(s32)); 892100384Speter if (error) 893100384Speter return (error); 894100384Speter CP(s32, s, tv_sec); 895100384Speter CP(s32, s, tv_usec); 896100384Speter error = copyout(&s, p, sizeof(s)); 897100384Speter if (error) 898100384Speter return (error); 899100384Speter } 900107849Salfred op32 = uap->olddelta; 901100384Speter if (op32) { 902100384Speter sg = stackgap_init(); 903100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 904107849Salfred uap->olddelta = (struct timeval32 *)op; 905100384Speter } 906100384Speter error = utimes(td, (struct utimes_args *) uap); 907100384Speter if (error) 908100384Speter return error; 909100384Speter if (op32) { 910100384Speter error = copyin(op, &s, sizeof(s)); 911100384Speter if (error) 912100384Speter return (error); 913100384Speter CP(s, s32, tv_sec); 914100384Speter CP(s, s32, tv_usec); 915100384Speter error = copyout(&s32, op32, sizeof(s32)); 916100384Speter } 917100384Speter return (error); 918100384Speter} 919100384Speter 920100384Speterint 921100384Speteria32_statfs(struct thread *td, struct ia32_statfs_args *uap) 922100384Speter{ 923100384Speter int error; 924100384Speter caddr_t sg; 925100384Speter struct statfs32 *p32, s32; 926100384Speter struct statfs *p = NULL, s; 927100384Speter 928107849Salfred p32 = uap->buf; 929100384Speter if (p32) { 930100384Speter sg = stackgap_init(); 931100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 932107849Salfred uap->buf = (struct statfs32 *)p; 933100384Speter } 934100384Speter error = statfs(td, (struct statfs_args *) uap); 935100384Speter if (error) 936100384Speter return (error); 937100384Speter if (p32) { 938100384Speter error = copyin(p, &s, sizeof(s)); 939100384Speter if (error) 940100384Speter return (error); 941100384Speter copy_statfs(&s, &s32); 942100384Speter error = copyout(&s32, p32, sizeof(s32)); 943100384Speter } 944100384Speter return (error); 945100384Speter} 946100384Speter 947100384Speterint 948100384Speteria32_fstatfs(struct thread *td, struct ia32_fstatfs_args *uap) 949100384Speter{ 950100384Speter int error; 951100384Speter caddr_t sg; 952100384Speter struct statfs32 *p32, s32; 953100384Speter struct statfs *p = NULL, s; 954100384Speter 955107849Salfred p32 = uap->buf; 956100384Speter if (p32) { 957100384Speter sg = stackgap_init(); 958100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 959107849Salfred uap->buf = (struct statfs32 *)p; 960100384Speter } 961100384Speter error = fstatfs(td, (struct fstatfs_args *) uap); 962100384Speter if (error) 963100384Speter return (error); 964100384Speter if (p32) { 965100384Speter error = copyin(p, &s, sizeof(s)); 966100384Speter if (error) 967100384Speter return (error); 968100384Speter copy_statfs(&s, &s32); 969100384Speter error = copyout(&s32, p32, sizeof(s32)); 970100384Speter } 971100384Speter return (error); 972100384Speter} 973100384Speter 974100384Speterint 975100384Speteria32_semsys(struct thread *td, struct ia32_semsys_args *uap) 976100384Speter{ 977100384Speter /* 978100384Speter * Vector through to semsys if it is loaded. 979100384Speter */ 980100384Speter return sysent[169].sy_call(td, uap); 981100384Speter} 982100384Speter 983100384Speterint 984100384Speteria32_msgsys(struct thread *td, struct ia32_msgsys_args *uap) 985100384Speter{ 986100384Speter /* 987100384Speter * Vector through to msgsys if it is loaded. 988100384Speter */ 989100384Speter return sysent[170].sy_call(td, uap); 990100384Speter} 991100384Speter 992100384Speterint 993100384Speteria32_shmsys(struct thread *td, struct ia32_shmsys_args *uap) 994100384Speter{ 995100384Speter /* 996100384Speter * Vector through to shmsys if it is loaded. 997100384Speter */ 998100384Speter return sysent[171].sy_call(td, uap); 999100384Speter} 1000100384Speter 1001100384Speterint 1002100384Speteria32_pread(struct thread *td, struct ia32_pread_args *uap) 1003100384Speter{ 1004100384Speter struct pread_args ap; 1005100384Speter 1006107849Salfred ap.fd = uap->fd; 1007107849Salfred ap.buf = uap->buf; 1008107849Salfred ap.nbyte = uap->nbyte; 1009107849Salfred ap.offset = (uap->offsetlo 1010107849Salfred | ((off_t)uap->offsethi << 32)); 1011100384Speter return (pread(td, &ap)); 1012100384Speter} 1013100384Speter 1014100384Speterint 1015100384Speteria32_pwrite(struct thread *td, struct ia32_pwrite_args *uap) 1016100384Speter{ 1017100384Speter struct pwrite_args ap; 1018100384Speter 1019107849Salfred ap.fd = uap->fd; 1020107849Salfred ap.buf = uap->buf; 1021107849Salfred ap.nbyte = uap->nbyte; 1022107849Salfred ap.offset = (uap->offsetlo 1023107849Salfred | ((off_t)uap->offsethi << 32)); 1024100384Speter return (pwrite(td, &ap)); 1025100384Speter} 1026100384Speter 1027100384Speterint 1028100384Speteria32_lseek(struct thread *td, struct ia32_lseek_args *uap) 1029100384Speter{ 1030100384Speter int error; 1031100384Speter struct lseek_args ap; 1032100384Speter off_t pos; 1033100384Speter 1034107849Salfred ap.fd = uap->fd; 1035107849Salfred ap.offset = (uap->offsetlo 1036107849Salfred | ((off_t)uap->offsethi << 32)); 1037107849Salfred ap.whence = uap->whence; 1038100384Speter error = lseek(td, &ap); 1039100384Speter /* Expand the quad return into two parts for eax and edx */ 1040100384Speter pos = *(off_t *)(td->td_retval); 1041100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1042100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1043100384Speter return error; 1044100384Speter} 1045100384Speter 1046100384Speterint 1047100384Speteria32_truncate(struct thread *td, struct ia32_truncate_args *uap) 1048100384Speter{ 1049100384Speter struct truncate_args ap; 1050100384Speter 1051107849Salfred ap.path = uap->path; 1052107849Salfred ap.length = (uap->lengthlo 1053107849Salfred | ((off_t)uap->lengthhi << 32)); 1054100384Speter return (truncate(td, &ap)); 1055100384Speter} 1056100384Speter 1057100384Speterint 1058100384Speteria32_ftruncate(struct thread *td, struct ia32_ftruncate_args *uap) 1059100384Speter{ 1060100384Speter struct ftruncate_args ap; 1061100384Speter 1062107849Salfred ap.fd = uap->fd; 1063107849Salfred ap.length = (uap->lengthlo 1064107849Salfred | ((off_t)uap->lengthhi << 32)); 1065100384Speter return (ftruncate(td, &ap)); 1066100384Speter} 1067100384Speter 1068104738Speter#ifdef COMPAT_FREEBSD4 1069100384Speterint 1070104738Speterfreebsd4_ia32_sendfile(struct thread *td, 1071104738Speter struct freebsd4_ia32_sendfile_args *uap) 1072104738Speter{ 1073104738Speter struct freebsd4_sendfile_args ap; 1074104738Speter 1075107849Salfred ap.fd = uap->fd; 1076107849Salfred ap.s = uap->s; 1077107849Salfred ap.offset = (uap->offsetlo 1078107849Salfred | ((off_t)uap->offsethi << 32)); 1079107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1080107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1081107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1082107849Salfred ap.flags = uap->flags; 1083104738Speter return (freebsd4_sendfile(td, &ap)); 1084104738Speter} 1085104738Speter#endif 1086104738Speter 1087104738Speterint 1088100384Speteria32_sendfile(struct thread *td, struct ia32_sendfile_args *uap) 1089100384Speter{ 1090100384Speter struct sendfile_args ap; 1091100384Speter 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; 1100100384Speter return (sendfile(td, &ap)); 1101100384Speter} 1102100384Speter 1103100384Speterstruct stat32 { 1104100384Speter udev_t st_dev; 1105100384Speter ino_t st_ino; 1106100384Speter mode_t st_mode; 1107100384Speter nlink_t st_nlink; 1108100384Speter uid_t st_uid; 1109100384Speter gid_t st_gid; 1110100384Speter udev_t st_rdev; 1111100384Speter struct timespec32 st_atimespec; 1112100384Speter struct timespec32 st_mtimespec; 1113100384Speter struct timespec32 st_ctimespec; 1114100384Speter off_t st_size; 1115100384Speter int64_t st_blocks; 1116100384Speter u_int32_t st_blksize; 1117100384Speter u_int32_t st_flags; 1118100384Speter u_int32_t st_gen; 1119100384Speter}; 1120100384Speter 1121100384Speterstatic void 1122100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1123100384Speter{ 1124100384Speter CP(*in, *out, st_dev); 1125100384Speter CP(*in, *out, st_ino); 1126100384Speter CP(*in, *out, st_mode); 1127100384Speter CP(*in, *out, st_nlink); 1128100384Speter CP(*in, *out, st_uid); 1129100384Speter CP(*in, *out, st_gid); 1130100384Speter CP(*in, *out, st_rdev); 1131100384Speter TS_CP(*in, *out, st_atimespec); 1132100384Speter TS_CP(*in, *out, st_mtimespec); 1133100384Speter TS_CP(*in, *out, st_ctimespec); 1134100384Speter CP(*in, *out, st_size); 1135100384Speter CP(*in, *out, st_blocks); 1136100384Speter CP(*in, *out, st_blksize); 1137100384Speter CP(*in, *out, st_flags); 1138100384Speter CP(*in, *out, st_gen); 1139100384Speter} 1140100384Speter 1141100384Speterint 1142100384Speteria32_stat(struct thread *td, struct ia32_stat_args *uap) 1143100384Speter{ 1144100384Speter int error; 1145100384Speter caddr_t sg; 1146100384Speter struct stat32 *p32, s32; 1147100384Speter struct stat *p = NULL, s; 1148100384Speter 1149107849Salfred p32 = uap->ub; 1150100384Speter if (p32) { 1151100384Speter sg = stackgap_init(); 1152100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1153107849Salfred uap->ub = (struct stat32 *)p; 1154100384Speter } 1155100384Speter error = stat(td, (struct stat_args *) uap); 1156100384Speter if (error) 1157100384Speter return (error); 1158100384Speter if (p32) { 1159100384Speter error = copyin(p, &s, sizeof(s)); 1160100384Speter if (error) 1161100384Speter return (error); 1162100384Speter copy_stat(&s, &s32); 1163100384Speter error = copyout(&s32, p32, sizeof(s32)); 1164100384Speter } 1165100384Speter return (error); 1166100384Speter} 1167100384Speter 1168100384Speterint 1169100384Speteria32_fstat(struct thread *td, struct ia32_fstat_args *uap) 1170100384Speter{ 1171100384Speter int error; 1172100384Speter caddr_t sg; 1173100384Speter struct stat32 *p32, s32; 1174100384Speter struct stat *p = NULL, s; 1175100384Speter 1176107849Salfred p32 = uap->ub; 1177100384Speter if (p32) { 1178100384Speter sg = stackgap_init(); 1179100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1180107849Salfred uap->ub = (struct stat32 *)p; 1181100384Speter } 1182100384Speter error = fstat(td, (struct fstat_args *) uap); 1183100384Speter if (error) 1184100384Speter return (error); 1185100384Speter if (p32) { 1186100384Speter error = copyin(p, &s, sizeof(s)); 1187100384Speter if (error) 1188100384Speter return (error); 1189100384Speter copy_stat(&s, &s32); 1190100384Speter error = copyout(&s32, p32, sizeof(s32)); 1191100384Speter } 1192100384Speter return (error); 1193100384Speter} 1194100384Speter 1195100384Speterint 1196100384Speteria32_lstat(struct thread *td, struct ia32_lstat_args *uap) 1197100384Speter{ 1198100384Speter int error; 1199100384Speter caddr_t sg; 1200100384Speter struct stat32 *p32, s32; 1201100384Speter struct stat *p = NULL, s; 1202100384Speter 1203107849Salfred p32 = uap->ub; 1204100384Speter if (p32) { 1205100384Speter sg = stackgap_init(); 1206100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1207107849Salfred uap->ub = (struct stat32 *)p; 1208100384Speter } 1209100384Speter error = lstat(td, (struct lstat_args *) uap); 1210100384Speter if (error) 1211100384Speter return (error); 1212100384Speter if (p32) { 1213100384Speter error = copyin(p, &s, sizeof(s)); 1214100384Speter if (error) 1215100384Speter return (error); 1216100384Speter copy_stat(&s, &s32); 1217100384Speter error = copyout(&s32, p32, sizeof(s32)); 1218100384Speter } 1219100384Speter return (error); 1220100384Speter} 1221100384Speter 1222100384Speter/* 1223100384Speter * MPSAFE 1224100384Speter */ 1225100384Speterint 1226100384Speteria32_sysctl(struct thread *td, struct ia32_sysctl_args *uap) 1227100384Speter{ 1228100384Speter int error, name[CTL_MAXNAME]; 1229100384Speter size_t j, oldlen; 1230100384Speter 1231100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1232100384Speter return (EINVAL); 1233100384Speter 1234100384Speter error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1235100384Speter if (error) 1236100384Speter return (error); 1237100384Speter 1238100384Speter mtx_lock(&Giant); 1239100384Speter 1240100384Speter if (uap->oldlenp) 1241100384Speter oldlen = fuword32(uap->oldlenp); 1242100384Speter else 1243100384Speter oldlen = 0; 1244100384Speter error = userland_sysctl(td, name, uap->namelen, 1245100384Speter uap->old, &oldlen, 1, 1246100384Speter uap->new, uap->newlen, &j); 1247100384Speter if (error && error != ENOMEM) 1248100384Speter goto done2; 1249100384Speter if (uap->oldlenp) { 1250100384Speter suword32(uap->oldlenp, j); 1251100384Speter } 1252100384Speterdone2: 1253100384Speter mtx_unlock(&Giant); 1254100384Speter return (error); 1255100384Speter} 1256100384Speter 1257100384Speterstruct sigaction32 { 1258100384Speter u_int32_t sa_u; 1259100384Speter int sa_flags; 1260100384Speter sigset_t sa_mask; 1261100384Speter}; 1262100384Speter 1263100384Speterint 1264100384Speteria32_sigaction(struct thread *td, struct ia32_sigaction_args *uap) 1265100384Speter{ 1266113859Sjhb struct sigaction32 s32; 1267113859Sjhb struct sigaction sa, osa, *sap; 1268100384Speter int error; 1269100384Speter 1270113859Sjhb if (uap->act) { 1271113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1272100384Speter if (error) 1273100384Speter return (error); 1274113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1275113859Sjhb CP(s32, sa, sa_flags); 1276113859Sjhb CP(s32, sa, sa_mask); 1277113859Sjhb sap = &sa; 1278113859Sjhb } else 1279113859Sjhb sap = NULL; 1280113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1281113859Sjhb if (error != 0 && uap->oact != NULL) { 1282113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1283113859Sjhb CP(osa, s32, sa_flags); 1284113859Sjhb CP(osa, s32, sa_mask); 1285113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1286100384Speter } 1287100384Speter return (error); 1288100384Speter} 1289100384Speter 1290100384Speter#if 0 1291100384Speter 1292100384Speterint 1293100384Speteria32_xxx(struct thread *td, struct ia32_xxx_args *uap) 1294100384Speter{ 1295100384Speter int error; 1296100384Speter caddr_t sg; 1297100384Speter struct yyy32 *p32, s32; 1298100384Speter struct yyy *p = NULL, s; 1299100384Speter 1300107849Salfred p32 = uap->zzz; 1301100384Speter if (p32) { 1302100384Speter sg = stackgap_init(); 1303100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1304107849Salfred uap->zzz = (struct yyy32 *)p; 1305100384Speter error = copyin(p32, &s32, sizeof(s32)); 1306100384Speter if (error) 1307100384Speter return (error); 1308100384Speter /* translate in */ 1309100384Speter error = copyout(&s, p, sizeof(s)); 1310100384Speter if (error) 1311100384Speter return (error); 1312100384Speter } 1313100384Speter error = xxx(td, (struct xxx_args *) uap); 1314100384Speter if (error) 1315100384Speter return (error); 1316100384Speter if (p32) { 1317100384Speter error = copyin(p, &s, sizeof(s)); 1318100384Speter if (error) 1319100384Speter return (error); 1320100384Speter /* translate out */ 1321100384Speter error = copyout(&s32, p32, sizeof(s32)); 1322100384Speter } 1323100384Speter return (error); 1324100384Speter} 1325100384Speter 1326100384Speter#endif 1327