freebsd32_misc.c revision 119333
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 119333 2003-08-22 23:07:28Z 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 82119333Speterextern const char freebsd32_emul_path[]; 83119333Speter 84100384Speter/* 85100384Speter * [ taken from the linux emulator ] 86100384Speter * Search an alternate path before passing pathname arguments on 87100384Speter * to system calls. Useful for keeping a separate 'emulation tree'. 88100384Speter * 89100384Speter * If cflag is set, we check if an attempt can be made to create 90100384Speter * the named file, i.e. we check if the directory it should 91100384Speter * be in exists. 92100384Speter */ 93100384Speterint 94119333Speterfreebsd32_emul_find(td, sgp, prefix, path, pbuf, cflag) 95100384Speter struct thread *td; 96100384Speter caddr_t *sgp; /* Pointer to stackgap memory */ 97100384Speter const char *prefix; 98100384Speter char *path; 99100384Speter char **pbuf; 100100384Speter int cflag; 101100384Speter{ 102100384Speter int error; 103100384Speter size_t len, sz; 104100384Speter char *buf, *cp, *ptr; 105100384Speter struct ucred *ucred; 106100384Speter struct nameidata nd; 107100384Speter struct nameidata ndroot; 108100384Speter struct vattr vat; 109100384Speter struct vattr vatroot; 110100384Speter 111111119Simp buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 112100384Speter *pbuf = path; 113100384Speter 114100384Speter for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) 115100384Speter continue; 116100384Speter 117100384Speter sz = MAXPATHLEN - (ptr - buf); 118100384Speter 119100384Speter /* 120100384Speter * If sgp is not given then the path is already in kernel space 121100384Speter */ 122100384Speter if (sgp == NULL) 123100384Speter error = copystr(path, ptr, sz, &len); 124100384Speter else 125100384Speter error = copyinstr(path, ptr, sz, &len); 126100384Speter 127100384Speter if (error) { 128100384Speter free(buf, M_TEMP); 129100384Speter return error; 130100384Speter } 131100384Speter 132100384Speter if (*ptr != '/') { 133100384Speter free(buf, M_TEMP); 134100384Speter return EINVAL; 135100384Speter } 136100384Speter 137100384Speter /* 138100384Speter * We know that there is a / somewhere in this pathname. 139100384Speter * Search backwards for it, to find the file's parent dir 140100384Speter * to see if it exists in the alternate tree. If it does, 141100384Speter * and we want to create a file (cflag is set). We don't 142100384Speter * need to worry about the root comparison in this case. 143100384Speter */ 144100384Speter 145100384Speter if (cflag) { 146100384Speter for (cp = &ptr[len] - 1; *cp != '/'; cp--) 147100384Speter ; 148100384Speter *cp = '\0'; 149100384Speter 150100384Speter NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 151100384Speter 152100384Speter if ((error = namei(&nd)) != 0) { 153100384Speter free(buf, M_TEMP); 154100384Speter return error; 155100384Speter } 156100384Speter 157100384Speter *cp = '/'; 158100384Speter } else { 159100384Speter NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 160100384Speter 161100384Speter if ((error = namei(&nd)) != 0) { 162100384Speter free(buf, M_TEMP); 163100384Speter return error; 164100384Speter } 165100384Speter 166100384Speter /* 167119333Speter * We now compare the vnode of the freebsd32_root to the one 168100384Speter * vnode asked. If they resolve to be the same, then we 169100384Speter * ignore the match so that the real root gets used. 170100384Speter * This avoids the problem of traversing "../.." to find the 171100384Speter * root directory and never finding it, because "/" resolves 172100384Speter * to the emulation root directory. This is expensive :-( 173100384Speter */ 174119333Speter NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, 175119333Speter freebsd32_emul_path, td); 176100384Speter 177100384Speter if ((error = namei(&ndroot)) != 0) { 178100384Speter /* Cannot happen! */ 179100384Speter free(buf, M_TEMP); 180100384Speter vrele(nd.ni_vp); 181100384Speter return error; 182100384Speter } 183100384Speter 184100384Speter ucred = td->td_ucred; 185100384Speter if ((error = VOP_GETATTR(nd.ni_vp, &vat, ucred, td)) != 0) { 186100384Speter goto bad; 187100384Speter } 188100384Speter 189100384Speter if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, ucred, 190100384Speter td)) != 0) { 191100384Speter goto bad; 192100384Speter } 193100384Speter 194100384Speter if (vat.va_fsid == vatroot.va_fsid && 195100384Speter vat.va_fileid == vatroot.va_fileid) { 196100384Speter error = ENOENT; 197100384Speter goto bad; 198100384Speter } 199100384Speter 200100384Speter } 201100384Speter if (sgp == NULL) 202100384Speter *pbuf = buf; 203100384Speter else { 204100384Speter sz = &ptr[len] - buf; 205100384Speter *pbuf = stackgap_alloc(sgp, sz + 1); 206100384Speter error = copyout(buf, *pbuf, sz); 207100384Speter free(buf, M_TEMP); 208100384Speter } 209100384Speter 210100384Speter vrele(nd.ni_vp); 211100384Speter if (!cflag) 212100384Speter vrele(ndroot.ni_vp); 213100384Speter 214100384Speter return error; 215100384Speter 216100384Speterbad: 217100384Speter vrele(ndroot.ni_vp); 218100384Speter vrele(nd.ni_vp); 219100384Speter free(buf, M_TEMP); 220100384Speter return error; 221100384Speter} 222100384Speter 223100384Speterint 224119333Speterfreebsd32_open(struct thread *td, struct freebsd32_open_args *uap) 225100384Speter{ 226100384Speter caddr_t sg; 227100384Speter 228100384Speter sg = stackgap_init(); 229100384Speter CHECKALTEXIST(td, &sg, uap->path); 230100384Speter 231100384Speter return open(td, (struct open_args *) uap); 232100384Speter} 233100384Speter 234100384Speterint 235119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 236100384Speter{ 237100384Speter int error; 238100384Speter caddr_t sg; 239100384Speter struct rusage32 *rusage32, ru32; 240100384Speter struct rusage *rusage = NULL, ru; 241100384Speter 242107849Salfred rusage32 = uap->rusage; 243100384Speter if (rusage32) { 244100384Speter sg = stackgap_init(); 245100384Speter rusage = stackgap_alloc(&sg, sizeof(struct rusage)); 246107849Salfred uap->rusage = (struct rusage32 *)rusage; 247100384Speter } 248100384Speter error = wait4(td, (struct wait_args *)uap); 249100384Speter if (error) 250100384Speter return (error); 251100384Speter if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) { 252100384Speter TV_CP(ru, ru32, ru_utime); 253100384Speter TV_CP(ru, ru32, ru_stime); 254100384Speter CP(ru, ru32, ru_maxrss); 255100384Speter CP(ru, ru32, ru_ixrss); 256100384Speter CP(ru, ru32, ru_idrss); 257100384Speter CP(ru, ru32, ru_isrss); 258100384Speter CP(ru, ru32, ru_minflt); 259100384Speter CP(ru, ru32, ru_majflt); 260100384Speter CP(ru, ru32, ru_nswap); 261100384Speter CP(ru, ru32, ru_inblock); 262100384Speter CP(ru, ru32, ru_oublock); 263100384Speter CP(ru, ru32, ru_msgsnd); 264100384Speter CP(ru, ru32, ru_msgrcv); 265100384Speter CP(ru, ru32, ru_nsignals); 266100384Speter CP(ru, ru32, ru_nvcsw); 267100384Speter CP(ru, ru32, ru_nivcsw); 268100384Speter error = copyout(&ru32, rusage32, sizeof(ru32)); 269100384Speter } 270100384Speter return (error); 271100384Speter} 272100384Speter 273100384Speterstatic void 274100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 275100384Speter{ 276100384Speter CP(*in, *out, f_bsize); 277100384Speter CP(*in, *out, f_iosize); 278100384Speter CP(*in, *out, f_blocks); 279100384Speter CP(*in, *out, f_bfree); 280100384Speter CP(*in, *out, f_bavail); 281100384Speter CP(*in, *out, f_files); 282100384Speter CP(*in, *out, f_ffree); 283100384Speter CP(*in, *out, f_fsid); 284100384Speter CP(*in, *out, f_owner); 285100384Speter CP(*in, *out, f_type); 286100384Speter CP(*in, *out, f_flags); 287100384Speter CP(*in, *out, f_flags); 288100384Speter CP(*in, *out, f_syncwrites); 289100384Speter CP(*in, *out, f_asyncwrites); 290100384Speter bcopy(in->f_fstypename, 291100384Speter out->f_fstypename, MFSNAMELEN); 292100384Speter bcopy(in->f_mntonname, 293100384Speter out->f_mntonname, MNAMELEN); 294100384Speter CP(*in, *out, f_syncreads); 295100384Speter CP(*in, *out, f_asyncreads); 296100384Speter bcopy(in->f_mntfromname, 297100384Speter out->f_mntfromname, MNAMELEN); 298100384Speter} 299100384Speter 300100384Speterint 301119333Speterfreebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap) 302100384Speter{ 303100384Speter int error; 304100384Speter caddr_t sg; 305100384Speter struct statfs32 *sp32, stat32; 306100384Speter struct statfs *sp = NULL, stat; 307100384Speter int maxcount, count, i; 308100384Speter 309107849Salfred sp32 = uap->buf; 310107849Salfred maxcount = uap->bufsize / sizeof(struct statfs32); 311100384Speter 312100384Speter if (sp32) { 313100384Speter sg = stackgap_init(); 314100384Speter sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 315107849Salfred uap->buf = (struct statfs32 *)sp; 316100384Speter } 317100384Speter error = getfsstat(td, (struct getfsstat_args *) uap); 318100384Speter if (sp32 && !error) { 319100384Speter count = td->td_retval[0]; 320100384Speter for (i = 0; i < count; i++) { 321100384Speter error = copyin(&sp[i], &stat, sizeof(stat)); 322100384Speter if (error) 323100384Speter return (error); 324100384Speter copy_statfs(&stat, &stat32); 325100384Speter error = copyout(&stat32, &sp32[i], sizeof(stat32)); 326100384Speter if (error) 327100384Speter return (error); 328100384Speter } 329100384Speter } 330100384Speter return (error); 331100384Speter} 332100384Speter 333100384Speterint 334119333Speterfreebsd32_access(struct thread *td, struct freebsd32_access_args *uap) 335100384Speter{ 336100384Speter caddr_t sg; 337100384Speter 338100384Speter sg = stackgap_init(); 339100384Speter CHECKALTEXIST(td, &sg, uap->path); 340100384Speter 341100384Speter return access(td, (struct access_args *)uap); 342100384Speter} 343100384Speter 344100384Speterint 345119333Speterfreebsd32_chflags(struct thread *td, struct freebsd32_chflags_args *uap) 346100384Speter{ 347100384Speter caddr_t sg; 348100384Speter 349100384Speter sg = stackgap_init(); 350100384Speter CHECKALTEXIST(td, &sg, uap->path); 351100384Speter 352100384Speter return chflags(td, (struct chflags_args *)uap); 353100384Speter} 354100384Speter 355100384Speterstruct sigaltstack32 { 356100384Speter u_int32_t ss_sp; 357100384Speter u_int32_t ss_size; 358100384Speter int ss_flags; 359100384Speter}; 360100384Speter 361100384Speterint 362119333Speterfreebsd32_sigaltstack(struct thread *td, 363119333Speter struct freebsd32_sigaltstack_args *uap) 364100384Speter{ 365113859Sjhb struct sigaltstack32 s32; 366113859Sjhb struct sigaltstack ss, oss, *ssp; 367100384Speter int error; 368100384Speter 369113859Sjhb if (uap->ss != NULL) { 370113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 371100384Speter if (error) 372100384Speter return (error); 373113859Sjhb PTRIN_CP(s32, ss, ss_sp); 374113859Sjhb CP(s32, ss, ss_size); 375113859Sjhb CP(s32, ss, ss_flags); 376113859Sjhb ssp = &ss; 377113859Sjhb } else 378113859Sjhb ssp = NULL; 379113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 380113859Sjhb if (error == 0 && uap->oss != NULL) { 381113859Sjhb PTROUT_CP(oss, s32, ss_sp); 382113859Sjhb CP(oss, s32, ss_size); 383113859Sjhb CP(oss, s32, ss_flags); 384113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 385100384Speter } 386100384Speter return (error); 387100384Speter} 388100384Speter 389100384Speterint 390119333Speterfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 391100384Speter{ 392100384Speter int error; 393100384Speter caddr_t sg; 394100384Speter struct execve_args ap; 395100384Speter u_int32_t *p32, arg; 396100384Speter char **p; 397100384Speter int count; 398100384Speter 399100384Speter sg = stackgap_init(); 400107849Salfred CHECKALTEXIST(td, &sg, uap->fname); 401107849Salfred ap.fname = uap->fname; 402100384Speter 403107849Salfred if (uap->argv) { 404100384Speter count = 0; 405107849Salfred p32 = uap->argv; 406100384Speter do { 407100384Speter error = copyin(p32++, &arg, sizeof(arg)); 408100384Speter if (error) 409100384Speter return error; 410100384Speter count++; 411100384Speter } while (arg != 0); 412100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 413107849Salfred ap.argv = p; 414107849Salfred p32 = uap->argv; 415100384Speter do { 416100384Speter error = copyin(p32++, &arg, sizeof(arg)); 417100384Speter if (error) 418100384Speter return error; 419100384Speter *p++ = PTRIN(arg); 420100384Speter } while (arg != 0); 421100384Speter } 422107849Salfred if (uap->envv) { 423100384Speter count = 0; 424107849Salfred p32 = uap->envv; 425100384Speter do { 426100384Speter error = copyin(p32++, &arg, sizeof(arg)); 427100384Speter if (error) 428100384Speter return error; 429100384Speter count++; 430100384Speter } while (arg != 0); 431100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 432107849Salfred ap.envv = p; 433107849Salfred p32 = uap->envv; 434100384Speter do { 435100384Speter error = copyin(p32++, &arg, sizeof(arg)); 436100384Speter if (error) 437100384Speter return error; 438100384Speter *p++ = PTRIN(arg); 439100384Speter } while (arg != 0); 440100384Speter } 441100384Speter 442100384Speter return execve(td, &ap); 443100384Speter} 444100384Speter 445114987Speter#ifdef __ia64__ 446100384Speterstatic int 447119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 448119333Speter int prot, int fd, off_t pos) 449100384Speter{ 450100384Speter vm_map_t map; 451100384Speter vm_map_entry_t entry; 452100384Speter int rv; 453100384Speter 454100384Speter map = &td->td_proc->p_vmspace->vm_map; 455100384Speter if (fd != -1) 456100384Speter prot |= VM_PROT_WRITE; 457100384Speter 458100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 459100384Speter if ((entry->protection & prot) != prot) { 460100384Speter rv = vm_map_protect(map, 461100384Speter trunc_page(start), 462100384Speter round_page(end), 463100384Speter entry->protection | prot, 464100384Speter FALSE); 465100384Speter if (rv != KERN_SUCCESS) 466100384Speter return (EINVAL); 467100384Speter } 468100384Speter } else { 469100384Speter vm_offset_t addr = trunc_page(start); 470100384Speter rv = vm_map_find(map, 0, 0, 471100384Speter &addr, PAGE_SIZE, FALSE, prot, 472100384Speter VM_PROT_ALL, 0); 473100384Speter if (rv != KERN_SUCCESS) 474100384Speter return (EINVAL); 475100384Speter } 476100384Speter 477100384Speter if (fd != -1) { 478100384Speter struct pread_args r; 479107849Salfred r.fd = fd; 480107849Salfred r.buf = (void *) start; 481107849Salfred r.nbyte = end - start; 482107849Salfred r.offset = pos; 483100384Speter return (pread(td, &r)); 484100384Speter } else { 485100384Speter while (start < end) { 486100384Speter subyte((void *) start, 0); 487100384Speter start++; 488100384Speter } 489100384Speter return (0); 490100384Speter } 491100384Speter} 492114987Speter#endif 493100384Speter 494100384Speterint 495119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 496100384Speter{ 497100384Speter struct mmap_args ap; 498107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 499107849Salfred vm_size_t len = uap->len; 500107849Salfred int prot = uap->prot; 501107849Salfred int flags = uap->flags; 502107849Salfred int fd = uap->fd; 503107849Salfred off_t pos = (uap->poslo 504107849Salfred | ((off_t)uap->poshi << 32)); 505114987Speter#ifdef __ia64__ 506100384Speter vm_size_t pageoff; 507100384Speter int error; 508100384Speter 509100384Speter /* 510100384Speter * Attempt to handle page size hassles. 511100384Speter */ 512100384Speter pageoff = (pos & PAGE_MASK); 513100384Speter if (flags & MAP_FIXED) { 514100384Speter vm_offset_t start, end; 515100384Speter start = addr; 516100384Speter end = addr + len; 517100384Speter 518100384Speter if (start != trunc_page(start)) { 519119333Speter error = freebsd32_mmap_partial(td, start, 520119333Speter round_page(start), prot, 521119333Speter fd, pos); 522100384Speter if (fd != -1) 523100384Speter pos += round_page(start) - start; 524100384Speter start = round_page(start); 525100384Speter } 526100384Speter if (end != round_page(end)) { 527100384Speter vm_offset_t t = trunc_page(end); 528119333Speter error = freebsd32_mmap_partial(td, t, end, 529100384Speter prot, fd, 530100384Speter pos + t - start); 531100384Speter end = trunc_page(end); 532100384Speter } 533100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 534100384Speter /* 535100384Speter * We can't map this region at all. The specified 536100384Speter * address doesn't have the same alignment as the file 537100384Speter * position. Fake the mapping by simply reading the 538100384Speter * entire region into memory. First we need to make 539100384Speter * sure the region exists. 540100384Speter */ 541100384Speter vm_map_t map; 542100384Speter struct pread_args r; 543100384Speter int rv; 544100384Speter 545100384Speter prot |= VM_PROT_WRITE; 546100384Speter map = &td->td_proc->p_vmspace->vm_map; 547100384Speter rv = vm_map_remove(map, start, end); 548100384Speter if (rv != KERN_SUCCESS) 549100384Speter return (EINVAL); 550100384Speter rv = vm_map_find(map, 0, 0, 551100384Speter &start, end - start, FALSE, 552100384Speter prot, VM_PROT_ALL, 0); 553100384Speter if (rv != KERN_SUCCESS) 554100384Speter return (EINVAL); 555107849Salfred r.fd = fd; 556107849Salfred r.buf = (void *) start; 557107849Salfred r.nbyte = end - start; 558107849Salfred r.offset = pos; 559100384Speter error = pread(td, &r); 560100384Speter if (error) 561100384Speter return (error); 562100384Speter 563100384Speter td->td_retval[0] = addr; 564100384Speter return (0); 565100384Speter } 566100384Speter if (end == start) { 567100384Speter /* 568100384Speter * After dealing with the ragged ends, there 569100384Speter * might be none left. 570100384Speter */ 571100384Speter td->td_retval[0] = addr; 572100384Speter return (0); 573100384Speter } 574100384Speter addr = start; 575100384Speter len = end - start; 576100384Speter } 577114987Speter#endif 578100384Speter 579107849Salfred ap.addr = (void *) addr; 580107849Salfred ap.len = len; 581107849Salfred ap.prot = prot; 582107849Salfred ap.flags = flags; 583107849Salfred ap.fd = fd; 584107849Salfred ap.pos = pos; 585100384Speter 586100384Speter return (mmap(td, &ap)); 587100384Speter} 588100384Speter 589100384Speterstruct itimerval32 { 590100384Speter struct timeval32 it_interval; 591100384Speter struct timeval32 it_value; 592100384Speter}; 593100384Speter 594100384Speterint 595119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 596100384Speter{ 597100384Speter int error; 598100384Speter caddr_t sg; 599100384Speter struct itimerval32 *p32, *op32, s32; 600100384Speter struct itimerval *p = NULL, *op = NULL, s; 601100384Speter 602107849Salfred p32 = uap->itv; 603100384Speter if (p32) { 604100384Speter sg = stackgap_init(); 605100384Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 606107849Salfred uap->itv = (struct itimerval32 *)p; 607100384Speter error = copyin(p32, &s32, sizeof(s32)); 608100384Speter if (error) 609100384Speter return (error); 610100384Speter TV_CP(s32, s, it_interval); 611100384Speter TV_CP(s32, s, it_value); 612100384Speter error = copyout(&s, p, sizeof(s)); 613100384Speter if (error) 614100384Speter return (error); 615100384Speter } 616107849Salfred op32 = uap->oitv; 617100384Speter if (op32) { 618100384Speter sg = stackgap_init(); 619100384Speter op = stackgap_alloc(&sg, sizeof(struct itimerval)); 620107849Salfred uap->oitv = (struct itimerval32 *)op; 621100384Speter } 622100384Speter error = setitimer(td, (struct setitimer_args *) uap); 623100384Speter if (error) 624100384Speter return (error); 625100384Speter if (op32) { 626100384Speter error = copyin(op, &s, sizeof(s)); 627100384Speter if (error) 628100384Speter return (error); 629100384Speter TV_CP(s, s32, it_interval); 630100384Speter TV_CP(s, s32, it_value); 631100384Speter error = copyout(&s32, op32, sizeof(s32)); 632100384Speter } 633100384Speter return (error); 634100384Speter} 635100384Speter 636100384Speterint 637119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 638100384Speter{ 639100384Speter int error; 640100384Speter caddr_t sg; 641100384Speter struct timeval32 *p32, s32; 642100384Speter struct timeval *p = NULL, s; 643100384Speter 644107849Salfred p32 = uap->tv; 645100384Speter if (p32) { 646100384Speter sg = stackgap_init(); 647100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 648107849Salfred uap->tv = (struct timeval32 *)p; 649100384Speter error = copyin(p32, &s32, sizeof(s32)); 650100384Speter if (error) 651100384Speter return (error); 652100384Speter CP(s32, s, tv_sec); 653100384Speter CP(s32, s, tv_usec); 654100384Speter error = copyout(&s, p, sizeof(s)); 655100384Speter if (error) 656100384Speter return (error); 657100384Speter } 658100384Speter /* 659100384Speter * XXX big-endian needs to convert the fd_sets too. 660100384Speter */ 661100384Speter return (select(td, (struct select_args *) uap)); 662100384Speter} 663100384Speter 664114987Speterstruct kevent32 { 665114987Speter u_int32_t ident; /* identifier for this event */ 666114987Speter short filter; /* filter for event */ 667114987Speter u_short flags; 668114987Speter u_int fflags; 669114987Speter int32_t data; 670114987Speter u_int32_t udata; /* opaque user data identifier */ 671114987Speter}; 672114987Speter 673100384Speterint 674119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 675114987Speter{ 676114987Speter int error; 677114987Speter caddr_t sg; 678114987Speter struct timespec32 ts32; 679114987Speter struct timespec ts; 680114987Speter struct kevent32 ks32; 681114987Speter struct kevent *ks; 682114987Speter struct kevent_args a; 683114987Speter int i; 684114987Speter 685114987Speter sg = stackgap_init(); 686114987Speter 687114987Speter a.fd = uap->fd; 688114987Speter a.changelist = uap->changelist; 689114987Speter a.nchanges = uap->nchanges; 690114987Speter a.eventlist = uap->eventlist; 691114987Speter a.nevents = uap->nevents; 692114987Speter a.timeout = NULL; 693114987Speter 694114987Speter if (uap->timeout) { 695114987Speter a.timeout = stackgap_alloc(&sg, sizeof(struct timespec)); 696114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 697114987Speter if (error) 698114987Speter return (error); 699114987Speter CP(ts32, ts, tv_sec); 700114987Speter CP(ts32, ts, tv_nsec); 701114987Speter error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts)); 702114987Speter if (error) 703114987Speter return (error); 704114987Speter } 705114987Speter if (uap->changelist) { 706119333Speter a.changelist = (struct kevent *)stackgap_alloc(&sg, 707119333Speter uap->nchanges * sizeof(struct kevent)); 708114987Speter for (i = 0; i < uap->nchanges; i++) { 709119333Speter error = copyin(&uap->changelist[i], &ks32, 710119333Speter sizeof(ks32)); 711114987Speter if (error) 712114987Speter return (error); 713114987Speter ks = (struct kevent *)(uintptr_t)&a.changelist[i]; 714114987Speter CP(ks32, *ks, ident); 715114987Speter CP(ks32, *ks, filter); 716114987Speter CP(ks32, *ks, flags); 717114987Speter CP(ks32, *ks, fflags); 718114987Speter CP(ks32, *ks, data); 719114987Speter PTRIN_CP(ks32, *ks, udata); 720114987Speter } 721114987Speter } 722114987Speter if (uap->eventlist) { 723119333Speter a.eventlist = stackgap_alloc(&sg, 724119333Speter uap->nevents * sizeof(struct kevent)); 725114987Speter } 726114987Speter error = kevent(td, &a); 727114987Speter if (uap->eventlist && error > 0) { 728114987Speter for (i = 0; i < error; i++) { 729114987Speter ks = &a.eventlist[i]; 730114987Speter CP(*ks, ks32, ident); 731114987Speter CP(*ks, ks32, filter); 732114987Speter CP(*ks, ks32, flags); 733114987Speter CP(*ks, ks32, fflags); 734114987Speter CP(*ks, ks32, data); 735114987Speter PTROUT_CP(*ks, ks32, udata); 736119333Speter error = copyout(&ks32, &uap->eventlist[i], 737119333Speter sizeof(ks32)); 738114987Speter if (error) 739114987Speter return (error); 740114987Speter } 741114987Speter } 742114987Speter return error; 743114987Speter} 744114987Speter 745114987Speterint 746119333Speterfreebsd32_gettimeofday(struct thread *td, 747119333Speter struct freebsd32_gettimeofday_args *uap) 748100384Speter{ 749100384Speter int error; 750100384Speter caddr_t sg; 751100384Speter struct timeval32 *p32, s32; 752100384Speter struct timeval *p = NULL, s; 753100384Speter 754107849Salfred p32 = uap->tp; 755100384Speter if (p32) { 756100384Speter sg = stackgap_init(); 757100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 758107849Salfred uap->tp = (struct timeval32 *)p; 759100384Speter } 760100384Speter error = gettimeofday(td, (struct gettimeofday_args *) uap); 761100384Speter if (error) 762100384Speter return (error); 763100384Speter if (p32) { 764100384Speter error = copyin(p, &s, sizeof(s)); 765100384Speter if (error) 766100384Speter return (error); 767100384Speter CP(s, s32, tv_sec); 768100384Speter CP(s, s32, tv_usec); 769100384Speter error = copyout(&s32, p32, sizeof(s32)); 770100384Speter if (error) 771100384Speter return (error); 772100384Speter } 773100384Speter return (error); 774100384Speter} 775100384Speter 776100384Speterint 777119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 778100384Speter{ 779100384Speter int error; 780100384Speter caddr_t sg; 781100384Speter struct rusage32 *p32, s32; 782100384Speter struct rusage *p = NULL, s; 783100384Speter 784107849Salfred p32 = uap->rusage; 785100384Speter if (p32) { 786100384Speter sg = stackgap_init(); 787100384Speter p = stackgap_alloc(&sg, sizeof(struct rusage)); 788107849Salfred uap->rusage = (struct rusage32 *)p; 789100384Speter } 790100384Speter error = getrusage(td, (struct getrusage_args *) uap); 791100384Speter if (error) 792100384Speter return (error); 793100384Speter if (p32) { 794100384Speter error = copyin(p, &s, sizeof(s)); 795100384Speter if (error) 796100384Speter return (error); 797100384Speter TV_CP(s, s32, ru_utime); 798100384Speter TV_CP(s, s32, ru_stime); 799100384Speter CP(s, s32, ru_maxrss); 800100384Speter CP(s, s32, ru_ixrss); 801100384Speter CP(s, s32, ru_idrss); 802100384Speter CP(s, s32, ru_isrss); 803100384Speter CP(s, s32, ru_minflt); 804100384Speter CP(s, s32, ru_majflt); 805100384Speter CP(s, s32, ru_nswap); 806100384Speter CP(s, s32, ru_inblock); 807100384Speter CP(s, s32, ru_oublock); 808100384Speter CP(s, s32, ru_msgsnd); 809100384Speter CP(s, s32, ru_msgrcv); 810100384Speter CP(s, s32, ru_nsignals); 811100384Speter CP(s, s32, ru_nvcsw); 812100384Speter CP(s, s32, ru_nivcsw); 813100384Speter error = copyout(&s32, p32, sizeof(s32)); 814100384Speter } 815100384Speter return (error); 816100384Speter} 817100384Speter 818100384Speterstruct iovec32 { 819100384Speter u_int32_t iov_base; 820100384Speter int iov_len; 821100384Speter}; 822100384Speter#define STACKGAPLEN 400 823100384Speter 824100384Speterint 825119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 826100384Speter{ 827100384Speter int error, osize, nsize, i; 828100384Speter caddr_t sg; 829100384Speter struct readv_args /* { 830100384Speter syscallarg(int) fd; 831100384Speter syscallarg(struct iovec *) iovp; 832100384Speter syscallarg(u_int) iovcnt; 833100384Speter } */ a; 834100384Speter struct iovec32 *oio; 835100384Speter struct iovec *nio; 836100384Speter 837100384Speter sg = stackgap_init(); 838100384Speter 839107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 840100384Speter return (EINVAL); 841100384Speter 842107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 843107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 844100384Speter 845111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 846111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 847100384Speter 848100384Speter error = 0; 849107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 850100384Speter goto punt; 851107849Salfred for (i = 0; i < uap->iovcnt; i++) { 852100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 853100384Speter nio[i].iov_len = oio[i].iov_len; 854100384Speter } 855100384Speter 856107849Salfred a.fd = uap->fd; 857107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 858107849Salfred a.iovcnt = uap->iovcnt; 859100384Speter 860107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 861100384Speter goto punt; 862100384Speter error = readv(td, &a); 863100384Speter 864100384Speterpunt: 865100384Speter free(oio, M_TEMP); 866100384Speter free(nio, M_TEMP); 867100384Speter return (error); 868100384Speter} 869100384Speter 870100384Speterint 871119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 872100384Speter{ 873100384Speter int error, i, nsize, osize; 874100384Speter caddr_t sg; 875100384Speter struct writev_args /* { 876100384Speter syscallarg(int) fd; 877100384Speter syscallarg(struct iovec *) iovp; 878100384Speter syscallarg(u_int) iovcnt; 879100384Speter } */ a; 880100384Speter struct iovec32 *oio; 881100384Speter struct iovec *nio; 882100384Speter 883100384Speter sg = stackgap_init(); 884100384Speter 885107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 886100384Speter return (EINVAL); 887100384Speter 888107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 889107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 890100384Speter 891111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 892111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 893100384Speter 894100384Speter error = 0; 895107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 896100384Speter goto punt; 897107849Salfred for (i = 0; i < uap->iovcnt; i++) { 898100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 899100384Speter nio[i].iov_len = oio[i].iov_len; 900100384Speter } 901100384Speter 902107849Salfred a.fd = uap->fd; 903107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 904107849Salfred a.iovcnt = uap->iovcnt; 905100384Speter 906107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 907100384Speter goto punt; 908100384Speter error = writev(td, &a); 909100384Speter 910100384Speterpunt: 911100384Speter free(oio, M_TEMP); 912100384Speter free(nio, M_TEMP); 913100384Speter return (error); 914100384Speter} 915100384Speter 916100384Speterint 917119333Speterfreebsd32_settimeofday(struct thread *td, 918119333Speter struct freebsd32_settimeofday_args *uap) 919100384Speter{ 920100384Speter int error; 921100384Speter caddr_t sg; 922100384Speter struct timeval32 *p32, s32; 923100384Speter struct timeval *p = NULL, s; 924100384Speter 925107849Salfred p32 = uap->tv; 926100384Speter if (p32) { 927100384Speter sg = stackgap_init(); 928100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 929107849Salfred uap->tv = (struct timeval32 *)p; 930100384Speter error = copyin(p32, &s32, sizeof(s32)); 931100384Speter if (error) 932100384Speter return (error); 933100384Speter CP(s32, s, tv_sec); 934100384Speter CP(s32, s, tv_usec); 935100384Speter error = copyout(&s, p, sizeof(s)); 936100384Speter if (error) 937100384Speter return (error); 938100384Speter } 939100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 940100384Speter} 941100384Speter 942100384Speterint 943119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 944100384Speter{ 945100384Speter int error; 946100384Speter caddr_t sg; 947100384Speter struct timeval32 *p32, s32[2]; 948100384Speter struct timeval *p = NULL, s[2]; 949100384Speter 950107849Salfred p32 = uap->tptr; 951100384Speter if (p32) { 952100384Speter sg = stackgap_init(); 953100384Speter p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 954107849Salfred uap->tptr = (struct timeval32 *)p; 955100384Speter error = copyin(p32, s32, sizeof(s32)); 956100384Speter if (error) 957100384Speter return (error); 958100384Speter CP(s32[0], s[0], tv_sec); 959100384Speter CP(s32[0], s[0], tv_usec); 960100384Speter CP(s32[1], s[1], tv_sec); 961100384Speter CP(s32[1], s[1], tv_usec); 962100384Speter error = copyout(s, p, sizeof(s)); 963100384Speter if (error) 964100384Speter return (error); 965100384Speter } 966100384Speter return (utimes(td, (struct utimes_args *) uap)); 967100384Speter} 968100384Speter 969100384Speterint 970119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 971100384Speter{ 972100384Speter int error; 973100384Speter caddr_t sg; 974100384Speter struct timeval32 *p32, *op32, s32; 975100384Speter struct timeval *p = NULL, *op = NULL, s; 976100384Speter 977107849Salfred p32 = uap->delta; 978100384Speter if (p32) { 979100384Speter sg = stackgap_init(); 980100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 981107849Salfred uap->delta = (struct timeval32 *)p; 982100384Speter error = copyin(p32, &s32, sizeof(s32)); 983100384Speter if (error) 984100384Speter return (error); 985100384Speter CP(s32, s, tv_sec); 986100384Speter CP(s32, s, tv_usec); 987100384Speter error = copyout(&s, p, sizeof(s)); 988100384Speter if (error) 989100384Speter return (error); 990100384Speter } 991107849Salfred op32 = uap->olddelta; 992100384Speter if (op32) { 993100384Speter sg = stackgap_init(); 994100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 995107849Salfred uap->olddelta = (struct timeval32 *)op; 996100384Speter } 997100384Speter error = utimes(td, (struct utimes_args *) uap); 998100384Speter if (error) 999100384Speter return error; 1000100384Speter if (op32) { 1001100384Speter error = copyin(op, &s, sizeof(s)); 1002100384Speter if (error) 1003100384Speter return (error); 1004100384Speter CP(s, s32, tv_sec); 1005100384Speter CP(s, s32, tv_usec); 1006100384Speter error = copyout(&s32, op32, sizeof(s32)); 1007100384Speter } 1008100384Speter return (error); 1009100384Speter} 1010100384Speter 1011100384Speterint 1012119333Speterfreebsd32_statfs(struct thread *td, struct freebsd32_statfs_args *uap) 1013100384Speter{ 1014100384Speter int error; 1015100384Speter caddr_t sg; 1016100384Speter struct statfs32 *p32, s32; 1017100384Speter struct statfs *p = NULL, s; 1018100384Speter 1019107849Salfred p32 = uap->buf; 1020100384Speter if (p32) { 1021100384Speter sg = stackgap_init(); 1022100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 1023107849Salfred uap->buf = (struct statfs32 *)p; 1024100384Speter } 1025100384Speter error = statfs(td, (struct statfs_args *) uap); 1026100384Speter if (error) 1027100384Speter return (error); 1028100384Speter if (p32) { 1029100384Speter error = copyin(p, &s, sizeof(s)); 1030100384Speter if (error) 1031100384Speter return (error); 1032100384Speter copy_statfs(&s, &s32); 1033100384Speter error = copyout(&s32, p32, sizeof(s32)); 1034100384Speter } 1035100384Speter return (error); 1036100384Speter} 1037100384Speter 1038100384Speterint 1039119333Speterfreebsd32_fstatfs(struct thread *td, struct freebsd32_fstatfs_args *uap) 1040100384Speter{ 1041100384Speter int error; 1042100384Speter caddr_t sg; 1043100384Speter struct statfs32 *p32, s32; 1044100384Speter struct statfs *p = NULL, s; 1045100384Speter 1046107849Salfred p32 = uap->buf; 1047100384Speter if (p32) { 1048100384Speter sg = stackgap_init(); 1049100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 1050107849Salfred uap->buf = (struct statfs32 *)p; 1051100384Speter } 1052100384Speter error = fstatfs(td, (struct fstatfs_args *) uap); 1053100384Speter if (error) 1054100384Speter return (error); 1055100384Speter if (p32) { 1056100384Speter error = copyin(p, &s, sizeof(s)); 1057100384Speter if (error) 1058100384Speter return (error); 1059100384Speter copy_statfs(&s, &s32); 1060100384Speter error = copyout(&s32, p32, sizeof(s32)); 1061100384Speter } 1062100384Speter return (error); 1063100384Speter} 1064100384Speter 1065100384Speterint 1066119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 1067100384Speter{ 1068100384Speter /* 1069100384Speter * Vector through to semsys if it is loaded. 1070100384Speter */ 1071100384Speter return sysent[169].sy_call(td, uap); 1072100384Speter} 1073100384Speter 1074100384Speterint 1075119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 1076100384Speter{ 1077100384Speter /* 1078100384Speter * Vector through to msgsys if it is loaded. 1079100384Speter */ 1080100384Speter return sysent[170].sy_call(td, uap); 1081100384Speter} 1082100384Speter 1083100384Speterint 1084119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 1085100384Speter{ 1086100384Speter /* 1087100384Speter * Vector through to shmsys if it is loaded. 1088100384Speter */ 1089100384Speter return sysent[171].sy_call(td, uap); 1090100384Speter} 1091100384Speter 1092100384Speterint 1093119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 1094100384Speter{ 1095100384Speter struct pread_args ap; 1096100384Speter 1097107849Salfred ap.fd = uap->fd; 1098107849Salfred ap.buf = uap->buf; 1099107849Salfred ap.nbyte = uap->nbyte; 1100119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1101100384Speter return (pread(td, &ap)); 1102100384Speter} 1103100384Speter 1104100384Speterint 1105119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 1106100384Speter{ 1107100384Speter struct pwrite_args ap; 1108100384Speter 1109107849Salfred ap.fd = uap->fd; 1110107849Salfred ap.buf = uap->buf; 1111107849Salfred ap.nbyte = uap->nbyte; 1112119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1113100384Speter return (pwrite(td, &ap)); 1114100384Speter} 1115100384Speter 1116100384Speterint 1117119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 1118100384Speter{ 1119100384Speter int error; 1120100384Speter struct lseek_args ap; 1121100384Speter off_t pos; 1122100384Speter 1123107849Salfred ap.fd = uap->fd; 1124119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1125107849Salfred ap.whence = uap->whence; 1126100384Speter error = lseek(td, &ap); 1127100384Speter /* Expand the quad return into two parts for eax and edx */ 1128100384Speter pos = *(off_t *)(td->td_retval); 1129100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1130100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1131100384Speter return error; 1132100384Speter} 1133100384Speter 1134100384Speterint 1135119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 1136100384Speter{ 1137100384Speter struct truncate_args ap; 1138100384Speter 1139107849Salfred ap.path = uap->path; 1140119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1141100384Speter return (truncate(td, &ap)); 1142100384Speter} 1143100384Speter 1144100384Speterint 1145119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1146100384Speter{ 1147100384Speter struct ftruncate_args ap; 1148100384Speter 1149107849Salfred ap.fd = uap->fd; 1150119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1151100384Speter return (ftruncate(td, &ap)); 1152100384Speter} 1153100384Speter 1154104738Speter#ifdef COMPAT_FREEBSD4 1155100384Speterint 1156119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1157119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1158104738Speter{ 1159104738Speter struct freebsd4_sendfile_args ap; 1160104738Speter 1161107849Salfred ap.fd = uap->fd; 1162107849Salfred ap.s = uap->s; 1163119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1164107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1165107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1166107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1167107849Salfred ap.flags = uap->flags; 1168104738Speter return (freebsd4_sendfile(td, &ap)); 1169104738Speter} 1170104738Speter#endif 1171104738Speter 1172104738Speterint 1173119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1174100384Speter{ 1175100384Speter struct sendfile_args ap; 1176100384Speter 1177107849Salfred ap.fd = uap->fd; 1178107849Salfred ap.s = uap->s; 1179119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1180107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1181107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1182107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1183107849Salfred ap.flags = uap->flags; 1184100384Speter return (sendfile(td, &ap)); 1185100384Speter} 1186100384Speter 1187100384Speterstruct stat32 { 1188100384Speter udev_t st_dev; 1189100384Speter ino_t st_ino; 1190100384Speter mode_t st_mode; 1191100384Speter nlink_t st_nlink; 1192100384Speter uid_t st_uid; 1193100384Speter gid_t st_gid; 1194100384Speter udev_t st_rdev; 1195100384Speter struct timespec32 st_atimespec; 1196100384Speter struct timespec32 st_mtimespec; 1197100384Speter struct timespec32 st_ctimespec; 1198100384Speter off_t st_size; 1199100384Speter int64_t st_blocks; 1200100384Speter u_int32_t st_blksize; 1201100384Speter u_int32_t st_flags; 1202100384Speter u_int32_t st_gen; 1203100384Speter}; 1204100384Speter 1205100384Speterstatic void 1206100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1207100384Speter{ 1208100384Speter CP(*in, *out, st_dev); 1209100384Speter CP(*in, *out, st_ino); 1210100384Speter CP(*in, *out, st_mode); 1211100384Speter CP(*in, *out, st_nlink); 1212100384Speter CP(*in, *out, st_uid); 1213100384Speter CP(*in, *out, st_gid); 1214100384Speter CP(*in, *out, st_rdev); 1215100384Speter TS_CP(*in, *out, st_atimespec); 1216100384Speter TS_CP(*in, *out, st_mtimespec); 1217100384Speter TS_CP(*in, *out, st_ctimespec); 1218100384Speter CP(*in, *out, st_size); 1219100384Speter CP(*in, *out, st_blocks); 1220100384Speter CP(*in, *out, st_blksize); 1221100384Speter CP(*in, *out, st_flags); 1222100384Speter CP(*in, *out, st_gen); 1223100384Speter} 1224100384Speter 1225100384Speterint 1226119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1227100384Speter{ 1228100384Speter int error; 1229100384Speter caddr_t sg; 1230100384Speter struct stat32 *p32, s32; 1231100384Speter struct stat *p = NULL, s; 1232100384Speter 1233107849Salfred p32 = uap->ub; 1234100384Speter if (p32) { 1235100384Speter sg = stackgap_init(); 1236100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1237107849Salfred uap->ub = (struct stat32 *)p; 1238100384Speter } 1239100384Speter error = stat(td, (struct stat_args *) uap); 1240100384Speter if (error) 1241100384Speter return (error); 1242100384Speter if (p32) { 1243100384Speter error = copyin(p, &s, sizeof(s)); 1244100384Speter if (error) 1245100384Speter return (error); 1246100384Speter copy_stat(&s, &s32); 1247100384Speter error = copyout(&s32, p32, sizeof(s32)); 1248100384Speter } 1249100384Speter return (error); 1250100384Speter} 1251100384Speter 1252100384Speterint 1253119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1254100384Speter{ 1255100384Speter int error; 1256100384Speter caddr_t sg; 1257100384Speter struct stat32 *p32, s32; 1258100384Speter struct stat *p = NULL, s; 1259100384Speter 1260107849Salfred p32 = uap->ub; 1261100384Speter if (p32) { 1262100384Speter sg = stackgap_init(); 1263100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1264107849Salfred uap->ub = (struct stat32 *)p; 1265100384Speter } 1266100384Speter error = fstat(td, (struct fstat_args *) uap); 1267100384Speter if (error) 1268100384Speter return (error); 1269100384Speter if (p32) { 1270100384Speter error = copyin(p, &s, sizeof(s)); 1271100384Speter if (error) 1272100384Speter return (error); 1273100384Speter copy_stat(&s, &s32); 1274100384Speter error = copyout(&s32, p32, sizeof(s32)); 1275100384Speter } 1276100384Speter return (error); 1277100384Speter} 1278100384Speter 1279100384Speterint 1280119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1281100384Speter{ 1282100384Speter int error; 1283100384Speter caddr_t sg; 1284100384Speter struct stat32 *p32, s32; 1285100384Speter struct stat *p = NULL, s; 1286100384Speter 1287107849Salfred p32 = uap->ub; 1288100384Speter if (p32) { 1289100384Speter sg = stackgap_init(); 1290100384Speter p = stackgap_alloc(&sg, sizeof(struct stat)); 1291107849Salfred uap->ub = (struct stat32 *)p; 1292100384Speter } 1293100384Speter error = lstat(td, (struct lstat_args *) uap); 1294100384Speter if (error) 1295100384Speter return (error); 1296100384Speter if (p32) { 1297100384Speter error = copyin(p, &s, sizeof(s)); 1298100384Speter if (error) 1299100384Speter return (error); 1300100384Speter copy_stat(&s, &s32); 1301100384Speter error = copyout(&s32, p32, sizeof(s32)); 1302100384Speter } 1303100384Speter return (error); 1304100384Speter} 1305100384Speter 1306100384Speter/* 1307100384Speter * MPSAFE 1308100384Speter */ 1309100384Speterint 1310119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1311100384Speter{ 1312100384Speter int error, name[CTL_MAXNAME]; 1313100384Speter size_t j, oldlen; 1314100384Speter 1315100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1316100384Speter return (EINVAL); 1317100384Speter 1318100384Speter error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1319100384Speter if (error) 1320100384Speter return (error); 1321100384Speter 1322100384Speter mtx_lock(&Giant); 1323100384Speter 1324100384Speter if (uap->oldlenp) 1325100384Speter oldlen = fuword32(uap->oldlenp); 1326100384Speter else 1327100384Speter oldlen = 0; 1328100384Speter error = userland_sysctl(td, name, uap->namelen, 1329100384Speter uap->old, &oldlen, 1, 1330100384Speter uap->new, uap->newlen, &j); 1331100384Speter if (error && error != ENOMEM) 1332100384Speter goto done2; 1333100384Speter if (uap->oldlenp) { 1334100384Speter suword32(uap->oldlenp, j); 1335100384Speter } 1336100384Speterdone2: 1337100384Speter mtx_unlock(&Giant); 1338100384Speter return (error); 1339100384Speter} 1340100384Speter 1341100384Speterstruct sigaction32 { 1342100384Speter u_int32_t sa_u; 1343100384Speter int sa_flags; 1344100384Speter sigset_t sa_mask; 1345100384Speter}; 1346100384Speter 1347100384Speterint 1348119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1349100384Speter{ 1350113859Sjhb struct sigaction32 s32; 1351113859Sjhb struct sigaction sa, osa, *sap; 1352100384Speter int error; 1353100384Speter 1354113859Sjhb if (uap->act) { 1355113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1356100384Speter if (error) 1357100384Speter return (error); 1358113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1359113859Sjhb CP(s32, sa, sa_flags); 1360113859Sjhb CP(s32, sa, sa_mask); 1361113859Sjhb sap = &sa; 1362113859Sjhb } else 1363113859Sjhb sap = NULL; 1364113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1365113859Sjhb if (error != 0 && uap->oact != NULL) { 1366113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1367113859Sjhb CP(osa, s32, sa_flags); 1368113859Sjhb CP(osa, s32, sa_mask); 1369113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1370100384Speter } 1371100384Speter return (error); 1372100384Speter} 1373100384Speter 1374114987Speter#ifdef COMPAT_FREEBSD4 1375114987Speterint 1376119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1377119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1378114987Speter{ 1379114987Speter struct sigaction32 s32; 1380114987Speter struct sigaction sa, osa, *sap; 1381114987Speter int error; 1382114987Speter 1383114987Speter if (uap->act) { 1384114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1385114987Speter if (error) 1386114987Speter return (error); 1387114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1388114987Speter CP(s32, sa, sa_flags); 1389114987Speter CP(s32, sa, sa_mask); 1390114987Speter sap = &sa; 1391114987Speter } else 1392114987Speter sap = NULL; 1393114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1394114987Speter if (error != 0 && uap->oact != NULL) { 1395114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1396114987Speter CP(osa, s32, sa_flags); 1397114987Speter CP(osa, s32, sa_mask); 1398114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1399114987Speter } 1400114987Speter return (error); 1401114987Speter} 1402114987Speter#endif 1403114987Speter 1404100384Speter#if 0 1405100384Speter 1406100384Speterint 1407119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1408100384Speter{ 1409100384Speter int error; 1410100384Speter caddr_t sg; 1411100384Speter struct yyy32 *p32, s32; 1412100384Speter struct yyy *p = NULL, s; 1413100384Speter 1414107849Salfred p32 = uap->zzz; 1415100384Speter if (p32) { 1416100384Speter sg = stackgap_init(); 1417100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1418107849Salfred uap->zzz = (struct yyy32 *)p; 1419100384Speter error = copyin(p32, &s32, sizeof(s32)); 1420100384Speter if (error) 1421100384Speter return (error); 1422100384Speter /* translate in */ 1423100384Speter error = copyout(&s, p, sizeof(s)); 1424100384Speter if (error) 1425100384Speter return (error); 1426100384Speter } 1427100384Speter error = xxx(td, (struct xxx_args *) uap); 1428100384Speter if (error) 1429100384Speter return (error); 1430100384Speter if (p32) { 1431100384Speter error = copyin(p, &s, sizeof(s)); 1432100384Speter if (error) 1433100384Speter return (error); 1434100384Speter /* translate out */ 1435100384Speter error = copyout(&s32, p32, sizeof(s32)); 1436100384Speter } 1437100384Speter return (error); 1438100384Speter} 1439100384Speter 1440100384Speter#endif 1441