freebsd32_misc.c revision 121719
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 27118031Sobrien#include <sys/cdefs.h> 28118031Sobrien__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 121719 2003-10-30 02:40:30Z peter $"); 29118031Sobrien 30104738Speter#include "opt_compat.h" 31104738Speter 32100384Speter#include <sys/param.h> 33100384Speter#include <sys/systm.h> 34100384Speter#include <sys/bus.h> 35100384Speter#include <sys/exec.h> 36100384Speter#include <sys/fcntl.h> 37100384Speter#include <sys/filedesc.h> 38100384Speter#include <sys/imgact.h> 39100384Speter#include <sys/kernel.h> 40100384Speter#include <sys/lock.h> 41100384Speter#include <sys/malloc.h> 42100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 43100384Speter#include <sys/mman.h> 44100384Speter#include <sys/module.h> 45100384Speter#include <sys/mount.h> 46100384Speter#include <sys/mutex.h> 47100384Speter#include <sys/namei.h> 48100384Speter#include <sys/param.h> 49100384Speter#include <sys/proc.h> 50100384Speter#include <sys/reboot.h> 51100384Speter#include <sys/resource.h> 52100384Speter#include <sys/resourcevar.h> 53100384Speter#include <sys/selinfo.h> 54100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 55100384Speter#include <sys/signal.h> 56100384Speter#include <sys/signalvar.h> 57100384Speter#include <sys/socket.h> 58100384Speter#include <sys/socketvar.h> 59100384Speter#include <sys/stat.h> 60113859Sjhb#include <sys/syscallsubr.h> 61100384Speter#include <sys/sysctl.h> 62100384Speter#include <sys/sysent.h> 63100384Speter#include <sys/sysproto.h> 64100384Speter#include <sys/systm.h> 65100384Speter#include <sys/unistd.h> 66100384Speter#include <sys/user.h> 67100384Speter#include <sys/utsname.h> 68100384Speter#include <sys/vnode.h> 69100384Speter 70100384Speter#include <vm/vm.h> 71100384Speter#include <vm/vm_kern.h> 72100384Speter#include <vm/vm_param.h> 73100384Speter#include <vm/pmap.h> 74100384Speter#include <vm/vm_map.h> 75100384Speter#include <vm/vm_object.h> 76100384Speter#include <vm/vm_extern.h> 77100384Speter 78119333Speter#include <compat/freebsd32/freebsd32_util.h> 79119333Speter#include <compat/freebsd32/freebsd32.h> 80119333Speter#include <compat/freebsd32/freebsd32_proto.h> 81100384Speter 82121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 83121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 84121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 85121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 86121719Speter 87100384Speter/* 88100384Speter * [ taken from the linux emulator ] 89100384Speter * Search an alternate path before passing pathname arguments on 90100384Speter * to system calls. Useful for keeping a separate 'emulation tree'. 91100384Speter * 92100384Speter * If cflag is set, we check if an attempt can be made to create 93100384Speter * the named file, i.e. we check if the directory it should 94100384Speter * be in exists. 95100384Speter */ 96100384Speterint 97119333Speterfreebsd32_emul_find(td, sgp, prefix, path, pbuf, cflag) 98100384Speter struct thread *td; 99100384Speter caddr_t *sgp; /* Pointer to stackgap memory */ 100100384Speter const char *prefix; 101100384Speter char *path; 102100384Speter char **pbuf; 103100384Speter int cflag; 104100384Speter{ 105100384Speter int error; 106100384Speter size_t len, sz; 107100384Speter char *buf, *cp, *ptr; 108100384Speter struct ucred *ucred; 109100384Speter struct nameidata nd; 110100384Speter struct nameidata ndroot; 111100384Speter struct vattr vat; 112100384Speter struct vattr vatroot; 113100384Speter 114111119Simp buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 115100384Speter *pbuf = path; 116100384Speter 117100384Speter for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) 118100384Speter continue; 119100384Speter 120100384Speter sz = MAXPATHLEN - (ptr - buf); 121100384Speter 122100384Speter /* 123100384Speter * If sgp is not given then the path is already in kernel space 124100384Speter */ 125100384Speter if (sgp == NULL) 126100384Speter error = copystr(path, ptr, sz, &len); 127100384Speter else 128100384Speter error = copyinstr(path, ptr, sz, &len); 129100384Speter 130100384Speter if (error) { 131100384Speter free(buf, M_TEMP); 132100384Speter return error; 133100384Speter } 134100384Speter 135100384Speter if (*ptr != '/') { 136100384Speter free(buf, M_TEMP); 137100384Speter return EINVAL; 138100384Speter } 139100384Speter 140100384Speter /* 141100384Speter * We know that there is a / somewhere in this pathname. 142100384Speter * Search backwards for it, to find the file's parent dir 143100384Speter * to see if it exists in the alternate tree. If it does, 144100384Speter * and we want to create a file (cflag is set). We don't 145100384Speter * need to worry about the root comparison in this case. 146100384Speter */ 147100384Speter 148100384Speter if (cflag) { 149100384Speter for (cp = &ptr[len] - 1; *cp != '/'; cp--) 150100384Speter ; 151100384Speter *cp = '\0'; 152100384Speter 153100384Speter NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 154100384Speter 155100384Speter if ((error = namei(&nd)) != 0) { 156100384Speter free(buf, M_TEMP); 157100384Speter return error; 158100384Speter } 159100384Speter 160100384Speter *cp = '/'; 161100384Speter } else { 162100384Speter NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 163100384Speter 164100384Speter if ((error = namei(&nd)) != 0) { 165100384Speter free(buf, M_TEMP); 166100384Speter return error; 167100384Speter } 168100384Speter 169100384Speter /* 170119333Speter * We now compare the vnode of the freebsd32_root to the one 171100384Speter * vnode asked. If they resolve to be the same, then we 172100384Speter * ignore the match so that the real root gets used. 173100384Speter * This avoids the problem of traversing "../.." to find the 174100384Speter * root directory and never finding it, because "/" resolves 175100384Speter * to the emulation root directory. This is expensive :-( 176100384Speter */ 177119333Speter NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, 178119333Speter freebsd32_emul_path, td); 179100384Speter 180100384Speter if ((error = namei(&ndroot)) != 0) { 181100384Speter /* Cannot happen! */ 182100384Speter free(buf, M_TEMP); 183100384Speter vrele(nd.ni_vp); 184100384Speter return error; 185100384Speter } 186100384Speter 187100384Speter ucred = td->td_ucred; 188100384Speter if ((error = VOP_GETATTR(nd.ni_vp, &vat, ucred, td)) != 0) { 189100384Speter goto bad; 190100384Speter } 191100384Speter 192100384Speter if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, ucred, 193100384Speter td)) != 0) { 194100384Speter goto bad; 195100384Speter } 196100384Speter 197100384Speter if (vat.va_fsid == vatroot.va_fsid && 198100384Speter vat.va_fileid == vatroot.va_fileid) { 199100384Speter error = ENOENT; 200100384Speter goto bad; 201100384Speter } 202100384Speter 203100384Speter } 204100384Speter if (sgp == NULL) 205100384Speter *pbuf = buf; 206100384Speter else { 207100384Speter sz = &ptr[len] - buf; 208100384Speter *pbuf = stackgap_alloc(sgp, sz + 1); 209100384Speter error = copyout(buf, *pbuf, sz); 210100384Speter free(buf, M_TEMP); 211100384Speter } 212100384Speter 213100384Speter vrele(nd.ni_vp); 214100384Speter if (!cflag) 215100384Speter vrele(ndroot.ni_vp); 216100384Speter 217100384Speter return error; 218100384Speter 219100384Speterbad: 220100384Speter vrele(ndroot.ni_vp); 221100384Speter vrele(nd.ni_vp); 222100384Speter free(buf, M_TEMP); 223100384Speter return error; 224100384Speter} 225100384Speter 226100384Speterint 227119333Speterfreebsd32_open(struct thread *td, struct freebsd32_open_args *uap) 228100384Speter{ 229100384Speter caddr_t sg; 230100384Speter 231100384Speter sg = stackgap_init(); 232100384Speter CHECKALTEXIST(td, &sg, uap->path); 233100384Speter 234100384Speter return open(td, (struct open_args *) uap); 235100384Speter} 236100384Speter 237100384Speterint 238119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 239100384Speter{ 240100384Speter int error; 241100384Speter caddr_t sg; 242100384Speter struct rusage32 *rusage32, ru32; 243100384Speter struct rusage *rusage = NULL, ru; 244100384Speter 245107849Salfred rusage32 = uap->rusage; 246100384Speter if (rusage32) { 247100384Speter sg = stackgap_init(); 248100384Speter rusage = stackgap_alloc(&sg, sizeof(struct rusage)); 249107849Salfred uap->rusage = (struct rusage32 *)rusage; 250100384Speter } 251100384Speter error = wait4(td, (struct wait_args *)uap); 252100384Speter if (error) 253100384Speter return (error); 254100384Speter if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) { 255100384Speter TV_CP(ru, ru32, ru_utime); 256100384Speter TV_CP(ru, ru32, ru_stime); 257100384Speter CP(ru, ru32, ru_maxrss); 258100384Speter CP(ru, ru32, ru_ixrss); 259100384Speter CP(ru, ru32, ru_idrss); 260100384Speter CP(ru, ru32, ru_isrss); 261100384Speter CP(ru, ru32, ru_minflt); 262100384Speter CP(ru, ru32, ru_majflt); 263100384Speter CP(ru, ru32, ru_nswap); 264100384Speter CP(ru, ru32, ru_inblock); 265100384Speter CP(ru, ru32, ru_oublock); 266100384Speter CP(ru, ru32, ru_msgsnd); 267100384Speter CP(ru, ru32, ru_msgrcv); 268100384Speter CP(ru, ru32, ru_nsignals); 269100384Speter CP(ru, ru32, ru_nvcsw); 270100384Speter CP(ru, ru32, ru_nivcsw); 271100384Speter error = copyout(&ru32, rusage32, sizeof(ru32)); 272100384Speter } 273100384Speter return (error); 274100384Speter} 275100384Speter 276100384Speterstatic void 277100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 278100384Speter{ 279100384Speter CP(*in, *out, f_bsize); 280100384Speter CP(*in, *out, f_iosize); 281100384Speter CP(*in, *out, f_blocks); 282100384Speter CP(*in, *out, f_bfree); 283100384Speter CP(*in, *out, f_bavail); 284100384Speter CP(*in, *out, f_files); 285100384Speter CP(*in, *out, f_ffree); 286100384Speter CP(*in, *out, f_fsid); 287100384Speter CP(*in, *out, f_owner); 288100384Speter CP(*in, *out, f_type); 289100384Speter CP(*in, *out, f_flags); 290100384Speter CP(*in, *out, f_flags); 291100384Speter CP(*in, *out, f_syncwrites); 292100384Speter CP(*in, *out, f_asyncwrites); 293100384Speter bcopy(in->f_fstypename, 294100384Speter out->f_fstypename, MFSNAMELEN); 295100384Speter bcopy(in->f_mntonname, 296100384Speter out->f_mntonname, MNAMELEN); 297100384Speter CP(*in, *out, f_syncreads); 298100384Speter CP(*in, *out, f_asyncreads); 299100384Speter bcopy(in->f_mntfromname, 300100384Speter out->f_mntfromname, MNAMELEN); 301100384Speter} 302100384Speter 303100384Speterint 304119333Speterfreebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap) 305100384Speter{ 306100384Speter int error; 307100384Speter caddr_t sg; 308100384Speter struct statfs32 *sp32, stat32; 309100384Speter struct statfs *sp = NULL, stat; 310100384Speter int maxcount, count, i; 311100384Speter 312107849Salfred sp32 = uap->buf; 313107849Salfred maxcount = uap->bufsize / sizeof(struct statfs32); 314100384Speter 315100384Speter if (sp32) { 316100384Speter sg = stackgap_init(); 317100384Speter sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 318107849Salfred uap->buf = (struct statfs32 *)sp; 319100384Speter } 320100384Speter error = getfsstat(td, (struct getfsstat_args *) uap); 321100384Speter if (sp32 && !error) { 322100384Speter count = td->td_retval[0]; 323100384Speter for (i = 0; i < count; i++) { 324100384Speter error = copyin(&sp[i], &stat, sizeof(stat)); 325100384Speter if (error) 326100384Speter return (error); 327100384Speter copy_statfs(&stat, &stat32); 328100384Speter error = copyout(&stat32, &sp32[i], sizeof(stat32)); 329100384Speter if (error) 330100384Speter return (error); 331100384Speter } 332100384Speter } 333100384Speter return (error); 334100384Speter} 335100384Speter 336100384Speterint 337119333Speterfreebsd32_access(struct thread *td, struct freebsd32_access_args *uap) 338100384Speter{ 339100384Speter caddr_t sg; 340100384Speter 341100384Speter sg = stackgap_init(); 342100384Speter CHECKALTEXIST(td, &sg, uap->path); 343100384Speter 344100384Speter return access(td, (struct access_args *)uap); 345100384Speter} 346100384Speter 347100384Speterint 348119333Speterfreebsd32_chflags(struct thread *td, struct freebsd32_chflags_args *uap) 349100384Speter{ 350100384Speter caddr_t sg; 351100384Speter 352100384Speter sg = stackgap_init(); 353100384Speter CHECKALTEXIST(td, &sg, uap->path); 354100384Speter 355100384Speter return chflags(td, (struct chflags_args *)uap); 356100384Speter} 357100384Speter 358100384Speterstruct sigaltstack32 { 359100384Speter u_int32_t ss_sp; 360100384Speter u_int32_t ss_size; 361100384Speter int ss_flags; 362100384Speter}; 363100384Speter 364121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 365121719Speter 366100384Speterint 367119333Speterfreebsd32_sigaltstack(struct thread *td, 368119333Speter struct freebsd32_sigaltstack_args *uap) 369100384Speter{ 370113859Sjhb struct sigaltstack32 s32; 371113859Sjhb struct sigaltstack ss, oss, *ssp; 372100384Speter int error; 373100384Speter 374113859Sjhb if (uap->ss != NULL) { 375113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 376100384Speter if (error) 377100384Speter return (error); 378113859Sjhb PTRIN_CP(s32, ss, ss_sp); 379113859Sjhb CP(s32, ss, ss_size); 380113859Sjhb CP(s32, ss, ss_flags); 381113859Sjhb ssp = &ss; 382113859Sjhb } else 383113859Sjhb ssp = NULL; 384113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 385113859Sjhb if (error == 0 && uap->oss != NULL) { 386113859Sjhb PTROUT_CP(oss, s32, ss_sp); 387113859Sjhb CP(oss, s32, ss_size); 388113859Sjhb CP(oss, s32, ss_flags); 389113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 390100384Speter } 391100384Speter return (error); 392100384Speter} 393100384Speter 394100384Speterint 395119333Speterfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 396100384Speter{ 397100384Speter int error; 398100384Speter caddr_t sg; 399100384Speter struct execve_args ap; 400100384Speter u_int32_t *p32, arg; 401100384Speter char **p; 402100384Speter int count; 403100384Speter 404100384Speter sg = stackgap_init(); 405107849Salfred CHECKALTEXIST(td, &sg, uap->fname); 406107849Salfred ap.fname = uap->fname; 407100384Speter 408107849Salfred if (uap->argv) { 409100384Speter count = 0; 410107849Salfred p32 = uap->argv; 411100384Speter do { 412100384Speter error = copyin(p32++, &arg, sizeof(arg)); 413100384Speter if (error) 414100384Speter return error; 415100384Speter count++; 416100384Speter } while (arg != 0); 417100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 418107849Salfred ap.argv = p; 419107849Salfred p32 = uap->argv; 420100384Speter do { 421100384Speter error = copyin(p32++, &arg, sizeof(arg)); 422100384Speter if (error) 423100384Speter return error; 424100384Speter *p++ = PTRIN(arg); 425100384Speter } while (arg != 0); 426100384Speter } 427107849Salfred if (uap->envv) { 428100384Speter count = 0; 429107849Salfred p32 = uap->envv; 430100384Speter do { 431100384Speter error = copyin(p32++, &arg, sizeof(arg)); 432100384Speter if (error) 433100384Speter return error; 434100384Speter count++; 435100384Speter } while (arg != 0); 436100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 437107849Salfred ap.envv = p; 438107849Salfred p32 = uap->envv; 439100384Speter do { 440100384Speter error = copyin(p32++, &arg, sizeof(arg)); 441100384Speter if (error) 442100384Speter return error; 443100384Speter *p++ = PTRIN(arg); 444100384Speter } while (arg != 0); 445100384Speter } 446100384Speter 447100384Speter return execve(td, &ap); 448100384Speter} 449100384Speter 450114987Speter#ifdef __ia64__ 451100384Speterstatic int 452119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 453119333Speter int prot, int fd, off_t pos) 454100384Speter{ 455100384Speter vm_map_t map; 456100384Speter vm_map_entry_t entry; 457100384Speter int rv; 458100384Speter 459100384Speter map = &td->td_proc->p_vmspace->vm_map; 460100384Speter if (fd != -1) 461100384Speter prot |= VM_PROT_WRITE; 462100384Speter 463100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 464100384Speter if ((entry->protection & prot) != prot) { 465100384Speter rv = vm_map_protect(map, 466100384Speter trunc_page(start), 467100384Speter round_page(end), 468100384Speter entry->protection | prot, 469100384Speter FALSE); 470100384Speter if (rv != KERN_SUCCESS) 471100384Speter return (EINVAL); 472100384Speter } 473100384Speter } else { 474100384Speter vm_offset_t addr = trunc_page(start); 475100384Speter rv = vm_map_find(map, 0, 0, 476100384Speter &addr, PAGE_SIZE, FALSE, prot, 477100384Speter VM_PROT_ALL, 0); 478100384Speter if (rv != KERN_SUCCESS) 479100384Speter return (EINVAL); 480100384Speter } 481100384Speter 482100384Speter if (fd != -1) { 483100384Speter struct pread_args r; 484107849Salfred r.fd = fd; 485107849Salfred r.buf = (void *) start; 486107849Salfred r.nbyte = end - start; 487107849Salfred r.offset = pos; 488100384Speter return (pread(td, &r)); 489100384Speter } else { 490100384Speter while (start < end) { 491100384Speter subyte((void *) start, 0); 492100384Speter start++; 493100384Speter } 494100384Speter return (0); 495100384Speter } 496100384Speter} 497114987Speter#endif 498100384Speter 499100384Speterint 500119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 501100384Speter{ 502100384Speter struct mmap_args ap; 503107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 504107849Salfred vm_size_t len = uap->len; 505107849Salfred int prot = uap->prot; 506107849Salfred int flags = uap->flags; 507107849Salfred int fd = uap->fd; 508107849Salfred off_t pos = (uap->poslo 509107849Salfred | ((off_t)uap->poshi << 32)); 510114987Speter#ifdef __ia64__ 511100384Speter vm_size_t pageoff; 512100384Speter int error; 513100384Speter 514100384Speter /* 515100384Speter * Attempt to handle page size hassles. 516100384Speter */ 517100384Speter pageoff = (pos & PAGE_MASK); 518100384Speter if (flags & MAP_FIXED) { 519100384Speter vm_offset_t start, end; 520100384Speter start = addr; 521100384Speter end = addr + len; 522100384Speter 523100384Speter if (start != trunc_page(start)) { 524119333Speter error = freebsd32_mmap_partial(td, start, 525119333Speter round_page(start), prot, 526119333Speter fd, pos); 527100384Speter if (fd != -1) 528100384Speter pos += round_page(start) - start; 529100384Speter start = round_page(start); 530100384Speter } 531100384Speter if (end != round_page(end)) { 532100384Speter vm_offset_t t = trunc_page(end); 533119333Speter error = freebsd32_mmap_partial(td, t, end, 534100384Speter prot, fd, 535100384Speter pos + t - start); 536100384Speter end = trunc_page(end); 537100384Speter } 538100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 539100384Speter /* 540100384Speter * We can't map this region at all. The specified 541100384Speter * address doesn't have the same alignment as the file 542100384Speter * position. Fake the mapping by simply reading the 543100384Speter * entire region into memory. First we need to make 544100384Speter * sure the region exists. 545100384Speter */ 546100384Speter vm_map_t map; 547100384Speter struct pread_args r; 548100384Speter int rv; 549100384Speter 550100384Speter prot |= VM_PROT_WRITE; 551100384Speter map = &td->td_proc->p_vmspace->vm_map; 552100384Speter rv = vm_map_remove(map, start, end); 553100384Speter if (rv != KERN_SUCCESS) 554100384Speter return (EINVAL); 555100384Speter rv = vm_map_find(map, 0, 0, 556100384Speter &start, end - start, FALSE, 557100384Speter prot, VM_PROT_ALL, 0); 558100384Speter if (rv != KERN_SUCCESS) 559100384Speter return (EINVAL); 560107849Salfred r.fd = fd; 561107849Salfred r.buf = (void *) start; 562107849Salfred r.nbyte = end - start; 563107849Salfred r.offset = pos; 564100384Speter error = pread(td, &r); 565100384Speter if (error) 566100384Speter return (error); 567100384Speter 568100384Speter td->td_retval[0] = addr; 569100384Speter return (0); 570100384Speter } 571100384Speter if (end == start) { 572100384Speter /* 573100384Speter * After dealing with the ragged ends, there 574100384Speter * might be none left. 575100384Speter */ 576100384Speter td->td_retval[0] = addr; 577100384Speter return (0); 578100384Speter } 579100384Speter addr = start; 580100384Speter len = end - start; 581100384Speter } 582114987Speter#endif 583100384Speter 584107849Salfred ap.addr = (void *) addr; 585107849Salfred ap.len = len; 586107849Salfred ap.prot = prot; 587107849Salfred ap.flags = flags; 588107849Salfred ap.fd = fd; 589107849Salfred ap.pos = pos; 590100384Speter 591100384Speter return (mmap(td, &ap)); 592100384Speter} 593100384Speter 594100384Speterstruct itimerval32 { 595100384Speter struct timeval32 it_interval; 596100384Speter struct timeval32 it_value; 597100384Speter}; 598100384Speter 599121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 600121719Speter 601100384Speterint 602119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 603100384Speter{ 604100384Speter int error; 605100384Speter caddr_t sg; 606100384Speter struct itimerval32 *p32, *op32, s32; 607100384Speter struct itimerval *p = NULL, *op = NULL, s; 608100384Speter 609107849Salfred p32 = uap->itv; 610100384Speter if (p32) { 611100384Speter sg = stackgap_init(); 612100384Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 613107849Salfred uap->itv = (struct itimerval32 *)p; 614100384Speter error = copyin(p32, &s32, sizeof(s32)); 615100384Speter if (error) 616100384Speter return (error); 617100384Speter TV_CP(s32, s, it_interval); 618100384Speter TV_CP(s32, s, it_value); 619100384Speter error = copyout(&s, p, sizeof(s)); 620100384Speter if (error) 621100384Speter return (error); 622100384Speter } 623107849Salfred op32 = uap->oitv; 624100384Speter if (op32) { 625100384Speter sg = stackgap_init(); 626100384Speter op = stackgap_alloc(&sg, sizeof(struct itimerval)); 627107849Salfred uap->oitv = (struct itimerval32 *)op; 628100384Speter } 629100384Speter error = setitimer(td, (struct setitimer_args *) uap); 630100384Speter if (error) 631100384Speter return (error); 632100384Speter if (op32) { 633100384Speter error = copyin(op, &s, sizeof(s)); 634100384Speter if (error) 635100384Speter return (error); 636100384Speter TV_CP(s, s32, it_interval); 637100384Speter TV_CP(s, s32, it_value); 638100384Speter error = copyout(&s32, op32, sizeof(s32)); 639100384Speter } 640100384Speter return (error); 641100384Speter} 642100384Speter 643100384Speterint 644119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 645100384Speter{ 646100384Speter int error; 647100384Speter caddr_t sg; 648100384Speter struct timeval32 *p32, s32; 649100384Speter struct timeval *p = NULL, s; 650100384Speter 651107849Salfred p32 = uap->tv; 652100384Speter if (p32) { 653100384Speter sg = stackgap_init(); 654100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 655107849Salfred uap->tv = (struct timeval32 *)p; 656100384Speter error = copyin(p32, &s32, sizeof(s32)); 657100384Speter if (error) 658100384Speter return (error); 659100384Speter CP(s32, s, tv_sec); 660100384Speter CP(s32, s, tv_usec); 661100384Speter error = copyout(&s, p, sizeof(s)); 662100384Speter if (error) 663100384Speter return (error); 664100384Speter } 665100384Speter /* 666100384Speter * XXX big-endian needs to convert the fd_sets too. 667100384Speter */ 668100384Speter return (select(td, (struct select_args *) uap)); 669100384Speter} 670100384Speter 671114987Speterstruct kevent32 { 672114987Speter u_int32_t ident; /* identifier for this event */ 673114987Speter short filter; /* filter for event */ 674114987Speter u_short flags; 675114987Speter u_int fflags; 676114987Speter int32_t data; 677114987Speter u_int32_t udata; /* opaque user data identifier */ 678114987Speter}; 679114987Speter 680121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 681121719Speter 682100384Speterint 683119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 684114987Speter{ 685114987Speter int error; 686114987Speter caddr_t sg; 687114987Speter struct timespec32 ts32; 688114987Speter struct timespec ts; 689114987Speter struct kevent32 ks32; 690114987Speter struct kevent *ks; 691114987Speter struct kevent_args a; 692114987Speter int i; 693114987Speter 694114987Speter sg = stackgap_init(); 695114987Speter 696114987Speter a.fd = uap->fd; 697114987Speter a.changelist = uap->changelist; 698114987Speter a.nchanges = uap->nchanges; 699114987Speter a.eventlist = uap->eventlist; 700114987Speter a.nevents = uap->nevents; 701114987Speter a.timeout = NULL; 702114987Speter 703114987Speter if (uap->timeout) { 704114987Speter a.timeout = stackgap_alloc(&sg, sizeof(struct timespec)); 705114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 706114987Speter if (error) 707114987Speter return (error); 708114987Speter CP(ts32, ts, tv_sec); 709114987Speter CP(ts32, ts, tv_nsec); 710114987Speter error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts)); 711114987Speter if (error) 712114987Speter return (error); 713114987Speter } 714114987Speter if (uap->changelist) { 715119333Speter a.changelist = (struct kevent *)stackgap_alloc(&sg, 716119333Speter uap->nchanges * sizeof(struct kevent)); 717114987Speter for (i = 0; i < uap->nchanges; i++) { 718119333Speter error = copyin(&uap->changelist[i], &ks32, 719119333Speter sizeof(ks32)); 720114987Speter if (error) 721114987Speter return (error); 722114987Speter ks = (struct kevent *)(uintptr_t)&a.changelist[i]; 723114987Speter CP(ks32, *ks, ident); 724114987Speter CP(ks32, *ks, filter); 725114987Speter CP(ks32, *ks, flags); 726114987Speter CP(ks32, *ks, fflags); 727114987Speter CP(ks32, *ks, data); 728114987Speter PTRIN_CP(ks32, *ks, udata); 729114987Speter } 730114987Speter } 731114987Speter if (uap->eventlist) { 732119333Speter a.eventlist = stackgap_alloc(&sg, 733119333Speter uap->nevents * sizeof(struct kevent)); 734114987Speter } 735114987Speter error = kevent(td, &a); 736114987Speter if (uap->eventlist && error > 0) { 737114987Speter for (i = 0; i < error; i++) { 738114987Speter ks = &a.eventlist[i]; 739114987Speter CP(*ks, ks32, ident); 740114987Speter CP(*ks, ks32, filter); 741114987Speter CP(*ks, ks32, flags); 742114987Speter CP(*ks, ks32, fflags); 743114987Speter CP(*ks, ks32, data); 744114987Speter PTROUT_CP(*ks, ks32, udata); 745119333Speter error = copyout(&ks32, &uap->eventlist[i], 746119333Speter sizeof(ks32)); 747114987Speter if (error) 748114987Speter return (error); 749114987Speter } 750114987Speter } 751114987Speter return error; 752114987Speter} 753114987Speter 754114987Speterint 755119333Speterfreebsd32_gettimeofday(struct thread *td, 756119333Speter struct freebsd32_gettimeofday_args *uap) 757100384Speter{ 758100384Speter int error; 759100384Speter caddr_t sg; 760100384Speter struct timeval32 *p32, s32; 761100384Speter struct timeval *p = NULL, s; 762100384Speter 763107849Salfred p32 = uap->tp; 764100384Speter if (p32) { 765100384Speter sg = stackgap_init(); 766100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 767107849Salfred uap->tp = (struct timeval32 *)p; 768100384Speter } 769100384Speter error = gettimeofday(td, (struct gettimeofday_args *) uap); 770100384Speter if (error) 771100384Speter return (error); 772100384Speter if (p32) { 773100384Speter error = copyin(p, &s, sizeof(s)); 774100384Speter if (error) 775100384Speter return (error); 776100384Speter CP(s, s32, tv_sec); 777100384Speter CP(s, s32, tv_usec); 778100384Speter error = copyout(&s32, p32, sizeof(s32)); 779100384Speter if (error) 780100384Speter return (error); 781100384Speter } 782100384Speter return (error); 783100384Speter} 784100384Speter 785100384Speterint 786119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 787100384Speter{ 788100384Speter int error; 789100384Speter caddr_t sg; 790100384Speter struct rusage32 *p32, s32; 791100384Speter struct rusage *p = NULL, s; 792100384Speter 793107849Salfred p32 = uap->rusage; 794100384Speter if (p32) { 795100384Speter sg = stackgap_init(); 796100384Speter p = stackgap_alloc(&sg, sizeof(struct rusage)); 797107849Salfred uap->rusage = (struct rusage32 *)p; 798100384Speter } 799100384Speter error = getrusage(td, (struct getrusage_args *) uap); 800100384Speter if (error) 801100384Speter return (error); 802100384Speter if (p32) { 803100384Speter error = copyin(p, &s, sizeof(s)); 804100384Speter if (error) 805100384Speter return (error); 806100384Speter TV_CP(s, s32, ru_utime); 807100384Speter TV_CP(s, s32, ru_stime); 808100384Speter CP(s, s32, ru_maxrss); 809100384Speter CP(s, s32, ru_ixrss); 810100384Speter CP(s, s32, ru_idrss); 811100384Speter CP(s, s32, ru_isrss); 812100384Speter CP(s, s32, ru_minflt); 813100384Speter CP(s, s32, ru_majflt); 814100384Speter CP(s, s32, ru_nswap); 815100384Speter CP(s, s32, ru_inblock); 816100384Speter CP(s, s32, ru_oublock); 817100384Speter CP(s, s32, ru_msgsnd); 818100384Speter CP(s, s32, ru_msgrcv); 819100384Speter CP(s, s32, ru_nsignals); 820100384Speter CP(s, s32, ru_nvcsw); 821100384Speter CP(s, s32, ru_nivcsw); 822100384Speter error = copyout(&s32, p32, sizeof(s32)); 823100384Speter } 824100384Speter return (error); 825100384Speter} 826100384Speter 827100384Speterstruct iovec32 { 828100384Speter u_int32_t iov_base; 829100384Speter int iov_len; 830100384Speter}; 831100384Speter#define STACKGAPLEN 400 832100384Speter 833121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 834121719Speter 835100384Speterint 836119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 837100384Speter{ 838100384Speter int error, osize, nsize, i; 839100384Speter caddr_t sg; 840100384Speter struct readv_args /* { 841100384Speter syscallarg(int) fd; 842100384Speter syscallarg(struct iovec *) iovp; 843100384Speter syscallarg(u_int) iovcnt; 844100384Speter } */ a; 845100384Speter struct iovec32 *oio; 846100384Speter struct iovec *nio; 847100384Speter 848100384Speter sg = stackgap_init(); 849100384Speter 850107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 851100384Speter return (EINVAL); 852100384Speter 853107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 854107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 855100384Speter 856111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 857111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 858100384Speter 859100384Speter error = 0; 860107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 861100384Speter goto punt; 862107849Salfred for (i = 0; i < uap->iovcnt; i++) { 863100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 864100384Speter nio[i].iov_len = oio[i].iov_len; 865100384Speter } 866100384Speter 867107849Salfred a.fd = uap->fd; 868107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 869107849Salfred a.iovcnt = uap->iovcnt; 870100384Speter 871107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 872100384Speter goto punt; 873100384Speter error = readv(td, &a); 874100384Speter 875100384Speterpunt: 876100384Speter free(oio, M_TEMP); 877100384Speter free(nio, M_TEMP); 878100384Speter return (error); 879100384Speter} 880100384Speter 881100384Speterint 882119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 883100384Speter{ 884100384Speter int error, i, nsize, osize; 885100384Speter caddr_t sg; 886100384Speter struct writev_args /* { 887100384Speter syscallarg(int) fd; 888100384Speter syscallarg(struct iovec *) iovp; 889100384Speter syscallarg(u_int) iovcnt; 890100384Speter } */ a; 891100384Speter struct iovec32 *oio; 892100384Speter struct iovec *nio; 893100384Speter 894100384Speter sg = stackgap_init(); 895100384Speter 896107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 897100384Speter return (EINVAL); 898100384Speter 899107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 900107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 901100384Speter 902111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 903111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 904100384Speter 905100384Speter error = 0; 906107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 907100384Speter goto punt; 908107849Salfred for (i = 0; i < uap->iovcnt; i++) { 909100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 910100384Speter nio[i].iov_len = oio[i].iov_len; 911100384Speter } 912100384Speter 913107849Salfred a.fd = uap->fd; 914107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 915107849Salfred a.iovcnt = uap->iovcnt; 916100384Speter 917107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 918100384Speter goto punt; 919100384Speter error = writev(td, &a); 920100384Speter 921100384Speterpunt: 922100384Speter free(oio, M_TEMP); 923100384Speter free(nio, M_TEMP); 924100384Speter return (error); 925100384Speter} 926100384Speter 927100384Speterint 928119333Speterfreebsd32_settimeofday(struct thread *td, 929119333Speter struct freebsd32_settimeofday_args *uap) 930100384Speter{ 931100384Speter int error; 932100384Speter caddr_t sg; 933100384Speter struct timeval32 *p32, s32; 934100384Speter struct timeval *p = NULL, s; 935100384Speter 936107849Salfred p32 = uap->tv; 937100384Speter if (p32) { 938100384Speter sg = stackgap_init(); 939100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 940107849Salfred uap->tv = (struct timeval32 *)p; 941100384Speter error = copyin(p32, &s32, sizeof(s32)); 942100384Speter if (error) 943100384Speter return (error); 944100384Speter CP(s32, s, tv_sec); 945100384Speter CP(s32, s, tv_usec); 946100384Speter error = copyout(&s, p, sizeof(s)); 947100384Speter if (error) 948100384Speter return (error); 949100384Speter } 950100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 951100384Speter} 952100384Speter 953100384Speterint 954119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 955100384Speter{ 956100384Speter int error; 957100384Speter caddr_t sg; 958100384Speter struct timeval32 *p32, s32[2]; 959100384Speter struct timeval *p = NULL, s[2]; 960100384Speter 961107849Salfred p32 = uap->tptr; 962100384Speter if (p32) { 963100384Speter sg = stackgap_init(); 964100384Speter p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 965107849Salfred uap->tptr = (struct timeval32 *)p; 966100384Speter error = copyin(p32, s32, sizeof(s32)); 967100384Speter if (error) 968100384Speter return (error); 969100384Speter CP(s32[0], s[0], tv_sec); 970100384Speter CP(s32[0], s[0], tv_usec); 971100384Speter CP(s32[1], s[1], tv_sec); 972100384Speter CP(s32[1], s[1], tv_usec); 973100384Speter error = copyout(s, p, sizeof(s)); 974100384Speter if (error) 975100384Speter return (error); 976100384Speter } 977100384Speter return (utimes(td, (struct utimes_args *) uap)); 978100384Speter} 979100384Speter 980100384Speterint 981119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 982100384Speter{ 983100384Speter int error; 984100384Speter caddr_t sg; 985100384Speter struct timeval32 *p32, *op32, s32; 986100384Speter struct timeval *p = NULL, *op = NULL, s; 987100384Speter 988107849Salfred p32 = uap->delta; 989100384Speter if (p32) { 990100384Speter sg = stackgap_init(); 991100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 992107849Salfred uap->delta = (struct timeval32 *)p; 993100384Speter error = copyin(p32, &s32, sizeof(s32)); 994100384Speter if (error) 995100384Speter return (error); 996100384Speter CP(s32, s, tv_sec); 997100384Speter CP(s32, s, tv_usec); 998100384Speter error = copyout(&s, p, sizeof(s)); 999100384Speter if (error) 1000100384Speter return (error); 1001100384Speter } 1002107849Salfred op32 = uap->olddelta; 1003100384Speter if (op32) { 1004100384Speter sg = stackgap_init(); 1005100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 1006107849Salfred uap->olddelta = (struct timeval32 *)op; 1007100384Speter } 1008100384Speter error = utimes(td, (struct utimes_args *) uap); 1009100384Speter if (error) 1010100384Speter return error; 1011100384Speter if (op32) { 1012100384Speter error = copyin(op, &s, sizeof(s)); 1013100384Speter if (error) 1014100384Speter return (error); 1015100384Speter CP(s, s32, tv_sec); 1016100384Speter CP(s, s32, tv_usec); 1017100384Speter error = copyout(&s32, op32, sizeof(s32)); 1018100384Speter } 1019100384Speter return (error); 1020100384Speter} 1021100384Speter 1022100384Speterint 1023119333Speterfreebsd32_statfs(struct thread *td, struct freebsd32_statfs_args *uap) 1024100384Speter{ 1025100384Speter int error; 1026100384Speter caddr_t sg; 1027100384Speter struct statfs32 *p32, s32; 1028100384Speter struct statfs *p = NULL, s; 1029100384Speter 1030107849Salfred p32 = uap->buf; 1031100384Speter if (p32) { 1032100384Speter sg = stackgap_init(); 1033100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 1034107849Salfred uap->buf = (struct statfs32 *)p; 1035100384Speter } 1036100384Speter error = statfs(td, (struct statfs_args *) uap); 1037100384Speter if (error) 1038100384Speter return (error); 1039100384Speter if (p32) { 1040100384Speter error = copyin(p, &s, sizeof(s)); 1041100384Speter if (error) 1042100384Speter return (error); 1043100384Speter copy_statfs(&s, &s32); 1044100384Speter error = copyout(&s32, p32, sizeof(s32)); 1045100384Speter } 1046100384Speter return (error); 1047100384Speter} 1048100384Speter 1049100384Speterint 1050119333Speterfreebsd32_fstatfs(struct thread *td, struct freebsd32_fstatfs_args *uap) 1051100384Speter{ 1052100384Speter int error; 1053100384Speter caddr_t sg; 1054100384Speter struct statfs32 *p32, s32; 1055100384Speter struct statfs *p = NULL, s; 1056100384Speter 1057107849Salfred p32 = uap->buf; 1058100384Speter if (p32) { 1059100384Speter sg = stackgap_init(); 1060100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 1061107849Salfred uap->buf = (struct statfs32 *)p; 1062100384Speter } 1063100384Speter error = fstatfs(td, (struct fstatfs_args *) uap); 1064100384Speter if (error) 1065100384Speter return (error); 1066100384Speter if (p32) { 1067100384Speter error = copyin(p, &s, sizeof(s)); 1068100384Speter if (error) 1069100384Speter return (error); 1070100384Speter copy_statfs(&s, &s32); 1071100384Speter error = copyout(&s32, p32, sizeof(s32)); 1072100384Speter } 1073100384Speter return (error); 1074100384Speter} 1075100384Speter 1076100384Speterint 1077119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 1078100384Speter{ 1079100384Speter /* 1080100384Speter * Vector through to semsys if it is loaded. 1081100384Speter */ 1082100384Speter return sysent[169].sy_call(td, uap); 1083100384Speter} 1084100384Speter 1085100384Speterint 1086119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 1087100384Speter{ 1088100384Speter /* 1089100384Speter * Vector through to msgsys if it is loaded. 1090100384Speter */ 1091100384Speter return sysent[170].sy_call(td, uap); 1092100384Speter} 1093100384Speter 1094100384Speterint 1095119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 1096100384Speter{ 1097100384Speter /* 1098100384Speter * Vector through to shmsys if it is loaded. 1099100384Speter */ 1100100384Speter return sysent[171].sy_call(td, uap); 1101100384Speter} 1102100384Speter 1103100384Speterint 1104119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 1105100384Speter{ 1106100384Speter struct pread_args ap; 1107100384Speter 1108107849Salfred ap.fd = uap->fd; 1109107849Salfred ap.buf = uap->buf; 1110107849Salfred ap.nbyte = uap->nbyte; 1111119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1112100384Speter return (pread(td, &ap)); 1113100384Speter} 1114100384Speter 1115100384Speterint 1116119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 1117100384Speter{ 1118100384Speter struct pwrite_args ap; 1119100384Speter 1120107849Salfred ap.fd = uap->fd; 1121107849Salfred ap.buf = uap->buf; 1122107849Salfred ap.nbyte = uap->nbyte; 1123119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1124100384Speter return (pwrite(td, &ap)); 1125100384Speter} 1126100384Speter 1127100384Speterint 1128119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 1129100384Speter{ 1130100384Speter int error; 1131100384Speter struct lseek_args ap; 1132100384Speter off_t pos; 1133100384Speter 1134107849Salfred ap.fd = uap->fd; 1135119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1136107849Salfred ap.whence = uap->whence; 1137100384Speter error = lseek(td, &ap); 1138100384Speter /* Expand the quad return into two parts for eax and edx */ 1139100384Speter pos = *(off_t *)(td->td_retval); 1140100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1141100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1142100384Speter return error; 1143100384Speter} 1144100384Speter 1145100384Speterint 1146119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 1147100384Speter{ 1148100384Speter struct truncate_args ap; 1149100384Speter 1150107849Salfred ap.path = uap->path; 1151119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1152100384Speter return (truncate(td, &ap)); 1153100384Speter} 1154100384Speter 1155100384Speterint 1156119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1157100384Speter{ 1158100384Speter struct ftruncate_args ap; 1159100384Speter 1160107849Salfred ap.fd = uap->fd; 1161119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1162100384Speter return (ftruncate(td, &ap)); 1163100384Speter} 1164100384Speter 1165104738Speter#ifdef COMPAT_FREEBSD4 1166100384Speterint 1167119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1168119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1169104738Speter{ 1170104738Speter struct freebsd4_sendfile_args ap; 1171104738Speter 1172107849Salfred ap.fd = uap->fd; 1173107849Salfred ap.s = uap->s; 1174119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1175107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1176107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1177107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1178107849Salfred ap.flags = uap->flags; 1179104738Speter return (freebsd4_sendfile(td, &ap)); 1180104738Speter} 1181104738Speter#endif 1182104738Speter 1183104738Speterint 1184119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1185100384Speter{ 1186100384Speter struct sendfile_args ap; 1187100384Speter 1188107849Salfred ap.fd = uap->fd; 1189107849Salfred ap.s = uap->s; 1190119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1191107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1192107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1193107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1194107849Salfred ap.flags = uap->flags; 1195100384Speter return (sendfile(td, &ap)); 1196100384Speter} 1197100384Speter 1198100384Speterstruct stat32 { 1199100384Speter udev_t st_dev; 1200100384Speter ino_t st_ino; 1201100384Speter mode_t st_mode; 1202100384Speter nlink_t st_nlink; 1203100384Speter uid_t st_uid; 1204100384Speter gid_t st_gid; 1205100384Speter udev_t st_rdev; 1206100384Speter struct timespec32 st_atimespec; 1207100384Speter struct timespec32 st_mtimespec; 1208100384Speter struct timespec32 st_ctimespec; 1209100384Speter off_t st_size; 1210100384Speter int64_t st_blocks; 1211100384Speter u_int32_t st_blksize; 1212100384Speter u_int32_t st_flags; 1213100384Speter u_int32_t st_gen; 1214121719Speter struct timespec32 st_birthtimespec; 1215121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1216121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1217100384Speter}; 1218100384Speter 1219121719Speter 1220121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1221121719Speter 1222100384Speterstatic void 1223100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1224100384Speter{ 1225100384Speter CP(*in, *out, st_dev); 1226100384Speter CP(*in, *out, st_ino); 1227100384Speter CP(*in, *out, st_mode); 1228100384Speter CP(*in, *out, st_nlink); 1229100384Speter CP(*in, *out, st_uid); 1230100384Speter CP(*in, *out, st_gid); 1231100384Speter CP(*in, *out, st_rdev); 1232100384Speter TS_CP(*in, *out, st_atimespec); 1233100384Speter TS_CP(*in, *out, st_mtimespec); 1234100384Speter TS_CP(*in, *out, st_ctimespec); 1235100384Speter CP(*in, *out, st_size); 1236100384Speter CP(*in, *out, st_blocks); 1237100384Speter CP(*in, *out, st_blksize); 1238100384Speter CP(*in, *out, st_flags); 1239100384Speter CP(*in, *out, st_gen); 1240100384Speter} 1241100384Speter 1242100384Speterint 1243119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1244100384Speter{ 1245100384Speter int error; 1246100384Speter caddr_t sg; 1247100384Speter struct stat32 *p32, s32; 1248100384Speter struct stat *p = NULL, s; 1249100384Speter 1250107849Salfred p32 = uap->ub; 1251100384Speter if (p32) { 1252100384Speter sg = stackgap_init(); 1253100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1254107849Salfred uap->ub = (struct stat32 *)p; 1255100384Speter } 1256100384Speter error = stat(td, (struct stat_args *) uap); 1257100384Speter if (error) 1258100384Speter return (error); 1259100384Speter if (p32) { 1260100384Speter error = copyin(p, &s, sizeof(s)); 1261100384Speter if (error) 1262100384Speter return (error); 1263100384Speter copy_stat(&s, &s32); 1264100384Speter error = copyout(&s32, p32, sizeof(s32)); 1265100384Speter } 1266100384Speter return (error); 1267100384Speter} 1268100384Speter 1269100384Speterint 1270119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1271100384Speter{ 1272100384Speter int error; 1273100384Speter caddr_t sg; 1274100384Speter struct stat32 *p32, s32; 1275100384Speter struct stat *p = NULL, s; 1276100384Speter 1277107849Salfred p32 = uap->ub; 1278100384Speter if (p32) { 1279100384Speter sg = stackgap_init(); 1280100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1281107849Salfred uap->ub = (struct stat32 *)p; 1282100384Speter } 1283100384Speter error = fstat(td, (struct fstat_args *) uap); 1284100384Speter if (error) 1285100384Speter return (error); 1286100384Speter if (p32) { 1287100384Speter error = copyin(p, &s, sizeof(s)); 1288100384Speter if (error) 1289100384Speter return (error); 1290100384Speter copy_stat(&s, &s32); 1291100384Speter error = copyout(&s32, p32, sizeof(s32)); 1292100384Speter } 1293100384Speter return (error); 1294100384Speter} 1295100384Speter 1296100384Speterint 1297119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1298100384Speter{ 1299100384Speter int error; 1300100384Speter caddr_t sg; 1301100384Speter struct stat32 *p32, s32; 1302100384Speter struct stat *p = NULL, s; 1303100384Speter 1304107849Salfred p32 = uap->ub; 1305100384Speter if (p32) { 1306100384Speter sg = stackgap_init(); 1307100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1308107849Salfred uap->ub = (struct stat32 *)p; 1309100384Speter } 1310100384Speter error = lstat(td, (struct lstat_args *) uap); 1311100384Speter if (error) 1312100384Speter return (error); 1313100384Speter if (p32) { 1314100384Speter error = copyin(p, &s, sizeof(s)); 1315100384Speter if (error) 1316100384Speter return (error); 1317100384Speter copy_stat(&s, &s32); 1318100384Speter error = copyout(&s32, p32, sizeof(s32)); 1319100384Speter } 1320100384Speter return (error); 1321100384Speter} 1322100384Speter 1323100384Speter/* 1324100384Speter * MPSAFE 1325100384Speter */ 1326100384Speterint 1327119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1328100384Speter{ 1329100384Speter int error, name[CTL_MAXNAME]; 1330100384Speter size_t j, oldlen; 1331100384Speter 1332100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1333100384Speter return (EINVAL); 1334100384Speter 1335100384Speter error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1336100384Speter if (error) 1337100384Speter return (error); 1338100384Speter 1339100384Speter mtx_lock(&Giant); 1340100384Speter 1341100384Speter if (uap->oldlenp) 1342100384Speter oldlen = fuword32(uap->oldlenp); 1343100384Speter else 1344100384Speter oldlen = 0; 1345100384Speter error = userland_sysctl(td, name, uap->namelen, 1346100384Speter uap->old, &oldlen, 1, 1347100384Speter uap->new, uap->newlen, &j); 1348100384Speter if (error && error != ENOMEM) 1349100384Speter goto done2; 1350100384Speter if (uap->oldlenp) { 1351100384Speter suword32(uap->oldlenp, j); 1352100384Speter } 1353100384Speterdone2: 1354100384Speter mtx_unlock(&Giant); 1355100384Speter return (error); 1356100384Speter} 1357100384Speter 1358100384Speterstruct sigaction32 { 1359100384Speter u_int32_t sa_u; 1360100384Speter int sa_flags; 1361100384Speter sigset_t sa_mask; 1362100384Speter}; 1363100384Speter 1364121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1365121719Speter 1366100384Speterint 1367119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1368100384Speter{ 1369113859Sjhb struct sigaction32 s32; 1370113859Sjhb struct sigaction sa, osa, *sap; 1371100384Speter int error; 1372100384Speter 1373113859Sjhb if (uap->act) { 1374113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1375100384Speter if (error) 1376100384Speter return (error); 1377113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1378113859Sjhb CP(s32, sa, sa_flags); 1379113859Sjhb CP(s32, sa, sa_mask); 1380113859Sjhb sap = &sa; 1381113859Sjhb } else 1382113859Sjhb sap = NULL; 1383113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1384113859Sjhb if (error != 0 && uap->oact != NULL) { 1385113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1386113859Sjhb CP(osa, s32, sa_flags); 1387113859Sjhb CP(osa, s32, sa_mask); 1388113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1389100384Speter } 1390100384Speter return (error); 1391100384Speter} 1392100384Speter 1393114987Speter#ifdef COMPAT_FREEBSD4 1394114987Speterint 1395119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1396119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1397114987Speter{ 1398114987Speter struct sigaction32 s32; 1399114987Speter struct sigaction sa, osa, *sap; 1400114987Speter int error; 1401114987Speter 1402114987Speter if (uap->act) { 1403114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1404114987Speter if (error) 1405114987Speter return (error); 1406114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1407114987Speter CP(s32, sa, sa_flags); 1408114987Speter CP(s32, sa, sa_mask); 1409114987Speter sap = &sa; 1410114987Speter } else 1411114987Speter sap = NULL; 1412114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1413114987Speter if (error != 0 && uap->oact != NULL) { 1414114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1415114987Speter CP(osa, s32, sa_flags); 1416114987Speter CP(osa, s32, sa_mask); 1417114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1418114987Speter } 1419114987Speter return (error); 1420114987Speter} 1421114987Speter#endif 1422114987Speter 1423100384Speter#if 0 1424100384Speter 1425100384Speterint 1426119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1427100384Speter{ 1428100384Speter int error; 1429100384Speter caddr_t sg; 1430100384Speter struct yyy32 *p32, s32; 1431100384Speter struct yyy *p = NULL, s; 1432100384Speter 1433107849Salfred p32 = uap->zzz; 1434100384Speter if (p32) { 1435100384Speter sg = stackgap_init(); 1436100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1437107849Salfred uap->zzz = (struct yyy32 *)p; 1438100384Speter error = copyin(p32, &s32, sizeof(s32)); 1439100384Speter if (error) 1440100384Speter return (error); 1441100384Speter /* translate in */ 1442100384Speter error = copyout(&s, p, sizeof(s)); 1443100384Speter if (error) 1444100384Speter return (error); 1445100384Speter } 1446100384Speter error = xxx(td, (struct xxx_args *) uap); 1447100384Speter if (error) 1448100384Speter return (error); 1449100384Speter if (p32) { 1450100384Speter error = copyin(p, &s, sizeof(s)); 1451100384Speter if (error) 1452100384Speter return (error); 1453100384Speter /* translate out */ 1454100384Speter error = copyout(&s32, p32, sizeof(s32)); 1455100384Speter } 1456100384Speter return (error); 1457100384Speter} 1458100384Speter 1459100384Speter#endif 1460