freebsd32_misc.c revision 114987
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 114987 2003-05-14 04:10:49Z peter $ 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 77114987Speter#include <amd64/ia32/ia32_util.h> 78114987Speter#include <amd64/ia32/ia32.h> 79114987Speter#include <amd64/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 442114987Speter#ifdef __ia64__ 443100384Speterstatic int 444100384Speteria32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 445100384Speter int prot, int fd, off_t pos) 446100384Speter{ 447100384Speter vm_map_t map; 448100384Speter vm_map_entry_t entry; 449100384Speter int rv; 450100384Speter 451100384Speter map = &td->td_proc->p_vmspace->vm_map; 452100384Speter if (fd != -1) 453100384Speter prot |= VM_PROT_WRITE; 454100384Speter 455100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 456100384Speter if ((entry->protection & prot) != prot) { 457100384Speter rv = vm_map_protect(map, 458100384Speter trunc_page(start), 459100384Speter round_page(end), 460100384Speter entry->protection | prot, 461100384Speter FALSE); 462100384Speter if (rv != KERN_SUCCESS) 463100384Speter return (EINVAL); 464100384Speter } 465100384Speter } else { 466100384Speter vm_offset_t addr = trunc_page(start); 467100384Speter rv = vm_map_find(map, 0, 0, 468100384Speter &addr, PAGE_SIZE, FALSE, prot, 469100384Speter VM_PROT_ALL, 0); 470100384Speter if (rv != KERN_SUCCESS) 471100384Speter return (EINVAL); 472100384Speter } 473100384Speter 474100384Speter if (fd != -1) { 475100384Speter struct pread_args r; 476107849Salfred r.fd = fd; 477107849Salfred r.buf = (void *) start; 478107849Salfred r.nbyte = end - start; 479107849Salfred r.offset = pos; 480100384Speter return (pread(td, &r)); 481100384Speter } else { 482100384Speter while (start < end) { 483100384Speter subyte((void *) start, 0); 484100384Speter start++; 485100384Speter } 486100384Speter return (0); 487100384Speter } 488100384Speter} 489114987Speter#endif 490100384Speter 491100384Speterint 492100384Speteria32_mmap(struct thread *td, struct ia32_mmap_args *uap) 493100384Speter{ 494100384Speter struct mmap_args ap; 495107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 496107849Salfred vm_size_t len = uap->len; 497107849Salfred int prot = uap->prot; 498107849Salfred int flags = uap->flags; 499107849Salfred int fd = uap->fd; 500107849Salfred off_t pos = (uap->poslo 501107849Salfred | ((off_t)uap->poshi << 32)); 502114987Speter#ifdef __ia64__ 503100384Speter vm_size_t pageoff; 504100384Speter int error; 505100384Speter 506100384Speter /* 507100384Speter * Attempt to handle page size hassles. 508100384Speter */ 509100384Speter pageoff = (pos & PAGE_MASK); 510100384Speter if (flags & MAP_FIXED) { 511100384Speter vm_offset_t start, end; 512100384Speter start = addr; 513100384Speter end = addr + len; 514100384Speter 515100384Speter if (start != trunc_page(start)) { 516100384Speter error = ia32_mmap_partial(td, start, round_page(start), 517100384Speter prot, fd, pos); 518100384Speter if (fd != -1) 519100384Speter pos += round_page(start) - start; 520100384Speter start = round_page(start); 521100384Speter } 522100384Speter if (end != round_page(end)) { 523100384Speter vm_offset_t t = trunc_page(end); 524100384Speter error = ia32_mmap_partial(td, t, end, 525100384Speter prot, fd, 526100384Speter pos + t - start); 527100384Speter end = trunc_page(end); 528100384Speter } 529100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 530100384Speter /* 531100384Speter * We can't map this region at all. The specified 532100384Speter * address doesn't have the same alignment as the file 533100384Speter * position. Fake the mapping by simply reading the 534100384Speter * entire region into memory. First we need to make 535100384Speter * sure the region exists. 536100384Speter */ 537100384Speter vm_map_t map; 538100384Speter struct pread_args r; 539100384Speter int rv; 540100384Speter 541100384Speter prot |= VM_PROT_WRITE; 542100384Speter map = &td->td_proc->p_vmspace->vm_map; 543100384Speter rv = vm_map_remove(map, start, end); 544100384Speter if (rv != KERN_SUCCESS) 545100384Speter return (EINVAL); 546100384Speter rv = vm_map_find(map, 0, 0, 547100384Speter &start, end - start, FALSE, 548100384Speter prot, VM_PROT_ALL, 0); 549100384Speter if (rv != KERN_SUCCESS) 550100384Speter return (EINVAL); 551107849Salfred r.fd = fd; 552107849Salfred r.buf = (void *) start; 553107849Salfred r.nbyte = end - start; 554107849Salfred r.offset = pos; 555100384Speter error = pread(td, &r); 556100384Speter if (error) 557100384Speter return (error); 558100384Speter 559100384Speter td->td_retval[0] = addr; 560100384Speter return (0); 561100384Speter } 562100384Speter if (end == start) { 563100384Speter /* 564100384Speter * After dealing with the ragged ends, there 565100384Speter * might be none left. 566100384Speter */ 567100384Speter td->td_retval[0] = addr; 568100384Speter return (0); 569100384Speter } 570100384Speter addr = start; 571100384Speter len = end - start; 572100384Speter } 573114987Speter#endif 574100384Speter 575107849Salfred ap.addr = (void *) addr; 576107849Salfred ap.len = len; 577107849Salfred ap.prot = prot; 578107849Salfred ap.flags = flags; 579107849Salfred ap.fd = fd; 580107849Salfred ap.pos = pos; 581100384Speter 582100384Speter return (mmap(td, &ap)); 583100384Speter} 584100384Speter 585100384Speterstruct itimerval32 { 586100384Speter struct timeval32 it_interval; 587100384Speter struct timeval32 it_value; 588100384Speter}; 589100384Speter 590100384Speterint 591100384Speteria32_setitimer(struct thread *td, struct ia32_setitimer_args *uap) 592100384Speter{ 593100384Speter int error; 594100384Speter caddr_t sg; 595100384Speter struct itimerval32 *p32, *op32, s32; 596100384Speter struct itimerval *p = NULL, *op = NULL, s; 597100384Speter 598107849Salfred p32 = uap->itv; 599100384Speter if (p32) { 600100384Speter sg = stackgap_init(); 601100384Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 602107849Salfred uap->itv = (struct itimerval32 *)p; 603100384Speter error = copyin(p32, &s32, sizeof(s32)); 604100384Speter if (error) 605100384Speter return (error); 606100384Speter TV_CP(s32, s, it_interval); 607100384Speter TV_CP(s32, s, it_value); 608100384Speter error = copyout(&s, p, sizeof(s)); 609100384Speter if (error) 610100384Speter return (error); 611100384Speter } 612107849Salfred op32 = uap->oitv; 613100384Speter if (op32) { 614100384Speter sg = stackgap_init(); 615100384Speter op = stackgap_alloc(&sg, sizeof(struct itimerval)); 616107849Salfred uap->oitv = (struct itimerval32 *)op; 617100384Speter } 618100384Speter error = setitimer(td, (struct setitimer_args *) uap); 619100384Speter if (error) 620100384Speter return (error); 621100384Speter if (op32) { 622100384Speter error = copyin(op, &s, sizeof(s)); 623100384Speter if (error) 624100384Speter return (error); 625100384Speter TV_CP(s, s32, it_interval); 626100384Speter TV_CP(s, s32, it_value); 627100384Speter error = copyout(&s32, op32, sizeof(s32)); 628100384Speter } 629100384Speter return (error); 630100384Speter} 631100384Speter 632100384Speterint 633100384Speteria32_select(struct thread *td, struct ia32_select_args *uap) 634100384Speter{ 635100384Speter int error; 636100384Speter caddr_t sg; 637100384Speter struct timeval32 *p32, s32; 638100384Speter struct timeval *p = NULL, s; 639100384Speter 640107849Salfred p32 = uap->tv; 641100384Speter if (p32) { 642100384Speter sg = stackgap_init(); 643100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 644107849Salfred uap->tv = (struct timeval32 *)p; 645100384Speter error = copyin(p32, &s32, sizeof(s32)); 646100384Speter if (error) 647100384Speter return (error); 648100384Speter CP(s32, s, tv_sec); 649100384Speter CP(s32, s, tv_usec); 650100384Speter error = copyout(&s, p, sizeof(s)); 651100384Speter if (error) 652100384Speter return (error); 653100384Speter } 654100384Speter /* 655100384Speter * XXX big-endian needs to convert the fd_sets too. 656100384Speter */ 657100384Speter return (select(td, (struct select_args *) uap)); 658100384Speter} 659100384Speter 660114987Speterstruct kevent32 { 661114987Speter u_int32_t ident; /* identifier for this event */ 662114987Speter short filter; /* filter for event */ 663114987Speter u_short flags; 664114987Speter u_int fflags; 665114987Speter int32_t data; 666114987Speter u_int32_t udata; /* opaque user data identifier */ 667114987Speter}; 668114987Speter 669100384Speterint 670114987Speteria32_kevent(struct thread *td, struct ia32_kevent_args *uap) 671114987Speter{ 672114987Speter int error; 673114987Speter caddr_t sg; 674114987Speter struct timespec32 ts32; 675114987Speter struct timespec ts; 676114987Speter struct kevent32 ks32; 677114987Speter struct kevent *ks; 678114987Speter struct kevent_args a; 679114987Speter int i; 680114987Speter 681114987Speter sg = stackgap_init(); 682114987Speter 683114987Speter a.fd = uap->fd; 684114987Speter a.changelist = uap->changelist; 685114987Speter a.nchanges = uap->nchanges; 686114987Speter a.eventlist = uap->eventlist; 687114987Speter a.nevents = uap->nevents; 688114987Speter a.timeout = NULL; 689114987Speter 690114987Speter if (uap->timeout) { 691114987Speter a.timeout = stackgap_alloc(&sg, sizeof(struct timespec)); 692114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 693114987Speter if (error) 694114987Speter return (error); 695114987Speter CP(ts32, ts, tv_sec); 696114987Speter CP(ts32, ts, tv_nsec); 697114987Speter error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts)); 698114987Speter if (error) 699114987Speter return (error); 700114987Speter } 701114987Speter if (uap->changelist) { 702114987Speter a.changelist = (struct kevent *)stackgap_alloc(&sg, uap->nchanges * sizeof(struct kevent)); 703114987Speter for (i = 0; i < uap->nchanges; i++) { 704114987Speter error = copyin(&uap->changelist[i], &ks32, sizeof(ks32)); 705114987Speter if (error) 706114987Speter return (error); 707114987Speter ks = (struct kevent *)(uintptr_t)&a.changelist[i]; 708114987Speter CP(ks32, *ks, ident); 709114987Speter CP(ks32, *ks, filter); 710114987Speter CP(ks32, *ks, flags); 711114987Speter CP(ks32, *ks, fflags); 712114987Speter CP(ks32, *ks, data); 713114987Speter PTRIN_CP(ks32, *ks, udata); 714114987Speter } 715114987Speter } 716114987Speter if (uap->eventlist) { 717114987Speter a.eventlist = stackgap_alloc(&sg, uap->nevents * sizeof(struct kevent)); 718114987Speter } 719114987Speter error = kevent(td, &a); 720114987Speter if (uap->eventlist && error > 0) { 721114987Speter for (i = 0; i < error; i++) { 722114987Speter ks = &a.eventlist[i]; 723114987Speter CP(*ks, ks32, ident); 724114987Speter CP(*ks, ks32, filter); 725114987Speter CP(*ks, ks32, flags); 726114987Speter CP(*ks, ks32, fflags); 727114987Speter CP(*ks, ks32, data); 728114987Speter PTROUT_CP(*ks, ks32, udata); 729114987Speter error = copyout(&ks32, &uap->eventlist[i], sizeof(ks32)); 730114987Speter if (error) 731114987Speter return (error); 732114987Speter } 733114987Speter } 734114987Speter return error; 735114987Speter} 736114987Speter 737114987Speterint 738100384Speteria32_gettimeofday(struct thread *td, struct ia32_gettimeofday_args *uap) 739100384Speter{ 740100384Speter int error; 741100384Speter caddr_t sg; 742100384Speter struct timeval32 *p32, s32; 743100384Speter struct timeval *p = NULL, s; 744100384Speter 745107849Salfred p32 = uap->tp; 746100384Speter if (p32) { 747100384Speter sg = stackgap_init(); 748100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 749107849Salfred uap->tp = (struct timeval32 *)p; 750100384Speter } 751100384Speter error = gettimeofday(td, (struct gettimeofday_args *) uap); 752100384Speter if (error) 753100384Speter return (error); 754100384Speter if (p32) { 755100384Speter error = copyin(p, &s, sizeof(s)); 756100384Speter if (error) 757100384Speter return (error); 758100384Speter CP(s, s32, tv_sec); 759100384Speter CP(s, s32, tv_usec); 760100384Speter error = copyout(&s32, p32, sizeof(s32)); 761100384Speter if (error) 762100384Speter return (error); 763100384Speter } 764100384Speter return (error); 765100384Speter} 766100384Speter 767100384Speterint 768100384Speteria32_getrusage(struct thread *td, struct ia32_getrusage_args *uap) 769100384Speter{ 770100384Speter int error; 771100384Speter caddr_t sg; 772100384Speter struct rusage32 *p32, s32; 773100384Speter struct rusage *p = NULL, s; 774100384Speter 775107849Salfred p32 = uap->rusage; 776100384Speter if (p32) { 777100384Speter sg = stackgap_init(); 778100384Speter p = stackgap_alloc(&sg, sizeof(struct rusage)); 779107849Salfred uap->rusage = (struct rusage32 *)p; 780100384Speter } 781100384Speter error = getrusage(td, (struct getrusage_args *) uap); 782100384Speter if (error) 783100384Speter return (error); 784100384Speter if (p32) { 785100384Speter error = copyin(p, &s, sizeof(s)); 786100384Speter if (error) 787100384Speter return (error); 788100384Speter TV_CP(s, s32, ru_utime); 789100384Speter TV_CP(s, s32, ru_stime); 790100384Speter CP(s, s32, ru_maxrss); 791100384Speter CP(s, s32, ru_ixrss); 792100384Speter CP(s, s32, ru_idrss); 793100384Speter CP(s, s32, ru_isrss); 794100384Speter CP(s, s32, ru_minflt); 795100384Speter CP(s, s32, ru_majflt); 796100384Speter CP(s, s32, ru_nswap); 797100384Speter CP(s, s32, ru_inblock); 798100384Speter CP(s, s32, ru_oublock); 799100384Speter CP(s, s32, ru_msgsnd); 800100384Speter CP(s, s32, ru_msgrcv); 801100384Speter CP(s, s32, ru_nsignals); 802100384Speter CP(s, s32, ru_nvcsw); 803100384Speter CP(s, s32, ru_nivcsw); 804100384Speter error = copyout(&s32, p32, sizeof(s32)); 805100384Speter } 806100384Speter return (error); 807100384Speter} 808100384Speter 809100384Speterstruct iovec32 { 810100384Speter u_int32_t iov_base; 811100384Speter int iov_len; 812100384Speter}; 813100384Speter#define STACKGAPLEN 400 814100384Speter 815100384Speterint 816100384Speteria32_readv(struct thread *td, struct ia32_readv_args *uap) 817100384Speter{ 818100384Speter int error, osize, nsize, i; 819100384Speter caddr_t sg; 820100384Speter struct readv_args /* { 821100384Speter syscallarg(int) fd; 822100384Speter syscallarg(struct iovec *) iovp; 823100384Speter syscallarg(u_int) iovcnt; 824100384Speter } */ a; 825100384Speter struct iovec32 *oio; 826100384Speter struct iovec *nio; 827100384Speter 828100384Speter sg = stackgap_init(); 829100384Speter 830107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 831100384Speter return (EINVAL); 832100384Speter 833107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 834107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 835100384Speter 836111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 837111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 838100384Speter 839100384Speter error = 0; 840107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 841100384Speter goto punt; 842107849Salfred for (i = 0; i < uap->iovcnt; i++) { 843100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 844100384Speter nio[i].iov_len = oio[i].iov_len; 845100384Speter } 846100384Speter 847107849Salfred a.fd = uap->fd; 848107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 849107849Salfred a.iovcnt = uap->iovcnt; 850100384Speter 851107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 852100384Speter goto punt; 853100384Speter error = readv(td, &a); 854100384Speter 855100384Speterpunt: 856100384Speter free(oio, M_TEMP); 857100384Speter free(nio, M_TEMP); 858100384Speter return (error); 859100384Speter} 860100384Speter 861100384Speterint 862100384Speteria32_writev(struct thread *td, struct ia32_writev_args *uap) 863100384Speter{ 864100384Speter int error, i, nsize, osize; 865100384Speter caddr_t sg; 866100384Speter struct writev_args /* { 867100384Speter syscallarg(int) fd; 868100384Speter syscallarg(struct iovec *) iovp; 869100384Speter syscallarg(u_int) iovcnt; 870100384Speter } */ a; 871100384Speter struct iovec32 *oio; 872100384Speter struct iovec *nio; 873100384Speter 874100384Speter sg = stackgap_init(); 875100384Speter 876107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 877100384Speter return (EINVAL); 878100384Speter 879107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 880107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 881100384Speter 882111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 883111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 884100384Speter 885100384Speter error = 0; 886107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 887100384Speter goto punt; 888107849Salfred for (i = 0; i < uap->iovcnt; i++) { 889100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 890100384Speter nio[i].iov_len = oio[i].iov_len; 891100384Speter } 892100384Speter 893107849Salfred a.fd = uap->fd; 894107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 895107849Salfred a.iovcnt = uap->iovcnt; 896100384Speter 897107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 898100384Speter goto punt; 899100384Speter error = writev(td, &a); 900100384Speter 901100384Speterpunt: 902100384Speter free(oio, M_TEMP); 903100384Speter free(nio, M_TEMP); 904100384Speter return (error); 905100384Speter} 906100384Speter 907100384Speterint 908100384Speteria32_settimeofday(struct thread *td, struct ia32_settimeofday_args *uap) 909100384Speter{ 910100384Speter int error; 911100384Speter caddr_t sg; 912100384Speter struct timeval32 *p32, s32; 913100384Speter struct timeval *p = NULL, s; 914100384Speter 915107849Salfred p32 = uap->tv; 916100384Speter if (p32) { 917100384Speter sg = stackgap_init(); 918100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 919107849Salfred uap->tv = (struct timeval32 *)p; 920100384Speter error = copyin(p32, &s32, sizeof(s32)); 921100384Speter if (error) 922100384Speter return (error); 923100384Speter CP(s32, s, tv_sec); 924100384Speter CP(s32, s, tv_usec); 925100384Speter error = copyout(&s, p, sizeof(s)); 926100384Speter if (error) 927100384Speter return (error); 928100384Speter } 929100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 930100384Speter} 931100384Speter 932100384Speterint 933100384Speteria32_utimes(struct thread *td, struct ia32_utimes_args *uap) 934100384Speter{ 935100384Speter int error; 936100384Speter caddr_t sg; 937100384Speter struct timeval32 *p32, s32[2]; 938100384Speter struct timeval *p = NULL, s[2]; 939100384Speter 940107849Salfred p32 = uap->tptr; 941100384Speter if (p32) { 942100384Speter sg = stackgap_init(); 943100384Speter p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 944107849Salfred uap->tptr = (struct timeval32 *)p; 945100384Speter error = copyin(p32, s32, sizeof(s32)); 946100384Speter if (error) 947100384Speter return (error); 948100384Speter CP(s32[0], s[0], tv_sec); 949100384Speter CP(s32[0], s[0], tv_usec); 950100384Speter CP(s32[1], s[1], tv_sec); 951100384Speter CP(s32[1], s[1], tv_usec); 952100384Speter error = copyout(s, p, sizeof(s)); 953100384Speter if (error) 954100384Speter return (error); 955100384Speter } 956100384Speter return (utimes(td, (struct utimes_args *) uap)); 957100384Speter} 958100384Speter 959100384Speterint 960100384Speteria32_adjtime(struct thread *td, struct ia32_adjtime_args *uap) 961100384Speter{ 962100384Speter int error; 963100384Speter caddr_t sg; 964100384Speter struct timeval32 *p32, *op32, s32; 965100384Speter struct timeval *p = NULL, *op = NULL, s; 966100384Speter 967107849Salfred p32 = uap->delta; 968100384Speter if (p32) { 969100384Speter sg = stackgap_init(); 970100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 971107849Salfred uap->delta = (struct timeval32 *)p; 972100384Speter error = copyin(p32, &s32, sizeof(s32)); 973100384Speter if (error) 974100384Speter return (error); 975100384Speter CP(s32, s, tv_sec); 976100384Speter CP(s32, s, tv_usec); 977100384Speter error = copyout(&s, p, sizeof(s)); 978100384Speter if (error) 979100384Speter return (error); 980100384Speter } 981107849Salfred op32 = uap->olddelta; 982100384Speter if (op32) { 983100384Speter sg = stackgap_init(); 984100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 985107849Salfred uap->olddelta = (struct timeval32 *)op; 986100384Speter } 987100384Speter error = utimes(td, (struct utimes_args *) uap); 988100384Speter if (error) 989100384Speter return error; 990100384Speter if (op32) { 991100384Speter error = copyin(op, &s, sizeof(s)); 992100384Speter if (error) 993100384Speter return (error); 994100384Speter CP(s, s32, tv_sec); 995100384Speter CP(s, s32, tv_usec); 996100384Speter error = copyout(&s32, op32, sizeof(s32)); 997100384Speter } 998100384Speter return (error); 999100384Speter} 1000100384Speter 1001100384Speterint 1002100384Speteria32_statfs(struct thread *td, struct ia32_statfs_args *uap) 1003100384Speter{ 1004100384Speter int error; 1005100384Speter caddr_t sg; 1006100384Speter struct statfs32 *p32, s32; 1007100384Speter struct statfs *p = NULL, s; 1008100384Speter 1009107849Salfred p32 = uap->buf; 1010100384Speter if (p32) { 1011100384Speter sg = stackgap_init(); 1012100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 1013107849Salfred uap->buf = (struct statfs32 *)p; 1014100384Speter } 1015100384Speter error = statfs(td, (struct statfs_args *) uap); 1016100384Speter if (error) 1017100384Speter return (error); 1018100384Speter if (p32) { 1019100384Speter error = copyin(p, &s, sizeof(s)); 1020100384Speter if (error) 1021100384Speter return (error); 1022100384Speter copy_statfs(&s, &s32); 1023100384Speter error = copyout(&s32, p32, sizeof(s32)); 1024100384Speter } 1025100384Speter return (error); 1026100384Speter} 1027100384Speter 1028100384Speterint 1029100384Speteria32_fstatfs(struct thread *td, struct ia32_fstatfs_args *uap) 1030100384Speter{ 1031100384Speter int error; 1032100384Speter caddr_t sg; 1033100384Speter struct statfs32 *p32, s32; 1034100384Speter struct statfs *p = NULL, s; 1035100384Speter 1036107849Salfred p32 = uap->buf; 1037100384Speter if (p32) { 1038100384Speter sg = stackgap_init(); 1039100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 1040107849Salfred uap->buf = (struct statfs32 *)p; 1041100384Speter } 1042100384Speter error = fstatfs(td, (struct fstatfs_args *) uap); 1043100384Speter if (error) 1044100384Speter return (error); 1045100384Speter if (p32) { 1046100384Speter error = copyin(p, &s, sizeof(s)); 1047100384Speter if (error) 1048100384Speter return (error); 1049100384Speter copy_statfs(&s, &s32); 1050100384Speter error = copyout(&s32, p32, sizeof(s32)); 1051100384Speter } 1052100384Speter return (error); 1053100384Speter} 1054100384Speter 1055100384Speterint 1056100384Speteria32_semsys(struct thread *td, struct ia32_semsys_args *uap) 1057100384Speter{ 1058100384Speter /* 1059100384Speter * Vector through to semsys if it is loaded. 1060100384Speter */ 1061100384Speter return sysent[169].sy_call(td, uap); 1062100384Speter} 1063100384Speter 1064100384Speterint 1065100384Speteria32_msgsys(struct thread *td, struct ia32_msgsys_args *uap) 1066100384Speter{ 1067100384Speter /* 1068100384Speter * Vector through to msgsys if it is loaded. 1069100384Speter */ 1070100384Speter return sysent[170].sy_call(td, uap); 1071100384Speter} 1072100384Speter 1073100384Speterint 1074100384Speteria32_shmsys(struct thread *td, struct ia32_shmsys_args *uap) 1075100384Speter{ 1076100384Speter /* 1077100384Speter * Vector through to shmsys if it is loaded. 1078100384Speter */ 1079100384Speter return sysent[171].sy_call(td, uap); 1080100384Speter} 1081100384Speter 1082100384Speterint 1083100384Speteria32_pread(struct thread *td, struct ia32_pread_args *uap) 1084100384Speter{ 1085100384Speter struct pread_args ap; 1086100384Speter 1087107849Salfred ap.fd = uap->fd; 1088107849Salfred ap.buf = uap->buf; 1089107849Salfred ap.nbyte = uap->nbyte; 1090107849Salfred ap.offset = (uap->offsetlo 1091107849Salfred | ((off_t)uap->offsethi << 32)); 1092100384Speter return (pread(td, &ap)); 1093100384Speter} 1094100384Speter 1095100384Speterint 1096100384Speteria32_pwrite(struct thread *td, struct ia32_pwrite_args *uap) 1097100384Speter{ 1098100384Speter struct pwrite_args ap; 1099100384Speter 1100107849Salfred ap.fd = uap->fd; 1101107849Salfred ap.buf = uap->buf; 1102107849Salfred ap.nbyte = uap->nbyte; 1103107849Salfred ap.offset = (uap->offsetlo 1104107849Salfred | ((off_t)uap->offsethi << 32)); 1105100384Speter return (pwrite(td, &ap)); 1106100384Speter} 1107100384Speter 1108100384Speterint 1109100384Speteria32_lseek(struct thread *td, struct ia32_lseek_args *uap) 1110100384Speter{ 1111100384Speter int error; 1112100384Speter struct lseek_args ap; 1113100384Speter off_t pos; 1114100384Speter 1115107849Salfred ap.fd = uap->fd; 1116107849Salfred ap.offset = (uap->offsetlo 1117107849Salfred | ((off_t)uap->offsethi << 32)); 1118107849Salfred ap.whence = uap->whence; 1119100384Speter error = lseek(td, &ap); 1120100384Speter /* Expand the quad return into two parts for eax and edx */ 1121100384Speter pos = *(off_t *)(td->td_retval); 1122100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1123100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1124100384Speter return error; 1125100384Speter} 1126100384Speter 1127100384Speterint 1128100384Speteria32_truncate(struct thread *td, struct ia32_truncate_args *uap) 1129100384Speter{ 1130100384Speter struct truncate_args ap; 1131100384Speter 1132107849Salfred ap.path = uap->path; 1133107849Salfred ap.length = (uap->lengthlo 1134107849Salfred | ((off_t)uap->lengthhi << 32)); 1135100384Speter return (truncate(td, &ap)); 1136100384Speter} 1137100384Speter 1138100384Speterint 1139100384Speteria32_ftruncate(struct thread *td, struct ia32_ftruncate_args *uap) 1140100384Speter{ 1141100384Speter struct ftruncate_args ap; 1142100384Speter 1143107849Salfred ap.fd = uap->fd; 1144107849Salfred ap.length = (uap->lengthlo 1145107849Salfred | ((off_t)uap->lengthhi << 32)); 1146100384Speter return (ftruncate(td, &ap)); 1147100384Speter} 1148100384Speter 1149104738Speter#ifdef COMPAT_FREEBSD4 1150100384Speterint 1151104738Speterfreebsd4_ia32_sendfile(struct thread *td, 1152104738Speter struct freebsd4_ia32_sendfile_args *uap) 1153104738Speter{ 1154104738Speter struct freebsd4_sendfile_args ap; 1155104738Speter 1156107849Salfred ap.fd = uap->fd; 1157107849Salfred ap.s = uap->s; 1158107849Salfred ap.offset = (uap->offsetlo 1159107849Salfred | ((off_t)uap->offsethi << 32)); 1160107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1161107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1162107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1163107849Salfred ap.flags = uap->flags; 1164104738Speter return (freebsd4_sendfile(td, &ap)); 1165104738Speter} 1166104738Speter#endif 1167104738Speter 1168104738Speterint 1169100384Speteria32_sendfile(struct thread *td, struct ia32_sendfile_args *uap) 1170100384Speter{ 1171100384Speter struct sendfile_args ap; 1172100384Speter 1173107849Salfred ap.fd = uap->fd; 1174107849Salfred ap.s = uap->s; 1175107849Salfred ap.offset = (uap->offsetlo 1176107849Salfred | ((off_t)uap->offsethi << 32)); 1177107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1178107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1179107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1180107849Salfred ap.flags = uap->flags; 1181100384Speter return (sendfile(td, &ap)); 1182100384Speter} 1183100384Speter 1184100384Speterstruct stat32 { 1185100384Speter udev_t st_dev; 1186100384Speter ino_t st_ino; 1187100384Speter mode_t st_mode; 1188100384Speter nlink_t st_nlink; 1189100384Speter uid_t st_uid; 1190100384Speter gid_t st_gid; 1191100384Speter udev_t st_rdev; 1192100384Speter struct timespec32 st_atimespec; 1193100384Speter struct timespec32 st_mtimespec; 1194100384Speter struct timespec32 st_ctimespec; 1195100384Speter off_t st_size; 1196100384Speter int64_t st_blocks; 1197100384Speter u_int32_t st_blksize; 1198100384Speter u_int32_t st_flags; 1199100384Speter u_int32_t st_gen; 1200100384Speter}; 1201100384Speter 1202100384Speterstatic void 1203100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1204100384Speter{ 1205100384Speter CP(*in, *out, st_dev); 1206100384Speter CP(*in, *out, st_ino); 1207100384Speter CP(*in, *out, st_mode); 1208100384Speter CP(*in, *out, st_nlink); 1209100384Speter CP(*in, *out, st_uid); 1210100384Speter CP(*in, *out, st_gid); 1211100384Speter CP(*in, *out, st_rdev); 1212100384Speter TS_CP(*in, *out, st_atimespec); 1213100384Speter TS_CP(*in, *out, st_mtimespec); 1214100384Speter TS_CP(*in, *out, st_ctimespec); 1215100384Speter CP(*in, *out, st_size); 1216100384Speter CP(*in, *out, st_blocks); 1217100384Speter CP(*in, *out, st_blksize); 1218100384Speter CP(*in, *out, st_flags); 1219100384Speter CP(*in, *out, st_gen); 1220100384Speter} 1221100384Speter 1222100384Speterint 1223100384Speteria32_stat(struct thread *td, struct ia32_stat_args *uap) 1224100384Speter{ 1225100384Speter int error; 1226100384Speter caddr_t sg; 1227100384Speter struct stat32 *p32, s32; 1228100384Speter struct stat *p = NULL, s; 1229100384Speter 1230107849Salfred p32 = uap->ub; 1231100384Speter if (p32) { 1232100384Speter sg = stackgap_init(); 1233100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1234107849Salfred uap->ub = (struct stat32 *)p; 1235100384Speter } 1236100384Speter error = stat(td, (struct stat_args *) uap); 1237100384Speter if (error) 1238100384Speter return (error); 1239100384Speter if (p32) { 1240100384Speter error = copyin(p, &s, sizeof(s)); 1241100384Speter if (error) 1242100384Speter return (error); 1243100384Speter copy_stat(&s, &s32); 1244100384Speter error = copyout(&s32, p32, sizeof(s32)); 1245100384Speter } 1246100384Speter return (error); 1247100384Speter} 1248100384Speter 1249100384Speterint 1250100384Speteria32_fstat(struct thread *td, struct ia32_fstat_args *uap) 1251100384Speter{ 1252100384Speter int error; 1253100384Speter caddr_t sg; 1254100384Speter struct stat32 *p32, s32; 1255100384Speter struct stat *p = NULL, s; 1256100384Speter 1257107849Salfred p32 = uap->ub; 1258100384Speter if (p32) { 1259100384Speter sg = stackgap_init(); 1260100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1261107849Salfred uap->ub = (struct stat32 *)p; 1262100384Speter } 1263100384Speter error = fstat(td, (struct fstat_args *) uap); 1264100384Speter if (error) 1265100384Speter return (error); 1266100384Speter if (p32) { 1267100384Speter error = copyin(p, &s, sizeof(s)); 1268100384Speter if (error) 1269100384Speter return (error); 1270100384Speter copy_stat(&s, &s32); 1271100384Speter error = copyout(&s32, p32, sizeof(s32)); 1272100384Speter } 1273100384Speter return (error); 1274100384Speter} 1275100384Speter 1276100384Speterint 1277100384Speteria32_lstat(struct thread *td, struct ia32_lstat_args *uap) 1278100384Speter{ 1279100384Speter int error; 1280100384Speter caddr_t sg; 1281100384Speter struct stat32 *p32, s32; 1282100384Speter struct stat *p = NULL, s; 1283100384Speter 1284107849Salfred p32 = uap->ub; 1285100384Speter if (p32) { 1286100384Speter sg = stackgap_init(); 1287100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1288107849Salfred uap->ub = (struct stat32 *)p; 1289100384Speter } 1290100384Speter error = lstat(td, (struct lstat_args *) uap); 1291100384Speter if (error) 1292100384Speter return (error); 1293100384Speter if (p32) { 1294100384Speter error = copyin(p, &s, sizeof(s)); 1295100384Speter if (error) 1296100384Speter return (error); 1297100384Speter copy_stat(&s, &s32); 1298100384Speter error = copyout(&s32, p32, sizeof(s32)); 1299100384Speter } 1300100384Speter return (error); 1301100384Speter} 1302100384Speter 1303100384Speter/* 1304100384Speter * MPSAFE 1305100384Speter */ 1306100384Speterint 1307100384Speteria32_sysctl(struct thread *td, struct ia32_sysctl_args *uap) 1308100384Speter{ 1309100384Speter int error, name[CTL_MAXNAME]; 1310100384Speter size_t j, oldlen; 1311100384Speter 1312100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1313100384Speter return (EINVAL); 1314100384Speter 1315100384Speter error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1316100384Speter if (error) 1317100384Speter return (error); 1318100384Speter 1319100384Speter mtx_lock(&Giant); 1320100384Speter 1321100384Speter if (uap->oldlenp) 1322100384Speter oldlen = fuword32(uap->oldlenp); 1323100384Speter else 1324100384Speter oldlen = 0; 1325100384Speter error = userland_sysctl(td, name, uap->namelen, 1326100384Speter uap->old, &oldlen, 1, 1327100384Speter uap->new, uap->newlen, &j); 1328100384Speter if (error && error != ENOMEM) 1329100384Speter goto done2; 1330100384Speter if (uap->oldlenp) { 1331100384Speter suword32(uap->oldlenp, j); 1332100384Speter } 1333100384Speterdone2: 1334100384Speter mtx_unlock(&Giant); 1335100384Speter return (error); 1336100384Speter} 1337100384Speter 1338100384Speterstruct sigaction32 { 1339100384Speter u_int32_t sa_u; 1340100384Speter int sa_flags; 1341100384Speter sigset_t sa_mask; 1342100384Speter}; 1343100384Speter 1344100384Speterint 1345100384Speteria32_sigaction(struct thread *td, struct ia32_sigaction_args *uap) 1346100384Speter{ 1347113859Sjhb struct sigaction32 s32; 1348113859Sjhb struct sigaction sa, osa, *sap; 1349100384Speter int error; 1350100384Speter 1351113859Sjhb if (uap->act) { 1352113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1353100384Speter if (error) 1354100384Speter return (error); 1355113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1356113859Sjhb CP(s32, sa, sa_flags); 1357113859Sjhb CP(s32, sa, sa_mask); 1358113859Sjhb sap = &sa; 1359113859Sjhb } else 1360113859Sjhb sap = NULL; 1361113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1362113859Sjhb if (error != 0 && uap->oact != NULL) { 1363113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1364113859Sjhb CP(osa, s32, sa_flags); 1365113859Sjhb CP(osa, s32, sa_mask); 1366113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1367100384Speter } 1368100384Speter return (error); 1369100384Speter} 1370100384Speter 1371114987Speter#ifdef COMPAT_FREEBSD4 1372114987Speterint 1373114987Speterfreebsd4_ia32_sigaction(struct thread *td, struct freebsd4_ia32_sigaction_args *uap) 1374114987Speter{ 1375114987Speter struct sigaction32 s32; 1376114987Speter struct sigaction sa, osa, *sap; 1377114987Speter int error; 1378114987Speter 1379114987Speter if (uap->act) { 1380114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1381114987Speter if (error) 1382114987Speter return (error); 1383114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1384114987Speter CP(s32, sa, sa_flags); 1385114987Speter CP(s32, sa, sa_mask); 1386114987Speter sap = &sa; 1387114987Speter } else 1388114987Speter sap = NULL; 1389114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1390114987Speter if (error != 0 && uap->oact != NULL) { 1391114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1392114987Speter CP(osa, s32, sa_flags); 1393114987Speter CP(osa, s32, sa_mask); 1394114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1395114987Speter } 1396114987Speter return (error); 1397114987Speter} 1398114987Speter#endif 1399114987Speter 1400100384Speter#if 0 1401100384Speter 1402100384Speterint 1403100384Speteria32_xxx(struct thread *td, struct ia32_xxx_args *uap) 1404100384Speter{ 1405100384Speter int error; 1406100384Speter caddr_t sg; 1407100384Speter struct yyy32 *p32, s32; 1408100384Speter struct yyy *p = NULL, s; 1409100384Speter 1410107849Salfred p32 = uap->zzz; 1411100384Speter if (p32) { 1412100384Speter sg = stackgap_init(); 1413100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1414107849Salfred uap->zzz = (struct yyy32 *)p; 1415100384Speter error = copyin(p32, &s32, sizeof(s32)); 1416100384Speter if (error) 1417100384Speter return (error); 1418100384Speter /* translate in */ 1419100384Speter error = copyout(&s, p, sizeof(s)); 1420100384Speter if (error) 1421100384Speter return (error); 1422100384Speter } 1423100384Speter error = xxx(td, (struct xxx_args *) uap); 1424100384Speter if (error) 1425100384Speter return (error); 1426100384Speter if (p32) { 1427100384Speter error = copyin(p, &s, sizeof(s)); 1428100384Speter if (error) 1429100384Speter return (error); 1430100384Speter /* translate out */ 1431100384Speter error = copyout(&s32, p32, sizeof(s32)); 1432100384Speter } 1433100384Speter return (error); 1434100384Speter} 1435100384Speter 1436100384Speter#endif 1437